1 // Copyright 2013 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 "chrome/browser/net/spdyproxy/data_reduction_proxy_settings.h"
8 #include "base/command_line.h"
9 #include "base/metrics/field_trial.h"
10 #include "base/metrics/histogram.h"
11 #include "base/prefs/pref_member.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/prefs/scoped_user_pref_update.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/prefs/proxy_prefs.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/profiles/profile_manager.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "chrome/common/pref_names.h"
24 #include "crypto/random.h"
25 #include "net/base/auth.h"
26 #include "net/base/host_port_pair.h"
27 #include "net/base/load_flags.h"
28 #include "net/base/net_errors.h"
29 #include "net/http/http_auth.h"
30 #include "net/http/http_auth_cache.h"
31 #include "net/http/http_network_session.h"
32 #include "net/http/http_response_headers.h"
33 #include "net/url_request/url_fetcher.h"
34 #include "net/url_request/url_fetcher_delegate.h"
35 #include "net/url_request/url_request_status.h"
38 using base::FieldTrialList
;
39 using base::StringPrintf
;
40 using spdyproxy::ProbeURLFetchResult
;
41 using spdyproxy::ProxyStartupState
;
45 // Key of the UMA DataReductionProxy.StartupState histogram.
46 const char kUMAProxyStartupStateHistogram
[] =
47 "DataReductionProxy.StartupState";
49 // Key of the UMA DataReductionProxy.ProbeURL histogram.
50 const char kUMAProxyProbeURL
[] = "DataReductionProxy.ProbeURL";
53 const char kEnabled
[] = "Enabled";
55 // TODO(marq): Factor this string out into a constant here and in
56 // http_auth_handler_spdyproxy.
57 const char kAuthenticationRealmName
[] = "SpdyProxy";
59 int64
GetInt64PrefValue(const base::ListValue
& list_value
, size_t index
) {
61 std::string pref_value
;
62 bool rv
= list_value
.GetString(index
, &pref_value
);
65 rv
= base::StringToInt64(pref_value
, &val
);
71 bool IsProxyOriginSetOnCommandLine() {
72 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
73 return command_line
.HasSwitch(switches::kSpdyProxyAuthOrigin
);
76 bool IsEnableSpdyProxyAuthSetOnCommandLine() {
77 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
78 return command_line
.HasSwitch(switches::kEnableSpdyProxyAuth
);
83 DataReductionProxySettings::DataReductionProxySettings()
84 : restricted_by_carrier_(false),
85 enabled_by_user_(false) {
88 DataReductionProxySettings::~DataReductionProxySettings() {
89 if (IsDataReductionProxyAllowed())
90 spdy_proxy_auth_enabled_
.Destroy();
93 void DataReductionProxySettings::InitPrefMembers() {
94 spdy_proxy_auth_enabled_
.Init(
95 prefs::kSpdyProxyAuthEnabled
,
96 GetOriginalProfilePrefs(),
97 base::Bind(&DataReductionProxySettings::OnProxyEnabledPrefChange
,
98 base::Unretained(this)));
101 void DataReductionProxySettings::InitDataReductionProxySettings() {
103 RecordDataReductionInit();
105 // Disable the proxy if it is not allowed to be used.
106 if (!IsDataReductionProxyAllowed())
109 AddDefaultProxyBypassRules();
110 net::NetworkChangeNotifier::AddIPAddressObserver(this);
112 // We set or reset the proxy pref at startup.
113 MaybeActivateDataReductionProxy(true);
117 void DataReductionProxySettings::InitDataReductionProxySession(
118 net::HttpNetworkSession
* session
) {
119 // This is a no-op unless the authentication parameters are compiled in.
120 // (even though values for them may be specified on the command line).
121 // Authentication will still work if the command line parameters are used,
122 // however there will be a round-trip overhead for each challenge/response
123 // (typically once per session).
124 #if defined(SPDY_PROXY_AUTH_ORIGIN) && defined(SPDY_PROXY_AUTH_VALUE)
126 net::HttpAuthCache
* auth_cache
= session
->http_auth_cache();
128 InitDataReductionAuthentication(auth_cache
);
129 #endif // defined(SPDY_PROXY_AUTH_ORIGIN) && defined(SPDY_PROXY_AUTH_VALUE)
133 void DataReductionProxySettings::InitDataReductionAuthentication(
134 net::HttpAuthCache
* auth_cache
) {
137 (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds() / 1000;
139 DataReductionProxyList proxies
= GetDataReductionProxies();
140 for (DataReductionProxyList::iterator it
= proxies
.begin();
141 it
!= proxies
.end(); ++it
) {
142 GURL auth_origin
= (*it
).GetOrigin();
144 crypto::RandBytes(rand
, 3 * sizeof(rand
[0]));
147 base::StringPrintf("%s%lld", kAuthenticationRealmName
, timestamp
);
148 std::string challenge
= base::StringPrintf(
149 "%s realm=\"%s\", ps=\"%lld-%u-%u-%u\"", kAuthenticationRealmName
,
150 realm
.data(), timestamp
, rand
[0], rand
[1], rand
[2]);
151 base::string16 password
= AuthHashForSalt(timestamp
);
153 DVLOG(1) << "origin: [" << auth_origin
<< "] realm: [" << realm
154 << "] challenge: [" << challenge
<< "] password: [" << password
<< "]";
156 net::AuthCredentials
credentials(base::string16(), password
);
157 // |HttpAuthController| searches this cache by origin and path, the latter
158 // being '/' in the case of the data reduction proxy.
159 auth_cache
->Add(auth_origin
,
161 net::HttpAuth::AUTH_SCHEME_SPDYPROXY
,
168 void DataReductionProxySettings::AddHostPatternToBypass(
169 const std::string
& pattern
) {
170 bypass_rules_
.push_back(pattern
);
173 void DataReductionProxySettings::AddURLPatternToBypass(
174 const std::string
& pattern
) {
175 size_t pos
= pattern
.find("/");
176 if (pattern
.find("/", pos
+ 1) == pos
+ 1)
177 pos
= pattern
.find("/", pos
+ 2);
179 std::string host_pattern
;
180 if (pos
!= std::string::npos
)
181 host_pattern
= pattern
.substr(0, pos
);
183 host_pattern
= pattern
;
185 AddHostPatternToBypass(host_pattern
);
189 bool DataReductionProxySettings::IsDataReductionProxyAllowed() {
190 return IsProxyOriginSetOnCommandLine() ||
191 (FieldTrialList::FindFullName("DataCompressionProxyRollout") == kEnabled
);
195 bool DataReductionProxySettings::IsDataReductionProxyPromoAllowed() {
196 return IsProxyOriginSetOnCommandLine() ||
197 (IsDataReductionProxyAllowed() &&
198 FieldTrialList::FindFullName("DataCompressionProxyPromoVisibility") ==
203 bool DataReductionProxySettings::IsPreconnectHintingAllowed() {
204 if (!IsDataReductionProxyAllowed())
206 return FieldTrialList::FindFullName("DataCompressionProxyPreconnectHints") ==
211 std::string
DataReductionProxySettings::GetDataReductionProxyOrigin() {
212 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
213 if (command_line
.HasSwitch(switches::kSpdyProxyDevAuthOrigin
))
214 return command_line
.GetSwitchValueASCII(switches::kSpdyProxyDevAuthOrigin
);
215 if (command_line
.HasSwitch(switches::kSpdyProxyAuthOrigin
))
216 return command_line
.GetSwitchValueASCII(switches::kSpdyProxyAuthOrigin
);
217 #if defined(DATA_REDUCTION_DEV_HOST)
218 if (FieldTrialList::FindFullName("DataCompressionProxyDevRollout") ==
220 return DATA_REDUCTION_DEV_HOST
;
223 #if defined(SPDY_PROXY_AUTH_ORIGIN)
224 return SPDY_PROXY_AUTH_ORIGIN
;
226 return std::string();
231 std::string
DataReductionProxySettings::GetDataReductionProxyFallback() {
232 // Regardless of what else is defined, only return a value if the main proxy
233 // origin is defined.
234 if (GetDataReductionProxyOrigin().empty())
235 return std::string();
236 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
237 if (command_line
.HasSwitch(switches::kSpdyProxyAuthFallback
))
238 return command_line
.GetSwitchValueASCII(switches::kSpdyProxyAuthFallback
);
239 #if defined(DATA_REDUCTION_FALLBACK_HOST)
240 return DATA_REDUCTION_FALLBACK_HOST
;
242 return std::string();
246 bool DataReductionProxySettings::IsAcceptableAuthChallenge(
247 net::AuthChallengeInfo
* auth_info
) {
248 // Challenge realm must start with the authentication realm name.
249 std::string realm_prefix
=
250 auth_info
->realm
.substr(0, strlen(kAuthenticationRealmName
));
251 if (realm_prefix
!= kAuthenticationRealmName
)
254 // The challenger must be one of the configured proxies.
255 DataReductionProxyList proxies
= GetDataReductionProxies();
256 for (DataReductionProxyList::iterator it
= proxies
.begin();
257 it
!= proxies
.end(); ++it
) {
258 net::HostPortPair origin_host
= net::HostPortPair::FromURL(*it
);
259 if (origin_host
.Equals(auth_info
->challenger
))
265 base::string16
DataReductionProxySettings::GetTokenForAuthChallenge(
266 net::AuthChallengeInfo
* auth_info
) {
267 if (auth_info
->realm
.length() > strlen(kAuthenticationRealmName
)) {
269 std::string realm_suffix
=
270 auth_info
->realm
.substr(strlen(kAuthenticationRealmName
));
271 if (base::StringToInt64(realm_suffix
, &salt
)) {
272 return AuthHashForSalt(salt
);
274 DVLOG(1) << "Unable to parse realm name " << auth_info
->realm
275 << "into an int for salting.";
276 return base::string16();
279 return base::string16();
283 bool DataReductionProxySettings::IsDataReductionProxyEnabled() {
284 return spdy_proxy_auth_enabled_
.GetValue() ||
285 IsEnableSpdyProxyAuthSetOnCommandLine();
288 bool DataReductionProxySettings::IsDataReductionProxyManaged() {
289 return spdy_proxy_auth_enabled_
.IsManaged();
293 DataReductionProxySettings::DataReductionProxyList
294 DataReductionProxySettings::GetDataReductionProxies() {
295 DataReductionProxyList proxies
;
296 std::string proxy
= GetDataReductionProxyOrigin();
297 std::string fallback
= GetDataReductionProxyFallback();
300 proxies
.push_back(GURL(proxy
));
302 if (!fallback
.empty()) {
303 // Sanity check: fallback isn't the only proxy.
304 DCHECK(!proxies
.empty());
305 proxies
.push_back(GURL(fallback
));
311 void DataReductionProxySettings::SetDataReductionProxyEnabled(bool enabled
) {
312 // Prevent configuring the proxy when it is not allowed to be used.
313 if (!IsDataReductionProxyAllowed())
316 if (spdy_proxy_auth_enabled_
.GetValue() != enabled
) {
317 spdy_proxy_auth_enabled_
.SetValue(enabled
);
318 OnProxyEnabledPrefChange();
322 int64
DataReductionProxySettings::GetDataReductionLastUpdateTime() {
323 PrefService
* local_state
= GetLocalStatePrefs();
324 int64 last_update_internal
=
325 local_state
->GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate
);
326 base::Time last_update
= base::Time::FromInternalValue(last_update_internal
);
327 return static_cast<int64
>(last_update
.ToJsTime());
330 DataReductionProxySettings::ContentLengthList
331 DataReductionProxySettings::GetDailyOriginalContentLengths() {
332 return GetDailyContentLengths(prefs::kDailyHttpOriginalContentLength
);
335 DataReductionProxySettings::ContentLengthList
336 DataReductionProxySettings::GetDailyReceivedContentLengths() {
337 return GetDailyContentLengths(prefs::kDailyHttpReceivedContentLength
);
340 void DataReductionProxySettings::OnURLFetchComplete(
341 const net::URLFetcher
* source
) {
342 net::URLRequestStatus status
= source
->GetStatus();
343 if (status
.status() == net::URLRequestStatus::FAILED
&&
344 status
.error() == net::ERR_INTERNET_DISCONNECTED
) {
345 RecordProbeURLFetchResult(spdyproxy::INTERNET_DISCONNECTED
);
349 std::string response
;
350 source
->GetResponseAsString(&response
);
352 if ("OK" == response
.substr(0, 2)) {
353 DVLOG(1) << "The data reduction proxy is unrestricted.";
355 if (enabled_by_user_
) {
356 if (restricted_by_carrier_
) {
357 // The user enabled the proxy, but sometime previously in the session,
358 // the network operator had blocked the canary and restricted the user.
359 // The current network doesn't block the canary, so don't restrict the
360 // proxy configurations.
361 SetProxyConfigs(true /* enabled */,
362 false /* restricted */,
363 false /* at_startup */);
364 RecordProbeURLFetchResult(spdyproxy::SUCCEEDED_PROXY_ENABLED
);
366 RecordProbeURLFetchResult(spdyproxy::SUCCEEDED_PROXY_ALREADY_ENABLED
);
369 restricted_by_carrier_
= false;
372 DVLOG(1) << "The data reduction proxy is restricted to the configured "
373 << "fallback proxy.";
375 if (enabled_by_user_
) {
376 if (!restricted_by_carrier_
) {
377 // Restrict the proxy.
378 SetProxyConfigs(true /* enabled */,
379 true /* restricted */,
380 false /* at_startup */);
381 RecordProbeURLFetchResult(spdyproxy::FAILED_PROXY_DISABLED
);
383 RecordProbeURLFetchResult(spdyproxy::FAILED_PROXY_ALREADY_DISABLED
);
386 restricted_by_carrier_
= true;
389 void DataReductionProxySettings::OnIPAddressChanged() {
390 if (enabled_by_user_
) {
391 DCHECK(IsDataReductionProxyAllowed());
392 ProbeWhetherDataReductionProxyIsAvailable();
396 void DataReductionProxySettings::OnProxyEnabledPrefChange() {
397 if (!DataReductionProxySettings::IsDataReductionProxyAllowed())
399 MaybeActivateDataReductionProxy(false);
402 void DataReductionProxySettings::AddDefaultProxyBypassRules() {
404 AddHostPatternToBypass("<local>");
405 // RFC1918 private addresses.
406 AddHostPatternToBypass("10.0.0.0/8");
407 AddHostPatternToBypass("172.16.0.0/12");
408 AddHostPatternToBypass("192.168.0.0/16");
409 // RFC4193 private addresses.
410 AddHostPatternToBypass("fc00::/7");
411 // IPV6 probe addresses.
412 AddHostPatternToBypass("*-ds.metric.gstatic.com");
413 AddHostPatternToBypass("*-v4.metric.gstatic.com");
416 void DataReductionProxySettings::LogProxyState(
417 bool enabled
, bool restricted
, bool at_startup
) {
418 // This must stay a LOG(WARNING); the output is used in processing customer
420 const char kAtStartup
[] = "at startup";
421 const char kByUser
[] = "by user action";
422 const char kOn
[] = "ON";
423 const char kOff
[] = "OFF";
424 const char kRestricted
[] = "(Restricted)";
425 const char kUnrestricted
[] = "(Unrestricted)";
427 std::string annotated_on
=
428 kOn
+ std::string(" ") + (restricted
? kRestricted
: kUnrestricted
);
430 LOG(WARNING
) << "SPDY proxy " << (enabled
? annotated_on
: kOff
)
431 << " " << (at_startup
? kAtStartup
: kByUser
);
434 PrefService
* DataReductionProxySettings::GetOriginalProfilePrefs() {
435 return g_browser_process
->profile_manager()->GetLastUsedProfile()->
436 GetOriginalProfile()->GetPrefs();
439 PrefService
* DataReductionProxySettings::GetLocalStatePrefs() {
440 return g_browser_process
->local_state();
443 void DataReductionProxySettings::ResetDataReductionStatistics() {
444 PrefService
* prefs
= GetLocalStatePrefs();
447 ListPrefUpdate
original_update(prefs
, prefs::kDailyHttpOriginalContentLength
);
448 ListPrefUpdate
received_update(prefs
, prefs::kDailyHttpReceivedContentLength
);
449 original_update
->Clear();
450 received_update
->Clear();
451 for (size_t i
= 0; i
< spdyproxy::kNumDaysInHistory
; ++i
) {
452 original_update
->AppendString(base::Int64ToString(0));
453 received_update
->AppendString(base::Int64ToString(0));
457 void DataReductionProxySettings::MaybeActivateDataReductionProxy(
459 PrefService
* prefs
= GetOriginalProfilePrefs();
461 // TODO(marq): Consider moving this so stats are wiped the first time the
462 // proxy settings are actually (not maybe) turned on.
463 if (spdy_proxy_auth_enabled_
.GetValue() &&
464 !prefs
->GetBoolean(prefs::kSpdyProxyAuthWasEnabledBefore
)) {
465 prefs
->SetBoolean(prefs::kSpdyProxyAuthWasEnabledBefore
, true);
466 ResetDataReductionStatistics();
469 std::string proxy
= GetDataReductionProxyOrigin();
470 // Configure use of the data reduction proxy if it is enabled and the proxy
471 // origin is non-empty.
472 enabled_by_user_
= IsDataReductionProxyEnabled() && !proxy
.empty();
473 SetProxyConfigs(enabled_by_user_
, restricted_by_carrier_
, at_startup
);
475 // Check if the proxy has been restricted explicitly by the carrier.
476 if (enabled_by_user_
)
477 ProbeWhetherDataReductionProxyIsAvailable();
480 void DataReductionProxySettings::SetProxyConfigs(
481 bool enabled
, bool restricted
, bool at_startup
) {
482 // If |restricted| is true and there is no defined fallback proxy.
483 // treat this as a disable.
484 std::string fallback
= GetDataReductionProxyFallback();
485 if (fallback
.empty() && enabled
&& restricted
)
488 LogProxyState(enabled
, restricted
, at_startup
);
489 PrefService
* prefs
= GetOriginalProfilePrefs();
491 DictionaryPrefUpdate
update(prefs
, prefs::kProxy
);
492 base::DictionaryValue
* dict
= update
.Get();
494 std::string proxy_list
;
496 DCHECK(!fallback
.empty());
497 proxy_list
= fallback
;
499 proxy_list
= GetDataReductionProxyOrigin() +
500 (fallback
.empty() ? "" : "," + fallback
);
503 std::string proxy_server_config
= "http=" + proxy_list
+ ",direct://;";
504 dict
->SetString("server", proxy_server_config
);
505 dict
->SetString("mode",
506 ProxyModeToString(ProxyPrefs::MODE_FIXED_SERVERS
));
507 dict
->SetString("bypass_list", JoinString(bypass_rules_
, ", "));
509 dict
->SetString("mode", ProxyModeToString(ProxyPrefs::MODE_SYSTEM
));
510 dict
->SetString("server", "");
511 dict
->SetString("bypass_list", "");
516 void DataReductionProxySettings::RecordDataReductionInit() {
517 ProxyStartupState state
= spdyproxy::PROXY_NOT_AVAILABLE
;
518 if (IsDataReductionProxyAllowed()) {
519 if (IsDataReductionProxyEnabled())
520 state
= spdyproxy::PROXY_ENABLED
;
522 state
= spdyproxy::PROXY_DISABLED
;
525 RecordStartupState(state
);
528 void DataReductionProxySettings::RecordProbeURLFetchResult(
529 ProbeURLFetchResult result
) {
530 UMA_HISTOGRAM_ENUMERATION(kUMAProxyProbeURL
,
532 spdyproxy::PROBE_URL_FETCH_RESULT_COUNT
);
535 void DataReductionProxySettings::RecordStartupState(ProxyStartupState state
) {
536 UMA_HISTOGRAM_ENUMERATION(kUMAProxyStartupStateHistogram
,
538 spdyproxy::PROXY_STARTUP_STATE_COUNT
);
541 DataReductionProxySettings::ContentLengthList
542 DataReductionProxySettings::GetDailyContentLengths(const char* pref_name
) {
543 DataReductionProxySettings::ContentLengthList content_lengths
;
544 const base::ListValue
* list_value
= GetLocalStatePrefs()->GetList(pref_name
);
545 if (list_value
->GetSize() == spdyproxy::kNumDaysInHistory
) {
546 for (size_t i
= 0; i
< spdyproxy::kNumDaysInHistory
; ++i
) {
547 content_lengths
.push_back(GetInt64PrefValue(*list_value
, i
));
550 return content_lengths
;
553 void DataReductionProxySettings::GetContentLengths(
555 int64
* original_content_length
,
556 int64
* received_content_length
,
557 int64
* last_update_time
) {
558 DCHECK_LE(days
, spdyproxy::kNumDaysInHistory
);
559 PrefService
* local_state
= GetLocalStatePrefs();
561 *original_content_length
= 0L;
562 *received_content_length
= 0L;
563 *last_update_time
= 0L;
567 const base::ListValue
* original_list
=
568 local_state
->GetList(prefs::kDailyHttpOriginalContentLength
);
569 const base::ListValue
* received_list
=
570 local_state
->GetList(prefs::kDailyHttpReceivedContentLength
);
572 if (original_list
->GetSize() != spdyproxy::kNumDaysInHistory
||
573 received_list
->GetSize() != spdyproxy::kNumDaysInHistory
) {
574 *original_content_length
= 0L;
575 *received_content_length
= 0L;
576 *last_update_time
= 0L;
582 // Include days from the end of the list going backwards.
583 for (size_t i
= spdyproxy::kNumDaysInHistory
- days
;
584 i
< spdyproxy::kNumDaysInHistory
; ++i
) {
585 orig
+= GetInt64PrefValue(*original_list
, i
);
586 recv
+= GetInt64PrefValue(*received_list
, i
);
588 *original_content_length
= orig
;
589 *received_content_length
= recv
;
591 local_state
->GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate
);
594 std::string
DataReductionProxySettings::GetProxyCheckURL() {
595 if (!IsDataReductionProxyAllowed())
596 return std::string();
597 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
598 if (command_line
.HasSwitch(switches::kDataReductionProxyProbeURL
)) {
599 return command_line
.GetSwitchValueASCII(
600 switches::kDataReductionProxyProbeURL
);
602 #if defined(DATA_REDUCTION_PROXY_PROBE_URL)
603 return DATA_REDUCTION_PROXY_PROBE_URL
;
605 return std::string();
610 base::string16
DataReductionProxySettings::AuthHashForSalt(int64 salt
) {
611 if (!IsDataReductionProxyAllowed())
612 return base::string16();
616 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
617 if (command_line
.HasSwitch(switches::kSpdyProxyAuthOrigin
)) {
618 // If an origin is provided via a switch, then only consider the value
619 // that is provided by a switch. Do not use the preprocessor constant.
620 // Don't expose SPDY_PROXY_AUTH_VALUE to a proxy passed in via the command
622 if (!command_line
.HasSwitch(switches::kSpdyProxyAuthValue
))
623 return base::string16();
624 key
= command_line
.GetSwitchValueASCII(switches::kSpdyProxyAuthValue
);
626 #if defined(SPDY_PROXY_AUTH_VALUE)
627 key
= SPDY_PROXY_AUTH_VALUE
;
629 return base::string16();
633 DCHECK(!key
.empty());
635 std::string salted_key
=
636 base::StringPrintf("%lld%s%lld", salt
, key
.c_str(), salt
);
637 return base::UTF8ToUTF16(base::MD5String(salted_key
));
640 net::URLFetcher
* DataReductionProxySettings::GetURLFetcher() {
641 std::string url
= GetProxyCheckURL();
644 net::URLFetcher
* fetcher
= net::URLFetcher::Create(GURL(url
),
645 net::URLFetcher::GET
,
647 fetcher
->SetLoadFlags(net::LOAD_DISABLE_CACHE
| net::LOAD_BYPASS_PROXY
);
648 // If this code ever goes multi profile, the used profile needs to be taken
649 // from the browser context.
650 Profile
* profile
= ProfileManager::GetActiveUserProfile();
651 fetcher
->SetRequestContext(profile
->GetRequestContext());
652 // Configure max retries to be at most kMaxRetries times for 5xx errors.
653 static const int kMaxRetries
= 5;
654 fetcher
->SetMaxRetriesOn5xx(kMaxRetries
);
659 DataReductionProxySettings::ProbeWhetherDataReductionProxyIsAvailable() {
660 net::URLFetcher
* fetcher
= GetURLFetcher();
663 fetcher_
.reset(fetcher
);