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

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

Issue 391763002: Initial implementation of Chrome-Freshness header. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comment and test name fixes. Created 6 years, 5 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 | « no previous file | net/http/http_cache_unittest.cc » ('j') | net/http/http_cache_unittest.cc » ('J')
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" 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";
rvargas (doing something else) 2014/07/24 00:54:06 Shouldn't we use some other prefix that states mor
Adam Rice 2014/07/28 11:11:13 Okay, I've changed to "Chromium-Resource-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
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
rvargas (doing something else) 2014/07/24 00:54:06 I think we should move this to http_response_heade
Adam Rice 2014/07/28 11:11:13 Done.
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";
rvargas (doing something else) 2014/07/24 00:54:06 nit: remove const and use constructor initializati
Adam Rice 2014/07/28 11:11:13 Done.
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 LowerCaseEqualsASCII(value.begin(),
257 value.begin() + kStaleWhileRevalidatePrefixLen,
258 kStaleWhileRevalidatePrefix)) {
259 int64 seconds = 0;
260 const base::StringPiece parameter = base::StringPiece(
261 value.begin() + kStaleWhileRevalidatePrefixLen, value.end());
262 if (!base::StringToInt64(parameter, &seconds) || seconds < 0)
263 continue;
264 *result = TimeDelta::FromSeconds(seconds);
265 return true;
266 }
267 }
268
269 return false;
270 }
271
235 } // namespace 272 } // namespace
236 273
237 namespace net { 274 namespace net {
238 275
239 struct HeaderNameAndValue { 276 struct HeaderNameAndValue {
240 const char* name; 277 const char* name;
241 const char* value; 278 const char* value;
242 }; 279 };
243 280
244 // If the request includes one of these request headers, then avoid caching 281 // If the request includes one of these request headers, then avoid caching
(...skipping 2005 matching lines...) Expand 10 before | Expand all | Expand 10 after
2250 if (!partial_.get()) { 2287 if (!partial_.get()) {
2251 // Need to customize the request, so this forces us to allocate :( 2288 // Need to customize the request, so this forces us to allocate :(
2252 custom_request_.reset(new HttpRequestInfo(*request_)); 2289 custom_request_.reset(new HttpRequestInfo(*request_));
2253 request_ = custom_request_.get(); 2290 request_ = custom_request_.get();
2254 } 2291 }
2255 DCHECK(custom_request_.get()); 2292 DCHECK(custom_request_.get());
2256 2293
2257 bool use_if_range = partial_.get() && !partial_->IsCurrentRangeCached() && 2294 bool use_if_range = partial_.get() && !partial_->IsCurrentRangeCached() &&
2258 !invalid_range_; 2295 !invalid_range_;
2259 2296
2297 if (!use_if_range && request_->privacy_mode != PRIVACY_MODE_ENABLED) {
2298 // stale-while-revalidate is not useful when we only have a partial response
2299 // cached, so don't set the header in that case.
2300 // Also don't send the header when privacy mode is enabled, to avoid
2301 // accidentally fingerprinting the user.
2302 base::TimeDelta stale_while_revalidate;
2303 if (GetStaleWhileRevalidateValue(*response_.headers,
2304 &stale_while_revalidate)) {
2305 base::TimeDelta max_age =
2306 response_.headers->GetFreshnessLifetime(response_.response_time);
2307 base::TimeDelta current_age = response_.headers->GetCurrentAge(
2308 response_.request_time, response_.response_time, Time::Now());
2309
2310 custom_request_->extra_headers.SetHeader(
rvargas (doing something else) 2014/07/24 00:54:06 We should probably send the header only when stale
Adam Rice 2014/07/28 11:11:13 I think this would probably make analysis too diff
2311 kFreshnessHeader,
2312 base::StringPrintf("max-age=%" PRId64
2313 ",stale-while-revalidate=%" PRId64 ",age=%" PRId64,
2314 max_age.InSeconds(),
2315 stale_while_revalidate.InSeconds(),
2316 current_age.InSeconds()));
2317 }
2318 }
2319
2260 if (!etag_value.empty()) { 2320 if (!etag_value.empty()) {
2261 if (use_if_range) { 2321 if (use_if_range) {
2262 // We don't want to switch to WRITE mode if we don't have this block of a 2322 // 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. 2323 // byte-range request because we may have other parts cached.
2264 custom_request_->extra_headers.SetHeader( 2324 custom_request_->extra_headers.SetHeader(
2265 HttpRequestHeaders::kIfRange, etag_value); 2325 HttpRequestHeaders::kIfRange, etag_value);
2266 } else { 2326 } else {
2267 custom_request_->extra_headers.SetHeader( 2327 custom_request_->extra_headers.SetHeader(
2268 HttpRequestHeaders::kIfNoneMatch, etag_value); 2328 HttpRequestHeaders::kIfNoneMatch, etag_value);
2269 } 2329 }
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
2746 default: 2806 default:
2747 NOTREACHED(); 2807 NOTREACHED();
2748 } 2808 }
2749 } 2809 }
2750 2810
2751 void HttpCache::Transaction::OnIOComplete(int result) { 2811 void HttpCache::Transaction::OnIOComplete(int result) {
2752 DoLoop(result); 2812 DoLoop(result);
2753 } 2813 }
2754 2814
2755 } // namespace net 2815 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/http/http_cache_unittest.cc » ('j') | net/http/http_cache_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698