Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Side by Side Diff: net/http/http_cache_transaction.cc

Issue 2922973003: RFC: use some in-memory state in SimpleCache to quickly cache-miss some CantConditionalize cases
Patch Set: Rebase Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/http/http_cache_transaction.h ('k') | net/http/http_cache_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_cache_transaction.h" 5 #include "net/http/http_cache_transaction.h"
6 6
7 #include "build/build_config.h" // For OS_POSIX 7 #include "build/build_config.h" // For OS_POSIX
8 8
9 #if defined(OS_POSIX) 9 #if defined(OS_POSIX)
10 #include <unistd.h> 10 #include <unistd.h>
(...skipping 2418 matching lines...) Expand 10 before | Expand all | Expand 10 after
2429 stale_entry_freshness_ = lifetimes.freshness; 2429 stale_entry_freshness_ = lifetimes.freshness;
2430 stale_entry_age_ = response_.headers->GetCurrentAge( 2430 stale_entry_age_ = response_.headers->GetCurrentAge(
2431 response_.request_time, response_.response_time, 2431 response_.request_time, response_.response_time,
2432 cache_->clock_->Now()); 2432 cache_->clock_->Now());
2433 } 2433 }
2434 } 2434 }
2435 2435
2436 return validation_required_by_headers; 2436 return validation_required_by_headers;
2437 } 2437 }
2438 2438
2439 bool HttpCache::Transaction::ResponseConditionalizable(
2440 std::string* etag_value,
2441 std::string* last_modified_value) {
2442 DCHECK(response_.headers.get());
2443
2444 // This only makes sense for cached 200 or 206 responses.
2445 if (response_.headers->response_code() != 200 &&
2446 response_.headers->response_code() != 206) {
2447 return false;
2448 }
2449
2450 // ### this looks scary.
2451 DCHECK(response_.headers->response_code() != 206 ||
2452 response_.headers->HasStrongValidators());
2453
2454 // Just use the first available ETag and/or Last-Modified header value.
2455 // TODO(darin): Or should we use the last?
2456
2457 if (response_.headers->GetHttpVersion() >= HttpVersion(1, 1))
2458 response_.headers->EnumerateHeader(NULL, "etag", etag_value);
2459
2460 response_.headers->EnumerateHeader(NULL, "last-modified",
2461 last_modified_value);
2462
2463 if (etag_value->empty() && last_modified_value->empty())
2464 return false;
2465
2466 return true;
2467 }
2468
2439 bool HttpCache::Transaction::ConditionalizeRequest() { 2469 bool HttpCache::Transaction::ConditionalizeRequest() {
2440 DCHECK(response_.headers.get()); 2470 DCHECK(response_.headers.get());
2441 2471
2442 if (method_ == "PUT" || method_ == "DELETE") 2472 if (method_ == "PUT" || method_ == "DELETE")
2443 return false; 2473 return false;
2444 2474
2445 // This only makes sense for cached 200 or 206 responses.
2446 if (response_.headers->response_code() != 200 &&
2447 response_.headers->response_code() != 206) {
2448 return false;
2449 }
2450
2451 if (fail_conditionalization_for_test_) 2475 if (fail_conditionalization_for_test_)
2452 return false; 2476 return false;
2453 2477
2454 DCHECK(response_.headers->response_code() != 206 || 2478 std::string etag_value;
2455 response_.headers->HasStrongValidators()); 2479 std::string last_modified_value;
2480 if (!ResponseConditionalizable(&etag_value, &last_modified_value))
2481 return false;
2456 2482
2457 // Just use the first available ETag and/or Last-Modified header value. 2483 if (vary_mismatch_) {
2458 // TODO(darin): Or should we use the last? 2484 // Can't rely on last-modified if vary is different.
2459 2485 last_modified_value.clear();
2460 std::string etag_value; 2486 if (etag_value.empty())
2461 if (response_.headers->GetHttpVersion() >= HttpVersion(1, 1)) 2487 return false;
2462 response_.headers->EnumerateHeader(NULL, "etag", &etag_value);
2463
2464 std::string last_modified_value;
2465 if (!vary_mismatch_) {
2466 response_.headers->EnumerateHeader(NULL, "last-modified",
2467 &last_modified_value);
2468 } 2488 }
2469 2489
2470 if (etag_value.empty() && last_modified_value.empty())
2471 return false;
2472
2473 if (!partial_) { 2490 if (!partial_) {
2474 // Need to customize the request, so this forces us to allocate :( 2491 // Need to customize the request, so this forces us to allocate :(
2475 custom_request_.reset(new HttpRequestInfo(*request_)); 2492 custom_request_.reset(new HttpRequestInfo(*request_));
2476 request_ = custom_request_.get(); 2493 request_ = custom_request_.get();
2477 } 2494 }
2478 DCHECK(custom_request_.get()); 2495 DCHECK(custom_request_.get());
2479 2496
2480 bool use_if_range = 2497 bool use_if_range =
2481 partial_ && !partial_->IsCurrentRangeCached() && !invalid_range_; 2498 partial_ && !partial_->IsCurrentRangeCached() && !invalid_range_;
2482 2499
(...skipping 19 matching lines...) Expand all
2502 HttpRequestHeaders::kIfRange, last_modified_value); 2519 HttpRequestHeaders::kIfRange, last_modified_value);
2503 } else { 2520 } else {
2504 custom_request_->extra_headers.SetHeader( 2521 custom_request_->extra_headers.SetHeader(
2505 HttpRequestHeaders::kIfModifiedSince, last_modified_value); 2522 HttpRequestHeaders::kIfModifiedSince, last_modified_value);
2506 } 2523 }
2507 } 2524 }
2508 2525
2509 return true; 2526 return true;
2510 } 2527 }
2511 2528
2529 bool HttpCache::Transaction::MaybeRejectBasedOnMemoryEntryData(
2530 uint8_t in_memory_info) {
2531 // Not going to be clever with those... though is it even set here?
2532 if (partial_)
2533 return false;
2534
2535 // We can tell that some entries in cache may be unusable under present
2536 // circumstances if:
2537 // 1) We aren't using everything because of LOAD_SKIP_CACHE_VALIDATION.
2538 // 2) We aren't holding on to results of an unused prefetch.
2539 // 3) The entry has zero freshness (so it's known to be expired!)
2540 // 4) We know the entry can't be revalidated
2541 // (we may be able to match more things here).
2542 if (effective_load_flags_ & LOAD_SKIP_CACHE_VALIDATION)
2543 return false;
2544
2545 if (in_memory_info & HttpCache::OBH_UNUSED_SINCE_PREFETCH)
2546 return false;
2547
2548 if (!(in_memory_info & HttpCache::OBH_ZERO_LIFETIME))
2549 return false;
2550
2551 if (!(in_memory_info & OBH_RESPONSE_CANT_CONDITIONALIZE))
2552 return false;
2553
2554 cache_pending_ = false;
2555 couldnt_conditionalize_request_ = true;
2556 response_.was_cached = true;
2557 UpdateCacheEntryStatus(CacheEntryStatus::ENTRY_CANT_CONDITIONALIZE);
2558 // ### ugh, this is bad, but just sketching.
2559 // TransitionToState(STATE_SEND_REQUEST);
2560 next_state_ = STATE_SEND_REQUEST;
Maks Orlovich 2017/06/14 19:59:29 So I just realized that this implementation is bog
2561
2562 return true;
2563 }
2564
2512 // We just received some headers from the server. We may have asked for a range, 2565 // We just received some headers from the server. We may have asked for a range,
2513 // in which case partial_ has an object. This could be the first network request 2566 // in which case partial_ has an object. This could be the first network request
2514 // we make to fulfill the original request, or we may be already reading (from 2567 // we make to fulfill the original request, or we may be already reading (from
2515 // the net and / or the cache). If we are not expecting a certain response, we 2568 // the net and / or the cache). If we are not expecting a certain response, we
2516 // just bypass the cache for this request (but again, maybe we are reading), and 2569 // just bypass the cache for this request (but again, maybe we are reading), and
2517 // delete partial_ (so we are not able to "fix" the headers that we return to 2570 // delete partial_ (so we are not able to "fix" the headers that we return to
2518 // the user). This results in either a weird response for the caller (we don't 2571 // the user). This results in either a weird response for the caller (we don't
2519 // expect it after all), or maybe a range that was not exactly what it was asked 2572 // expect it after all), or maybe a range that was not exactly what it was asked
2520 // for. 2573 // for.
2521 // 2574 //
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
2724 if (truncated) 2777 if (truncated)
2725 DCHECK_EQ(200, response_.headers->response_code()); 2778 DCHECK_EQ(200, response_.headers->response_code());
2726 2779
2727 // When writing headers, we normally only write the non-transient headers. 2780 // When writing headers, we normally only write the non-transient headers.
2728 bool skip_transient_headers = true; 2781 bool skip_transient_headers = true;
2729 scoped_refptr<PickledIOBuffer> data(new PickledIOBuffer()); 2782 scoped_refptr<PickledIOBuffer> data(new PickledIOBuffer());
2730 response_.Persist(data->pickle(), skip_transient_headers, truncated); 2783 response_.Persist(data->pickle(), skip_transient_headers, truncated);
2731 data->Done(); 2784 data->Done();
2732 2785
2733 io_buf_len_ = data->pickle()->size(); 2786 io_buf_len_ = data->pickle()->size();
2787
2788 uint8_t hints = 0;
2789 // ### recomputing this too much?
2790 if (response_.headers->GetFreshnessLifetimes(response_.response_time)
2791 .freshness.is_zero())
2792 hints |= HttpCache::OBH_ZERO_LIFETIME;
2793 std::string etag_ignored, last_modified_ignored;
2794 if (!ResponseConditionalizable(&etag_ignored, &last_modified_ignored))
2795 hints |= HttpCache::OBH_RESPONSE_CANT_CONDITIONALIZE;
2796 if (response_.unused_since_prefetch)
2797 hints |= HttpCache::OBH_UNUSED_SINCE_PREFETCH;
2798 cache_->GetCurrentBackend()->SetMemoryEntryData(cache_key_, hints);
2734 return entry_->disk_entry->WriteData(kResponseInfoIndex, 0, data.get(), 2799 return entry_->disk_entry->WriteData(kResponseInfoIndex, 0, data.get(),
2735 io_buf_len_, io_callback_, true); 2800 io_buf_len_, io_callback_, true);
2736 } 2801 }
2737 2802
2738 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) { 2803 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) {
2739 if (!entry_) 2804 if (!entry_)
2740 return OK; 2805 return OK;
2741 if (net_log_.IsCapturing()) { 2806 if (net_log_.IsCapturing()) {
2742 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, 2807 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO,
2743 result); 2808 result);
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
3124 } 3189 }
3125 3190
3126 void HttpCache::Transaction::TransitionToState(State state) { 3191 void HttpCache::Transaction::TransitionToState(State state) {
3127 // Ensure that the state is only set once per Do* state. 3192 // Ensure that the state is only set once per Do* state.
3128 DCHECK(in_do_loop_); 3193 DCHECK(in_do_loop_);
3129 DCHECK_EQ(STATE_UNSET, next_state_) << "Next state is " << state; 3194 DCHECK_EQ(STATE_UNSET, next_state_) << "Next state is " << state;
3130 next_state_ = state; 3195 next_state_ = state;
3131 } 3196 }
3132 3197
3133 } // namespace net 3198 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_cache_transaction.h ('k') | net/http/http_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698