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

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: cleanup naming in SimpleCache impl of this some 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
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 2319 matching lines...) Expand 10 before | Expand all | Expand 10 after
2330 stale_entry_freshness_ = lifetimes.freshness; 2330 stale_entry_freshness_ = lifetimes.freshness;
2331 stale_entry_age_ = response_.headers->GetCurrentAge( 2331 stale_entry_age_ = response_.headers->GetCurrentAge(
2332 response_.request_time, response_.response_time, 2332 response_.request_time, response_.response_time,
2333 cache_->clock_->Now()); 2333 cache_->clock_->Now());
2334 } 2334 }
2335 } 2335 }
2336 2336
2337 return validation_required_by_headers; 2337 return validation_required_by_headers;
2338 } 2338 }
2339 2339
2340 bool HttpCache::Transaction::ResponseConditionalizable(
2341 std::string* etag_value,
2342 std::string* last_modified_value) {
2343 DCHECK(response_.headers.get());
2344
2345 // This only makes sense for cached 200 or 206 responses.
2346 if (response_.headers->response_code() != 200 &&
2347 response_.headers->response_code() != 206) {
2348 return false;
2349 }
2350
2351 // ### this looks scary.
2352 DCHECK(response_.headers->response_code() != 206 ||
2353 response_.headers->HasStrongValidators());
2354
2355 // Just use the first available ETag and/or Last-Modified header value.
2356 // TODO(darin): Or should we use the last?
2357
2358 if (response_.headers->GetHttpVersion() >= HttpVersion(1, 1))
2359 response_.headers->EnumerateHeader(NULL, "etag", etag_value);
2360
2361 response_.headers->EnumerateHeader(NULL, "last-modified",
2362 last_modified_value);
2363
2364 if (etag_value->empty() && last_modified_value->empty())
2365 return false;
2366
2367 return true;
2368 }
2369
2340 bool HttpCache::Transaction::ConditionalizeRequest() { 2370 bool HttpCache::Transaction::ConditionalizeRequest() {
2341 DCHECK(response_.headers.get()); 2371 DCHECK(response_.headers.get());
2342 2372
2343 if (request_->method == "PUT" || request_->method == "DELETE") 2373 if (request_->method == "PUT" || request_->method == "DELETE")
2344 return false; 2374 return false;
2345 2375
2346 // This only makes sense for cached 200 or 206 responses.
2347 if (response_.headers->response_code() != 200 &&
2348 response_.headers->response_code() != 206) {
2349 return false;
2350 }
2351
2352 if (fail_conditionalization_for_test_) 2376 if (fail_conditionalization_for_test_)
2353 return false; 2377 return false;
2354 2378
2355 DCHECK(response_.headers->response_code() != 206 || 2379 std::string etag_value;
2356 response_.headers->HasStrongValidators()); 2380 std::string last_modified_value;
2381 if (!ResponseConditionalizable(&etag_value, &last_modified_value))
2382 return false;
2357 2383
2358 // Just use the first available ETag and/or Last-Modified header value. 2384 if (vary_mismatch_) {
2359 // TODO(darin): Or should we use the last? 2385 // Can't rely on last-modified if vary is different.
2360 2386 last_modified_value.clear();
2361 std::string etag_value; 2387 if (etag_value.empty())
2362 if (response_.headers->GetHttpVersion() >= HttpVersion(1, 1)) 2388 return false;
2363 response_.headers->EnumerateHeader(NULL, "etag", &etag_value);
2364
2365 std::string last_modified_value;
2366 if (!vary_mismatch_) {
2367 response_.headers->EnumerateHeader(NULL, "last-modified",
2368 &last_modified_value);
2369 } 2389 }
2370 2390
2371 if (etag_value.empty() && last_modified_value.empty())
2372 return false;
2373
2374 if (!partial_) { 2391 if (!partial_) {
2375 // Need to customize the request, so this forces us to allocate :( 2392 // Need to customize the request, so this forces us to allocate :(
2376 custom_request_.reset(new HttpRequestInfo(*request_)); 2393 custom_request_.reset(new HttpRequestInfo(*request_));
2377 request_ = custom_request_.get(); 2394 request_ = custom_request_.get();
2378 } 2395 }
2379 DCHECK(custom_request_.get()); 2396 DCHECK(custom_request_.get());
2380 2397
2381 bool use_if_range = 2398 bool use_if_range =
2382 partial_ && !partial_->IsCurrentRangeCached() && !invalid_range_; 2399 partial_ && !partial_->IsCurrentRangeCached() && !invalid_range_;
2383 2400
(...skipping 19 matching lines...) Expand all
2403 HttpRequestHeaders::kIfRange, last_modified_value); 2420 HttpRequestHeaders::kIfRange, last_modified_value);
2404 } else { 2421 } else {
2405 custom_request_->extra_headers.SetHeader( 2422 custom_request_->extra_headers.SetHeader(
2406 HttpRequestHeaders::kIfModifiedSince, last_modified_value); 2423 HttpRequestHeaders::kIfModifiedSince, last_modified_value);
2407 } 2424 }
2408 } 2425 }
2409 2426
2410 return true; 2427 return true;
2411 } 2428 }
2412 2429
2430 bool HttpCache::Transaction::CanRejectBasedOnMemoryEntryData(
2431 uint8_t in_memory_info) {
2432 // We can tell that some entries in cache may be unusable under present
2433 // circumstances if:
2434 // 1) We aren't using everything because of LOAD_SKIP_CACHE_VALIDATION.
2435 // 2) We aren't holding on to results of an unused prefetch.
2436 // 3) The entry has zero freshness (so it's known to be expired!)
2437 // 4) We know the entry can't be revalidated
2438 // (we may be able to match more things here).
2439 if (effective_load_flags_ & LOAD_SKIP_CACHE_VALIDATION)
2440 return false;
2441
2442 return (in_memory_info & HttpCache::OBH_ZERO_LIFETIME) &&
2443 (in_memory_info & HttpCache::OBH_RESPONSE_CANT_CONDITIONALIZE) &&
2444 !(in_memory_info & OBH_UNUSED_SINCE_PREFETCH);
2445 }
2446
2413 // We just received some headers from the server. We may have asked for a range, 2447 // We just received some headers from the server. We may have asked for a range,
2414 // in which case partial_ has an object. This could be the first network request 2448 // in which case partial_ has an object. This could be the first network request
2415 // we make to fulfill the original request, or we may be already reading (from 2449 // we make to fulfill the original request, or we may be already reading (from
2416 // the net and / or the cache). If we are not expecting a certain response, we 2450 // the net and / or the cache). If we are not expecting a certain response, we
2417 // just bypass the cache for this request (but again, maybe we are reading), and 2451 // just bypass the cache for this request (but again, maybe we are reading), and
2418 // delete partial_ (so we are not able to "fix" the headers that we return to 2452 // delete partial_ (so we are not able to "fix" the headers that we return to
2419 // the user). This results in either a weird response for the caller (we don't 2453 // the user). This results in either a weird response for the caller (we don't
2420 // expect it after all), or maybe a range that was not exactly what it was asked 2454 // expect it after all), or maybe a range that was not exactly what it was asked
2421 // for. 2455 // for.
2422 // 2456 //
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
2624 if (truncated) 2658 if (truncated)
2625 DCHECK_EQ(200, response_.headers->response_code()); 2659 DCHECK_EQ(200, response_.headers->response_code());
2626 2660
2627 // When writing headers, we normally only write the non-transient headers. 2661 // When writing headers, we normally only write the non-transient headers.
2628 bool skip_transient_headers = true; 2662 bool skip_transient_headers = true;
2629 scoped_refptr<PickledIOBuffer> data(new PickledIOBuffer()); 2663 scoped_refptr<PickledIOBuffer> data(new PickledIOBuffer());
2630 response_.Persist(data->pickle(), skip_transient_headers, truncated); 2664 response_.Persist(data->pickle(), skip_transient_headers, truncated);
2631 data->Done(); 2665 data->Done();
2632 2666
2633 io_buf_len_ = data->pickle()->size(); 2667 io_buf_len_ = data->pickle()->size();
2668
2669 uint8_t hints = 0;
2670 // ### recomputing this too much?
2671 if (response_.headers->GetFreshnessLifetimes(response_.response_time)
2672 .freshness.is_zero())
2673 hints |= HttpCache::OBH_ZERO_LIFETIME;
2674 std::string etag_ignored, last_modified_ignored;
2675 if (!ResponseConditionalizable(&etag_ignored, &last_modified_ignored))
2676 hints |= HttpCache::OBH_RESPONSE_CANT_CONDITIONALIZE;
2677 if (response_.unused_since_prefetch)
2678 hints |= HttpCache::OBH_UNUSED_SINCE_PREFETCH;
2679 cache_->GetCurrentBackend()->SetMemoryEntryData(cache_key_, hints);
2634 return entry_->disk_entry->WriteData(kResponseInfoIndex, 0, data.get(), 2680 return entry_->disk_entry->WriteData(kResponseInfoIndex, 0, data.get(),
2635 io_buf_len_, io_callback_, true); 2681 io_buf_len_, io_callback_, true);
2636 } 2682 }
2637 2683
2638 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) { 2684 int HttpCache::Transaction::OnWriteResponseInfoToEntryComplete(int result) {
2639 if (!entry_) 2685 if (!entry_)
2640 return OK; 2686 return OK;
2641 if (net_log_.IsCapturing()) { 2687 if (net_log_.IsCapturing()) {
2642 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO, 2688 net_log_.EndEventWithNetErrorCode(NetLogEventType::HTTP_CACHE_WRITE_INFO,
2643 result); 2689 result);
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
3017 } 3063 }
3018 3064
3019 void HttpCache::Transaction::TransitionToState(State state) { 3065 void HttpCache::Transaction::TransitionToState(State state) {
3020 // Ensure that the state is only set once per Do* state. 3066 // Ensure that the state is only set once per Do* state.
3021 DCHECK(in_do_loop_); 3067 DCHECK(in_do_loop_);
3022 DCHECK_EQ(STATE_UNSET, next_state_) << "Next state is " << state; 3068 DCHECK_EQ(STATE_UNSET, next_state_) << "Next state is " << state;
3023 next_state_ = state; 3069 next_state_ = state;
3024 } 3070 }
3025 3071
3026 } // namespace net 3072 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698