Chromium Code Reviews| OLD | NEW |
|---|---|
| 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> |
| 11 #endif | 11 #endif |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <string> | 14 #include <string> |
| 15 | 15 |
| 16 #include "base/bind.h" | 16 #include "base/bind.h" |
| 17 #include "base/callback_helpers.h" | 17 #include "base/callback_helpers.h" |
| 18 #include "base/compiler_specific.h" | 18 #include "base/compiler_specific.h" |
| 19 #include "base/format_macros.h" | |
| 20 #include "base/location.h" | 19 #include "base/location.h" |
| 21 #include "base/macros.h" | 20 #include "base/macros.h" |
| 22 #include "base/metrics/histogram_macros.h" | 21 #include "base/metrics/histogram_macros.h" |
| 23 #include "base/metrics/sparse_histogram.h" | 22 #include "base/metrics/sparse_histogram.h" |
| 24 #include "base/single_thread_task_runner.h" | 23 #include "base/single_thread_task_runner.h" |
| 25 #include "base/strings/string_number_conversions.h" // For HexEncode. | 24 #include "base/strings/string_number_conversions.h" // For HexEncode. |
| 26 #include "base/strings/string_piece.h" | |
| 27 #include "base/strings/string_util.h" // For LowerCaseEqualsASCII. | 25 #include "base/strings/string_util.h" // For LowerCaseEqualsASCII. |
| 28 #include "base/strings/stringprintf.h" | |
| 29 #include "base/threading/thread_task_runner_handle.h" | 26 #include "base/threading/thread_task_runner_handle.h" |
| 30 #include "base/time/clock.h" | 27 #include "base/time/clock.h" |
| 31 #include "base/trace_event/trace_event.h" | 28 #include "base/trace_event/trace_event.h" |
| 32 #include "base/values.h" | 29 #include "base/values.h" |
|
mmenke
2017/03/23 21:39:35
Tiny nit: Is this still used in this file? It wa
scottmg
2017/03/24 22:46:00
Done.
| |
| 33 #include "net/base/auth.h" | 30 #include "net/base/auth.h" |
| 34 #include "net/base/load_flags.h" | 31 #include "net/base/load_flags.h" |
| 35 #include "net/base/load_timing_info.h" | 32 #include "net/base/load_timing_info.h" |
| 36 #include "net/base/trace_constants.h" | 33 #include "net/base/trace_constants.h" |
| 37 #include "net/base/upload_data_stream.h" | 34 #include "net/base/upload_data_stream.h" |
| 38 #include "net/cert/cert_status_flags.h" | 35 #include "net/cert/cert_status_flags.h" |
| 39 #include "net/cert/x509_certificate.h" | 36 #include "net/cert/x509_certificate.h" |
| 40 #include "net/disk_cache/disk_cache.h" | 37 #include "net/disk_cache/disk_cache.h" |
| 41 #include "net/http/http_network_session.h" | 38 #include "net/http/http_network_session.h" |
| 42 #include "net/http/http_request_info.h" | 39 #include "net/http/http_request_info.h" |
| 43 #include "net/http/http_util.h" | 40 #include "net/http/http_util.h" |
| 44 #include "net/log/net_log_event_type.h" | 41 #include "net/log/net_log_event_type.h" |
| 45 #include "net/ssl/ssl_cert_request_info.h" | 42 #include "net/ssl/ssl_cert_request_info.h" |
| 46 #include "net/ssl/ssl_config_service.h" | 43 #include "net/ssl/ssl_config_service.h" |
| 47 | 44 |
| 48 using base::Time; | 45 using base::Time; |
| 49 using base::TimeDelta; | 46 using base::TimeDelta; |
| 50 using base::TimeTicks; | 47 using base::TimeTicks; |
| 51 | 48 |
| 52 namespace net { | 49 namespace net { |
| 53 | 50 |
| 54 using CacheEntryStatus = HttpResponseInfo::CacheEntryStatus; | 51 using CacheEntryStatus = HttpResponseInfo::CacheEntryStatus; |
| 55 | 52 |
| 56 namespace { | 53 namespace { |
| 57 | 54 |
| 58 // TODO(ricea): Move this to HttpResponseHeaders once it is standardised. | |
| 59 static const char kFreshnessHeader[] = "Resource-Freshness"; | |
| 60 | |
| 61 // From http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-21#section-6 | 55 // From http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-21#section-6 |
| 62 // a "non-error response" is one with a 2xx (Successful) or 3xx | 56 // a "non-error response" is one with a 2xx (Successful) or 3xx |
| 63 // (Redirection) status code. | 57 // (Redirection) status code. |
| 64 bool NonErrorResponse(int status_code) { | 58 bool NonErrorResponse(int status_code) { |
| 65 int status_code_range = status_code / 100; | 59 int status_code_range = status_code / 100; |
| 66 return status_code_range == 2 || status_code_range == 3; | 60 return status_code_range == 2 || status_code_range == 3; |
| 67 } | 61 } |
| 68 | 62 |
| 69 void RecordNoStoreHeaderHistogram(int load_flags, | 63 void RecordNoStoreHeaderHistogram(int load_flags, |
| 70 const HttpResponseInfo* response) { | 64 const HttpResponseInfo* response) { |
| 71 if (load_flags & LOAD_MAIN_FRAME_DEPRECATED) { | 65 if (load_flags & LOAD_MAIN_FRAME_DEPRECATED) { |
| 72 UMA_HISTOGRAM_BOOLEAN( | 66 UMA_HISTOGRAM_BOOLEAN( |
| 73 "Net.MainFrameNoStore", | 67 "Net.MainFrameNoStore", |
| 74 response->headers->HasHeaderValue("cache-control", "no-store")); | 68 response->headers->HasHeaderValue("cache-control", "no-store")); |
| 75 } | 69 } |
| 76 } | 70 } |
| 77 | 71 |
| 78 enum ExternallyConditionalizedType { | 72 enum ExternallyConditionalizedType { |
| 79 EXTERNALLY_CONDITIONALIZED_CACHE_REQUIRES_VALIDATION, | 73 EXTERNALLY_CONDITIONALIZED_CACHE_REQUIRES_VALIDATION, |
| 80 EXTERNALLY_CONDITIONALIZED_CACHE_USABLE, | 74 EXTERNALLY_CONDITIONALIZED_CACHE_USABLE, |
| 81 EXTERNALLY_CONDITIONALIZED_MISMATCHED_VALIDATORS, | 75 EXTERNALLY_CONDITIONALIZED_MISMATCHED_VALIDATORS, |
| 82 EXTERNALLY_CONDITIONALIZED_MAX | 76 EXTERNALLY_CONDITIONALIZED_MAX |
| 83 }; | 77 }; |
|
mmenke
2017/03/23 21:39:35
This enum (And the related histogram) look to have
scottmg
2017/03/24 22:45:59
Aha, good catch. Done.
| |
| 84 | 78 |
| 85 } // namespace | 79 } // namespace |
| 86 | 80 |
| 87 #define CACHE_STATUS_HISTOGRAMS(type) \ | 81 #define CACHE_STATUS_HISTOGRAMS(type) \ |
| 88 do { \ | 82 do { \ |
| 89 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern" type, cache_entry_status_, \ | 83 UMA_HISTOGRAM_ENUMERATION("HttpCache.Pattern" type, cache_entry_status_, \ |
| 90 CacheEntryStatus::ENTRY_MAX); \ | 84 CacheEntryStatus::ENTRY_MAX); \ |
| 91 if (validation_request) { \ | 85 if (validation_request) { \ |
| 92 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause" type, \ | 86 UMA_HISTOGRAM_ENUMERATION("HttpCache.ValidationCause" type, \ |
| 93 validation_cause_, VALIDATION_CAUSE_MAX); \ | 87 validation_cause_, VALIDATION_CAUSE_MAX); \ |
| (...skipping 2000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2094 next_state_ = STATE_NONE; | 2088 next_state_ = STATE_NONE; |
| 2095 return ERR_CACHE_MISS; | 2089 return ERR_CACHE_MISS; |
| 2096 } | 2090 } |
| 2097 | 2091 |
| 2098 // We don't have the whole resource. | 2092 // We don't have the whole resource. |
| 2099 if (truncated_) { | 2093 if (truncated_) { |
| 2100 next_state_ = STATE_NONE; | 2094 next_state_ = STATE_NONE; |
| 2101 return ERR_CACHE_MISS; | 2095 return ERR_CACHE_MISS; |
| 2102 } | 2096 } |
| 2103 | 2097 |
| 2104 if (RequiresValidation() != VALIDATION_NONE) { | 2098 if (RequiresValidation()) { |
| 2105 next_state_ = STATE_NONE; | 2099 next_state_ = STATE_NONE; |
| 2106 return ERR_CACHE_MISS; | 2100 return ERR_CACHE_MISS; |
| 2107 } | 2101 } |
| 2108 | 2102 |
| 2109 if (request_->method == "HEAD") | 2103 if (request_->method == "HEAD") |
| 2110 FixHeadersForHead(); | 2104 FixHeadersForHead(); |
| 2111 | 2105 |
| 2112 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) | 2106 if (entry_->disk_entry->GetDataSize(kMetadataIndex)) |
| 2113 next_state_ = STATE_CACHE_READ_METADATA; | 2107 next_state_ = STATE_CACHE_READ_METADATA; |
| 2114 else | 2108 else |
| 2115 next_state_ = STATE_NONE; | 2109 next_state_ = STATE_NONE; |
| 2116 | 2110 |
| 2117 return OK; | 2111 return OK; |
| 2118 } | 2112 } |
| 2119 | 2113 |
| 2120 int HttpCache::Transaction::BeginCacheValidation() { | 2114 int HttpCache::Transaction::BeginCacheValidation() { |
| 2121 DCHECK_EQ(mode_, READ_WRITE); | 2115 DCHECK_EQ(mode_, READ_WRITE); |
| 2122 | 2116 |
| 2123 ValidationType required_validation = RequiresValidation(); | 2117 bool skip_validation = !RequiresValidation(); |
| 2124 | |
| 2125 bool skip_validation = (required_validation == VALIDATION_NONE); | |
| 2126 | |
| 2127 if ((effective_load_flags_ & LOAD_SUPPORT_ASYNC_REVALIDATION) && | |
| 2128 required_validation == VALIDATION_ASYNCHRONOUS) { | |
| 2129 DCHECK_EQ(request_->method, "GET"); | |
| 2130 skip_validation = true; | |
| 2131 response_.async_revalidation_required = true; | |
| 2132 } | |
| 2133 | 2118 |
| 2134 if (request_->method == "HEAD" && | 2119 if (request_->method == "HEAD" && |
| 2135 (truncated_ || response_.headers->response_code() == 206)) { | 2120 (truncated_ || response_.headers->response_code() == 206)) { |
| 2136 DCHECK(!partial_); | 2121 DCHECK(!partial_); |
| 2137 if (skip_validation) | 2122 if (skip_validation) |
| 2138 return SetupEntryForRead(); | 2123 return SetupEntryForRead(); |
| 2139 | 2124 |
| 2140 // Bail out! | 2125 // Bail out! |
| 2141 next_state_ = STATE_SEND_REQUEST; | 2126 next_state_ = STATE_SEND_REQUEST; |
| 2142 mode_ = NONE; | 2127 mode_ = NONE; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2251 } | 2236 } |
| 2252 } | 2237 } |
| 2253 | 2238 |
| 2254 // TODO(ricea): This calculation is expensive to perform just to collect | 2239 // TODO(ricea): This calculation is expensive to perform just to collect |
| 2255 // statistics. Either remove it or use the result, depending on the result of | 2240 // statistics. Either remove it or use the result, depending on the result of |
| 2256 // the experiment. | 2241 // the experiment. |
| 2257 ExternallyConditionalizedType type = | 2242 ExternallyConditionalizedType type = |
| 2258 EXTERNALLY_CONDITIONALIZED_CACHE_USABLE; | 2243 EXTERNALLY_CONDITIONALIZED_CACHE_USABLE; |
| 2259 if (mode_ == NONE) | 2244 if (mode_ == NONE) |
| 2260 type = EXTERNALLY_CONDITIONALIZED_MISMATCHED_VALIDATORS; | 2245 type = EXTERNALLY_CONDITIONALIZED_MISMATCHED_VALIDATORS; |
| 2261 else if (RequiresValidation() != VALIDATION_NONE) | 2246 else if (RequiresValidation()) |
| 2262 type = EXTERNALLY_CONDITIONALIZED_CACHE_REQUIRES_VALIDATION; | 2247 type = EXTERNALLY_CONDITIONALIZED_CACHE_REQUIRES_VALIDATION; |
| 2263 | 2248 |
| 2264 // TODO(ricea): Add CACHE_USABLE_STALE once stale-while-revalidate CL landed. | |
| 2265 // TODO(ricea): Either remove this histogram or make it permanent by M40. | 2249 // TODO(ricea): Either remove this histogram or make it permanent by M40. |
| 2266 UMA_HISTOGRAM_ENUMERATION("HttpCache.ExternallyConditionalized", | 2250 UMA_HISTOGRAM_ENUMERATION("HttpCache.ExternallyConditionalized", |
| 2267 type, | 2251 type, |
| 2268 EXTERNALLY_CONDITIONALIZED_MAX); | 2252 EXTERNALLY_CONDITIONALIZED_MAX); |
| 2269 | 2253 |
| 2270 next_state_ = STATE_SEND_REQUEST; | 2254 next_state_ = STATE_SEND_REQUEST; |
| 2271 return OK; | 2255 return OK; |
| 2272 } | 2256 } |
| 2273 | 2257 |
| 2274 int HttpCache::Transaction::RestartNetworkRequest() { | 2258 int HttpCache::Transaction::RestartNetworkRequest() { |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 2304 DCHECK(network_trans_.get()); | 2288 DCHECK(network_trans_.get()); |
| 2305 DCHECK_EQ(STATE_NONE, next_state_); | 2289 DCHECK_EQ(STATE_NONE, next_state_); |
| 2306 | 2290 |
| 2307 next_state_ = STATE_SEND_REQUEST_COMPLETE; | 2291 next_state_ = STATE_SEND_REQUEST_COMPLETE; |
| 2308 int rv = network_trans_->RestartWithAuth(credentials, io_callback_); | 2292 int rv = network_trans_->RestartWithAuth(credentials, io_callback_); |
| 2309 if (rv != ERR_IO_PENDING) | 2293 if (rv != ERR_IO_PENDING) |
| 2310 return DoLoop(rv); | 2294 return DoLoop(rv); |
| 2311 return rv; | 2295 return rv; |
| 2312 } | 2296 } |
| 2313 | 2297 |
| 2314 ValidationType HttpCache::Transaction::RequiresValidation() { | 2298 bool HttpCache::Transaction::RequiresValidation() { |
| 2315 // TODO(darin): need to do more work here: | 2299 // TODO(darin): need to do more work here: |
| 2316 // - make sure we have a matching request method | 2300 // - make sure we have a matching request method |
| 2317 // - watch out for cached responses that depend on authentication | 2301 // - watch out for cached responses that depend on authentication |
| 2318 | 2302 |
| 2319 if (!(effective_load_flags_ & LOAD_SKIP_VARY_CHECK) && | 2303 if (!(effective_load_flags_ & LOAD_SKIP_VARY_CHECK) && |
| 2320 response_.vary_data.is_valid() && | 2304 response_.vary_data.is_valid() && |
| 2321 !response_.vary_data.MatchesRequest(*request_, | 2305 !response_.vary_data.MatchesRequest(*request_, |
| 2322 *response_.headers.get())) { | 2306 *response_.headers.get())) { |
| 2323 vary_mismatch_ = true; | 2307 vary_mismatch_ = true; |
| 2324 validation_cause_ = VALIDATION_CAUSE_VARY_MISMATCH; | 2308 validation_cause_ = VALIDATION_CAUSE_VARY_MISMATCH; |
| 2325 return VALIDATION_SYNCHRONOUS; | 2309 return true; |
| 2326 } | 2310 } |
| 2327 | 2311 |
| 2328 if (effective_load_flags_ & LOAD_SKIP_CACHE_VALIDATION) | 2312 if (effective_load_flags_ & LOAD_SKIP_CACHE_VALIDATION) |
| 2329 return VALIDATION_NONE; | 2313 return false; |
| 2330 | 2314 |
| 2331 if (response_.unused_since_prefetch && | 2315 if (response_.unused_since_prefetch && |
| 2332 !(effective_load_flags_ & LOAD_PREFETCH) && | 2316 !(effective_load_flags_ & LOAD_PREFETCH) && |
| 2333 response_.headers->GetCurrentAge( | 2317 response_.headers->GetCurrentAge( |
| 2334 response_.request_time, response_.response_time, | 2318 response_.request_time, response_.response_time, |
| 2335 cache_->clock_->Now()) < TimeDelta::FromMinutes(kPrefetchReuseMins)) { | 2319 cache_->clock_->Now()) < TimeDelta::FromMinutes(kPrefetchReuseMins)) { |
| 2336 // The first use of a resource after prefetch within a short window skips | 2320 // The first use of a resource after prefetch within a short window skips |
| 2337 // validation. | 2321 // validation. |
| 2338 return VALIDATION_NONE; | 2322 return false; |
| 2339 } | 2323 } |
| 2340 | 2324 |
| 2341 if (effective_load_flags_ & LOAD_VALIDATE_CACHE) { | 2325 if (effective_load_flags_ & LOAD_VALIDATE_CACHE) { |
| 2342 validation_cause_ = VALIDATION_CAUSE_VALIDATE_FLAG; | 2326 validation_cause_ = VALIDATION_CAUSE_VALIDATE_FLAG; |
| 2343 return VALIDATION_SYNCHRONOUS; | 2327 return true; |
| 2344 } | 2328 } |
| 2345 | 2329 |
| 2346 if (request_->method == "PUT" || request_->method == "DELETE") | 2330 if (request_->method == "PUT" || request_->method == "DELETE") |
| 2347 return VALIDATION_SYNCHRONOUS; | 2331 return true; |
| 2348 | 2332 |
| 2349 ValidationType validation_required_by_headers = | 2333 bool validation_required_by_headers = response_.headers->RequiresValidation( |
| 2350 response_.headers->RequiresValidation(response_.request_time, | 2334 response_.request_time, response_.response_time, cache_->clock_->Now()); |
| 2351 response_.response_time, | |
| 2352 cache_->clock_->Now()); | |
| 2353 | 2335 |
| 2354 if (validation_required_by_headers != VALIDATION_NONE) { | 2336 if (validation_required_by_headers) { |
| 2355 HttpResponseHeaders::FreshnessLifetimes lifetimes = | 2337 HttpResponseHeaders::FreshnessLifetimes lifetimes = |
| 2356 response_.headers->GetFreshnessLifetimes(response_.response_time); | 2338 response_.headers->GetFreshnessLifetimes(response_.response_time); |
| 2357 if (lifetimes.freshness == base::TimeDelta()) { | 2339 if (lifetimes.freshness == base::TimeDelta()) { |
| 2358 validation_cause_ = VALIDATION_CAUSE_ZERO_FRESHNESS; | 2340 validation_cause_ = VALIDATION_CAUSE_ZERO_FRESHNESS; |
| 2359 } else { | 2341 } else { |
| 2360 validation_cause_ = VALIDATION_CAUSE_STALE; | 2342 validation_cause_ = VALIDATION_CAUSE_STALE; |
| 2361 stale_entry_freshness_ = lifetimes.freshness; | 2343 stale_entry_freshness_ = lifetimes.freshness; |
| 2362 stale_entry_age_ = response_.headers->GetCurrentAge( | 2344 stale_entry_age_ = response_.headers->GetCurrentAge( |
| 2363 response_.request_time, response_.response_time, | 2345 response_.request_time, response_.response_time, |
| 2364 cache_->clock_->Now()); | 2346 cache_->clock_->Now()); |
| 2365 } | 2347 } |
| 2366 } | 2348 } |
| 2367 | 2349 |
| 2368 if (validation_required_by_headers == VALIDATION_ASYNCHRONOUS) { | |
| 2369 // Asynchronous revalidation is only supported for GET methods. | |
| 2370 if (request_->method != "GET") | |
| 2371 return VALIDATION_SYNCHRONOUS; | |
| 2372 } | |
| 2373 | |
| 2374 return validation_required_by_headers; | 2350 return validation_required_by_headers; |
| 2375 } | 2351 } |
| 2376 | 2352 |
| 2377 bool HttpCache::Transaction::ConditionalizeRequest() { | 2353 bool HttpCache::Transaction::ConditionalizeRequest() { |
| 2378 DCHECK(response_.headers.get()); | 2354 DCHECK(response_.headers.get()); |
| 2379 | 2355 |
| 2380 if (request_->method == "PUT" || request_->method == "DELETE") | 2356 if (request_->method == "PUT" || request_->method == "DELETE") |
| 2381 return false; | 2357 return false; |
| 2382 | 2358 |
| 2383 // This only makes sense for cached 200 or 206 responses. | 2359 // This only makes sense for cached 200 or 206 responses. |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 2411 if (!partial_) { | 2387 if (!partial_) { |
| 2412 // Need to customize the request, so this forces us to allocate :( | 2388 // Need to customize the request, so this forces us to allocate :( |
| 2413 custom_request_.reset(new HttpRequestInfo(*request_)); | 2389 custom_request_.reset(new HttpRequestInfo(*request_)); |
| 2414 request_ = custom_request_.get(); | 2390 request_ = custom_request_.get(); |
| 2415 } | 2391 } |
| 2416 DCHECK(custom_request_.get()); | 2392 DCHECK(custom_request_.get()); |
| 2417 | 2393 |
| 2418 bool use_if_range = | 2394 bool use_if_range = |
| 2419 partial_ && !partial_->IsCurrentRangeCached() && !invalid_range_; | 2395 partial_ && !partial_->IsCurrentRangeCached() && !invalid_range_; |
| 2420 | 2396 |
| 2421 if (!use_if_range) { | |
| 2422 // stale-while-revalidate is not useful when we only have a partial response | |
| 2423 // cached, so don't set the header in that case. | |
| 2424 HttpResponseHeaders::FreshnessLifetimes lifetimes = | |
| 2425 response_.headers->GetFreshnessLifetimes(response_.response_time); | |
| 2426 if (lifetimes.staleness > TimeDelta()) { | |
| 2427 TimeDelta current_age = response_.headers->GetCurrentAge( | |
| 2428 response_.request_time, response_.response_time, | |
| 2429 cache_->clock_->Now()); | |
| 2430 | |
| 2431 custom_request_->extra_headers.SetHeader( | |
| 2432 kFreshnessHeader, | |
| 2433 base::StringPrintf("max-age=%" PRId64 | |
| 2434 ",stale-while-revalidate=%" PRId64 ",age=%" PRId64, | |
| 2435 lifetimes.freshness.InSeconds(), | |
| 2436 lifetimes.staleness.InSeconds(), | |
| 2437 current_age.InSeconds())); | |
| 2438 } | |
| 2439 } | |
| 2440 | |
| 2441 if (!etag_value.empty()) { | 2397 if (!etag_value.empty()) { |
| 2442 if (use_if_range) { | 2398 if (use_if_range) { |
| 2443 // We don't want to switch to WRITE mode if we don't have this block of a | 2399 // We don't want to switch to WRITE mode if we don't have this block of a |
| 2444 // byte-range request because we may have other parts cached. | 2400 // byte-range request because we may have other parts cached. |
| 2445 custom_request_->extra_headers.SetHeader( | 2401 custom_request_->extra_headers.SetHeader( |
| 2446 HttpRequestHeaders::kIfRange, etag_value); | 2402 HttpRequestHeaders::kIfRange, etag_value); |
| 2447 } else { | 2403 } else { |
| 2448 custom_request_->extra_headers.SetHeader( | 2404 custom_request_->extra_headers.SetHeader( |
| 2449 HttpRequestHeaders::kIfNoneMatch, etag_value); | 2405 HttpRequestHeaders::kIfNoneMatch, etag_value); |
| 2450 } | 2406 } |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3067 default: | 3023 default: |
| 3068 NOTREACHED(); | 3024 NOTREACHED(); |
| 3069 } | 3025 } |
| 3070 } | 3026 } |
| 3071 | 3027 |
| 3072 void HttpCache::Transaction::OnIOComplete(int result) { | 3028 void HttpCache::Transaction::OnIOComplete(int result) { |
| 3073 DoLoop(result); | 3029 DoLoop(result); |
| 3074 } | 3030 } |
| 3075 | 3031 |
| 3076 } // namespace net | 3032 } // namespace net |
| OLD | NEW |