#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_tamper_detection.h"
+#include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h"
#include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h"
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
+#include "net/proxy/proxy_config.h"
#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_list.h"
+#include "net/proxy/proxy_retry_info.h"
#include "net/proxy/proxy_server.h"
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request.h"
#include "url/gurl.h"
namespace {
+
bool SetProxyServerFromGURL(const GURL& gurl,
net::ProxyServer* proxy_server) {
DCHECK(proxy_server);
net::HostPortPair::FromURL(gurl));
return true;
}
+
} // namespace
namespace data_reduction_proxy {
const DataReductionProxyParams* data_reduction_proxy_params,
net::URLRequest* request,
const net::HttpResponseHeaders* original_response_headers,
- scoped_refptr<net::HttpResponseHeaders>* override_response_headers) {
+ scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
+ DataReductionProxyBypassType* proxy_bypass_type) {
if (!data_reduction_proxy_params)
return false;
- std::pair<GURL, GURL> data_reduction_proxies;
+ DataReductionProxyTypeInfo data_reduction_proxy_type_info;
if (!data_reduction_proxy_params->WasDataReductionProxyUsed(
- request, &data_reduction_proxies)) {
+ request, &data_reduction_proxy_type_info)) {
return false;
}
if (request->proxy_server().IsEmpty())
return false;
- if (data_reduction_proxies.first.is_empty())
+ if (data_reduction_proxy_type_info.proxy_servers.first.is_empty())
return false;
+ DataReductionProxyTamperDetection::DetectAndReport(
+ original_response_headers,
+ data_reduction_proxy_type_info.proxy_servers.first.SchemeIsSecure());
+
DataReductionProxyInfo data_reduction_proxy_info;
- net::ProxyService::DataReductionProxyBypassEventType bypass_type =
- GetDataReductionProxyBypassEventType(
- original_response_headers, &data_reduction_proxy_info);
- if (bypass_type == net::ProxyService::BYPASS_EVENT_TYPE_MAX) {
+ DataReductionProxyBypassType bypass_type =
+ GetDataReductionProxyBypassType(original_response_headers,
+ &data_reduction_proxy_info);
+ if (proxy_bypass_type)
+ *proxy_bypass_type = bypass_type;
+ if (bypass_type == BYPASS_EVENT_TYPE_MAX)
return false;
- }
DCHECK(request->context());
DCHECK(request->context()->proxy_service());
net::ProxyServer proxy_server;
- SetProxyServerFromGURL(data_reduction_proxies.first, &proxy_server);
- request->context()->proxy_service()->RecordDataReductionProxyBypassInfo(
- !data_reduction_proxies.second.is_empty(), proxy_server, bypass_type);
+ SetProxyServerFromGURL(
+ data_reduction_proxy_type_info.proxy_servers.first, &proxy_server);
+
+ // Only record UMA if the proxy isn't already on the retry list.
+ const net::ProxyRetryInfoMap& proxy_retry_info =
+ request->context()->proxy_service()->proxy_retry_info();
+ if (proxy_retry_info.find(proxy_server.ToURI()) == proxy_retry_info.end()) {
+ DataReductionProxyUsageStats::RecordDataReductionProxyBypassInfo(
+ !data_reduction_proxy_type_info.proxy_servers.second.is_empty(),
+ data_reduction_proxy_info.bypass_all,
+ proxy_server,
+ bypass_type);
+ }
- MarkProxiesAsBadUntil(request,
- data_reduction_proxy_info.bypass_duration,
- data_reduction_proxy_info.bypass_all,
- data_reduction_proxies);
+ if (data_reduction_proxy_info.mark_proxies_as_bad) {
+ MarkProxiesAsBadUntil(request,
+ data_reduction_proxy_info.bypass_duration,
+ data_reduction_proxy_info.bypass_all,
+ data_reduction_proxy_type_info.proxy_servers);
+ }
// Only retry idempotent methods.
if (!IsRequestIdempotent(request))
return true;
}
+void OnResolveProxyHandler(const GURL& url,
+ int load_flags,
+ const net::ProxyConfig& data_reduction_proxy_config,
+ const net::ProxyRetryInfoMap& proxy_retry_info,
+ const DataReductionProxyParams* params,
+ net::ProxyInfo* result) {
+ if (data_reduction_proxy_config.is_valid() &&
+ result->proxy_server().is_direct()) {
+ net::ProxyInfo data_reduction_proxy_info;
+ data_reduction_proxy_config.proxy_rules().Apply(
+ url, &data_reduction_proxy_info);
+ data_reduction_proxy_info.DeprioritizeBadProxies(proxy_retry_info);
+ result->Use(data_reduction_proxy_info);
+ }
+ if ((load_flags & net::LOAD_BYPASS_DATA_REDUCTION_PROXY) &&
+ DataReductionProxyParams::IsIncludedInCriticalPathBypassFieldTrial() &&
+ !result->is_empty() &&
+ !result->is_direct() &&
+ params &&
+ params->IsDataReductionProxy(
+ result->proxy_server().host_port_pair(), NULL)) {
+ result->UseDirect();
+ }
+}
bool IsRequestIdempotent(const net::URLRequest* request) {
DCHECK(request);
DCHECK(override_response_headers->get() == NULL);
request->SetLoadFlags(request->load_flags() |
- net::LOAD_DISABLE_CACHE |
- net::LOAD_BYPASS_PROXY);
+ net::LOAD_DISABLE_CACHE |
+ net::LOAD_BYPASS_PROXY);
*override_response_headers = new net::HttpResponseHeaders(
original_response_headers->raw_headers());
(*override_response_headers)->ReplaceStatusLine("HTTP/1.1 302 Found");