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" | 7 #include "build/build_config.h" |
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/compiler_specific.h" | 17 #include "base/compiler_specific.h" |
18 #include "base/format_macros.h" | |
18 #include "base/memory/ref_counted.h" | 19 #include "base/memory/ref_counted.h" |
19 #include "base/metrics/field_trial.h" | 20 #include "base/metrics/field_trial.h" |
20 #include "base/metrics/histogram.h" | 21 #include "base/metrics/histogram.h" |
21 #include "base/metrics/sparse_histogram.h" | 22 #include "base/metrics/sparse_histogram.h" |
22 #include "base/rand_util.h" | 23 #include "base/rand_util.h" |
23 #include "base/strings/string_number_conversions.h" | 24 #include "base/strings/string_number_conversions.h" |
25 #include "base/strings/string_piece.h" | |
24 #include "base/strings/string_util.h" | 26 #include "base/strings/string_util.h" |
27 #include "base/strings/stringprintf.h" | |
25 #include "base/time/time.h" | 28 #include "base/time/time.h" |
26 #include "net/base/completion_callback.h" | 29 #include "net/base/completion_callback.h" |
27 #include "net/base/io_buffer.h" | 30 #include "net/base/io_buffer.h" |
28 #include "net/base/load_flags.h" | 31 #include "net/base/load_flags.h" |
29 #include "net/base/load_timing_info.h" | 32 #include "net/base/load_timing_info.h" |
30 #include "net/base/net_errors.h" | 33 #include "net/base/net_errors.h" |
31 #include "net/base/net_log.h" | 34 #include "net/base/net_log.h" |
32 #include "net/base/upload_data_stream.h" | 35 #include "net/base/upload_data_stream.h" |
33 #include "net/cert/cert_status_flags.h" | 36 #include "net/cert/cert_status_flags.h" |
34 #include "net/disk_cache/disk_cache.h" | 37 #include "net/disk_cache/disk_cache.h" |
35 #include "net/http/disk_based_cert_cache.h" | 38 #include "net/http/disk_based_cert_cache.h" |
36 #include "net/http/http_network_session.h" | 39 #include "net/http/http_network_session.h" |
37 #include "net/http/http_request_info.h" | 40 #include "net/http/http_request_info.h" |
38 #include "net/http/http_response_headers.h" | 41 #include "net/http/http_response_headers.h" |
39 #include "net/http/http_transaction.h" | 42 #include "net/http/http_transaction.h" |
40 #include "net/http/http_util.h" | 43 #include "net/http/http_util.h" |
41 #include "net/http/partial_data.h" | 44 #include "net/http/partial_data.h" |
42 #include "net/ssl/ssl_cert_request_info.h" | 45 #include "net/ssl/ssl_cert_request_info.h" |
43 #include "net/ssl/ssl_config_service.h" | 46 #include "net/ssl/ssl_config_service.h" |
44 | 47 |
45 using base::Time; | 48 using base::Time; |
46 using base::TimeDelta; | 49 using base::TimeDelta; |
47 using base::TimeTicks; | 50 using base::TimeTicks; |
48 | 51 |
49 namespace { | 52 namespace { |
50 | 53 |
54 // TODO(ricea): Move this to HttpResponseHeaders once it is standardised. | |
55 static const char kFreshnessHeader[] = "Chrome-Freshness"; | |
56 | |
51 // Stores data relevant to the statistics of writing and reading entire | 57 // Stores data relevant to the statistics of writing and reading entire |
52 // certificate chains using DiskBasedCertCache. |num_pending_ops| is the number | 58 // certificate chains using DiskBasedCertCache. |num_pending_ops| is the number |
53 // of certificates in the chain that have pending operations in the | 59 // of certificates in the chain that have pending operations in the |
54 // DiskBasedCertCache. |start_time| is the time that the read and write | 60 // DiskBasedCertCache. |start_time| is the time that the read and write |
55 // commands began being issued to the DiskBasedCertCache. | 61 // commands began being issued to the DiskBasedCertCache. |
56 // TODO(brandonsalmon): Remove this when it is no longer necessary to | 62 // TODO(brandonsalmon): Remove this when it is no longer necessary to |
57 // collect data. | 63 // collect data. |
58 class SharedChainData : public base::RefCounted<SharedChainData> { | 64 class SharedChainData : public base::RefCounted<SharedChainData> { |
59 public: | 65 public: |
60 SharedChainData(int num_ops, TimeTicks start) | 66 SharedChainData(int num_ops, TimeTicks start) |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
225 | 231 |
226 void RecordNoStoreHeaderHistogram(int load_flags, | 232 void RecordNoStoreHeaderHistogram(int load_flags, |
227 const net::HttpResponseInfo* response) { | 233 const net::HttpResponseInfo* response) { |
228 if (load_flags & net::LOAD_MAIN_FRAME) { | 234 if (load_flags & net::LOAD_MAIN_FRAME) { |
229 UMA_HISTOGRAM_BOOLEAN( | 235 UMA_HISTOGRAM_BOOLEAN( |
230 "Net.MainFrameNoStore", | 236 "Net.MainFrameNoStore", |
231 response->headers->HasHeaderValue("cache-control", "no-store")); | 237 response->headers->HasHeaderValue("cache-control", "no-store")); |
232 } | 238 } |
233 } | 239 } |
234 | 240 |
241 // TODO(ricea): Move this to a more appropriate home. Also, this is closely | |
242 // based on HttpResponseHeaders::GetMaxAgeValue so they should probably share | |
243 // implementation. | |
244 bool GetStaleWhileRevalidateValue(const net::HttpResponseHeaders& headers, | |
245 TimeDelta* result) { | |
246 const std::string name = "cache-control"; | |
247 std::string value; | |
248 | |
249 const char kStaleWhileRevalidatePrefix[] = "stale-while-revalidate="; | |
250 const size_t kStaleWhileRevalidatePrefixLen = | |
251 arraysize(kStaleWhileRevalidatePrefix) - 1; | |
252 | |
253 void* iter = NULL; | |
254 while (headers.EnumerateHeader(&iter, name, &value)) { | |
255 if (value.size() > kStaleWhileRevalidatePrefixLen) { | |
256 if (LowerCaseEqualsASCII(value.begin(), | |
257 value.begin() + kStaleWhileRevalidatePrefixLen, | |
258 kStaleWhileRevalidatePrefix)) { | |
259 int64 seconds; | |
260 base::StringToInt64( | |
tyoshino (SeeGerritForStatus)
2014/07/18 02:29:55
handle failure?
Adam Rice
2014/07/18 04:16:51
It looks like the code I copy-and-pasted relied on
| |
261 base::StringPiece(value.begin() + kStaleWhileRevalidatePrefixLen, | |
262 value.end()), | |
tyoshino (SeeGerritForStatus)
2014/07/18 02:29:55
indent
Adam Rice
2014/07/18 04:16:51
Done.
| |
263 &seconds); | |
264 *result = TimeDelta::FromSeconds(seconds); | |
265 return true; | |
266 } | |
267 } | |
268 } | |
269 | |
270 return false; | |
271 } | |
272 | |
235 } // namespace | 273 } // namespace |
236 | 274 |
237 namespace net { | 275 namespace net { |
238 | 276 |
239 struct HeaderNameAndValue { | 277 struct HeaderNameAndValue { |
240 const char* name; | 278 const char* name; |
241 const char* value; | 279 const char* value; |
242 }; | 280 }; |
243 | 281 |
244 // If the request includes one of these request headers, then avoid caching | 282 // If the request includes one of these request headers, then avoid caching |
(...skipping 2005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2250 if (!partial_.get()) { | 2288 if (!partial_.get()) { |
2251 // Need to customize the request, so this forces us to allocate :( | 2289 // Need to customize the request, so this forces us to allocate :( |
2252 custom_request_.reset(new HttpRequestInfo(*request_)); | 2290 custom_request_.reset(new HttpRequestInfo(*request_)); |
2253 request_ = custom_request_.get(); | 2291 request_ = custom_request_.get(); |
2254 } | 2292 } |
2255 DCHECK(custom_request_.get()); | 2293 DCHECK(custom_request_.get()); |
2256 | 2294 |
2257 bool use_if_range = partial_.get() && !partial_->IsCurrentRangeCached() && | 2295 bool use_if_range = partial_.get() && !partial_->IsCurrentRangeCached() && |
2258 !invalid_range_; | 2296 !invalid_range_; |
2259 | 2297 |
2298 if (!use_if_range && request_->privacy_mode != PRIVACY_MODE_ENABLED) { | |
2299 // stale-while-revalidate is not useful when we only have a partial response | |
2300 // cached, so don't set the header in that case. | |
2301 // Also don't send the header when DO_NOT_SEND_COOKIES is set, to avoid | |
tyoshino (SeeGerritForStatus)
2014/07/18 02:29:54
the if-clause is looking at privacy_mode which is
Adam Rice
2014/07/18 04:16:51
Sorry, yes, I found that DO_NOT_SEND_COOKIES was i
| |
2302 // accidentally fingerprinting the user. | |
2303 base::TimeDelta stale_while_revalidate; | |
2304 if (GetStaleWhileRevalidateValue(*response_.headers, | |
2305 &stale_while_revalidate)) { | |
2306 base::TimeDelta max_age = | |
2307 response_.headers->GetFreshnessLifetime(response_.response_time); | |
2308 base::TimeDelta current_age = response_.headers->GetCurrentAge( | |
2309 response_.request_time, response_.response_time, Time::Now()); | |
2310 | |
2311 custom_request_->extra_headers.SetHeader( | |
2312 kFreshnessHeader, | |
2313 base::StringPrintf("max-age=%" PRId64 | |
2314 ",stale-while-revalidate=%" PRId64 ",age=%" PRId64, | |
2315 max_age.InSeconds(), | |
2316 stale_while_revalidate.InSeconds(), | |
2317 current_age.InSeconds())); | |
2318 } | |
2319 } | |
2320 | |
2260 if (!etag_value.empty()) { | 2321 if (!etag_value.empty()) { |
2261 if (use_if_range) { | 2322 if (use_if_range) { |
2262 // We don't want to switch to WRITE mode if we don't have this block of a | 2323 // We don't want to switch to WRITE mode if we don't have this block of a |
2263 // byte-range request because we may have other parts cached. | 2324 // byte-range request because we may have other parts cached. |
2264 custom_request_->extra_headers.SetHeader( | 2325 custom_request_->extra_headers.SetHeader( |
2265 HttpRequestHeaders::kIfRange, etag_value); | 2326 HttpRequestHeaders::kIfRange, etag_value); |
2266 } else { | 2327 } else { |
2267 custom_request_->extra_headers.SetHeader( | 2328 custom_request_->extra_headers.SetHeader( |
2268 HttpRequestHeaders::kIfNoneMatch, etag_value); | 2329 HttpRequestHeaders::kIfNoneMatch, etag_value); |
2269 } | 2330 } |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2746 default: | 2807 default: |
2747 NOTREACHED(); | 2808 NOTREACHED(); |
2748 } | 2809 } |
2749 } | 2810 } |
2750 | 2811 |
2751 void HttpCache::Transaction::OnIOComplete(int result) { | 2812 void HttpCache::Transaction::OnIOComplete(int result) { |
2752 DoLoop(result); | 2813 DoLoop(result); |
2753 } | 2814 } |
2754 | 2815 |
2755 } // namespace net | 2816 } // namespace net |
OLD | NEW |