18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file.
48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
58bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings.h"
68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/bind.h"
88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/command_line.h"
98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/metrics/field_trial.h"
108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/metrics/histogram.h"
118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/prefs/pref_member.h"
128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/prefs/pref_service.h"
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h"
148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/strings/string_util.h"
168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/strings/stringprintf.h"
178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/browser_process.h"
198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/prefs/proxy_prefs.h"
208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/common/pref_names.h"
241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "crypto/random.h"
251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/base/auth.h"
268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/base/host_port_pair.h"
278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/base/load_flags.h"
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/base/net_errors.h"
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/http/http_auth.h"
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/http/http_auth_cache.h"
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/http/http_network_session.h"
32d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#include "net/http/http_response_headers.h"
338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/url_request/url_fetcher.h"
348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "net/url_request/url_request_status.h"
368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "url/gurl.h"
378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)using base::FieldTrialList;
398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)using base::StringPrintf;
408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace {
428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Key of the UMA DataReductionProxy.StartupState histogram.
448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kUMAProxyStartupStateHistogram[] =
458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    "DataReductionProxy.StartupState";
468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Values of the UMA DataReductionProxy.StartupState histogram.
478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)enum ProxyStartupState {
488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PROXY_NOT_AVAILABLE = 0,
498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PROXY_DISABLED,
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PROXY_ENABLED,
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PROXY_STARTUP_STATE_COUNT,
528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)};
538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Key of the UMA DataReductionProxy.ProbeURL histogram.
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kUMAProxyProbeURL[] = "DataReductionProxy.ProbeURL";
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Values of the UMA DataReductionProxy.ProbeURL histogram.
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// This enum must remain synchronized with DataReductionProxyProbeURLFetchResult
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// in metrics/histograms/histograms.xml.
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)enum ProbeURLFetchResult {
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The probe failed because the internet was disconnected.
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  INTERNET_DISCONNECTED = 0,
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The probe failed for any other reason, and as a result, the proxy was
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // disabled.
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FAILED_PROXY_DISABLED,
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The probe failed, but the proxy was already disabled.
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FAILED_PROXY_ALREADY_DISABLED,
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // THe probe succeeded, and as a result the proxy was enabled.
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SUCCEEDED_PROXY_ENABLED,
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The probe succeeded, but the proxy was already enabled.
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SUCCEEDED_PROXY_ALREADY_ENABLED,
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // This must always be last.
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FETCH_RESULT_COUNT
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void RecordProbeURLFetchResult(ProbeURLFetchResult result) {
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION(kUMAProxyProbeURL, result, FETCH_RESULT_COUNT);
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kEnabled[] = "Enabled";
858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// TODO(marq): Factor this string out into a constant here and in
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)//             http_auth_handler_spdyproxy.
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char kAuthenticationRealmName[] = "SpdyProxy";
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int64 GetInt64PrefValue(const ListValue& list_value, size_t index) {
918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int64 val = 0;
928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string pref_value;
938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  bool rv = list_value.GetString(index, &pref_value);
948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(rv);
958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (rv) {
968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    rv = base::StringToInt64(pref_value, &val);
978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    DCHECK(rv);
988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return val;
1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool IsProxyOriginSetOnCommandLine() {
1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return command_line.HasSwitch(switches::kSpdyProxyAuthOrigin);
1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace
1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)DataReductionProxySettings::DataReductionProxySettings()
110d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    : restricted_by_carrier_(false),
1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      enabled_by_user_(false) {
1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)DataReductionProxySettings::~DataReductionProxySettings() {
1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (IsDataReductionProxyAllowed())
1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    spdy_proxy_auth_enabled_.Destroy();
1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DataReductionProxySettings::InitPrefMembers() {
1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  spdy_proxy_auth_enabled_.Init(
1218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      prefs::kSpdyProxyAuthEnabled,
1228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      GetOriginalProfilePrefs(),
1238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::Bind(&DataReductionProxySettings::OnProxyEnabledPrefChange,
1248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 base::Unretained(this)));
1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DataReductionProxySettings::InitDataReductionProxySettings() {
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  InitPrefMembers();
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Disable the proxy if it is not allowed to be used.
1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!IsDataReductionProxyAllowed())
1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
1338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AddDefaultProxyBypassRules();
1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  net::NetworkChangeNotifier::AddIPAddressObserver(this);
1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Setting the kEnableSpdyProxyAuth switch has the same effect as enabling
1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // the feature via settings, in that once set, the preference will be sticky
1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // across instances of Chrome. Disabling the feature can only be done through
1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // the settings menu.
1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  RecordDataReductionInit();
1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (spdy_proxy_auth_enabled_.GetValue() ||
1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      command_line.HasSwitch(switches::kEnableSpdyProxyAuth)) {
1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    MaybeActivateDataReductionProxy(true);
1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else {
1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // This is logged so we can use this information in user feedback.
149d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    LogProxyState(false /* enabled */,
150d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                  false /* restricted */,
151d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                  true /* at startup */);
1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
155d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// static
1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void DataReductionProxySettings::InitDataReductionProxySession(
1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    net::HttpNetworkSession* session) {
1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// This is a no-op unless the authentication parameters are compiled in.
1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// (even though values for them may be specified on the command line).
1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Authentication will still work if the command line parameters are used,
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// however there will be a round-trip overhead for each challenge/response
1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// (typically once per session).
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(SPDY_PROXY_AUTH_ORIGIN) && defined(SPDY_PROXY_AUTH_VALUE)
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(session);
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  net::HttpAuthCache* auth_cache = session->http_auth_cache();
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(auth_cache);
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  InitDataReductionAuthentication(auth_cache);
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif  // defined(SPDY_PROXY_AUTH_ORIGIN) && defined(SPDY_PROXY_AUTH_VALUE)
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
171d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// static
1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void DataReductionProxySettings::InitDataReductionAuthentication(
1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    net::HttpAuthCache* auth_cache) {
1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(auth_cache);
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int64 timestamp =
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds() / 1000;
1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DataReductionProxyList proxies = GetDataReductionProxies();
1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (DataReductionProxyList::iterator it = proxies.begin();
1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      it != proxies.end(); ++it) {
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    GURL auth_origin = (*it).GetOrigin();
1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    int32 rand[3];
1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    crypto::RandBytes(rand, 3 * sizeof(rand[0]));
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::string realm =
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::StringPrintf("%s%lld", kAuthenticationRealmName, timestamp);
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::string challenge = base::StringPrintf(
1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        "%s realm=\"%s\", ps=\"%lld-%u-%u-%u\"", kAuthenticationRealmName,
1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        realm.data(), timestamp, rand[0], rand[1], rand[2]);
1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    base::string16 password = AuthHashForSalt(timestamp);
1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DVLOG(1) << "origin: [" << auth_origin << "] realm: [" << realm
1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        << "] challenge: [" << challenge << "] password: [" << password << "]";
1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    net::AuthCredentials credentials(base::string16(), password);
196f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)    // |HttpAuthController| searches this cache by origin and path, the latter
197f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)    // being '/' in the case of the data reduction proxy.
1981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    auth_cache->Add(auth_origin,
1991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                    realm,
2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                    net::HttpAuth::AUTH_SCHEME_SPDYPROXY,
2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                    challenge,
2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                    credentials,
203f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)                    std::string("/"));
2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DataReductionProxySettings::AddHostPatternToBypass(
2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& pattern) {
2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  bypass_rules_.push_back(pattern);
2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DataReductionProxySettings::AddURLPatternToBypass(
2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& pattern) {
2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  size_t pos = pattern.find("/");
2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (pattern.find("/", pos + 1) == pos + 1)
2168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    pos = pattern.find("/", pos + 2);
2178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string host_pattern;
2198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (pos != std::string::npos)
2208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    host_pattern = pattern.substr(0, pos);
2218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  else
2228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    host_pattern = pattern;
2238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AddHostPatternToBypass(host_pattern);
2258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
227d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// static
2288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool DataReductionProxySettings::IsDataReductionProxyAllowed() {
2298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return IsProxyOriginSetOnCommandLine() ||
2308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      (FieldTrialList::FindFullName("DataCompressionProxyRollout") == kEnabled);
2318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
233d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// static
2348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool DataReductionProxySettings::IsDataReductionProxyPromoAllowed() {
2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return IsProxyOriginSetOnCommandLine() ||
2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      (IsDataReductionProxyAllowed() &&
2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        FieldTrialList::FindFullName("DataCompressionProxyPromoVisibility") ==
2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            kEnabled);
2398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
241d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// static
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool DataReductionProxySettings::IsPreconnectHintingAllowed() {
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!IsDataReductionProxyAllowed())
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return FieldTrialList::FindFullName("DataCompressionProxyPreconnectHints") ==
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      kEnabled;
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
249d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// static
250d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)bool DataReductionProxySettings::WasFetchedViaProxy(
251d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    const net::HttpResponseHeaders* headers) {
252d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  const char kChromeProxyViaValue[] = "1.1 Chrome Compression Proxy";
253d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  void* iter = NULL;
254d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  std::string value;
255d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  while (headers->EnumerateHeader(&iter, "via", &value))
256d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    if (value == kChromeProxyViaValue) return true;
257d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  return false;
258d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)}
259d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
260d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// static
2618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string DataReductionProxySettings::GetDataReductionProxyOrigin() {
2628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (command_line.HasSwitch(switches::kSpdyProxyAuthOrigin))
2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthOrigin);
2658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(SPDY_PROXY_AUTH_ORIGIN)
2668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return SPDY_PROXY_AUTH_ORIGIN;
2678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#else
2688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return std::string();
2698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif
2708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
272d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// static
2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)std::string DataReductionProxySettings::GetDataReductionProxyFallback() {
2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Regardless of what else is defined, only return a value if the main proxy
2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // origin is defined.
2761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (GetDataReductionProxyOrigin().empty())
2778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return std::string();
2788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (command_line.HasSwitch(switches::kSpdyProxyAuthFallback))
2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthFallback);
2811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(DATA_REDUCTION_FALLBACK_HOST)
2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return DATA_REDUCTION_FALLBACK_HOST;
2838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#else
2848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return std::string();
2858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif
2868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool DataReductionProxySettings::IsAcceptableAuthChallenge(
2891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    net::AuthChallengeInfo* auth_info) {
2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Challenge realm must start with the authentication realm name.
2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string realm_prefix =
2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      auth_info->realm.substr(0, strlen(kAuthenticationRealmName));
2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (realm_prefix != kAuthenticationRealmName)
2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return false;
2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // The challenger must be one of the configured proxies.
2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DataReductionProxyList proxies = GetDataReductionProxies();
2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (DataReductionProxyList::iterator it = proxies.begin();
2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)       it != proxies.end(); ++it) {
3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    net::HostPortPair origin_host = net::HostPortPair::FromURL(*it);
3011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (origin_host.Equals(auth_info->challenger))
3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return true;
3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return false;
3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)base::string16 DataReductionProxySettings::GetTokenForAuthChallenge(
3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    net::AuthChallengeInfo* auth_info) {
3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (auth_info->realm.length() > strlen(kAuthenticationRealmName)) {
3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    int64 salt;
3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::string realm_suffix =
3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        auth_info->realm.substr(strlen(kAuthenticationRealmName));
3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (base::StringToInt64(realm_suffix, &salt)) {
3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return AuthHashForSalt(salt);
3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    } else {
3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      DVLOG(1) << "Unable to parse realm name " << auth_info->realm
3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)               << "into an int for salting.";
3181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return base::string16();
3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return base::string16();
3221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool DataReductionProxySettings::IsDataReductionProxyEnabled() {
3268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return spdy_proxy_auth_enabled_.GetValue();
3278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool DataReductionProxySettings::IsDataReductionProxyManaged() {
3308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return spdy_proxy_auth_enabled_.IsManaged();
3318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
333d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// static
3341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)DataReductionProxySettings::DataReductionProxyList
3351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)DataReductionProxySettings::GetDataReductionProxies() {
3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DataReductionProxyList proxies;
3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string proxy = GetDataReductionProxyOrigin();
3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string fallback = GetDataReductionProxyFallback();
3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!proxy.empty())
3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    proxies.push_back(GURL(proxy));
3421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!fallback.empty()) {
3441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Sanity check: fallback isn't the only proxy.
3451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(!proxies.empty());
3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    proxies.push_back(GURL(fallback));
3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
3481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return proxies;
3501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DataReductionProxySettings::SetDataReductionProxyEnabled(bool enabled) {
3538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Prevent configuring the proxy when it is not allowed to be used.
3548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!IsDataReductionProxyAllowed())
3558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
3568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  spdy_proxy_auth_enabled_.SetValue(enabled);
3588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  OnProxyEnabledPrefChange();
3598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)int64 DataReductionProxySettings::GetDataReductionLastUpdateTime() {
3628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* local_state = GetLocalStatePrefs();
3638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int64 last_update_internal =
3648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      local_state->GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate);
3658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::Time last_update = base::Time::FromInternalValue(last_update_internal);
3668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return static_cast<int64>(last_update.ToJsTime());
3678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)DataReductionProxySettings::ContentLengthList
3708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)DataReductionProxySettings::GetDailyOriginalContentLengths() {
3718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return GetDailyContentLengths(prefs::kDailyHttpOriginalContentLength);
3728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)DataReductionProxySettings::ContentLengthList
3758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)DataReductionProxySettings::GetDailyReceivedContentLengths() {
3768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return GetDailyContentLengths(prefs::kDailyHttpReceivedContentLength);
3778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DataReductionProxySettings::OnURLFetchComplete(
3808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const net::URLFetcher* source) {
3818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  net::URLRequestStatus status = source->GetStatus();
3828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (status.status() == net::URLRequestStatus::FAILED &&
3838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      status.error() == net::ERR_INTERNET_DISCONNECTED) {
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    RecordProbeURLFetchResult(INTERNET_DISCONNECTED);
3858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
3868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string response;
3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  source->GetResponseAsString(&response);
3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if ("OK" == response.substr(0, 2)) {
392d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    DVLOG(1) << "The data reduction proxy is unrestricted.";
3938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (enabled_by_user_) {
395d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      if (restricted_by_carrier_) {
396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        // The user enabled the proxy, but sometime previously in the session,
397d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)        // the network operator had blocked the canary and restricted the user.
398d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)        // The current network doesn't block the canary, so don't restrict the
399d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)        // proxy configurations.
400d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)        SetProxyConfigs(true /* enabled */,
401d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                        false /* restricted */,
402d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                        false /* at_startup */);
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        RecordProbeURLFetchResult(SUCCEEDED_PROXY_ENABLED);
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      } else {
405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        RecordProbeURLFetchResult(SUCCEEDED_PROXY_ALREADY_ENABLED);
406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      }
4078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
408d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    restricted_by_carrier_ = false;
4098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
4108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
411d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  DVLOG(1) << "The data reduction proxy is restricted to the configured "
412d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)           << "fallback proxy.";
4138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (enabled_by_user_) {
415d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    if (!restricted_by_carrier_) {
416d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      // Restrict the proxy.
417d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      SetProxyConfigs(true /* enabled */,
418d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                      true /* restricted */,
419d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)                      false /* at_startup */);
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      RecordProbeURLFetchResult(FAILED_PROXY_DISABLED);
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else {
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      RecordProbeURLFetchResult(FAILED_PROXY_ALREADY_DISABLED);
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
4248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
425d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  restricted_by_carrier_ = true;
4268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DataReductionProxySettings::OnIPAddressChanged() {
4298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (enabled_by_user_) {
4308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    DCHECK(IsDataReductionProxyAllowed());
4318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ProbeWhetherDataReductionProxyIsAvailable();
4328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DataReductionProxySettings::OnProxyEnabledPrefChange() {
4361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!DataReductionProxySettings::IsDataReductionProxyAllowed())
4378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
4388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  MaybeActivateDataReductionProxy(false);
4398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DataReductionProxySettings::AddDefaultProxyBypassRules() {
4428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // localhost
4438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AddHostPatternToBypass("<local>");
4448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // RFC1918 private addresses.
4458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AddHostPatternToBypass("10.0.0.0/8");
4468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AddHostPatternToBypass("172.16.0.0/12");
4478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AddHostPatternToBypass("192.168.0.0/16");
448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // RFC4193 private addresses.
4498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AddHostPatternToBypass("fc00::/7");
450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // IPV6 probe addresses.
451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddHostPatternToBypass("*-ds.metric.gstatic.com");
452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddHostPatternToBypass("*-v4.metric.gstatic.com");
4538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
455d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)void DataReductionProxySettings::LogProxyState(
456d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    bool enabled, bool restricted, bool at_startup) {
4578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // This must stay a LOG(WARNING); the output is used in processing customer
4588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // feedback.
4598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const char kAtStartup[] = "at startup";
4608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const char kByUser[] = "by user action";
4618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const char kOn[] = "ON";
4628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const char kOff[] = "OFF";
463d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  const char kRestricted[] = "(Restricted)";
464d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  const char kUnrestricted[] = "(Unrestricted)";
4658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
466d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  std::string annotated_on =
467d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      kOn + std::string(" ") + (restricted ? kRestricted : kUnrestricted);
468d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
469d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  LOG(WARNING) << "SPDY proxy " << (enabled ? annotated_on : kOff)
4708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               << " " << (at_startup ? kAtStartup : kByUser);
4718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)PrefService* DataReductionProxySettings::GetOriginalProfilePrefs() {
4748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return g_browser_process->profile_manager()->GetLastUsedProfile()->
4758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      GetOriginalProfile()->GetPrefs();
4768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)PrefService* DataReductionProxySettings::GetLocalStatePrefs() {
4798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return g_browser_process->local_state();
4808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DataReductionProxySettings::ResetDataReductionStatistics() {
4838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* prefs = GetLocalStatePrefs();
4848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!prefs)
4858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
4868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ListPrefUpdate original_update(prefs, prefs::kDailyHttpOriginalContentLength);
4878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ListPrefUpdate received_update(prefs, prefs::kDailyHttpReceivedContentLength);
4888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  original_update->Clear();
4898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  received_update->Clear();
4908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t i = 0; i < spdyproxy::kNumDaysInHistory; ++i) {
4918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    original_update->AppendString(base::Int64ToString(0));
4928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    received_update->AppendString(base::Int64ToString(0));
4938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DataReductionProxySettings::MaybeActivateDataReductionProxy(
4978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    bool at_startup) {
4988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* prefs = GetOriginalProfilePrefs();
4998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // TODO(marq): Consider moving this so stats are wiped the first time the
5018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // proxy settings are actually (not maybe) turned on.
5028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (spdy_proxy_auth_enabled_.GetValue() &&
5038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      !prefs->GetBoolean(prefs::kSpdyProxyAuthWasEnabledBefore)) {
5048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    prefs->SetBoolean(prefs::kSpdyProxyAuthWasEnabledBefore, true);
5058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ResetDataReductionStatistics();
5068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string proxy = GetDataReductionProxyOrigin();
5098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Configure use of the data reduction proxy if it is enabled and the proxy
5108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // origin is non-empty.
5111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  enabled_by_user_= spdy_proxy_auth_enabled_.GetValue() && !proxy.empty();
512d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  SetProxyConfigs(enabled_by_user_, restricted_by_carrier_, at_startup);
5138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
514d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  // Check if the proxy has been restricted explicitly by the carrier.
5158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (enabled_by_user_)
5168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ProbeWhetherDataReductionProxyIsAvailable();
5178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
519d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)void DataReductionProxySettings::SetProxyConfigs(
520d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    bool enabled, bool restricted, bool at_startup) {
521d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  // If |restricted| is true and there is no defined fallback proxy.
522d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  // treat this as a disable.
523d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  std::string fallback = GetDataReductionProxyFallback();
524d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (fallback.empty() && enabled && restricted)
525d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      enabled = false;
526d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
527d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  LogProxyState(enabled, restricted, at_startup);
5288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* prefs = GetOriginalProfilePrefs();
5298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(prefs);
5308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DictionaryPrefUpdate update(prefs, prefs::kProxy);
5318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::DictionaryValue* dict = update.Get();
5328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (enabled) {
533d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    std::string proxy_list;
534d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    if (restricted) {
535d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      DCHECK(!fallback.empty());
536d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      proxy_list = fallback;
537d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    } else {
538d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      proxy_list = GetDataReductionProxyOrigin() +
539d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)          (fallback.empty() ? "" : "," + fallback);
540d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    }
541d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
542d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    std::string proxy_server_config = "http=" + proxy_list + ",direct://;";
5438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    dict->SetString("server", proxy_server_config);
5448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    dict->SetString("mode",
5458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                    ProxyModeToString(ProxyPrefs::MODE_FIXED_SERVERS));
5468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    dict->SetString("bypass_list", JoinString(bypass_rules_, ", "));
5478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else {
5488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    dict->SetString("mode", ProxyModeToString(ProxyPrefs::MODE_SYSTEM));
5498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    dict->SetString("server", "");
5508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    dict->SetString("bypass_list", "");
5518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Metrics methods
5558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DataReductionProxySettings::RecordDataReductionInit() {
5568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ProxyStartupState state = PROXY_NOT_AVAILABLE;
5578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (IsDataReductionProxyAllowed())
5588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    state = IsDataReductionProxyEnabled() ? PROXY_ENABLED : PROXY_DISABLED;
5598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION(kUMAProxyStartupStateHistogram,
5608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                            state,
5618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                            PROXY_STARTUP_STATE_COUNT);
5628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)DataReductionProxySettings::ContentLengthList
5658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)DataReductionProxySettings::GetDailyContentLengths(const char* pref_name) {
5668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DataReductionProxySettings::ContentLengthList content_lengths;
5678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const ListValue* list_value = GetLocalStatePrefs()->GetList(pref_name);
5688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (list_value->GetSize() == spdyproxy::kNumDaysInHistory) {
5698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    for (size_t i = 0; i < spdyproxy::kNumDaysInHistory; ++i) {
5708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      content_lengths.push_back(GetInt64PrefValue(*list_value, i));
5718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
5728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return content_lengths;
5748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) }
5758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void DataReductionProxySettings::GetContentLengths(
5778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    unsigned int days,
5788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    int64* original_content_length,
5798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    int64* received_content_length,
5808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    int64* last_update_time) {
5818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK_LE(days, spdyproxy::kNumDaysInHistory);
5828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* local_state = GetLocalStatePrefs();
5838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!local_state) {
5848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    *original_content_length = 0L;
5858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    *received_content_length = 0L;
5868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    *last_update_time = 0L;
5878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
5888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const ListValue* original_list =
5918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      local_state->GetList(prefs::kDailyHttpOriginalContentLength);
5928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const ListValue* received_list =
5938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      local_state->GetList(prefs::kDailyHttpReceivedContentLength);
5948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (original_list->GetSize() != spdyproxy::kNumDaysInHistory ||
5968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      received_list->GetSize() != spdyproxy::kNumDaysInHistory) {
5978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    *original_content_length = 0L;
5988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    *received_content_length = 0L;
5998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    *last_update_time = 0L;
6008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
6018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
6028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int64 orig = 0L;
6048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int64 recv = 0L;
6058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Include days from the end of the list going backwards.
6068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t i = spdyproxy::kNumDaysInHistory - days;
6078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)       i < spdyproxy::kNumDaysInHistory; ++i) {
6088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    orig += GetInt64PrefValue(*original_list, i);
6098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    recv += GetInt64PrefValue(*received_list, i);
6108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
6118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  *original_content_length = orig;
6128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  *received_content_length = recv;
6138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  *last_update_time =
6148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      local_state->GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate);
6158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
6168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string DataReductionProxySettings::GetProxyCheckURL() {
6188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!IsDataReductionProxyAllowed())
6198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return std::string();
6208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
6218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (command_line.HasSwitch(switches::kDataReductionProxyProbeURL)) {
6228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return command_line.GetSwitchValueASCII(
6238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        switches::kDataReductionProxyProbeURL);
6248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
6258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(DATA_REDUCTION_PROXY_PROBE_URL)
6268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return DATA_REDUCTION_PROXY_PROBE_URL;
6278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#else
6288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return std::string();
6298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif
6308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
6318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
632d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// static
6331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)base::string16 DataReductionProxySettings::AuthHashForSalt(int64 salt) {
6341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!IsDataReductionProxyAllowed())
6351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return base::string16();
6361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string key;
6381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
6401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (command_line.HasSwitch(switches::kSpdyProxyAuthOrigin)) {
6411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // If an origin is provided via a switch, then only consider the value
6421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // that is provided by a switch. Do not use the preprocessor constant.
6431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // Don't expose SPDY_PROXY_AUTH_VALUE to a proxy passed in via the command
6441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // line.
6451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (!command_line.HasSwitch(switches::kSpdyProxyAuthValue))
6461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      return base::string16();
6471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    key = command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthValue);
6481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else {
6491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(SPDY_PROXY_AUTH_VALUE)
6501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    key = SPDY_PROXY_AUTH_VALUE;
6511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#else
6521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return base::string16();
6531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif
6541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
6551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK(!key.empty());
6571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string salted_key =
6591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::StringPrintf("%lld%s%lld", salt, key.c_str(), salt);
6601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return UTF8ToUTF16(base::MD5String(salted_key));
6611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
6621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
6638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)net::URLFetcher* DataReductionProxySettings::GetURLFetcher() {
6648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string url = GetProxyCheckURL();
6658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (url.empty())
6668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return NULL;
6678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  net::URLFetcher* fetcher = net::URLFetcher::Create(GURL(url),
6688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                     net::URLFetcher::GET,
6698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                     this);
6701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE | net::LOAD_BYPASS_PROXY);
6718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  Profile* profile = g_browser_process->profile_manager()->
6728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      GetDefaultProfile();
6738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  fetcher->SetRequestContext(profile->GetRequestContext());
6748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Configure max retries to be at most kMaxRetries times for 5xx errors.
6758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  static const int kMaxRetries = 5;
6768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  fetcher->SetMaxRetriesOn5xx(kMaxRetries);
6778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return fetcher;
6788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
6798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void
6818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)DataReductionProxySettings::ProbeWhetherDataReductionProxyIsAvailable() {
6828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  net::URLFetcher* fetcher = GetURLFetcher();
6838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!fetcher)
6848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
6858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  fetcher_.reset(fetcher);
6868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  fetcher_->Start();
6878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
688