Index: components/data_reduction_proxy/common/data_reduction_proxy_headers.cc |
diff --git a/components/data_reduction_proxy/common/data_reduction_proxy_headers.cc b/components/data_reduction_proxy/common/data_reduction_proxy_headers.cc |
index b5c6119080948ba3618b2c0d02b51fcb521eb860..c6ed0faeaa718d3ff5ec2e5b20fbee5e24a0d3c4 100644 |
--- a/components/data_reduction_proxy/common/data_reduction_proxy_headers.cc |
+++ b/components/data_reduction_proxy/common/data_reduction_proxy_headers.cc |
@@ -6,6 +6,7 @@ |
#include <string> |
+#include "base/rand_util.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/strings/string_piece.h" |
#include "base/strings/string_util.h" |
@@ -20,10 +21,22 @@ using net::ProxyService; |
namespace data_reduction_proxy { |
-bool GetDataReductionProxyBypassDuration( |
+namespace { |
bengr
2014/07/21 22:45:15
nit: this doesn't have to be inside data_reduction
Not at Google. Contact bengr
2014/07/22 00:12:09
Done.
|
+ |
+// Returns a random bypass duration between 1 and 5 minutes. |
+base::TimeDelta GetRandBypassDuration() { |
bengr
2014/07/21 22:45:14
Suggest changing name to GetDefaultBypassDuration(
Not at Google. Contact bengr
2014/07/22 00:12:09
Done.
|
+ const int64 delta_ms = base::RandInt( |
+ base::TimeDelta::FromMinutes(1).InMilliseconds(), |
+ base::TimeDelta::FromMinutes(5).InMilliseconds()); |
+ return TimeDelta::FromMilliseconds(delta_ms); |
+} |
+ |
+} // namespace anonymous |
+ |
+bool ParseHeadersAndSetBypassDuration( |
const net::HttpResponseHeaders* headers, |
const std::string& action_prefix, |
- base::TimeDelta* duration) { |
+ base::TimeDelta* bypass_duration) { |
void* iter = NULL; |
std::string value; |
std::string name = "chrome-proxy"; |
@@ -39,7 +52,13 @@ bool GetDataReductionProxyBypassDuration( |
&seconds) || seconds < 0) { |
continue; // In case there is a well formed instruction. |
} |
- *duration = TimeDelta::FromSeconds(seconds); |
+ if (seconds != 0) { |
+ *bypass_duration = TimeDelta::FromSeconds(seconds); |
+ } else { |
+ // Server deferred to us to choose a duration. Default to a range from |
bengr
2014/07/21 22:45:16
range from... -> random duration between one and f
Not at Google. Contact bengr
2014/07/22 00:12:09
Done.
|
+ // one to five minutes. |
+ *bypass_duration = GetRandBypassDuration(); |
+ } |
return true; |
} |
} |
@@ -47,11 +66,11 @@ bool GetDataReductionProxyBypassDuration( |
return false; |
} |
-bool GetDataReductionProxyInfo(const net::HttpResponseHeaders* headers, |
- DataReductionProxyInfo* proxy_info) { |
+bool ParseHeadersAndSetProxyInfo(const net::HttpResponseHeaders* headers, |
+ DataReductionProxyInfo* proxy_info) { |
DCHECK(proxy_info); |
proxy_info->bypass_all = false; |
- proxy_info->bypass_duration = TimeDelta(); |
+ |
// Support header of the form Chrome-Proxy: bypass|block=<duration>, where |
// <duration> is the number of seconds to wait before retrying |
// the proxy. If the duration is 0, then the default proxy retry delay |
@@ -62,14 +81,14 @@ bool GetDataReductionProxyInfo(const net::HttpResponseHeaders* headers, |
// 'block' takes precedence over 'bypass', so look for it first. |
// TODO(bengr): Reduce checks for 'block' and 'bypass' to a single loop. |
- if (GetDataReductionProxyBypassDuration( |
+ if (ParseHeadersAndSetBypassDuration( |
headers, "block=", &proxy_info->bypass_duration)) { |
proxy_info->bypass_all = true; |
return true; |
} |
// Next, look for 'bypass'. |
- if (GetDataReductionProxyBypassDuration( |
+ if (ParseHeadersAndSetBypassDuration( |
headers, "bypass=", &proxy_info->bypass_duration)) { |
return true; |
} |
@@ -110,7 +129,7 @@ GetDataReductionProxyBypassType( |
const net::HttpResponseHeaders* headers, |
DataReductionProxyInfo* data_reduction_proxy_info) { |
DCHECK(data_reduction_proxy_info); |
- if (GetDataReductionProxyInfo(headers, data_reduction_proxy_info)) { |
+ if (ParseHeadersAndSetProxyInfo(headers, data_reduction_proxy_info)) { |
// A chrome-proxy response header is only present in a 502. For proper |
// reporting, this check must come before the 5xx checks below. |
const TimeDelta& duration = data_reduction_proxy_info->bypass_duration; |
@@ -120,21 +139,31 @@ GetDataReductionProxyBypassType( |
return ProxyService::MEDIUM_BYPASS; |
return ProxyService::LONG_BYPASS; |
} |
+ |
// Fall back if a 500, 502 or 503 is returned. |
- if (headers->response_code() == net::HTTP_INTERNAL_SERVER_ERROR) |
- return ProxyService::STATUS_500_HTTP_INTERNAL_SERVER_ERROR; |
- if (headers->response_code() == net::HTTP_BAD_GATEWAY) |
- return ProxyService::STATUS_502_HTTP_BAD_GATEWAY; |
- if (headers->response_code() == net::HTTP_SERVICE_UNAVAILABLE) |
- return ProxyService::STATUS_503_HTTP_SERVICE_UNAVAILABLE; |
+ if (headers->response_code() == net::HTTP_INTERNAL_SERVER_ERROR || |
bengr
2014/07/21 22:45:15
Coordinate with megjablon when landing.
Not at Google. Contact bengr
2014/07/22 00:12:09
Acknowledged.
|
+ headers->response_code() == net::HTTP_BAD_GATEWAY || |
+ headers->response_code() == net::HTTP_SERVICE_UNAVAILABLE) { |
+ data_reduction_proxy_info->bypass_duration = GetRandBypassDuration(); |
+ |
+ if (headers->response_code() == net::HTTP_INTERNAL_SERVER_ERROR) |
+ return ProxyService::STATUS_500_HTTP_INTERNAL_SERVER_ERROR; |
+ if (headers->response_code() == net::HTTP_BAD_GATEWAY) |
+ return ProxyService::STATUS_502_HTTP_BAD_GATEWAY; |
+ if (headers->response_code() == net::HTTP_SERVICE_UNAVAILABLE) |
+ return ProxyService::STATUS_503_HTTP_SERVICE_UNAVAILABLE; |
+ } |
+ |
// TODO(kundaji): Bypass if Proxy-Authenticate header value cannot be |
// interpreted by data reduction proxy. |
if (headers->response_code() == net::HTTP_PROXY_AUTHENTICATION_REQUIRED && |
!headers->HasHeader("Proxy-Authenticate")) { |
+ data_reduction_proxy_info->bypass_duration = GetRandBypassDuration(); |
return ProxyService::MALFORMED_407; |
} |
if (!HasDataReductionProxyViaHeader(headers) && |
(headers->response_code() != net::HTTP_NOT_MODIFIED)) { |
+ data_reduction_proxy_info->bypass_duration = GetRandBypassDuration(); |
// A Via header might not be present in a 304. Since the goal of a 304 |
// response is to minimize information transfer, a sender in general |
// should not generate representation metadata other than Cache-Control, |