Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2898)

Unified Diff: chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc

Issue 30883003: Simple fallback implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@patched
Patch Set: Unit tests passing, feedback applied. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc
diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc
index 4318d770545b5b7eb7818aaf49d33ad3db4b43d6..fe86a08257e5b895c50dde524a3158ce1413022c 100644
--- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc
+++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc
@@ -21,9 +21,13 @@
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
+#include "crypto/random.h"
+#include "net/base/auth.h"
#include "net/base/host_port_pair.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
+#include "net/http/http_auth.h"
+#include "net/http/http_network_session.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_request_status.h"
@@ -47,6 +51,10 @@ enum ProxyStartupState {
const char kEnabled[] = "Enabled";
+// TODO(marq): factor this string out into a constant here and in
bengr 2013/10/22 17:49:30 Factor
marq (ping after 24h) 2013/10/22 21:18:01 Done.
+// http_auth_handler_spdyproxy.
+const char kAuthenticationRealmName[] = "SpdyProxy";
+
int64 GetInt64PrefValue(const ListValue& list_value, size_t index) {
int64 val = 0;
std::string pref_value;
@@ -107,6 +115,42 @@ void DataReductionProxySettings::InitDataReductionProxySettings() {
}
}
+void DataReductionProxySettings::InitDataReductionProxySession(
+ net::HttpNetworkSession* session) {
bengr 2013/10/22 17:49:30 indent +2
marq (ping after 24h) 2013/10/22 21:18:01 Done.
+// This is a no-op unless the authentication params are compiled in.
bengr 2013/10/22 17:49:30 parameters
marq (ping after 24h) 2013/10/22 21:18:01 Done.
+// (even though values for them may be specified on the command line).
bengr 2013/10/22 17:49:30 It's probably worth saying that when specified in
marq (ping after 24h) 2013/10/22 21:18:01 Done.
+#if defined(SPDY_PROXY_AUTH_ORIGIN) && defined(SPDY_PROXY_AUTH_VALUE)
+ DCHECK(session);
+ int64 timestamp =
+ (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds() / 1000;
bengr 2013/10/22 17:49:30 indent -1
marq (ping after 24h) 2013/10/22 21:18:01 Done.
+
+ DataReductionProxyList proxies = GetDataReductionProxies();
+ for (DataReductionProxyList::iterator it = proxies.begin();
+ it != proxies.end(); ++it) {
+ net::HostPortPair auth_origin = *it;
bengr 2013/10/22 17:49:30 const ref?
marq (ping after 24h) 2013/10/22 21:18:01 Yes, but the code's changed slightly.
+ int32 rand1, rand2, rand3;
+ crypto::RandBytes(&rand1, sizeof(rand1));
+ crypto::RandBytes(&rand2, sizeof(rand2));
+ crypto::RandBytes(&rand3, sizeof(rand3));
+
+ std::string realm =
+ base::StringPrintf("%s%lld", kAuthenticationRealmName, timestamp);
+ std::string challenge = base::StringPrintf(
+ "%s realm=\"%s\", ps=\"%lld-%u-%u-%u\"",
+ kAuthenticationRealmName, realm.data(), timestamp, rand1, rand2, rand3);
+ base::string16 password = AuthHashForSalt(timestamp);
+
+ DVLOG(1) << "origin: [" << auth_origin.ToString() << "] realm: [" << realm
+ << "] challenge: [" << challenge << "] password: [" << password << "]";
+
+ net::AuthCredentials credentials(base::string16(), password);
+ session->http_auth_cache()->Add(GURL(auth_origin.ToString()), realm,
+ net::HttpAuth::AUTH_SCHEME_SPDYPROXY,
+ challenge, credentials, std::string("/"));
+ }
+#endif // defined(SPDY_PROXY_AUTH_ORIGIN) && defined(SPDY_PROXY_AUTH_VALUE)
+}
+
void DataReductionProxySettings::AddHostPatternToBypass(
const std::string& pattern) {
bypass_rules_.push_back(pattern);
@@ -143,31 +187,55 @@ std::string DataReductionProxySettings::GetDataReductionProxyOrigin() {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (command_line.HasSwitch(switches::kSpdyProxyAuthOrigin))
return command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthOrigin);
-#if defined(SPDY_PROXY_AUTH_ORIGIN)
- return SPDY_PROXY_AUTH_ORIGIN;
-#else
- return std::string();
-#endif
+ return GetDefaultProxyHost();
}
-std::string DataReductionProxySettings::GetDataReductionProxyAuth() {
- if (!IsDataReductionProxyAllowed())
+std::string DataReductionProxySettings::GetDataReductionProxyFallback() {
+ // Regardless of what else is defined, only return a value if the main proxy
+ // origin is defined.
+ if (GetDataReductionProxyOrigin().empty())
return std::string();
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kSpdyProxyAuthOrigin)) {
- // If an origin is provided via a switch, then only consider the value
- // that is provided by a switch. Do not use the preprocessor constant.
- // Don't expose SPDY_PROXY_AUTH_VALUE to a proxy passed in via the command
- // line.
- if (command_line.HasSwitch(switches::kSpdyProxyAuthValue))
- return command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthValue);
- return std::string();
+ if (command_line.HasSwitch(switches::kSpdyProxyAuthFallback))
+ return command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthFallback);
+ return GetDefaultFallbackProxyHost();
+}
+
+bool DataReductionProxySettings::IsAcceptableAuthChallenge(
+ net::AuthChallengeInfo* auth_info) {
+ // Challenge realm must start with the authentication realm name.
+ std::string realm_prefix =
+ auth_info->realm.substr(0, strlen(kAuthenticationRealmName));
+ if (realm_prefix != kAuthenticationRealmName)
+ return false;
+
+ // The challenger must be one of the configured proxies.
+ DataReductionProxyList proxies = GetDataReductionProxies();
+ for (DataReductionProxyList::iterator it = proxies.begin();
+ it != proxies.end(); ++it) {
+ net::HostPortPair origin_host = *it;
+ if (origin_host.Equals(auth_info->challenger))
+ return true;
+ }
+ return false;
+}
+
+base::string16 DataReductionProxySettings::GetTokenForAuthChallenge(
+ net::AuthChallengeInfo* auth_info) {
+ if (auth_info->realm.length() > strlen(kAuthenticationRealmName)) {
+ int64 salt;
+ std::string realm_suffix =
+ auth_info->realm.substr(strlen(kAuthenticationRealmName));
+ if (base::StringToInt64(realm_suffix, &salt)) {
+ return AuthHashForSalt(salt);
+ } else {
+ DVLOG(1) << "Unable to parse realm name " << auth_info->realm
+ << "into an int for salting.";
+ return base::string16();
+ }
+ } else {
+ return base::string16();
}
-#if defined(SPDY_PROXY_AUTH_VALUE)
- return SPDY_PROXY_AUTH_VALUE;
-#else
- return std::string();
-#endif
}
bool DataReductionProxySettings::IsDataReductionProxyEnabled() {
@@ -178,6 +246,24 @@ bool DataReductionProxySettings::IsDataReductionProxyManaged() {
return spdy_proxy_auth_enabled_.IsManaged();
}
+DataReductionProxySettings::DataReductionProxyList
+DataReductionProxySettings::GetDataReductionProxies() {
+ DataReductionProxyList proxies;
+ std::string proxy = GetDataReductionProxyOrigin();
+ std::string fallback = GetDataReductionProxyFallback();
+
+ if (!proxy.empty())
+ proxies.push_back(net::HostPortPair::FromURL(GURL(proxy)));
+
+ if (!fallback.empty()) {
+ // Sanity check: fallback isn't the only proxy.
+ DCHECK(!proxies.empty());
+ proxies.push_back(net::HostPortPair::FromURL(GURL(fallback)));
+ }
+
+ return proxies;
+}
+
void DataReductionProxySettings::SetDataReductionProxyEnabled(bool enabled) {
// Prevent configuring the proxy when it is not allowed to be used.
if (!IsDataReductionProxyAllowed())
@@ -195,12 +281,12 @@ int64 DataReductionProxySettings::GetDataReductionLastUpdateTime() {
return static_cast<int64>(last_update.ToJsTime());
}
-std::vector<long long>
+DataReductionProxySettings::ContentLengthList
DataReductionProxySettings::GetDailyOriginalContentLengths() {
return GetDailyContentLengths(prefs::kDailyHttpOriginalContentLength);
}
-std::vector<long long>
+DataReductionProxySettings::ContentLengthList
DataReductionProxySettings::GetDailyReceivedContentLengths() {
return GetDailyContentLengths(prefs::kDailyHttpReceivedContentLength);
}
@@ -237,17 +323,6 @@ void DataReductionProxySettings::OnURLFetchComplete(
disabled_by_carrier_ = true;
}
-std::string DataReductionProxySettings::GetDataReductionProxyOriginHostPort() {
- std::string spdy_proxy = GetDataReductionProxyOrigin();
- if (spdy_proxy.empty()) {
- DLOG(ERROR) << "A SPDY proxy has not been set.";
- return spdy_proxy;
- }
- // Remove a trailing slash from the proxy string if one exists as well as
- // leading HTTPS scheme.
- return net::HostPortPair::FromURL(GURL(spdy_proxy)).ToString();
-}
-
void DataReductionProxySettings::OnIPAddressChanged() {
if (enabled_by_user_) {
DCHECK(IsDataReductionProxyAllowed());
@@ -284,6 +359,22 @@ void DataReductionProxySettings::LogProxyState(bool enabled, bool at_startup) {
<< " " << (at_startup ? kAtStartup : kByUser);
}
+std::string DataReductionProxySettings::GetDefaultProxyHost() {
bengr 2013/10/22 17:49:30 Why isn't the handling of command line switch valu
marq (ping after 24h) 2013/10/22 21:18:01 These two methods are used so that unit tests can
+#if defined(SPDY_PROXY_AUTH_ORIGIN)
+ return SPDY_PROXY_AUTH_ORIGIN;
+#else
+ return std::string();
+#endif
+}
+
+std::string DataReductionProxySettings::GetDefaultFallbackProxyHost() {
+#if defined(DATA_REDUCTION_FALLBACK_HOST)
+ return DATA_REDUCTION_FALLBACK_HOST;
bengr 2013/10/22 17:49:30 why not check in this function if GetDefaultProxyH
marq (ping after 24h) 2013/10/22 21:18:01 I don't think the default value here is of necessi
+#else
+ return std::string();
+#endif
+}
+
PrefService* DataReductionProxySettings::GetOriginalProfilePrefs() {
return g_browser_process->profile_manager()->GetLastUsedProfile()->
GetOriginalProfile()->GetPrefs();
@@ -324,12 +415,10 @@ void DataReductionProxySettings::MaybeActivateDataReductionProxy(
ResetDataReductionStatistics();
}
- std::string spdy_proxy_origin = GetDataReductionProxyOriginHostPort();
-
+ std::string proxy = GetDataReductionProxyOrigin();
// Configure use of the data reduction proxy if it is enabled and the proxy
// origin is non-empty.
- enabled_by_user_=
- spdy_proxy_auth_enabled_.GetValue() && !spdy_proxy_origin.empty();
+ enabled_by_user_= spdy_proxy_auth_enabled_.GetValue() && !proxy.empty();
SetProxyConfigs(enabled_by_user_ && !disabled_by_carrier_, at_startup);
// Check if the proxy has been disabled explicitly by the carrier.
@@ -345,8 +434,11 @@ void DataReductionProxySettings::SetProxyConfigs(bool enabled,
DictionaryPrefUpdate update(prefs, prefs::kProxy);
base::DictionaryValue* dict = update.Get();
if (enabled) {
+ std::string fallback = GetDataReductionProxyFallback();
std::string proxy_server_config =
- "http=" + GetDataReductionProxyOrigin() + ",direct://;";
+ "http=" + GetDataReductionProxyOrigin() +
+ (fallback.empty() ? "" : "," + fallback) +
+ ",direct://;";
dict->SetString("server", proxy_server_config);
dict->SetString("mode",
ProxyModeToString(ProxyPrefs::MODE_FIXED_SERVERS));
@@ -436,6 +528,36 @@ std::string DataReductionProxySettings::GetProxyCheckURL() {
#endif
}
+base::string16 DataReductionProxySettings::AuthHashForSalt(int64 salt) {
+ if (!IsDataReductionProxyAllowed())
+ return base::string16();
+
+ std::string key;
+
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ if (command_line.HasSwitch(switches::kSpdyProxyAuthOrigin)) {
+ // If an origin is provided via a switch, then only consider the value
+ // that is provided by a switch. Do not use the preprocessor constant.
+ // Don't expose SPDY_PROXY_AUTH_VALUE to a proxy passed in via the command
+ // line.
+ if (!command_line.HasSwitch(switches::kSpdyProxyAuthValue))
+ return base::string16();
+ key = command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthValue);
+ } else {
+#if defined(SPDY_PROXY_AUTH_VALUE)
+ key = SPDY_PROXY_AUTH_VALUE;
+#else
+ return base::string16();
+#endif
+ }
+
+ DCHECK(!key.empty());
+
+ std::string salted_key =
+ base::StringPrintf("%lld%s%lld", salt, key.c_str(), salt);
+ return UTF8ToUTF16(base::MD5String(salted_key));
+}
+
net::URLFetcher* DataReductionProxySettings::GetURLFetcher() {
std::string url = GetProxyCheckURL();
if (url.empty())

Powered by Google App Engine
This is Rietveld 408576698