Chromium Code Reviews| Index: components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc |
| diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc |
| index a8dca30a4f656e1d5a40a5e3703b85387eb506f2..50335495e1db25163bf65ac4960a0c670e660d2b 100644 |
| --- a/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc |
| +++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_headers.cc |
| @@ -20,6 +20,7 @@ |
| #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" |
| #include "net/http/http_response_headers.h" |
| #include "net/http/http_status_code.h" |
| +#include "net/url_request/url_request.h" |
| using base::StringPiece; |
| using base::TimeDelta; |
| @@ -106,6 +107,26 @@ bool IsPreviewType(const net::HttpResponseHeaders& headers, |
| return IsPreviewTypeInHeaderValue(header_value, transform_type); |
| } |
| +// Returns true if there is a cycle in |url_chain|. |
| +bool HasURLRedirectCycle(const std::vector<GURL>& url_chain) { |
| + if (url_chain.size() <= 1) |
| + return false; |
| + |
| + // If the last entry occurs more than once, then very likely there is a |
| + // redirect cycle. |
| + GURL last_entry = url_chain.back(); |
| + size_t last_entry_number_occurences = 0; |
| + |
| + for (const auto& url : url_chain) { |
| + if (url == last_entry) { |
| + last_entry_number_occurences++; |
| + if (last_entry_number_occurences >= 2) |
|
RyanSturm
2017/03/28 18:03:19
This looks confusing with the >=2 condition. Since
tbansal1
2017/03/28 19:59:48
Done.
|
| + return true; |
| + } |
| + } |
| + return false; |
| +} |
| + |
| } // namespace |
| namespace data_reduction_proxy { |
| @@ -283,10 +304,22 @@ bool HasDataReductionProxyViaHeader(const net::HttpResponseHeaders* headers, |
| } |
| DataReductionProxyBypassType GetDataReductionProxyBypassType( |
| - const net::HttpResponseHeaders* headers, |
| + const std::vector<GURL>& url_chain, |
| + const net::HttpResponseHeaders& headers, |
| DataReductionProxyInfo* data_reduction_proxy_info) { |
| DCHECK(data_reduction_proxy_info); |
| - if (ParseHeadersForBypassInfo(headers, data_reduction_proxy_info)) { |
| + |
| + bool has_via_header = HasDataReductionProxyViaHeader(&headers, nullptr); |
|
RyanSturm
2017/03/28 18:03:19
Any chance you want to change HasDataReductionProx
tbansal1
2017/03/28 19:59:48
I was planning to do it in a separate CL, but I ha
|
| + |
| + if (has_via_header && HasURLRedirectCycle(url_chain)) { |
| + data_reduction_proxy_info->bypass_all = true; |
| + data_reduction_proxy_info->mark_proxies_as_bad = false; |
| + data_reduction_proxy_info->bypass_duration = base::TimeDelta(); |
| + data_reduction_proxy_info->bypass_action = BYPASS_ACTION_TYPE_BLOCK_ONCE; |
| + return BYPASS_EVENT_TYPE_URL_REDIRECT_CYCLE; |
| + } |
| + |
| + if (ParseHeadersForBypassInfo(&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. |
| if (!data_reduction_proxy_info->mark_proxies_as_bad) |
| @@ -307,20 +340,19 @@ DataReductionProxyBypassType GetDataReductionProxyBypassType( |
| data_reduction_proxy_info->bypass_duration = GetDefaultBypassDuration(); |
| // Fall back if a 500, 502 or 503 is returned. |
| - if (headers->response_code() == net::HTTP_INTERNAL_SERVER_ERROR) |
| + if (headers.response_code() == net::HTTP_INTERNAL_SERVER_ERROR) |
| return BYPASS_EVENT_TYPE_STATUS_500_HTTP_INTERNAL_SERVER_ERROR; |
| - if (headers->response_code() == net::HTTP_BAD_GATEWAY) |
| + if (headers.response_code() == net::HTTP_BAD_GATEWAY) |
| return BYPASS_EVENT_TYPE_STATUS_502_HTTP_BAD_GATEWAY; |
| - if (headers->response_code() == net::HTTP_SERVICE_UNAVAILABLE) |
| + if (headers.response_code() == net::HTTP_SERVICE_UNAVAILABLE) |
| return BYPASS_EVENT_TYPE_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")) { |
| + if (headers.response_code() == net::HTTP_PROXY_AUTHENTICATION_REQUIRED && |
| + !headers.HasHeader("Proxy-Authenticate")) { |
| return BYPASS_EVENT_TYPE_MALFORMED_407; |
| } |
| - if (!HasDataReductionProxyViaHeader(headers, NULL) && |
| - (headers->response_code() != net::HTTP_NOT_MODIFIED)) { |
| + if (!has_via_header && (headers.response_code() != net::HTTP_NOT_MODIFIED)) { |
| // 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, |
| @@ -328,8 +360,8 @@ DataReductionProxyBypassType GetDataReductionProxyBypassType( |
| // The proxy Via header might also not be present in a 4xx response. |
| // Separate this case from other responses that are missing the header. |
| - if (headers->response_code() >= net::HTTP_BAD_REQUEST && |
| - headers->response_code() < net::HTTP_INTERNAL_SERVER_ERROR) { |
| + if (headers.response_code() >= net::HTTP_BAD_REQUEST && |
| + headers.response_code() < net::HTTP_INTERNAL_SERVER_ERROR) { |
| // At this point, any 4xx response that is missing the via header |
| // indicates an issue that is scoped to only the current request, so only |
| // bypass the data reduction proxy for the current request. |