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> |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 | 169 |
170 void RecordNoStoreHeaderHistogram(int load_flags, | 170 void RecordNoStoreHeaderHistogram(int load_flags, |
171 const HttpResponseInfo* response) { | 171 const HttpResponseInfo* response) { |
172 if (load_flags & LOAD_MAIN_FRAME) { | 172 if (load_flags & LOAD_MAIN_FRAME) { |
173 UMA_HISTOGRAM_BOOLEAN( | 173 UMA_HISTOGRAM_BOOLEAN( |
174 "Net.MainFrameNoStore", | 174 "Net.MainFrameNoStore", |
175 response->headers->HasHeaderValue("cache-control", "no-store")); | 175 response->headers->HasHeaderValue("cache-control", "no-store")); |
176 } | 176 } |
177 } | 177 } |
178 | 178 |
179 scoped_ptr<base::Value> NetLogAsyncRevalidationInfoCallback( | |
180 const NetLog::Source& source, | |
181 const HttpRequestInfo* request, | |
182 NetLogCaptureMode capture_mode) { | |
183 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | |
184 source.AddToEventParameters(dict.get()); | |
185 | |
186 dict->SetString("url", request->url.possibly_invalid_spec()); | |
187 dict->SetString("method", request->method); | |
188 return dict.Pass(); | |
189 } | |
190 | |
191 enum ExternallyConditionalizedType { | 179 enum ExternallyConditionalizedType { |
192 EXTERNALLY_CONDITIONALIZED_CACHE_REQUIRES_VALIDATION, | 180 EXTERNALLY_CONDITIONALIZED_CACHE_REQUIRES_VALIDATION, |
193 EXTERNALLY_CONDITIONALIZED_CACHE_USABLE, | 181 EXTERNALLY_CONDITIONALIZED_CACHE_USABLE, |
194 EXTERNALLY_CONDITIONALIZED_MISMATCHED_VALIDATORS, | 182 EXTERNALLY_CONDITIONALIZED_MISMATCHED_VALIDATORS, |
195 EXTERNALLY_CONDITIONALIZED_MAX | 183 EXTERNALLY_CONDITIONALIZED_MAX |
196 }; | 184 }; |
197 | 185 |
198 } // namespace | 186 } // namespace |
199 | 187 |
200 struct HeaderNameAndValue { | 188 struct HeaderNameAndValue { |
(...skipping 1922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2123 return OK; | 2111 return OK; |
2124 } | 2112 } |
2125 | 2113 |
2126 int HttpCache::Transaction::BeginCacheValidation() { | 2114 int HttpCache::Transaction::BeginCacheValidation() { |
2127 DCHECK(mode_ == READ_WRITE); | 2115 DCHECK(mode_ == READ_WRITE); |
2128 | 2116 |
2129 ValidationType required_validation = RequiresValidation(); | 2117 ValidationType required_validation = RequiresValidation(); |
2130 | 2118 |
2131 bool skip_validation = (required_validation == VALIDATION_NONE); | 2119 bool skip_validation = (required_validation == VALIDATION_NONE); |
2132 | 2120 |
2133 if (required_validation == VALIDATION_ASYNCHRONOUS && | |
2134 !(request_->method == "GET" && (truncated_ || partial_)) && cache_ && | |
2135 cache_->use_stale_while_revalidate()) { | |
2136 TriggerAsyncValidation(); | |
2137 skip_validation = true; | |
2138 } | |
2139 | |
2140 if (request_->method == "HEAD" && | 2121 if (request_->method == "HEAD" && |
2141 (truncated_ || response_.headers->response_code() == 206)) { | 2122 (truncated_ || response_.headers->response_code() == 206)) { |
2142 DCHECK(!partial_); | 2123 DCHECK(!partial_); |
2143 if (skip_validation) | 2124 if (skip_validation) |
2144 return SetupEntryForRead(); | 2125 return SetupEntryForRead(); |
2145 | 2126 |
2146 // Bail out! | 2127 // Bail out! |
2147 next_state_ = STATE_SEND_REQUEST; | 2128 next_state_ = STATE_SEND_REQUEST; |
2148 mode_ = NONE; | 2129 mode_ = NONE; |
2149 return OK; | 2130 return OK; |
2150 } | 2131 } |
2151 | 2132 |
2152 if (truncated_) { | 2133 if (truncated_) { |
2153 // Truncated entries can cause partial gets, so we shouldn't record this | 2134 // Truncated entries can cause partial gets, so we shouldn't record this |
2154 // load in histograms. | 2135 // load in histograms. |
2155 UpdateTransactionPattern(PATTERN_NOT_COVERED); | 2136 UpdateTransactionPattern(PATTERN_NOT_COVERED); |
2156 skip_validation = !partial_->initial_validation(); | 2137 skip_validation = !partial_->initial_validation(); |
2157 } | 2138 } |
2158 | 2139 |
2159 if (partial_.get() && (is_sparse_ || truncated_) && | 2140 if (partial_.get() && (is_sparse_ || truncated_) && |
2160 (!partial_->IsCurrentRangeCached() || invalid_range_)) { | 2141 (!partial_->IsCurrentRangeCached() || invalid_range_)) { |
2161 // Force revalidation for sparse or truncated entries. Note that we don't | 2142 // Force revalidation for sparse or truncated entries. Note that we don't |
2162 // want to ignore the regular validation logic just because a byte range was | 2143 // want to ignore the regular validation logic just because a byte range was |
2163 // part of the request. | 2144 // part of the request. |
2164 skip_validation = false; | 2145 skip_validation = false; |
2165 } | 2146 } |
2166 | 2147 |
2167 if (skip_validation) { | 2148 if (skip_validation) { |
2168 // TODO(ricea): Is this pattern okay for asynchronous revalidations? | |
2169 UpdateTransactionPattern(PATTERN_ENTRY_USED); | 2149 UpdateTransactionPattern(PATTERN_ENTRY_USED); |
2170 return SetupEntryForRead(); | 2150 return SetupEntryForRead(); |
2171 } else { | 2151 } else { |
2172 // Make the network request conditional, to see if we may reuse our cached | 2152 // Make the network request conditional, to see if we may reuse our cached |
2173 // response. If we cannot do so, then we just resort to a normal fetch. | 2153 // response. If we cannot do so, then we just resort to a normal fetch. |
2174 // Our mode remains READ_WRITE for a conditional request. Even if the | 2154 // Our mode remains READ_WRITE for a conditional request. Even if the |
2175 // conditionalization fails, we don't switch to WRITE mode until we | 2155 // conditionalization fails, we don't switch to WRITE mode until we |
2176 // know we won't be falling back to using the cache entry in the | 2156 // know we won't be falling back to using the cache entry in the |
2177 // LOAD_FROM_CACHE_IF_OFFLINE case. | 2157 // LOAD_FROM_CACHE_IF_OFFLINE case. |
2178 if (!ConditionalizeRequest()) { | 2158 if (!ConditionalizeRequest()) { |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2338 if (response_.unused_since_prefetch && | 2318 if (response_.unused_since_prefetch && |
2339 !(effective_load_flags_ & LOAD_PREFETCH) && | 2319 !(effective_load_flags_ & LOAD_PREFETCH) && |
2340 response_.headers->GetCurrentAge( | 2320 response_.headers->GetCurrentAge( |
2341 response_.request_time, response_.response_time, | 2321 response_.request_time, response_.response_time, |
2342 cache_->clock_->Now()) < TimeDelta::FromMinutes(kPrefetchReuseMins)) { | 2322 cache_->clock_->Now()) < TimeDelta::FromMinutes(kPrefetchReuseMins)) { |
2343 // The first use of a resource after prefetch within a short window skips | 2323 // The first use of a resource after prefetch within a short window skips |
2344 // validation. | 2324 // validation. |
2345 return VALIDATION_NONE; | 2325 return VALIDATION_NONE; |
2346 } | 2326 } |
2347 | 2327 |
2348 if (effective_load_flags_ & (LOAD_VALIDATE_CACHE | LOAD_ASYNC_REVALIDATION)) | 2328 if (effective_load_flags_ & LOAD_VALIDATE_CACHE) |
2349 return VALIDATION_SYNCHRONOUS; | 2329 return VALIDATION_SYNCHRONOUS; |
2350 | 2330 |
2351 if (request_->method == "PUT" || request_->method == "DELETE") | 2331 if (request_->method == "PUT" || request_->method == "DELETE") |
2352 return VALIDATION_SYNCHRONOUS; | 2332 return VALIDATION_SYNCHRONOUS; |
2353 | 2333 |
2354 ValidationType validation_required_by_headers = | 2334 ValidationType validation_required_by_headers = |
2355 response_.headers->RequiresValidation(response_.request_time, | 2335 response_.headers->RequiresValidation(response_.request_time, |
2356 response_.response_time, | 2336 response_.response_time, |
2357 cache_->clock_->Now()); | 2337 cache_->clock_->Now()); |
2358 | 2338 |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2592 mode_ = NONE; | 2572 mode_ = NONE; |
2593 } | 2573 } |
2594 | 2574 |
2595 void HttpCache::Transaction::FixHeadersForHead() { | 2575 void HttpCache::Transaction::FixHeadersForHead() { |
2596 if (response_.headers->response_code() == 206) { | 2576 if (response_.headers->response_code() == 206) { |
2597 response_.headers->RemoveHeader("Content-Range"); | 2577 response_.headers->RemoveHeader("Content-Range"); |
2598 response_.headers->ReplaceStatusLine("HTTP/1.1 200 OK"); | 2578 response_.headers->ReplaceStatusLine("HTTP/1.1 200 OK"); |
2599 } | 2579 } |
2600 } | 2580 } |
2601 | 2581 |
2602 void HttpCache::Transaction::TriggerAsyncValidation() { | |
2603 DCHECK(!request_->upload_data_stream); | |
2604 BoundNetLog async_revalidation_net_log( | |
2605 BoundNetLog::Make(net_log_.net_log(), NetLog::SOURCE_ASYNC_REVALIDATION)); | |
2606 net_log_.AddEvent( | |
2607 NetLog::TYPE_HTTP_CACHE_VALIDATE_RESOURCE_ASYNC, | |
2608 async_revalidation_net_log.source().ToEventParametersCallback()); | |
2609 async_revalidation_net_log.BeginEvent( | |
2610 NetLog::TYPE_ASYNC_REVALIDATION, | |
2611 base::Bind( | |
2612 &NetLogAsyncRevalidationInfoCallback, net_log_.source(), request_)); | |
2613 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
2614 FROM_HERE, base::Bind(&HttpCache::PerformAsyncValidation, | |
2615 cache_, // cache_ is a weak pointer. | |
2616 *request_, async_revalidation_net_log)); | |
2617 } | |
2618 | |
2619 void HttpCache::Transaction::FailRangeRequest() { | 2582 void HttpCache::Transaction::FailRangeRequest() { |
2620 response_ = *new_response_; | 2583 response_ = *new_response_; |
2621 partial_->FixResponseHeaders(response_.headers.get(), false); | 2584 partial_->FixResponseHeaders(response_.headers.get(), false); |
2622 } | 2585 } |
2623 | 2586 |
2624 int HttpCache::Transaction::SetupEntryForRead() { | 2587 int HttpCache::Transaction::SetupEntryForRead() { |
2625 if (network_trans_) | 2588 if (network_trans_) |
2626 ResetNetworkTransaction(); | 2589 ResetNetworkTransaction(); |
2627 if (partial_.get()) { | 2590 if (partial_.get()) { |
2628 if (truncated_ || is_sparse_ || !invalid_range_) { | 2591 if (truncated_ || is_sparse_ || !invalid_range_) { |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2974 default: | 2937 default: |
2975 NOTREACHED(); | 2938 NOTREACHED(); |
2976 } | 2939 } |
2977 } | 2940 } |
2978 | 2941 |
2979 void HttpCache::Transaction::OnIOComplete(int result) { | 2942 void HttpCache::Transaction::OnIOComplete(int result) { |
2980 DoLoop(result); | 2943 DoLoop(result); |
2981 } | 2944 } |
2982 | 2945 |
2983 } // namespace net | 2946 } // namespace net |
OLD | NEW |