ProjectingObserverChromeos: Drop DBusThreadManager dependency for better testing.
[chromium-blink-merge.git] / components / data_reduction_proxy / browser / data_reduction_proxy_params.cc
blobd7dcde52008fafbb71e7c325cd58e0702982312c
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_params.h"
7 #include <vector>
9 #include "base/command_line.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/metrics/field_trial.h"
12 #include "base/time/time.h"
13 #include "components/data_reduction_proxy/common/data_reduction_proxy_switches.h"
14 #include "net/base/host_port_pair.h"
15 #include "net/proxy/proxy_config.h"
16 #include "net/proxy/proxy_info.h"
17 #include "net/proxy/proxy_retry_info.h"
18 #include "net/proxy/proxy_server.h"
19 #include "net/proxy/proxy_service.h"
20 #include "net/url_request/url_request.h"
21 #include "net/url_request/url_request_context.h"
22 #include "url/url_constants.h"
24 using base::FieldTrialList;
26 namespace {
28 const char kEnabled[] = "Enabled";
29 const char kDefaultOrigin[] = "https://proxy.googlezip.net:443/";
30 const char kDevOrigin[] = "https://proxy-dev.googlezip.net:443/";
31 const char kDevFallbackOrigin[] = "http://proxy-dev.googlezip.net:80/";
32 const char kDefaultFallbackOrigin[] = "http://compress.googlezip.net:80/";
33 // This is for a proxy that supports HTTP CONNECT to tunnel SSL traffic.
34 // The proxy listens on port 443, but uses the HTTP protocol to set up
35 // the tunnel, not HTTPS.
36 const char kDefaultSslOrigin[] = "http://ssl.googlezip.net:443/";
37 const char kDefaultAltOrigin[] = "http://ssl.googlezip.net:80/";
38 const char kDefaultAltFallbackOrigin[] = "http://ssl.googlezip.net:80/";
39 const char kDefaultProbeUrl[] = "http://check.googlezip.net/connect";
40 const char kDefaultWarmupUrl[] = "http://www.gstatic.com/generate_204";
42 } // namespace
44 namespace data_reduction_proxy {
46 // static
47 bool DataReductionProxyParams::IsIncludedInAlternativeFieldTrial() {
48 const std::string group_name = base::FieldTrialList::FindFullName(
49 "DataCompressionProxyAlternativeConfiguration");
50 if (CommandLine::ForCurrentProcess()->HasSwitch(
51 data_reduction_proxy::switches::kEnableDataReductionProxyAlt)) {
52 return true;
54 return group_name == kEnabled;
57 // static
58 bool DataReductionProxyParams::IsIncludedInPromoFieldTrial() {
59 return FieldTrialList::FindFullName(
60 "DataCompressionProxyPromoVisibility") == kEnabled;
63 // static
64 bool DataReductionProxyParams::IsIncludedInPreconnectHintingFieldTrial() {
65 return FieldTrialList::FindFullName(
66 "DataCompressionProxyPreconnectHints") == kEnabled;
69 // static
70 bool DataReductionProxyParams::IsIncludedInCriticalPathBypassFieldTrial() {
71 return FieldTrialList::FindFullName(
72 "DataCompressionProxyCriticalBypass") == kEnabled;
75 // static
76 bool DataReductionProxyParams::IsIncludedInHoldbackFieldTrial() {
77 return FieldTrialList::FindFullName(
78 "DataCompressionProxyHoldback") == kEnabled;
81 // static
82 bool DataReductionProxyParams::
83 IsIncludedInRemoveMissingViaHeaderOtherBypassFieldTrial() {
84 return FieldTrialList::FindFullName(
85 "DataReductionProxyRemoveMissingViaHeaderOtherBypass") == kEnabled;
88 DataReductionProxyTypeInfo::DataReductionProxyTypeInfo()
89 : proxy_servers(),
90 is_fallback(false),
91 is_alternative(false),
92 is_ssl(false) {
95 DataReductionProxyTypeInfo::~DataReductionProxyTypeInfo(){
98 DataReductionProxyParams::DataReductionProxyParams(int flags)
99 : allowed_((flags & kAllowed) == kAllowed),
100 fallback_allowed_((flags & kFallbackAllowed) == kFallbackAllowed),
101 alt_allowed_((flags & kAlternativeAllowed) == kAlternativeAllowed),
102 alt_fallback_allowed_(
103 (flags & kAlternativeFallbackAllowed) == kAlternativeFallbackAllowed),
104 promo_allowed_((flags & kPromoAllowed) == kPromoAllowed),
105 holdback_((flags & kHoldback) == kHoldback),
106 configured_on_command_line_(false) {
107 bool result = Init(
108 allowed_, fallback_allowed_, alt_allowed_, alt_fallback_allowed_);
109 DCHECK(result);
112 scoped_ptr<DataReductionProxyParams> DataReductionProxyParams::Clone() {
113 return scoped_ptr<DataReductionProxyParams>(
114 new DataReductionProxyParams(*this));
117 DataReductionProxyParams::DataReductionProxyParams(
118 const DataReductionProxyParams& other)
119 : origin_(other.origin_),
120 fallback_origin_(other.fallback_origin_),
121 ssl_origin_(other.ssl_origin_),
122 alt_origin_(other.alt_origin_),
123 alt_fallback_origin_(other.alt_fallback_origin_),
124 probe_url_(other.probe_url_),
125 warmup_url_(other.warmup_url_),
126 allowed_(other.allowed_),
127 fallback_allowed_(other.fallback_allowed_),
128 alt_allowed_(other.alt_allowed_),
129 alt_fallback_allowed_(other.alt_fallback_allowed_),
130 promo_allowed_(other.promo_allowed_),
131 holdback_(other.holdback_),
132 configured_on_command_line_(other.configured_on_command_line_) {
135 DataReductionProxyParams::~DataReductionProxyParams() {
138 DataReductionProxyParams::DataReductionProxyList
139 DataReductionProxyParams::GetAllowedProxies() const {
140 DataReductionProxyList list;
141 if (allowed_) {
142 list.push_back(origin_);
144 if (allowed_ && fallback_allowed_)
145 list.push_back(fallback_origin_);
146 if (alt_allowed_) {
147 list.push_back(alt_origin_);
148 list.push_back(ssl_origin_);
150 if (alt_allowed_ && alt_fallback_allowed_)
151 list.push_back(alt_fallback_origin_);
152 return list;
155 DataReductionProxyParams::DataReductionProxyParams(int flags,
156 bool should_call_init)
157 : allowed_((flags & kAllowed) == kAllowed),
158 fallback_allowed_((flags & kFallbackAllowed) == kFallbackAllowed),
159 alt_allowed_((flags & kAlternativeAllowed) == kAlternativeAllowed),
160 alt_fallback_allowed_(
161 (flags & kAlternativeFallbackAllowed) == kAlternativeFallbackAllowed),
162 promo_allowed_((flags & kPromoAllowed) == kPromoAllowed),
163 holdback_((flags & kHoldback) == kHoldback),
164 configured_on_command_line_(false) {
165 if (should_call_init) {
166 bool result = Init(
167 allowed_, fallback_allowed_, alt_allowed_, alt_fallback_allowed_);
168 DCHECK(result);
172 bool DataReductionProxyParams::Init(bool allowed,
173 bool fallback_allowed,
174 bool alt_allowed,
175 bool alt_fallback_allowed) {
176 InitWithoutChecks();
177 // Verify that all necessary params are set.
178 if (allowed) {
179 if (!origin_.is_valid()) {
180 DVLOG(1) << "Invalid data reduction proxy origin: " << origin_.spec();
181 return false;
185 if (allowed && fallback_allowed) {
186 if (!fallback_origin_.is_valid()) {
187 DVLOG(1) << "Invalid data reduction proxy fallback origin: "
188 << fallback_origin_.spec();
189 return false;
193 if (alt_allowed) {
194 if (!allowed) {
195 DVLOG(1) << "Alternative data reduction proxy configuration cannot "
196 << "be allowed if the regular configuration is not allowed";
197 return false;
199 if (!alt_origin_.is_valid()) {
200 DVLOG(1) << "Invalid alternative origin:" << alt_origin_.spec();
201 return false;
203 if (!ssl_origin_.is_valid()) {
204 DVLOG(1) << "Invalid ssl origin: " << ssl_origin_.spec();
205 return false;
209 if (alt_allowed && alt_fallback_allowed) {
210 if (!alt_fallback_origin_.is_valid()) {
211 DVLOG(1) << "Invalid alternative fallback origin:"
212 << alt_fallback_origin_.spec();
213 return false;
217 if (allowed && !probe_url_.is_valid()) {
218 DVLOG(1) << "Invalid probe url: <null>";
219 return false;
222 if (fallback_allowed_ && !allowed_) {
223 DVLOG(1) << "The data reduction proxy fallback cannot be allowed if "
224 << "the data reduction proxy is not allowed";
225 return false;
227 if (alt_fallback_allowed_ && !alt_allowed_) {
228 DVLOG(1) << "The data reduction proxy alternative fallback cannot be "
229 << "allowed if the alternative data reduction proxy is not allowed";
230 return false;
232 if (promo_allowed_ && !allowed_) {
233 DVLOG(1) << "The data reduction proxy promo cannot be allowed if the "
234 << "data reduction proxy is not allowed";
235 return false;
237 return true;
241 void DataReductionProxyParams::InitWithoutChecks() {
242 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
243 std::string origin;
244 if (!command_line.HasSwitch(switches::kDisableDataReductionProxyDev)) {
245 origin = command_line.GetSwitchValueASCII(
246 switches::kDataReductionProxyDev);
248 if (origin.empty())
249 origin = command_line.GetSwitchValueASCII(switches::kDataReductionProxy);
250 std::string fallback_origin =
251 command_line.GetSwitchValueASCII(switches::kDataReductionProxyFallback);
252 std::string ssl_origin =
253 command_line.GetSwitchValueASCII(switches::kDataReductionSSLProxy);
254 std::string alt_origin =
255 command_line.GetSwitchValueASCII(switches::kDataReductionProxyAlt);
256 std::string alt_fallback_origin = command_line.GetSwitchValueASCII(
257 switches::kDataReductionProxyAltFallback);
259 configured_on_command_line_ =
260 !(origin.empty() && fallback_origin.empty() && ssl_origin.empty() &&
261 alt_origin.empty() && alt_fallback_origin.empty());
264 // Configuring the proxy on the command line overrides the values of
265 // |allowed_| and |alt_allowed_|.
266 if (configured_on_command_line_)
267 allowed_ = true;
268 if (!(ssl_origin.empty() &&
269 alt_origin.empty()))
270 alt_allowed_ = true;
272 std::string probe_url = command_line.GetSwitchValueASCII(
273 switches::kDataReductionProxyProbeURL);
274 std::string warmup_url = command_line.GetSwitchValueASCII(
275 switches::kDataReductionProxyWarmupURL);
277 // Set from preprocessor constants those params that are not specified on the
278 // command line.
279 if (origin.empty())
280 origin = GetDefaultDevOrigin();
281 if (origin.empty())
282 origin = GetDefaultOrigin();
283 if (fallback_origin.empty())
284 fallback_origin = GetDefaultDevFallbackOrigin();
285 if (fallback_origin.empty())
286 fallback_origin = GetDefaultFallbackOrigin();
287 if (ssl_origin.empty())
288 ssl_origin = GetDefaultSSLOrigin();
289 if (alt_origin.empty())
290 alt_origin = GetDefaultAltOrigin();
291 if (alt_fallback_origin.empty())
292 alt_fallback_origin = GetDefaultAltFallbackOrigin();
293 if (probe_url.empty())
294 probe_url = GetDefaultProbeURL();
295 if (warmup_url.empty())
296 warmup_url = GetDefaultWarmupURL();
298 origin_ = GURL(origin);
299 fallback_origin_ = GURL(fallback_origin);
300 ssl_origin_ = GURL(ssl_origin);
301 alt_origin_ = GURL(alt_origin);
302 alt_fallback_origin_ = GURL(alt_fallback_origin);
303 probe_url_ = GURL(probe_url);
304 warmup_url_ = GURL(warmup_url);
308 bool DataReductionProxyParams::WasDataReductionProxyUsed(
309 const net::URLRequest* request,
310 DataReductionProxyTypeInfo* proxy_info) const {
311 DCHECK(request);
312 return IsDataReductionProxy(request->proxy_server(), proxy_info);
315 bool DataReductionProxyParams::IsDataReductionProxy(
316 const net::HostPortPair& host_port_pair,
317 DataReductionProxyTypeInfo* proxy_info) const {
318 if (net::HostPortPair::FromURL(origin()).Equals(host_port_pair)) {
319 if (proxy_info) {
320 proxy_info->proxy_servers.first = origin();
321 if (fallback_allowed())
322 proxy_info->proxy_servers.second = fallback_origin();
324 return true;
327 if (fallback_allowed() &&
328 net::HostPortPair::FromURL(fallback_origin()).Equals(host_port_pair)) {
329 if (proxy_info) {
330 proxy_info->proxy_servers.first = fallback_origin();
331 proxy_info->proxy_servers.second = GURL();
332 proxy_info->is_fallback = true;
334 return true;
336 if (net::HostPortPair::FromURL(alt_origin()).Equals(host_port_pair)) {
337 if (proxy_info) {
338 proxy_info->proxy_servers.first = alt_origin();
339 proxy_info->is_alternative = true;
340 if (alternative_fallback_allowed())
341 proxy_info->proxy_servers.second = alt_fallback_origin();
343 return true;
345 if (alternative_fallback_allowed() &&
346 net::HostPortPair::FromURL(alt_fallback_origin()).Equals(
347 host_port_pair)) {
348 if (proxy_info) {
349 proxy_info->proxy_servers.first = alt_fallback_origin();
350 proxy_info->proxy_servers.second = GURL();
351 proxy_info->is_fallback = true;
352 proxy_info->is_alternative = true;
354 return true;
356 if (net::HostPortPair::FromURL(ssl_origin()).Equals(host_port_pair)) {
357 if (proxy_info) {
358 proxy_info->proxy_servers.first = ssl_origin();
359 proxy_info->proxy_servers.second = GURL();
360 proxy_info->is_ssl = true;
362 return true;
364 return false;
367 bool DataReductionProxyParams::IsBypassedByDataReductionProxyLocalRules(
368 const net::URLRequest& request,
369 const net::ProxyConfig& data_reduction_proxy_config) const {
370 DCHECK(request.context());
371 DCHECK(request.context()->proxy_service());
372 net::ProxyInfo result;
373 data_reduction_proxy_config.proxy_rules().Apply(
374 request.url(), &result);
375 if (!result.proxy_server().is_valid())
376 return true;
377 if (result.proxy_server().is_direct())
378 return true;
379 return !IsDataReductionProxy(result.proxy_server().host_port_pair(), NULL);
382 std::string DataReductionProxyParams::GetDefaultDevOrigin() const {
383 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
384 if (command_line.HasSwitch(switches::kDisableDataReductionProxyDev))
385 return std::string();
386 if (command_line.HasSwitch(switches::kEnableDataReductionProxyDev) ||
387 (FieldTrialList::FindFullName("DataCompressionProxyDevRollout") ==
388 kEnabled)) {
389 return kDevOrigin;
391 return std::string();
394 std::string DataReductionProxyParams::GetDefaultDevFallbackOrigin() const {
395 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
396 if (command_line.HasSwitch(switches::kDisableDataReductionProxyDev))
397 return std::string();
398 if (command_line.HasSwitch(switches::kEnableDataReductionProxyDev) ||
399 (FieldTrialList::FindFullName("DataCompressionProxyDevRollout") ==
400 kEnabled)) {
401 return kDevFallbackOrigin;
403 return std::string();
406 bool DataReductionProxyParams::AreDataReductionProxiesBypassed(
407 const net::URLRequest& request, base::TimeDelta* min_retry_delay) const {
408 if (request.context() != NULL &&
409 request.context()->proxy_service() != NULL) {
410 return AreProxiesBypassed(
411 request.context()->proxy_service()->proxy_retry_info(),
412 request.url().SchemeIs(url::kHttpsScheme),
413 min_retry_delay);
416 return false;
419 bool DataReductionProxyParams::AreProxiesBypassed(
420 const net::ProxyRetryInfoMap& retry_map,
421 bool is_https,
422 base::TimeDelta* min_retry_delay) const {
423 if (retry_map.size() == 0)
424 return false;
426 // If the request is https, consider only the ssl proxy.
427 if (is_https) {
428 if (alt_allowed_) {
429 return ArePrimaryAndFallbackBypassed(
430 retry_map, ssl_origin_, GURL(), min_retry_delay);
432 NOTREACHED();
433 return false;
436 if (allowed_ && ArePrimaryAndFallbackBypassed(
437 retry_map, origin_, fallback_origin_, min_retry_delay)) {
438 return true;
441 if (alt_allowed_ && ArePrimaryAndFallbackBypassed(
442 retry_map, alt_origin_, alt_fallback_origin_, min_retry_delay)) {
443 return true;
446 return false;
449 bool DataReductionProxyParams::ArePrimaryAndFallbackBypassed(
450 const net::ProxyRetryInfoMap& retry_map,
451 const GURL& primary,
452 const GURL& fallback,
453 base::TimeDelta* min_retry_delay) const {
454 net::ProxyRetryInfoMap::const_iterator found = retry_map.end();
455 if (min_retry_delay)
456 *min_retry_delay = base::TimeDelta::Max();
458 // Look for the primary proxy in the retry map. This must be done before
459 // looking for the fallback in order to assign |min_retry_delay| if the
460 // primary proxy has a shorter delay.
461 if (!fallback_allowed_ || !fallback.is_valid() || min_retry_delay) {
462 found = retry_map.find(
463 net::ProxyServer(primary.SchemeIs(url::kHttpsScheme) ?
464 net::ProxyServer::SCHEME_HTTPS :
465 net::ProxyServer::SCHEME_HTTP,
466 net::HostPortPair::FromURL(primary)).ToURI());
467 if (found != retry_map.end() && min_retry_delay) {
468 *min_retry_delay = found->second.current_delay;
472 if (fallback_allowed_ && fallback.is_valid()) {
473 // If fallback is allowed, only the fallback proxy needs to be on the retry
474 // map to know if there was a bypass. We can reset found and forget if the
475 // primary was on the retry map.
476 found = retry_map.find(
477 net::ProxyServer(fallback.SchemeIs(url::kHttpsScheme) ?
478 net::ProxyServer::SCHEME_HTTPS :
479 net::ProxyServer::SCHEME_HTTP,
480 net::HostPortPair::FromURL(fallback)).ToURI());
481 if (found != retry_map.end() &&
482 min_retry_delay &&
483 *min_retry_delay > found->second.current_delay) {
484 *min_retry_delay = found->second.current_delay;
488 return found != retry_map.end();
491 // TODO(kundaji): Remove tests for macro definitions.
492 std::string DataReductionProxyParams::GetDefaultOrigin() const {
493 return kDefaultOrigin;
496 std::string DataReductionProxyParams::GetDefaultFallbackOrigin() const {
497 return kDefaultFallbackOrigin;
500 std::string DataReductionProxyParams::GetDefaultSSLOrigin() const {
501 return kDefaultSslOrigin;
504 std::string DataReductionProxyParams::GetDefaultAltOrigin() const {
505 return kDefaultAltOrigin;
508 std::string DataReductionProxyParams::GetDefaultAltFallbackOrigin() const {
509 return kDefaultAltFallbackOrigin;
512 std::string DataReductionProxyParams::GetDefaultProbeURL() const {
513 return kDefaultProbeUrl;
516 std::string DataReductionProxyParams::GetDefaultWarmupURL() const {
517 return kDefaultWarmupUrl;
520 } // namespace data_reduction_proxy