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

Side by Side Diff: components/data_reduction_proxy/common/data_reduction_proxy_headers.cc

Issue 382313003: Add data reduction functionality to all platforms. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed bengr comments - II. 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/data_reduction_proxy/common/data_reduction_proxy_headers.h" 5 #include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/rand_util.h"
9 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_piece.h" 11 #include "base/strings/string_piece.h"
11 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
12 #include "base/time/time.h" 13 #include "base/time/time.h"
13 #include "net/http/http_response_headers.h" 14 #include "net/http/http_response_headers.h"
14 #include "net/http/http_status_code.h" 15 #include "net/http/http_status_code.h"
15 #include "net/proxy/proxy_service.h" 16 #include "net/proxy/proxy_service.h"
16 17
17 using base::StringPiece; 18 using base::StringPiece;
18 using base::TimeDelta; 19 using base::TimeDelta;
19 using net::ProxyService; 20 using net::ProxyService;
20 21
22 namespace {
23
24 // Returns a random bypass duration between 1 and 5 minutes.
25 base::TimeDelta GetDefaultBypassDuration() {
26 const int64 delta_ms = base::RandInt(
27 base::TimeDelta::FromMinutes(1).InMilliseconds(),
28 base::TimeDelta::FromMinutes(5).InMilliseconds());
29 return TimeDelta::FromMilliseconds(delta_ms);
30 }
31
32 } // namespace anonymous
Ryan Sleevi 2014/07/22 08:22:24 1) line break after this 2) It's not // namespace
Not at Google. Contact bengr 2014/07/22 23:03:53 Done.
21 namespace data_reduction_proxy { 33 namespace data_reduction_proxy {
22 34
23 bool GetDataReductionProxyBypassDuration( 35 bool ParseHeadersAndSetBypassDuration(
24 const net::HttpResponseHeaders* headers, 36 const net::HttpResponseHeaders* headers,
25 const std::string& action_prefix, 37 const std::string& action_prefix,
26 base::TimeDelta* duration) { 38 base::TimeDelta* bypass_duration) {
27 void* iter = NULL; 39 void* iter = NULL;
28 std::string value; 40 std::string value;
29 std::string name = "chrome-proxy"; 41 std::string name = "chrome-proxy";
Ryan Sleevi 2014/07/22 08:22:24 You're adding a new header into the exposed web pl
bengr 2014/07/22 19:57:15 This isn't going to change, even for desktop. We'v
30 42
31 while (headers->EnumerateHeader(&iter, name, &value)) { 43 while (headers->EnumerateHeader(&iter, name, &value)) {
32 if (value.size() > action_prefix.size()) { 44 if (value.size() > action_prefix.size()) {
33 if (LowerCaseEqualsASCII(value.begin(), 45 if (LowerCaseEqualsASCII(value.begin(),
34 value.begin() + action_prefix.size(), 46 value.begin() + action_prefix.size(),
35 action_prefix.c_str())) { 47 action_prefix.c_str())) {
36 int64 seconds; 48 int64 seconds;
37 if (!base::StringToInt64( 49 if (!base::StringToInt64(
38 StringPiece(value.begin() + action_prefix.size(), value.end()), 50 StringPiece(value.begin() + action_prefix.size(), value.end()),
39 &seconds) || seconds < 0) { 51 &seconds) || seconds < 0) {
40 continue; // In case there is a well formed instruction. 52 continue; // In case there is a well formed instruction.
41 } 53 }
42 *duration = TimeDelta::FromSeconds(seconds); 54 if (seconds != 0) {
55 *bypass_duration = TimeDelta::FromSeconds(seconds);
56 } else {
57 // Server deferred to us to choose a duration. Default to a random
58 // duration between one and five minutes.
59 *bypass_duration = GetDefaultBypassDuration();
60 }
43 return true; 61 return true;
44 } 62 }
45 } 63 }
46 } 64 }
47 return false; 65 return false;
48 } 66 }
49 67
50 bool GetDataReductionProxyInfo(const net::HttpResponseHeaders* headers, 68 bool ParseHeadersAndSetProxyInfo(const net::HttpResponseHeaders* headers,
51 DataReductionProxyInfo* proxy_info) { 69 DataReductionProxyInfo* proxy_info) {
52 DCHECK(proxy_info); 70 DCHECK(proxy_info);
53 proxy_info->bypass_all = false; 71 proxy_info->bypass_all = false;
54 proxy_info->bypass_duration = TimeDelta(); 72
55 // Support header of the form Chrome-Proxy: bypass|block=<duration>, where 73 // Support header of the form Chrome-Proxy: bypass|block=<duration>, where
56 // <duration> is the number of seconds to wait before retrying 74 // <duration> is the number of seconds to wait before retrying
57 // the proxy. If the duration is 0, then the default proxy retry delay 75 // the proxy. If the duration is 0, then the default proxy retry delay
58 // (specified in |ProxyList::UpdateRetryInfoOnFallback|) will be used. 76 // (specified in |ProxyList::UpdateRetryInfoOnFallback|) will be used.
59 // 'bypass' instructs Chrome to bypass the currently connected data reduction 77 // 'bypass' instructs Chrome to bypass the currently connected data reduction
60 // proxy, whereas 'block' instructs Chrome to bypass all available data 78 // proxy, whereas 'block' instructs Chrome to bypass all available data
61 // reduction proxies. 79 // reduction proxies.
62 80
63 // 'block' takes precedence over 'bypass', so look for it first. 81 // 'block' takes precedence over 'bypass', so look for it first.
64 // TODO(bengr): Reduce checks for 'block' and 'bypass' to a single loop. 82 // TODO(bengr): Reduce checks for 'block' and 'bypass' to a single loop.
65 if (GetDataReductionProxyBypassDuration( 83 if (ParseHeadersAndSetBypassDuration(
66 headers, "block=", &proxy_info->bypass_duration)) { 84 headers, "block=", &proxy_info->bypass_duration)) {
67 proxy_info->bypass_all = true; 85 proxy_info->bypass_all = true;
68 return true; 86 return true;
69 } 87 }
70 88
71 // Next, look for 'bypass'. 89 // Next, look for 'bypass'.
72 if (GetDataReductionProxyBypassDuration( 90 if (ParseHeadersAndSetBypassDuration(
73 headers, "bypass=", &proxy_info->bypass_duration)) { 91 headers, "bypass=", &proxy_info->bypass_duration)) {
74 return true; 92 return true;
75 } 93 }
76 return false; 94 return false;
77 } 95 }
78 96
79 bool HasDataReductionProxyViaHeader(const net::HttpResponseHeaders* headers) { 97 bool HasDataReductionProxyViaHeader(const net::HttpResponseHeaders* headers) {
80 const size_t kVersionSize = 4; 98 const size_t kVersionSize = 4;
81 const char kDataReductionProxyViaValue[] = "Chrome-Compression-Proxy"; 99 const char kDataReductionProxyViaValue[] = "Chrome-Compression-Proxy";
82 size_t value_len = strlen(kDataReductionProxyViaValue); 100 size_t value_len = strlen(kDataReductionProxyViaValue);
(...skipping 15 matching lines...) Expand all
98 iter = NULL; 116 iter = NULL;
99 while (headers->EnumerateHeader(&iter, "via", &value)) 117 while (headers->EnumerateHeader(&iter, "via", &value))
100 if (value == kDeprecatedDataReductionProxyViaValue) 118 if (value == kDeprecatedDataReductionProxyViaValue)
101 return true; 119 return true;
102 120
103 return false; 121 return false;
104 } 122 }
105 123
106 const int kShortBypassMaxSeconds = 59; 124 const int kShortBypassMaxSeconds = 59;
107 const int kMediumBypassMaxSeconds = 300; 125 const int kMediumBypassMaxSeconds = 300;
108 net::ProxyService::DataReductionProxyBypassType 126 net::ProxyService::DataReductionProxyBypassType
Ryan Sleevi 2014/07/22 08:22:24 1) linebreak between these constants. 2) Follow ht
Not at Google. Contact bengr 2014/07/22 23:03:53 Moved constants to top in anonymous namespace.
109 GetDataReductionProxyBypassType( 127 GetDataReductionProxyBypassType(
110 const net::HttpResponseHeaders* headers, 128 const net::HttpResponseHeaders* headers,
111 DataReductionProxyInfo* data_reduction_proxy_info) { 129 DataReductionProxyInfo* data_reduction_proxy_info) {
112 DCHECK(data_reduction_proxy_info); 130 DCHECK(data_reduction_proxy_info);
113 if (GetDataReductionProxyInfo(headers, data_reduction_proxy_info)) { 131 if (ParseHeadersAndSetProxyInfo(headers, data_reduction_proxy_info)) {
114 // A chrome-proxy response header is only present in a 502. For proper 132 // A chrome-proxy response header is only present in a 502. For proper
115 // reporting, this check must come before the 5xx checks below. 133 // reporting, this check must come before the 5xx checks below.
116 const TimeDelta& duration = data_reduction_proxy_info->bypass_duration; 134 const TimeDelta& duration = data_reduction_proxy_info->bypass_duration;
117 if (duration <= TimeDelta::FromSeconds(kShortBypassMaxSeconds)) 135 if (duration <= TimeDelta::FromSeconds(kShortBypassMaxSeconds))
118 return ProxyService::SHORT_BYPASS; 136 return ProxyService::SHORT_BYPASS;
119 if (duration <= TimeDelta::FromSeconds(kMediumBypassMaxSeconds)) 137 if (duration <= TimeDelta::FromSeconds(kMediumBypassMaxSeconds))
120 return ProxyService::MEDIUM_BYPASS; 138 return ProxyService::MEDIUM_BYPASS;
121 return ProxyService::LONG_BYPASS; 139 return ProxyService::LONG_BYPASS;
122 } 140 }
141
123 // Fall back if a 500, 502 or 503 is returned. 142 // Fall back if a 500, 502 or 503 is returned.
124 if (headers->response_code() == net::HTTP_INTERNAL_SERVER_ERROR) 143 if (headers->response_code() == net::HTTP_INTERNAL_SERVER_ERROR ||
125 return ProxyService::STATUS_500_HTTP_INTERNAL_SERVER_ERROR; 144 headers->response_code() == net::HTTP_BAD_GATEWAY ||
126 if (headers->response_code() == net::HTTP_BAD_GATEWAY) 145 headers->response_code() == net::HTTP_SERVICE_UNAVAILABLE) {
127 return ProxyService::STATUS_502_HTTP_BAD_GATEWAY; 146 data_reduction_proxy_info->bypass_duration = GetDefaultBypassDuration();
128 if (headers->response_code() == net::HTTP_SERVICE_UNAVAILABLE) 147
129 return ProxyService::STATUS_503_HTTP_SERVICE_UNAVAILABLE; 148 if (headers->response_code() == net::HTTP_INTERNAL_SERVER_ERROR)
149 return ProxyService::STATUS_500_HTTP_INTERNAL_SERVER_ERROR;
150 if (headers->response_code() == net::HTTP_BAD_GATEWAY)
151 return ProxyService::STATUS_502_HTTP_BAD_GATEWAY;
152 if (headers->response_code() == net::HTTP_SERVICE_UNAVAILABLE)
153 return ProxyService::STATUS_503_HTTP_SERVICE_UNAVAILABLE;
154 }
155
130 // TODO(kundaji): Bypass if Proxy-Authenticate header value cannot be 156 // TODO(kundaji): Bypass if Proxy-Authenticate header value cannot be
131 // interpreted by data reduction proxy. 157 // interpreted by data reduction proxy.
132 if (headers->response_code() == net::HTTP_PROXY_AUTHENTICATION_REQUIRED && 158 if (headers->response_code() == net::HTTP_PROXY_AUTHENTICATION_REQUIRED &&
133 !headers->HasHeader("Proxy-Authenticate")) { 159 !headers->HasHeader("Proxy-Authenticate")) {
160 data_reduction_proxy_info->bypass_duration = GetDefaultBypassDuration();
134 return ProxyService::MALFORMED_407; 161 return ProxyService::MALFORMED_407;
135 } 162 }
136 if (!HasDataReductionProxyViaHeader(headers) && 163 if (!HasDataReductionProxyViaHeader(headers) &&
137 (headers->response_code() != net::HTTP_NOT_MODIFIED)) { 164 (headers->response_code() != net::HTTP_NOT_MODIFIED)) {
165 data_reduction_proxy_info->bypass_duration = GetDefaultBypassDuration();
138 // A Via header might not be present in a 304. Since the goal of a 304 166 // A Via header might not be present in a 304. Since the goal of a 304
139 // response is to minimize information transfer, a sender in general 167 // response is to minimize information transfer, a sender in general
140 // should not generate representation metadata other than Cache-Control, 168 // should not generate representation metadata other than Cache-Control,
141 // Content-Location, Date, ETag, Expires, and Vary. 169 // Content-Location, Date, ETag, Expires, and Vary.
142 170
143 // The proxy Via header might also not be present in a 4xx response. 171 // The proxy Via header might also not be present in a 4xx response.
144 // Separate this case from other responses that are missing the header. 172 // Separate this case from other responses that are missing the header.
145 if (headers->response_code() >= net::HTTP_BAD_REQUEST && 173 if (headers->response_code() >= net::HTTP_BAD_REQUEST &&
146 headers->response_code() < net::HTTP_INTERNAL_SERVER_ERROR) { 174 headers->response_code() < net::HTTP_INTERNAL_SERVER_ERROR) {
147 return ProxyService::MISSING_VIA_HEADER_4XX; 175 return ProxyService::MISSING_VIA_HEADER_4XX;
148 } 176 }
149 return ProxyService::MISSING_VIA_HEADER_OTHER; 177 return ProxyService::MISSING_VIA_HEADER_OTHER;
150 } 178 }
151 // There is no bypass event. 179 // There is no bypass event.
152 return ProxyService::BYPASS_EVENT_TYPE_MAX; 180 return ProxyService::BYPASS_EVENT_TYPE_MAX;
153 } 181 }
154 182
155 } // namespace data_reduction_proxy 183 } // namespace data_reduction_proxy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698