| 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..37b4c5f01b6a4433186ef5693bc14f8b9a63600f 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,20 @@ using net::ProxyService;
|
|
|
| namespace data_reduction_proxy {
|
|
|
| -bool GetDataReductionProxyBypassDuration(
|
| +namespace {
|
| +
|
| +// Sets a random bypass duration between 1 and 5 minutes.
|
| +void SetRandBypassDuration(DataReductionProxyInfo* data_reduction_proxy_info) {
|
| + data_reduction_proxy_info->bypass_duration = TimeDelta::FromMilliseconds(
|
| + base::RandInt(1 * 60 * 1000, 5 * 60 * 1000));
|
| +}
|
| +
|
| +} // namespace anonymous
|
| +
|
| +bool ParseHeadersAndSetProxyInfoBypassDuration(
|
| const net::HttpResponseHeaders* headers,
|
| const std::string& action_prefix,
|
| - base::TimeDelta* duration) {
|
| + DataReductionProxyInfo* proxy_info) {
|
| void* iter = NULL;
|
| std::string value;
|
| std::string name = "chrome-proxy";
|
| @@ -39,7 +50,13 @@ bool GetDataReductionProxyBypassDuration(
|
| &seconds) || seconds < 0) {
|
| continue; // In case there is a well formed instruction.
|
| }
|
| - *duration = TimeDelta::FromSeconds(seconds);
|
| + if (seconds != 0) {
|
| + proxy_info->bypass_duration = TimeDelta::FromSeconds(seconds);
|
| + } else {
|
| + // Server deferred to us to choose a duration. Default to a range from
|
| + // one to five minutes.
|
| + SetRandBypassDuration(proxy_info);
|
| + }
|
| return true;
|
| }
|
| }
|
| @@ -47,11 +64,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,15 +79,15 @@ 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(
|
| - headers, "block=", &proxy_info->bypass_duration)) {
|
| + if (ParseHeadersAndSetProxyInfoBypassDuration(
|
| + headers, "block=", proxy_info)) {
|
| proxy_info->bypass_all = true;
|
| return true;
|
| }
|
|
|
| // Next, look for 'bypass'.
|
| - if (GetDataReductionProxyBypassDuration(
|
| - headers, "bypass=", &proxy_info->bypass_duration)) {
|
| + if (ParseHeadersAndSetProxyInfoBypassDuration(
|
| + headers, "bypass=", proxy_info)) {
|
| return true;
|
| }
|
| return false;
|
| @@ -110,7 +127,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 +137,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 ||
|
| + headers->response_code() == net::HTTP_BAD_GATEWAY ||
|
| + headers->response_code() == net::HTTP_SERVICE_UNAVAILABLE) {
|
| + SetRandBypassDuration(data_reduction_proxy_info);
|
| +
|
| + 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")) {
|
| + SetRandBypassDuration(data_reduction_proxy_info);
|
| return ProxyService::MALFORMED_407;
|
| }
|
| if (!HasDataReductionProxyViaHeader(headers) &&
|
| (headers->response_code() != net::HTTP_NOT_MODIFIED)) {
|
| + SetRandBypassDuration(data_reduction_proxy_info);
|
| // 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,
|
|
|