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

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

Issue 467823002: Added support for 'Chrome-Proxy: block-once' header (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased on master Created 6 years, 4 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 #include <vector> 8 #include <vector>
9 9
10 #include "base/rand_util.h" 10 #include "base/rand_util.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_piece.h" 12 #include "base/strings/string_piece.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/time/time.h" 14 #include "base/time/time.h"
15 #include "net/http/http_response_headers.h" 15 #include "net/http/http_response_headers.h"
16 #include "net/http/http_status_code.h" 16 #include "net/http/http_status_code.h"
17 17
18 using base::StringPiece; 18 using base::StringPiece;
19 using base::TimeDelta; 19 using base::TimeDelta;
20 20
21 namespace { 21 namespace {
22 22
23 const char kChromeProxyHeader[] = "chrome-proxy"; 23 const char kChromeProxyHeader[] = "chrome-proxy";
24 const char kActionValueDelimiter = '='; 24 const char kActionValueDelimiter = '=';
25 25
26 const char kChromeProxyActionBlockOnce[] = "block-once";
26 const char kChromeProxyActionBlock[] = "block"; 27 const char kChromeProxyActionBlock[] = "block";
27 const char kChromeProxyActionBypass[] = "bypass"; 28 const char kChromeProxyActionBypass[] = "bypass";
28 29
29 // Actions for tamper detection fingerprints. 30 // Actions for tamper detection fingerprints.
30 const char kChromeProxyActionFingerprintChromeProxy[] = "fcp"; 31 const char kChromeProxyActionFingerprintChromeProxy[] = "fcp";
31 const char kChromeProxyActionFingerprintVia[] = "fvia"; 32 const char kChromeProxyActionFingerprintVia[] = "fvia";
32 const char kChromeProxyActionFingerprintOtherHeaders[] = "foh"; 33 const char kChromeProxyActionFingerprintOtherHeaders[] = "foh";
33 const char kChromeProxyActionFingerprintContentLength[] = "fcl"; 34 const char kChromeProxyActionFingerprintContentLength[] = "fcl";
34 35
35 const int kShortBypassMaxSeconds = 59; 36 const int kShortBypassMaxSeconds = 59;
36 const int kMediumBypassMaxSeconds = 300; 37 const int kMediumBypassMaxSeconds = 300;
37 38
38 // Returns a random bypass duration between 1 and 5 minutes. 39 // Returns a random bypass duration between 1 and 5 minutes.
39 base::TimeDelta GetDefaultBypassDuration() { 40 base::TimeDelta GetDefaultBypassDuration() {
40 const int64 delta_ms = 41 const int64 delta_ms =
41 base::RandInt(base::TimeDelta::FromMinutes(1).InMilliseconds(), 42 base::RandInt(base::TimeDelta::FromMinutes(1).InMilliseconds(),
42 base::TimeDelta::FromMinutes(5).InMilliseconds()); 43 base::TimeDelta::FromMinutes(5).InMilliseconds());
43 return TimeDelta::FromMilliseconds(delta_ms); 44 return TimeDelta::FromMilliseconds(delta_ms);
44 } 45 }
46
45 } // namespace 47 } // namespace
46 48
47 namespace data_reduction_proxy { 49 namespace data_reduction_proxy {
48 50
49 bool GetDataReductionProxyActionValue( 51 bool GetDataReductionProxyActionValue(
50 const net::HttpResponseHeaders* headers, 52 const net::HttpResponseHeaders* headers,
51 const std::string& action_prefix, 53 const std::string& action_prefix,
52 std::string* action_value) { 54 std::string* action_value) {
53 DCHECK(headers); 55 DCHECK(headers);
54 DCHECK(!action_prefix.empty()); 56 DCHECK(!action_prefix.empty());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 return true; 106 return true;
105 } 107 }
106 } 108 }
107 } 109 }
108 return false; 110 return false;
109 } 111 }
110 112
111 bool ParseHeadersAndSetProxyInfo(const net::HttpResponseHeaders* headers, 113 bool ParseHeadersAndSetProxyInfo(const net::HttpResponseHeaders* headers,
112 DataReductionProxyInfo* proxy_info) { 114 DataReductionProxyInfo* proxy_info) {
113 DCHECK(proxy_info); 115 DCHECK(proxy_info);
114 proxy_info->bypass_all = false; 116
115 // Support header of the form Chrome-Proxy: bypass|block=<duration>, where 117 // Support header of the form Chrome-Proxy: bypass|block=<duration>, where
116 // <duration> is the number of seconds to wait before retrying 118 // <duration> is the number of seconds to wait before retrying
117 // the proxy. If the duration is 0, then the default proxy retry delay 119 // the proxy. If the duration is 0, then the default proxy retry delay
118 // (specified in |ProxyList::UpdateRetryInfoOnFallback|) will be used. 120 // (specified in |ProxyList::UpdateRetryInfoOnFallback|) will be used.
119 // 'bypass' instructs Chrome to bypass the currently connected data reduction 121 // 'bypass' instructs Chrome to bypass the currently connected data reduction
120 // proxy, whereas 'block' instructs Chrome to bypass all available data 122 // proxy, whereas 'block' instructs Chrome to bypass all available data
121 // reduction proxies. 123 // reduction proxies.
122 124
123 // 'block' takes precedence over 'bypass', so look for it first. 125 // 'block' takes precedence over 'bypass' and 'block-once', so look for it
126 // first.
124 // TODO(bengr): Reduce checks for 'block' and 'bypass' to a single loop. 127 // TODO(bengr): Reduce checks for 'block' and 'bypass' to a single loop.
125 if (ParseHeadersAndSetBypassDuration( 128 if (ParseHeadersAndSetBypassDuration(
126 headers, kChromeProxyActionBlock, &proxy_info->bypass_duration)) { 129 headers, kChromeProxyActionBlock, &proxy_info->bypass_duration)) {
127 proxy_info->bypass_all = true; 130 proxy_info->bypass_all = true;
131 proxy_info->mark_proxies_as_bad = true;
128 return true; 132 return true;
129 } 133 }
130 134
131 // Next, look for 'bypass'. 135 // Next, look for 'bypass'.
132 if (ParseHeadersAndSetBypassDuration( 136 if (ParseHeadersAndSetBypassDuration(
133 headers, kChromeProxyActionBypass, &proxy_info->bypass_duration)) { 137 headers, kChromeProxyActionBypass, &proxy_info->bypass_duration)) {
138 proxy_info->bypass_all = false;
139 proxy_info->mark_proxies_as_bad = true;
134 return true; 140 return true;
135 } 141 }
142
143 // Lastly, look for 'block-once'. 'block-once' instructs Chrome to retry the
144 // current request (if it's idempotent), bypassing all available data
145 // reduction proxies. Unlike 'block', 'block-once' does not cause data
146 // reduction proxies to be bypassed for an extended period of time;
147 // 'block-once' only affects the retry of the current request.
148 if (headers->HasHeaderValue(kChromeProxyHeader,
149 kChromeProxyActionBlockOnce)) {
150 proxy_info->bypass_all = true;
151 proxy_info->mark_proxies_as_bad = false;
152 proxy_info->bypass_duration = TimeDelta();
153 return true;
154 }
155
136 return false; 156 return false;
137 } 157 }
138 158
139 bool HasDataReductionProxyViaHeader(const net::HttpResponseHeaders* headers, 159 bool HasDataReductionProxyViaHeader(const net::HttpResponseHeaders* headers,
140 bool* has_intermediary) { 160 bool* has_intermediary) {
141 const size_t kVersionSize = 4; 161 const size_t kVersionSize = 4;
142 const char kDataReductionProxyViaValue[] = "Chrome-Compression-Proxy"; 162 const char kDataReductionProxyViaValue[] = "Chrome-Compression-Proxy";
143 size_t value_len = strlen(kDataReductionProxyViaValue); 163 size_t value_len = strlen(kDataReductionProxyViaValue);
144 void* iter = NULL; 164 void* iter = NULL;
145 std::string value; 165 std::string value;
(...skipping 26 matching lines...) Expand all
172 return false; 192 return false;
173 } 193 }
174 194
175 DataReductionProxyBypassType GetDataReductionProxyBypassType( 195 DataReductionProxyBypassType GetDataReductionProxyBypassType(
176 const net::HttpResponseHeaders* headers, 196 const net::HttpResponseHeaders* headers,
177 DataReductionProxyInfo* data_reduction_proxy_info) { 197 DataReductionProxyInfo* data_reduction_proxy_info) {
178 DCHECK(data_reduction_proxy_info); 198 DCHECK(data_reduction_proxy_info);
179 if (ParseHeadersAndSetProxyInfo(headers, data_reduction_proxy_info)) { 199 if (ParseHeadersAndSetProxyInfo(headers, data_reduction_proxy_info)) {
180 // A chrome-proxy response header is only present in a 502. For proper 200 // A chrome-proxy response header is only present in a 502. For proper
181 // reporting, this check must come before the 5xx checks below. 201 // reporting, this check must come before the 5xx checks below.
202 if (!data_reduction_proxy_info->mark_proxies_as_bad)
203 return BYPASS_EVENT_TYPE_CURRENT;
204
182 const TimeDelta& duration = data_reduction_proxy_info->bypass_duration; 205 const TimeDelta& duration = data_reduction_proxy_info->bypass_duration;
183 // bypass=0 means bypass for a random duration between 1 to 5 minutes
184 if (duration == TimeDelta())
185 return BYPASS_EVENT_TYPE_MEDIUM;
186 if (duration <= TimeDelta::FromSeconds(kShortBypassMaxSeconds)) 206 if (duration <= TimeDelta::FromSeconds(kShortBypassMaxSeconds))
187 return BYPASS_EVENT_TYPE_SHORT; 207 return BYPASS_EVENT_TYPE_SHORT;
188 if (duration <= TimeDelta::FromSeconds(kMediumBypassMaxSeconds)) 208 if (duration <= TimeDelta::FromSeconds(kMediumBypassMaxSeconds))
189 return BYPASS_EVENT_TYPE_MEDIUM; 209 return BYPASS_EVENT_TYPE_MEDIUM;
190 return BYPASS_EVENT_TYPE_LONG; 210 return BYPASS_EVENT_TYPE_LONG;
191 } 211 }
212
213 // If a bypass is triggered by any of the following cases, then the data
214 // reduction proxy should be bypassed for a random duration between 1 and 5
215 // minutes.
216 data_reduction_proxy_info->mark_proxies_as_bad = true;
192 data_reduction_proxy_info->bypass_duration = GetDefaultBypassDuration(); 217 data_reduction_proxy_info->bypass_duration = GetDefaultBypassDuration();
218
193 // Fall back if a 500, 502 or 503 is returned. 219 // Fall back if a 500, 502 or 503 is returned.
194 if (headers->response_code() == net::HTTP_INTERNAL_SERVER_ERROR) 220 if (headers->response_code() == net::HTTP_INTERNAL_SERVER_ERROR)
195 return BYPASS_EVENT_TYPE_STATUS_500_HTTP_INTERNAL_SERVER_ERROR; 221 return BYPASS_EVENT_TYPE_STATUS_500_HTTP_INTERNAL_SERVER_ERROR;
196 if (headers->response_code() == net::HTTP_BAD_GATEWAY) 222 if (headers->response_code() == net::HTTP_BAD_GATEWAY)
197 return BYPASS_EVENT_TYPE_STATUS_502_HTTP_BAD_GATEWAY; 223 return BYPASS_EVENT_TYPE_STATUS_502_HTTP_BAD_GATEWAY;
198 if (headers->response_code() == net::HTTP_SERVICE_UNAVAILABLE) 224 if (headers->response_code() == net::HTTP_SERVICE_UNAVAILABLE)
199 return BYPASS_EVENT_TYPE_STATUS_503_HTTP_SERVICE_UNAVAILABLE; 225 return BYPASS_EVENT_TYPE_STATUS_503_HTTP_SERVICE_UNAVAILABLE;
200 // TODO(kundaji): Bypass if Proxy-Authenticate header value cannot be 226 // TODO(kundaji): Bypass if Proxy-Authenticate header value cannot be
201 // interpreted by data reduction proxy. 227 // interpreted by data reduction proxy.
202 if (headers->response_code() == net::HTTP_PROXY_AUTHENTICATION_REQUIRED && 228 if (headers->response_code() == net::HTTP_PROXY_AUTHENTICATION_REQUIRED &&
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 value.begin() + chrome_proxy_fingerprint_prefix.size(), 300 value.begin() + chrome_proxy_fingerprint_prefix.size(),
275 chrome_proxy_fingerprint_prefix.c_str())) { 301 chrome_proxy_fingerprint_prefix.c_str())) {
276 continue; 302 continue;
277 } 303 }
278 } 304 }
279 values->push_back(value); 305 values->push_back(value);
280 } 306 }
281 } 307 }
282 308
283 } // namespace data_reduction_proxy 309 } // namespace data_reduction_proxy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698