Add diagnostics_writer.cc to the list of files allowed to printf.
[chromium-blink-merge.git] / components / data_reduction_proxy / browser / data_reduction_proxy_protocol.cc
blobf6b785dca91ab1b53b1c61b0c0ba2f7302496c5e
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
3 // found in the LICENSE file.
5 #include "components/data_reduction_proxy/browser/data_reduction_proxy_protocol.h"
7 #include "base/memory/ref_counted.h"
8 #include "base/time/time.h"
9 #include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
10 #include "components/data_reduction_proxy/common/data_reduction_proxy_headers.h"
11 #include "net/base/load_flags.h"
12 #include "net/http/http_response_headers.h"
13 #include "net/proxy/proxy_info.h"
14 #include "net/proxy/proxy_list.h"
15 #include "net/proxy/proxy_server.h"
16 #include "net/proxy/proxy_service.h"
17 #include "net/url_request/url_request.h"
18 #include "net/url_request/url_request_context.h"
19 #include "url/gurl.h"
21 namespace {
23 bool SetProxyServerFromGURL(const GURL& gurl,
24 net::ProxyServer* proxy_server) {
25 DCHECK(proxy_server);
26 if (!gurl.SchemeIsHTTPOrHTTPS())
27 return false;
28 *proxy_server = net::ProxyServer(gurl.SchemeIs("http") ?
29 net::ProxyServer::SCHEME_HTTP :
30 net::ProxyServer::SCHEME_HTTPS,
31 net::HostPortPair::FromURL(gurl));
32 return true;
35 } // namespace
37 namespace data_reduction_proxy {
39 bool MaybeBypassProxyAndPrepareToRetry(
40 const DataReductionProxyParams* data_reduction_proxy_params,
41 net::URLRequest* request,
42 const net::HttpResponseHeaders* original_response_headers,
43 scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
44 net::ProxyService::DataReductionProxyBypassType* proxy_bypass_type) {
45 if (!data_reduction_proxy_params)
46 return false;
47 std::pair<GURL, GURL> data_reduction_proxies;
48 if (!data_reduction_proxy_params->WasDataReductionProxyUsed(
49 request, &data_reduction_proxies)) {
50 return false;
53 // Empty implies either that the request was served from cache or that
54 // request was served directly from the origin.
55 if (request->proxy_server().IsEmpty())
56 return false;
58 if (data_reduction_proxies.first.is_empty())
59 return false;
61 DataReductionProxyInfo data_reduction_proxy_info;
62 net::ProxyService::DataReductionProxyBypassType bypass_type =
63 GetDataReductionProxyBypassType(original_response_headers,
64 &data_reduction_proxy_info);
65 if (proxy_bypass_type)
66 *proxy_bypass_type = bypass_type;
67 if (bypass_type == net::ProxyService::BYPASS_EVENT_TYPE_MAX)
68 return false;
70 DCHECK(request->context());
71 DCHECK(request->context()->proxy_service());
72 net::ProxyServer proxy_server;
73 SetProxyServerFromGURL(data_reduction_proxies.first, &proxy_server);
74 request->context()->proxy_service()->RecordDataReductionProxyBypassInfo(
75 !data_reduction_proxies.second.is_empty(),
76 data_reduction_proxy_info.bypass_all,
77 proxy_server,
78 bypass_type);
80 MarkProxiesAsBadUntil(request,
81 data_reduction_proxy_info.bypass_duration,
82 data_reduction_proxy_info.bypass_all,
83 data_reduction_proxies);
85 // Only retry idempotent methods.
86 if (!IsRequestIdempotent(request))
87 return false;
89 OverrideResponseAsRedirect(request,
90 original_response_headers,
91 override_response_headers);
92 return true;
95 void OnResolveProxyHandler(const GURL& url,
96 int load_flags,
97 const DataReductionProxyParams* params,
98 net::ProxyInfo* result) {
99 if ((load_flags & net::LOAD_BYPASS_DATA_REDUCTION_PROXY) &&
100 DataReductionProxyParams::IsIncludedInCriticalPathBypassFieldTrial() &&
101 !result->is_empty() &&
102 !result->is_direct() &&
103 params &&
104 params->IsDataReductionProxy(
105 result->proxy_server().host_port_pair(), NULL)) {
106 result->UseDirect();
110 bool IsRequestIdempotent(const net::URLRequest* request) {
111 DCHECK(request);
112 if (request->method() == "GET" ||
113 request->method() == "OPTIONS" ||
114 request->method() == "HEAD" ||
115 request->method() == "PUT" ||
116 request->method() == "DELETE" ||
117 request->method() == "TRACE")
118 return true;
119 return false;
122 void OverrideResponseAsRedirect(
123 net::URLRequest* request,
124 const net::HttpResponseHeaders* original_response_headers,
125 scoped_refptr<net::HttpResponseHeaders>* override_response_headers) {
126 DCHECK(request);
127 DCHECK(original_response_headers);
128 DCHECK(override_response_headers->get() == NULL);
130 request->SetLoadFlags(request->load_flags() |
131 net::LOAD_DISABLE_CACHE |
132 net::LOAD_BYPASS_PROXY);
133 *override_response_headers = new net::HttpResponseHeaders(
134 original_response_headers->raw_headers());
135 (*override_response_headers)->ReplaceStatusLine("HTTP/1.1 302 Found");
136 (*override_response_headers)->RemoveHeader("Location");
137 (*override_response_headers)->AddHeader("Location: " +
138 request->url().spec());
139 // TODO(bengr): Should we pop_back the request->url_chain?
142 void MarkProxiesAsBadUntil(
143 net::URLRequest* request,
144 base::TimeDelta& bypass_duration,
145 bool bypass_all,
146 const std::pair<GURL, GURL>& data_reduction_proxies) {
147 DCHECK(!data_reduction_proxies.first.is_empty());
148 // Synthesize a suitable |ProxyInfo| to add the proxies to the
149 // |ProxyRetryInfoMap| of the proxy service.
150 net::ProxyList proxy_list;
151 net::ProxyServer primary;
152 SetProxyServerFromGURL(data_reduction_proxies.first, &primary);
153 if (primary.is_valid())
154 proxy_list.AddProxyServer(primary);
155 net::ProxyServer fallback;
156 if (bypass_all) {
157 if (!data_reduction_proxies.second.is_empty())
158 SetProxyServerFromGURL(data_reduction_proxies.second, &fallback);
159 if (fallback.is_valid())
160 proxy_list.AddProxyServer(fallback);
161 proxy_list.AddProxyServer(net::ProxyServer::Direct());
163 net::ProxyInfo proxy_info;
164 proxy_info.UseProxyList(proxy_list);
165 DCHECK(request->context());
166 net::ProxyService* proxy_service = request->context()->proxy_service();
167 DCHECK(proxy_service);
169 proxy_service->MarkProxiesAsBadUntil(proxy_info,
170 bypass_duration,
171 fallback,
172 request->net_log());
175 } // namespace data_reduction_proxy