| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.
h" | 5 #include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.
h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/metrics/field_trial.h" | 9 #include "base/metrics/field_trial.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 rv = base::StringToInt64(pref_value, &val); | 60 rv = base::StringToInt64(pref_value, &val); |
| 61 DCHECK(rv); | 61 DCHECK(rv); |
| 62 } | 62 } |
| 63 return val; | 63 return val; |
| 64 } | 64 } |
| 65 | 65 |
| 66 } // namespace | 66 } // namespace |
| 67 | 67 |
| 68 namespace data_reduction_proxy { | 68 namespace data_reduction_proxy { |
| 69 | 69 |
| 70 std::string DataReductionProxySettings::key_; | |
| 71 bool DataReductionProxySettings::allowed_; | 70 bool DataReductionProxySettings::allowed_; |
| 72 bool DataReductionProxySettings::promo_allowed_; | 71 bool DataReductionProxySettings::promo_allowed_; |
| 73 | 72 |
| 74 // static | 73 // static |
| 75 bool DataReductionProxySettings::IsProxyOriginSetOnCommandLine() { | 74 bool DataReductionProxySettings::IsProxyOriginSetOnCommandLine() { |
| 76 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 75 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 77 return command_line.HasSwitch( | 76 return command_line.HasSwitch( |
| 78 data_reduction_proxy::switches::kDataReductionProxy); | 77 data_reduction_proxy::switches::kDataReductionProxy); |
| 79 } | 78 } |
| 80 | 79 |
| 81 // static | 80 // static |
| 82 bool DataReductionProxySettings::IsProxyKeySetOnCommandLine() { | 81 bool DataReductionProxySettings::IsProxyKeySetOnCommandLine() { |
| 83 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 82 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 84 return command_line.HasSwitch( | 83 return command_line.HasSwitch( |
| 85 data_reduction_proxy::switches::kEnableDataReductionProxy); | 84 data_reduction_proxy::switches::kEnableDataReductionProxy); |
| 86 } | 85 } |
| 87 | 86 |
| 88 // static | 87 // static |
| 89 bool DataReductionProxySettings::IsIncludedInFieldTrialOrFlags() { | 88 bool DataReductionProxySettings::IsIncludedInFieldTrialOrFlags() { |
| 90 return (base::FieldTrialList::FindFullName( | 89 return (base::FieldTrialList::FindFullName( |
| 91 "DataCompressionProxyRollout") == kEnabled || | 90 "DataCompressionProxyRollout") == kEnabled || |
| 92 IsProxyOriginSetOnCommandLine()); | 91 IsProxyOriginSetOnCommandLine()); |
| 93 } | 92 } |
| 94 | 93 |
| 95 // static | 94 // static |
| 96 void DataReductionProxySettings::SetKey(const std::string& key) { | |
| 97 key_ = key; | |
| 98 } | |
| 99 | |
| 100 // static | |
| 101 void DataReductionProxySettings::SetAllowed(bool allowed) { | 95 void DataReductionProxySettings::SetAllowed(bool allowed) { |
| 102 allowed_ = allowed; | 96 allowed_ = allowed; |
| 103 } | 97 } |
| 104 | 98 |
| 105 // static | 99 // static |
| 106 void DataReductionProxySettings::SetPromoAllowed(bool promo_allowed) { | 100 void DataReductionProxySettings::SetPromoAllowed(bool promo_allowed) { |
| 107 promo_allowed_ = promo_allowed; | 101 promo_allowed_ = promo_allowed; |
| 108 } | 102 } |
| 109 | 103 |
| 110 DataReductionProxySettings::DataReductionProxySettings() | 104 DataReductionProxySettings::DataReductionProxySettings() |
| 111 : restricted_by_carrier_(false), | 105 : key_(), |
| 106 restricted_by_carrier_(false), |
| 112 enabled_by_user_(false), | 107 enabled_by_user_(false), |
| 113 prefs_(NULL), | 108 prefs_(NULL), |
| 114 local_state_prefs_(NULL), | 109 local_state_prefs_(NULL), |
| 115 url_request_context_getter_(NULL), | 110 url_request_context_getter_(NULL), |
| 116 fallback_allowed_(true) { | 111 fallback_allowed_(true) { |
| 117 } | 112 } |
| 118 | 113 |
| 119 DataReductionProxySettings::~DataReductionProxySettings() { | 114 DataReductionProxySettings::~DataReductionProxySettings() { |
| 120 if (IsDataReductionProxyAllowed()) | 115 if (IsDataReductionProxyAllowed()) |
| 121 spdy_proxy_auth_enabled_.Destroy(); | 116 spdy_proxy_auth_enabled_.Destroy(); |
| 122 } | 117 } |
| 123 | 118 |
| 119 void DataReductionProxySettings::set_key(const std::string& key) { |
| 120 key_ = key; |
| 121 } |
| 122 |
| 123 std::string DataReductionProxySettings::key() { |
| 124 return key_; |
| 125 } |
| 126 |
| 127 |
| 124 void DataReductionProxySettings::InitPrefMembers() { | 128 void DataReductionProxySettings::InitPrefMembers() { |
| 125 DCHECK(thread_checker_.CalledOnValidThread()); | 129 DCHECK(thread_checker_.CalledOnValidThread()); |
| 126 spdy_proxy_auth_enabled_.Init( | 130 spdy_proxy_auth_enabled_.Init( |
| 127 prefs::kDataReductionProxyEnabled, | 131 prefs::kDataReductionProxyEnabled, |
| 128 GetOriginalProfilePrefs(), | 132 GetOriginalProfilePrefs(), |
| 129 base::Bind(&DataReductionProxySettings::OnProxyEnabledPrefChange, | 133 base::Bind(&DataReductionProxySettings::OnProxyEnabledPrefChange, |
| 130 base::Unretained(this))); | 134 base::Unretained(this))); |
| 131 } | 135 } |
| 132 | 136 |
| 133 void DataReductionProxySettings::InitDataReductionProxySettings( | 137 void DataReductionProxySettings::InitDataReductionProxySettings( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 } | 171 } |
| 168 | 172 |
| 169 void DataReductionProxySettings::SetProxyConfigurator( | 173 void DataReductionProxySettings::SetProxyConfigurator( |
| 170 scoped_ptr<DataReductionProxyConfigurator> configurator) { | 174 scoped_ptr<DataReductionProxyConfigurator> configurator) { |
| 171 DCHECK(configurator); | 175 DCHECK(configurator); |
| 172 config_ = configurator.Pass(); | 176 config_ = configurator.Pass(); |
| 173 } | 177 } |
| 174 | 178 |
| 175 // static | 179 // static |
| 176 void DataReductionProxySettings::InitDataReductionProxySession( | 180 void DataReductionProxySettings::InitDataReductionProxySession( |
| 177 net::HttpNetworkSession* session) { | 181 net::HttpNetworkSession* session, |
| 182 const std::string& key) { |
| 178 // This is a no-op unless the authentication parameters are compiled in. | 183 // This is a no-op unless the authentication parameters are compiled in. |
| 179 // (even though values for them may be specified on the command line). | 184 // (even though values for them may be specified on the command line). |
| 180 // Authentication will still work if the command line parameters are used, | 185 // Authentication will still work if the command line parameters are used, |
| 181 // however there will be a round-trip overhead for each challenge/response | 186 // however there will be a round-trip overhead for each challenge/response |
| 182 // (typically once per session). | 187 // (typically once per session). |
| 183 // TODO(bengr):Pass a configuration struct into DataReductionProxyConfigurator's | 188 // TODO(bengr):Pass a configuration struct into DataReductionProxyConfigurator's |
| 184 // constructor. The struct would carry everything in the preprocessor flags. | 189 // constructor. The struct would carry everything in the preprocessor flags. |
| 185 if (key_.empty()) | 190 if (key.empty()) |
| 186 return; | 191 return; |
| 187 DCHECK(session); | 192 DCHECK(session); |
| 188 net::HttpAuthCache* auth_cache = session->http_auth_cache(); | 193 net::HttpAuthCache* auth_cache = session->http_auth_cache(); |
| 189 DCHECK(auth_cache); | 194 DCHECK(auth_cache); |
| 190 InitDataReductionAuthentication(auth_cache); | 195 InitDataReductionAuthentication(auth_cache, key); |
| 191 } | 196 } |
| 192 | 197 |
| 193 // static | 198 // static |
| 194 void DataReductionProxySettings::InitDataReductionAuthentication( | 199 void DataReductionProxySettings::InitDataReductionAuthentication( |
| 195 net::HttpAuthCache* auth_cache) { | 200 net::HttpAuthCache* auth_cache, |
| 201 const std::string& key) { |
| 196 DCHECK(auth_cache); | 202 DCHECK(auth_cache); |
| 197 int64 timestamp = | 203 int64 timestamp = |
| 198 (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds() / 1000; | 204 (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds() / 1000; |
| 199 | 205 |
| 200 DataReductionProxyList proxies = GetDataReductionProxies(); | 206 DataReductionProxyList proxies = GetDataReductionProxies(); |
| 201 for (DataReductionProxyList::iterator it = proxies.begin(); | 207 for (DataReductionProxyList::iterator it = proxies.begin(); |
| 202 it != proxies.end(); ++it) { | 208 it != proxies.end(); ++it) { |
| 203 GURL auth_origin = (*it).GetOrigin(); | 209 GURL auth_origin = (*it).GetOrigin(); |
| 204 int32 rand[3]; | 210 int32 rand[3]; |
| 205 crypto::RandBytes(rand, 3 * sizeof(rand[0])); | 211 crypto::RandBytes(rand, 3 * sizeof(rand[0])); |
| 206 | 212 |
| 207 std::string realm = | 213 std::string realm = |
| 208 base::StringPrintf("%s%lld", kAuthenticationRealmName, | 214 base::StringPrintf("%s%lld", kAuthenticationRealmName, |
| 209 static_cast<long long>(timestamp)); | 215 static_cast<long long>(timestamp)); |
| 210 std::string challenge = base::StringPrintf( | 216 std::string challenge = base::StringPrintf( |
| 211 "%s realm=\"%s\", ps=\"%lld-%u-%u-%u\"", | 217 "%s realm=\"%s\", ps=\"%lld-%u-%u-%u\"", |
| 212 kAuthenticationRealmName, | 218 kAuthenticationRealmName, |
| 213 realm.data(), | 219 realm.data(), |
| 214 static_cast<long long>(timestamp), | 220 static_cast<long long>(timestamp), |
| 215 rand[0], | 221 rand[0], |
| 216 rand[1], | 222 rand[1], |
| 217 rand[2]); | 223 rand[2]); |
| 218 base::string16 password = AuthHashForSalt(timestamp); | 224 base::string16 password = AuthHashForSalt(timestamp, key); |
| 219 | 225 |
| 220 DVLOG(1) << "origin: [" << auth_origin << "] realm: [" << realm | 226 DVLOG(1) << "origin: [" << auth_origin << "] realm: [" << realm |
| 221 << "] challenge: [" << challenge << "] password: [" << password << "]"; | 227 << "] challenge: [" << challenge << "] password: [" << password << "]"; |
| 222 | 228 |
| 223 net::AuthCredentials credentials(base::string16(), password); | 229 net::AuthCredentials credentials(base::string16(), password); |
| 224 // |HttpAuthController| searches this cache by origin and path, the latter | 230 // |HttpAuthController| searches this cache by origin and path, the latter |
| 225 // being '/' in the case of the data reduction proxy. | 231 // being '/' in the case of the data reduction proxy. |
| 226 auth_cache->Add(auth_origin, | 232 auth_cache->Add(auth_origin, |
| 227 realm, | 233 realm, |
| 228 net::HttpAuth::AUTH_SCHEME_SPDYPROXY, | 234 net::HttpAuth::AUTH_SCHEME_SPDYPROXY, |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 DataReductionProxyList proxies = GetDataReductionProxies(); | 309 DataReductionProxyList proxies = GetDataReductionProxies(); |
| 304 for (DataReductionProxyList::iterator it = proxies.begin(); | 310 for (DataReductionProxyList::iterator it = proxies.begin(); |
| 305 it != proxies.end(); ++it) { | 311 it != proxies.end(); ++it) { |
| 306 net::HostPortPair origin_host = net::HostPortPair::FromURL(*it); | 312 net::HostPortPair origin_host = net::HostPortPair::FromURL(*it); |
| 307 if (origin_host.Equals(auth_info->challenger)) | 313 if (origin_host.Equals(auth_info->challenger)) |
| 308 return true; | 314 return true; |
| 309 } | 315 } |
| 310 return false; | 316 return false; |
| 311 } | 317 } |
| 312 | 318 |
| 313 // static | |
| 314 base::string16 DataReductionProxySettings::GetTokenForAuthChallenge( | 319 base::string16 DataReductionProxySettings::GetTokenForAuthChallenge( |
| 315 net::AuthChallengeInfo* auth_info) { | 320 net::AuthChallengeInfo* auth_info) { |
| 316 if (auth_info->realm.length() > strlen(kAuthenticationRealmName)) { | 321 if (auth_info->realm.length() > strlen(kAuthenticationRealmName)) { |
| 317 int64 salt; | 322 int64 salt; |
| 318 std::string realm_suffix = | 323 std::string realm_suffix = |
| 319 auth_info->realm.substr(strlen(kAuthenticationRealmName)); | 324 auth_info->realm.substr(strlen(kAuthenticationRealmName)); |
| 320 if (base::StringToInt64(realm_suffix, &salt)) { | 325 if (base::StringToInt64(realm_suffix, &salt)) { |
| 321 return AuthHashForSalt(salt); | 326 return AuthHashForSalt(salt, key_); |
| 322 } else { | 327 } else { |
| 323 DVLOG(1) << "Unable to parse realm name " << auth_info->realm | 328 DVLOG(1) << "Unable to parse realm name " << auth_info->realm |
| 324 << "into an int for salting."; | 329 << "into an int for salting."; |
| 325 return base::string16(); | 330 return base::string16(); |
| 326 } | 331 } |
| 327 } else { | 332 } else { |
| 328 return base::string16(); | 333 return base::string16(); |
| 329 } | 334 } |
| 330 } | 335 } |
| 331 | 336 |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 switches::kDataReductionProxyProbeURL); | 650 switches::kDataReductionProxyProbeURL); |
| 646 } | 651 } |
| 647 #if defined(DATA_REDUCTION_PROXY_PROBE_URL) | 652 #if defined(DATA_REDUCTION_PROXY_PROBE_URL) |
| 648 return DATA_REDUCTION_PROXY_PROBE_URL; | 653 return DATA_REDUCTION_PROXY_PROBE_URL; |
| 649 #else | 654 #else |
| 650 return std::string(); | 655 return std::string(); |
| 651 #endif | 656 #endif |
| 652 } | 657 } |
| 653 | 658 |
| 654 // static | 659 // static |
| 655 base::string16 DataReductionProxySettings::AuthHashForSalt(int64 salt) { | 660 base::string16 DataReductionProxySettings::AuthHashForSalt( |
| 656 if (!IsDataReductionProxyAllowed()) | 661 int64 salt, |
| 657 return base::string16(); | 662 const std::string& key) { |
| 658 | 663 std::string active_key; |
| 659 std::string key; | |
| 660 | 664 |
| 661 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 665 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 662 if (command_line.HasSwitch(switches::kDataReductionProxy)) { | 666 if (command_line.HasSwitch(switches::kDataReductionProxy)) { |
| 663 // If an origin is provided via a switch, then only consider the value | 667 // If an origin is provided via a switch, then only consider the value |
| 664 // that is provided by a switch. Do not use the preprocessor constant. | 668 // that is provided by a switch. Do not use the preprocessor constant. |
| 665 // Don't expose |key_| to a proxy passed in via the command line. | 669 // Don't expose |key_| to a proxy passed in via the command line. |
| 666 if (!command_line.HasSwitch(switches::kDataReductionProxyKey)) | 670 if (!command_line.HasSwitch(switches::kDataReductionProxyKey)) |
| 667 return base::string16(); | 671 return base::string16(); |
| 668 key = command_line.GetSwitchValueASCII(switches::kDataReductionProxyKey); | 672 active_key = command_line.GetSwitchValueASCII( |
| 673 switches::kDataReductionProxyKey); |
| 669 } else { | 674 } else { |
| 670 key = key_; | 675 active_key = key; |
| 671 } | 676 } |
| 672 | 677 DCHECK(!active_key.empty()); |
| 673 DCHECK(!key.empty()); | |
| 674 | 678 |
| 675 std::string salted_key = | 679 std::string salted_key = |
| 676 base::StringPrintf("%lld%s%lld", | 680 base::StringPrintf("%lld%s%lld", |
| 677 static_cast<long long>(salt), | 681 static_cast<long long>(salt), |
| 678 key.c_str(), | 682 active_key.c_str(), |
| 679 static_cast<long long>(salt)); | 683 static_cast<long long>(salt)); |
| 680 return base::UTF8ToUTF16(base::MD5String(salted_key)); | 684 return base::UTF8ToUTF16(base::MD5String(salted_key)); |
| 681 } | 685 } |
| 682 | 686 |
| 683 net::URLFetcher* DataReductionProxySettings::GetURLFetcher() { | 687 net::URLFetcher* DataReductionProxySettings::GetURLFetcher() { |
| 684 DCHECK(url_request_context_getter_); | 688 DCHECK(url_request_context_getter_); |
| 685 std::string url = GetProxyCheckURL(); | 689 std::string url = GetProxyCheckURL(); |
| 686 if (url.empty()) | 690 if (url.empty()) |
| 687 return NULL; | 691 return NULL; |
| 688 net::URLFetcher* fetcher = net::URLFetcher::Create(GURL(url), | 692 net::URLFetcher* fetcher = net::URLFetcher::Create(GURL(url), |
| 689 net::URLFetcher::GET, | 693 net::URLFetcher::GET, |
| 690 this); | 694 this); |
| 691 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE | net::LOAD_BYPASS_PROXY); | 695 fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE | net::LOAD_BYPASS_PROXY); |
| 692 fetcher->SetRequestContext(url_request_context_getter_); | 696 fetcher->SetRequestContext(url_request_context_getter_); |
| 693 // Configure max retries to be at most kMaxRetries times for 5xx errors. | 697 // Configure max retries to be at most kMaxRetries times for 5xx errors. |
| 694 static const int kMaxRetries = 5; | 698 static const int kMaxRetries = 5; |
| 695 fetcher->SetMaxRetriesOn5xx(kMaxRetries); | 699 fetcher->SetMaxRetriesOn5xx(kMaxRetries); |
| 696 return fetcher; | 700 return fetcher; |
| 697 } | 701 } |
| 698 | 702 |
| 699 void DataReductionProxySettings::ProbeWhetherDataReductionProxyIsAvailable() { | 703 void DataReductionProxySettings::ProbeWhetherDataReductionProxyIsAvailable() { |
| 700 net::URLFetcher* fetcher = GetURLFetcher(); | 704 net::URLFetcher* fetcher = GetURLFetcher(); |
| 701 if (!fetcher) | 705 if (!fetcher) |
| 702 return; | 706 return; |
| 703 fetcher_.reset(fetcher); | 707 fetcher_.reset(fetcher); |
| 704 fetcher_->Start(); | 708 fetcher_->Start(); |
| 705 } | 709 } |
| 706 | 710 |
| 707 } // namespace data_reduction_proxy | 711 } // namespace data_reduction_proxy |
| OLD | NEW |