diff options
author | asanka@chromium.org <asanka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-12 23:32:51 +0000 |
---|---|---|
committer | asanka@chromium.org <asanka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-12 23:32:51 +0000 |
commit | db8ff912c0325d5bbff4b989de637ee371d09406 (patch) | |
tree | d76d169b88f42e8a53e193afddc851012bb5d122 /net | |
parent | 72cf3215b9359e1f7c454e9d3f281edef5bf3fc7 (diff) | |
download | chromium_src-db8ff912c0325d5bbff4b989de637ee371d09406.zip chromium_src-db8ff912c0325d5bbff4b989de637ee371d09406.tar.gz chromium_src-db8ff912c0325d5bbff4b989de637ee371d09406.tar.bz2 |
Track sources of proxy settings.
ProxyConfig keeps track of the source of proxy settings. During proxy resolution ProxyService tags the resulting ProxyInfo with the same source information.
BUG=none
TEST=net_unittests
Review URL: https://chromiumcodereview.appspot.com/10310179
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@141784 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/net.gyp | 3 | ||||
-rw-r--r-- | net/proxy/proxy_config.cc | 18 | ||||
-rw-r--r-- | net/proxy/proxy_config.h | 19 | ||||
-rw-r--r-- | net/proxy/proxy_config_service_linux.cc | 24 | ||||
-rw-r--r-- | net/proxy/proxy_config_service_linux.h | 5 | ||||
-rw-r--r-- | net/proxy/proxy_config_service_linux_unittest.cc | 4 | ||||
-rw-r--r-- | net/proxy/proxy_config_service_mac.cc | 3 | ||||
-rw-r--r-- | net/proxy/proxy_config_service_win.cc | 4 | ||||
-rw-r--r-- | net/proxy/proxy_config_service_win_unittest.cc | 3 | ||||
-rw-r--r-- | net/proxy/proxy_config_source.cc | 35 | ||||
-rw-r--r-- | net/proxy/proxy_config_source.h | 38 | ||||
-rw-r--r-- | net/proxy/proxy_config_unittest.cc | 31 | ||||
-rw-r--r-- | net/proxy/proxy_info.cc | 32 | ||||
-rw-r--r-- | net/proxy/proxy_info.h | 36 | ||||
-rw-r--r-- | net/proxy/proxy_info_unittest.cc | 41 | ||||
-rw-r--r-- | net/proxy/proxy_list.cc | 10 | ||||
-rw-r--r-- | net/proxy/proxy_list.h | 8 | ||||
-rw-r--r-- | net/proxy/proxy_service.cc | 9 | ||||
-rw-r--r-- | net/proxy/proxy_service_unittest.cc | 82 |
19 files changed, 370 insertions, 35 deletions
diff --git a/net/net.gyp b/net/net.gyp index af65034..6820b7a 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -557,6 +557,8 @@ 'proxy/proxy_config_service_mac.h', 'proxy/proxy_config_service_win.cc', 'proxy/proxy_config_service_win.h', + 'proxy/proxy_config_source.cc', + 'proxy/proxy_config_source.h', 'proxy/proxy_info.cc', 'proxy/proxy_info.h', 'proxy/proxy_list.cc', @@ -1184,6 +1186,7 @@ 'proxy/proxy_config_service_linux_unittest.cc', 'proxy/proxy_config_service_win_unittest.cc', 'proxy/proxy_config_unittest.cc', + 'proxy/proxy_info_unittest.cc', 'proxy/proxy_list_unittest.cc', 'proxy/proxy_resolver_js_bindings_unittest.cc', 'proxy/proxy_resolver_v8_unittest.cc', diff --git a/net/proxy/proxy_config.cc b/net/proxy/proxy_config.cc index d160fa4..12acc5a 100644 --- a/net/proxy/proxy_config.cc +++ b/net/proxy/proxy_config.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -32,7 +32,7 @@ ProxyConfig::ProxyRules::ProxyRules() ProxyConfig::ProxyRules::~ProxyRules() { } -void ProxyConfig::ProxyRules::Apply(const GURL& url, ProxyInfo* result) { +void ProxyConfig::ProxyRules::Apply(const GURL& url, ProxyInfo* result) const { if (empty()) { result->UseDirect(); return; @@ -42,7 +42,7 @@ void ProxyConfig::ProxyRules::Apply(const GURL& url, ProxyInfo* result) { if (reverse_bypass) bypass_proxy = !bypass_proxy; if (bypass_proxy) { - result->UseDirect(); + result->UseDirectWithBypassedProxy(); return; } @@ -159,7 +159,8 @@ ProxyServer* ProxyConfig::ProxyRules::MapUrlSchemeToProxyNoFallback( } ProxyConfig::ProxyConfig() - : auto_detect_(false), pac_mandatory_(false), id_(kInvalidConfigID) { + : auto_detect_(false), pac_mandatory_(false), + source_(PROXY_CONFIG_SOURCE_UNKNOWN), id_(kInvalidConfigID) { } ProxyConfig::ProxyConfig(const ProxyConfig& config) @@ -167,6 +168,7 @@ ProxyConfig::ProxyConfig(const ProxyConfig& config) pac_url_(config.pac_url_), pac_mandatory_(config.pac_mandatory_), proxy_rules_(config.proxy_rules_), + source_(config.source_), id_(config.id_) { } @@ -178,13 +180,14 @@ ProxyConfig& ProxyConfig::operator=(const ProxyConfig& config) { pac_url_ = config.pac_url_; pac_mandatory_ = config.pac_mandatory_; proxy_rules_ = config.proxy_rules_; + source_ = config.source_; id_ = config.id_; return *this; } bool ProxyConfig::Equals(const ProxyConfig& other) const { - // The two configs can have different IDs. We are just interested in if they - // have the same settings. + // The two configs can have different IDs and sources. We are just interested + // in if they have the same settings. return auto_detect_ == other.auto_detect_ && pac_url_ == other.pac_url_ && pac_mandatory_ == other.pac_mandatory_ && @@ -249,6 +252,9 @@ Value* ProxyConfig::ToValue() const { } } + // Output the source. + dict->SetString("source", ProxyConfigSourceToString(source_)); + return dict; } diff --git a/net/proxy/proxy_config.h b/net/proxy/proxy_config.h index fa2f6e8..4b1293d 100644 --- a/net/proxy/proxy_config.h +++ b/net/proxy/proxy_config.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -11,6 +11,7 @@ #include "googleurl/src/gurl.h" #include "net/base/net_export.h" #include "net/proxy/proxy_bypass_rules.h" +#include "net/proxy/proxy_config_source.h" #include "net/proxy/proxy_server.h" namespace base { @@ -53,7 +54,7 @@ class NET_EXPORT ProxyConfig { } // Sets |result| with the proxy to use for |url| based on the current rules. - void Apply(const GURL& url, ProxyInfo* result); + void Apply(const GURL& url, ProxyInfo* result) const; // Parses the rules from a string, indicating which proxies to use. // @@ -122,7 +123,8 @@ class NET_EXPORT ProxyConfig { void set_id(ID id) { id_ = id; } bool is_valid() const { return id_ != kInvalidConfigID; } - // Returns true if the given config is equivalent to this config. + // Returns true if the given config is equivalent to this config. The + // comparison ignores differences in |id()| and |source()|. bool Equals(const ProxyConfig& other) const; // Returns true if this config contains any "automatic" settings. See the @@ -171,6 +173,14 @@ class NET_EXPORT ProxyConfig { return auto_detect_; } + void set_source(ProxyConfigSource source) { + source_ = source; + } + + ProxyConfigSource source() const { + return source_; + } + // Helpers to construct some common proxy configurations. static ProxyConfig CreateDirect() { @@ -205,6 +215,9 @@ class NET_EXPORT ProxyConfig { // Manual proxy settings. ProxyRules proxy_rules_; + // Source of proxy settings. + ProxyConfigSource source_; + ID id_; }; diff --git a/net/proxy/proxy_config_service_linux.cc b/net/proxy/proxy_config_service_linux.cc index fb001cd..fc85947 100644 --- a/net/proxy/proxy_config_service_linux.cc +++ b/net/proxy/proxy_config_service_linux.cc @@ -320,8 +320,8 @@ class SettingGetterImplGConf : public ProxyConfigServiceLinux::SettingGetter { return task_runner_; } - virtual const char* GetDataSource() OVERRIDE { - return "gconf"; + virtual ProxyConfigSource GetConfigSource() OVERRIDE { + return PROXY_CONFIG_SOURCE_GCONF; } virtual bool GetString(StringSetting key, std::string* result) OVERRIDE { @@ -637,8 +637,8 @@ class SettingGetterImplGSettings return task_runner_; } - virtual const char* GetDataSource() OVERRIDE { - return "gsettings"; + virtual ProxyConfigSource GetConfigSource() OVERRIDE { + return PROXY_CONFIG_SOURCE_GSETTINGS; } virtual bool GetString(StringSetting key, std::string* result) OVERRIDE { @@ -1045,8 +1045,8 @@ class SettingGetterImplKDE : public ProxyConfigServiceLinux::SettingGetter, NOTREACHED(); } - virtual const char* GetDataSource() OVERRIDE { - return "KDE"; + virtual ProxyConfigSource GetConfigSource() OVERRIDE { + return PROXY_CONFIG_SOURCE_KDE; } virtual bool GetString(StringSetting key, std::string* result) OVERRIDE { @@ -1634,8 +1634,9 @@ void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig( setting_getter_->Init(glib_thread_task_runner, file_loop) && GetConfigFromSettings(&cached_config_)) { cached_config_.set_id(1); // Mark it as valid. + cached_config_.set_source(setting_getter_->GetConfigSource()); VLOG(1) << "Obtained proxy settings from " - << setting_getter_->GetDataSource(); + << ProxyConfigSourceToString(cached_config_.source()); // If gconf proxy mode is "none", meaning direct, then we take // that to be a valid config and will not check environment @@ -1675,6 +1676,7 @@ void ProxyConfigServiceLinux::Delegate::SetUpAndFetchInitialConfig( // Consulting environment variables doesn't need to be done from the // default glib main loop, but it's a tiny enough amount of work. if (GetConfigFromEnv(&cached_config_)) { + cached_config_.set_source(PROXY_CONFIG_SOURCE_ENV); cached_config_.set_id(1); // Mark it as valid. VLOG(1) << "Obtained proxy settings from environment variables"; } @@ -1708,8 +1710,12 @@ ProxyConfigService::ConfigAvailability // Simply return the last proxy configuration that glib_default_loop // notified us of. - *config = cached_config_.is_valid() ? - cached_config_ : ProxyConfig::CreateDirect(); + if (cached_config_.is_valid()) { + *config = cached_config_; + } else { + *config = ProxyConfig::CreateDirect(); + config->set_source(PROXY_CONFIG_SOURCE_SYSTEM_FAILED); + } // We return CONFIG_VALID to indicate that *config was filled in. It is always // going to be available since we initialized eagerly on the UI thread. diff --git a/net/proxy/proxy_config_service_linux.h b/net/proxy/proxy_config_service_linux.h index ed8cef1..290fe3c 100644 --- a/net/proxy/proxy_config_service_linux.h +++ b/net/proxy/proxy_config_service_linux.h @@ -68,9 +68,8 @@ class NET_EXPORT_PRIVATE ProxyConfigServiceLinux : public ProxyConfigService { // Returns NULL if it does not matter. virtual base::SingleThreadTaskRunner* GetNotificationTaskRunner() = 0; - // Returns the data source's name (e.g. "gconf", "gsettings", "KDE", - // "test"). Used only for diagnostic purposes (e.g. VLOG(1) etc.). - virtual const char* GetDataSource() = 0; + // Returns the source of proxy settings. + virtual ProxyConfigSource GetConfigSource() = 0; // These are all the values that can be fetched. We used to just use the // corresponding paths in gconf for these, but gconf is now obsolete and diff --git a/net/proxy/proxy_config_service_linux_unittest.cc b/net/proxy/proxy_config_service_linux_unittest.cc index d25dde9..2b836e0 100644 --- a/net/proxy/proxy_config_service_linux_unittest.cc +++ b/net/proxy/proxy_config_service_linux_unittest.cc @@ -191,8 +191,8 @@ class MockSettingGetter return NULL; } - virtual const char* GetDataSource() OVERRIDE { - return "test"; + virtual ProxyConfigSource GetConfigSource() OVERRIDE { + return PROXY_CONFIG_SOURCE_TEST; } virtual bool GetString(StringSetting key, std::string* result) OVERRIDE { diff --git a/net/proxy/proxy_config_service_mac.cc b/net/proxy/proxy_config_service_mac.cc index 7c4b8bf..c27ede0 100644 --- a/net/proxy/proxy_config_service_mac.cc +++ b/net/proxy/proxy_config_service_mac.cc @@ -154,6 +154,9 @@ void GetCurrentProxyConfig(ProxyConfig* config) { false)) { config->proxy_rules().bypass_rules.AddRuleToBypassLocal(); } + + // Source + config->set_source(PROXY_CONFIG_SOURCE_SYSTEM); } } // namespace diff --git a/net/proxy/proxy_config_service_win.cc b/net/proxy/proxy_config_service_win.cc index d57088d..60f6f74 100644 --- a/net/proxy/proxy_config_service_win.cc +++ b/net/proxy/proxy_config_service_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -159,6 +159,7 @@ void ProxyConfigServiceWin::GetCurrentProxyConfig(ProxyConfig* config) { LOG(ERROR) << "WinHttpGetIEProxyConfigForCurrentUser failed: " << GetLastError(); *config = ProxyConfig::CreateDirect(); + config->set_source(PROXY_CONFIG_SOURCE_SYSTEM_FAILED); return; } SetFromIEConfig(config, ie_config); @@ -187,6 +188,7 @@ void ProxyConfigServiceWin::SetFromIEConfig( } if (ie_config.lpszAutoConfigUrl) config->set_pac_url(GURL(ie_config.lpszAutoConfigUrl)); + config->set_source(PROXY_CONFIG_SOURCE_SYSTEM); } } // namespace net diff --git a/net/proxy/proxy_config_service_win_unittest.cc b/net/proxy/proxy_config_service_win_unittest.cc index 1bdf8b8..911949d 100644 --- a/net/proxy/proxy_config_service_win_unittest.cc +++ b/net/proxy/proxy_config_service_win_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -196,6 +196,7 @@ TEST(ProxyConfigServiceWinTest, SetFromIEConfig) { EXPECT_EQ(tests[i].auto_detect, config.auto_detect()); EXPECT_EQ(tests[i].pac_url, config.pac_url()); EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules())); + EXPECT_EQ(PROXY_CONFIG_SOURCE_SYSTEM, config.source()); } } diff --git a/net/proxy/proxy_config_source.cc b/net/proxy/proxy_config_source.cc new file mode 100644 index 0000000..5695b9b --- /dev/null +++ b/net/proxy/proxy_config_source.cc @@ -0,0 +1,35 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/proxy/proxy_config_source.h" + +#include "base/basictypes.h" +#include "base/logging.h" + +namespace net { + +namespace { + +const char* kSourceNames[] = { + "UNKNOWN", + "SYSTEM", + "SYSTEM FAILED", + "GCONF", + "GSETTINGS", + "KDE", + "ENV", + "CUSTOM", + "TEST" +}; +COMPILE_ASSERT(ARRAYSIZE_UNSAFE(kSourceNames) == NUM_PROXY_CONFIG_SOURCES, + source_names_incorrect_size); + +} // namespace + +const char* ProxyConfigSourceToString(ProxyConfigSource source) { + DCHECK_GT(NUM_PROXY_CONFIG_SOURCES, source); + return kSourceNames[source]; +} + +} // namespace net diff --git a/net/proxy/proxy_config_source.h b/net/proxy/proxy_config_source.h new file mode 100644 index 0000000..efa583e --- /dev/null +++ b/net/proxy/proxy_config_source.h @@ -0,0 +1,38 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_PROXY_PROXY_CONFIG_SOURCE_H_ +#define NET_PROXY_PROXY_CONFIG_SOURCE_H_ +#pragma once + +namespace net { + +// Source of the configuration settings encapsulated in a ProxyConfig object. + +// The source information is used for determining how credentials are used and +// for logging. When adding new values, remember to add a string to +// kSourceNames[] in proxy_config_source.cc. +enum ProxyConfigSource { + PROXY_CONFIG_SOURCE_UNKNOWN, // The source hasn't been set. + PROXY_CONFIG_SOURCE_SYSTEM, // System settings (Win/Mac). + PROXY_CONFIG_SOURCE_SYSTEM_FAILED, // Default settings after failure to + // determine system settings. + PROXY_CONFIG_SOURCE_GCONF, // GConf (Linux) + PROXY_CONFIG_SOURCE_GSETTINGS, // GSettings (Linux). + PROXY_CONFIG_SOURCE_KDE, // KDE (Linux). + PROXY_CONFIG_SOURCE_ENV, // Environment variables. + PROXY_CONFIG_SOURCE_CUSTOM, // Custom settings local to the + // application (command line, + // extensions, application + // specific preferences, etc.) + PROXY_CONFIG_SOURCE_TEST, // Test settings. + NUM_PROXY_CONFIG_SOURCES +}; + +// Returns a textual representation of the source. +const char* ProxyConfigSourceToString(ProxyConfigSource source); + +} // namespace net + +#endif // NET_PROXY_PROXY_CONFIG_SOURCE_H_ diff --git a/net/proxy/proxy_config_unittest.cc b/net/proxy/proxy_config_unittest.cc index 1947ce4..47ea689 100644 --- a/net/proxy/proxy_config_unittest.cc +++ b/net/proxy/proxy_config_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -251,6 +251,33 @@ TEST(ProxyConfigTest, ParseProxyRules) { } } +TEST(ProxyConfigTest, ProxyRulesSetBypassFlag) { + // Test whether the did_bypass_proxy() flag is set in proxy info correctly. + ProxyConfig::ProxyRules rules; + ProxyInfo result; + + rules.ParseFromString("http=httpproxy:80"); + rules.bypass_rules.AddRuleFromString(".com"); + + rules.Apply(GURL("http://example.com"), &result); + EXPECT_TRUE(result.is_direct_only()); + EXPECT_TRUE(result.did_bypass_proxy()); + + rules.Apply(GURL("http://example.org"), &result); + EXPECT_FALSE(result.is_direct()); + EXPECT_FALSE(result.did_bypass_proxy()); + + // Try with reversed bypass rules. + rules.reverse_bypass = true; + + rules.Apply(GURL("http://example.org"), &result); + EXPECT_TRUE(result.is_direct_only()); + EXPECT_TRUE(result.did_bypass_proxy()); + + rules.Apply(GURL("http://example.com"), &result); + EXPECT_FALSE(result.is_direct()); + EXPECT_FALSE(result.did_bypass_proxy()); +} + } // namespace } // namespace net - diff --git a/net/proxy/proxy_info.cc b/net/proxy/proxy_info.cc index b7d40a0..26018cf 100644 --- a/net/proxy/proxy_info.cc +++ b/net/proxy/proxy_info.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,7 +8,11 @@ namespace net { -ProxyInfo::ProxyInfo() : config_id_(ProxyConfig::kInvalidConfigID) { +ProxyInfo::ProxyInfo() + : config_id_(ProxyConfig::kInvalidConfigID), + config_source_(PROXY_CONFIG_SOURCE_UNKNOWN), + did_bypass_proxy_(false), + did_use_pac_script_(false) { } ProxyInfo::~ProxyInfo() { @@ -17,21 +21,30 @@ ProxyInfo::~ProxyInfo() { void ProxyInfo::Use(const ProxyInfo& other) { proxy_list_ = other.proxy_list_; proxy_retry_info_ = other.proxy_retry_info_; + config_id_ = other.config_id_; + config_source_ = other.config_source_; + did_bypass_proxy_ = other.did_bypass_proxy_; + did_use_pac_script_ = other.did_use_pac_script_; } void ProxyInfo::UseDirect() { + Reset(); proxy_list_.SetSingleProxyServer(ProxyServer::Direct()); - proxy_retry_info_.clear(); +} + +void ProxyInfo::UseDirectWithBypassedProxy() { + UseDirect(); + did_bypass_proxy_ = true; } void ProxyInfo::UseNamedProxy(const std::string& proxy_uri_list) { + Reset(); proxy_list_.Set(proxy_uri_list); - proxy_retry_info_.clear(); } void ProxyInfo::UseProxyServer(const ProxyServer& proxy_server) { + Reset(); proxy_list_.SetSingleProxyServer(proxy_server); - proxy_retry_info_.clear(); } std::string ProxyInfo::ToPacString() const { @@ -51,4 +64,13 @@ void ProxyInfo::RemoveProxiesWithoutScheme(int scheme_bit_field) { proxy_list_.RemoveProxiesWithoutScheme(scheme_bit_field); } +void ProxyInfo::Reset() { + proxy_list_.Clear(); + proxy_retry_info_.clear(); + config_id_ = ProxyConfig::kInvalidConfigID; + config_source_ = PROXY_CONFIG_SOURCE_UNKNOWN; + did_bypass_proxy_ = false; + did_use_pac_script_ = false; +} + } // namespace net diff --git a/net/proxy/proxy_info.h b/net/proxy/proxy_info.h index 2ff8136..1c4c0a9 100644 --- a/net/proxy/proxy_info.h +++ b/net/proxy/proxy_info.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -30,6 +30,10 @@ class NET_EXPORT ProxyInfo { // Uses a direct connection. void UseDirect(); + // Uses a direct connection. did_bypass_proxy() will return true to indicate + // that the direct connection is the result of configured proxy bypass rules. + void UseDirectWithBypassedProxy(); + // Uses a specific proxy server, of the form: // proxy-uri = [<scheme> "://"] <hostname> [":" <port>] // This may optionally be a semi-colon delimited list of <proxy-uri>. @@ -52,6 +56,10 @@ class NET_EXPORT ProxyInfo { return proxy_list_.Get().is_direct(); } + bool is_direct_only() const { + return is_direct() && proxy_list_.size() == 1 && proxy_retry_info_.empty(); + } + // Returns true if the first valid proxy server is an https proxy. bool is_https() const { if (is_empty()) @@ -78,10 +86,24 @@ class NET_EXPORT ProxyInfo { return proxy_list_.IsEmpty(); } + // Returns true if this proxy resolution is using a direct connection due to + // proxy bypass rules. + bool did_bypass_proxy() const { + return did_bypass_proxy_; + } + + // Returns true if the proxy resolution was done using a PAC script. + bool did_use_pac_script() const { + return did_use_pac_script_; + } + // Returns the first valid proxy server. is_empty() must be false to be able // to call this function. const ProxyServer& proxy_server() const { return proxy_list_.Get(); } + // Returns the source for configuration settings used for proxy resolution. + ProxyConfigSource config_source() const { return config_source_; } + // See description in ProxyList::ToPacString(). std::string ToPacString() const; @@ -103,6 +125,9 @@ class NET_EXPORT ProxyInfo { return proxy_retry_info_; } + // Reset proxy and config settings. + void Reset(); + // The ordered list of proxy servers (including DIRECT attempts) remaining to // try. If proxy_list_ is empty, then there is nothing left to fall back to. ProxyList proxy_list_; @@ -112,6 +137,15 @@ class NET_EXPORT ProxyInfo { // This value identifies the proxy config used to initialize this object. ProxyConfig::ID config_id_; + + // The source of the proxy settings used, + ProxyConfigSource config_source_; + + // Whether the proxy result represent a proxy bypass. + bool did_bypass_proxy_; + + // Whether we used a PAC script for resolving the proxy. + bool did_use_pac_script_; }; } // namespace net diff --git a/net/proxy/proxy_info_unittest.cc b/net/proxy/proxy_info_unittest.cc new file mode 100644 index 0000000..377cff34 --- /dev/null +++ b/net/proxy/proxy_info_unittest.cc @@ -0,0 +1,41 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/proxy/proxy_info.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { +namespace { + +TEST(ProxyInfoTest, ProxyInfoIsDirectOnly) { + // Test the is_direct_only() predicate. + ProxyInfo info; + + // An empty ProxyInfo is not considered direct. + EXPECT_FALSE(info.is_direct_only()); + + info.UseDirect(); + EXPECT_TRUE(info.is_direct_only()); + + info.UsePacString("DIRECT"); + EXPECT_TRUE(info.is_direct_only()); + + info.UsePacString("PROXY myproxy:80"); + EXPECT_FALSE(info.is_direct_only()); + + info.UsePacString("DIRECT; PROXY myproxy:80"); + EXPECT_TRUE(info.is_direct()); + EXPECT_FALSE(info.is_direct_only()); + + info.UsePacString("PROXY myproxy:80; DIRECT"); + EXPECT_FALSE(info.is_direct()); + EXPECT_FALSE(info.is_direct_only()); + // After falling back to direct, we shouldn't consider it DIRECT only. + EXPECT_TRUE(info.Fallback(BoundNetLog())); + EXPECT_TRUE(info.is_direct()); + EXPECT_FALSE(info.is_direct_only()); +} + +} // namespace +} // namespace net diff --git a/net/proxy/proxy_list.cc b/net/proxy/proxy_list.cc index cdc8cc2..d4867e0 100644 --- a/net/proxy/proxy_list.cc +++ b/net/proxy/proxy_list.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -77,10 +77,18 @@ void ProxyList::RemoveProxiesWithoutScheme(int scheme_bit_field) { } } +void ProxyList::Clear() { + proxies_.clear(); +} + bool ProxyList::IsEmpty() const { return proxies_.empty(); } +size_t ProxyList::size() const { + return proxies_.size(); +} + const ProxyServer& ProxyList::Get() const { DCHECK(!proxies_.empty()); return proxies_[0]; diff --git a/net/proxy/proxy_list.h b/net/proxy/proxy_list.h index a377553..f090833 100644 --- a/net/proxy/proxy_list.h +++ b/net/proxy/proxy_list.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -40,9 +40,15 @@ class NET_EXPORT_PRIVATE ProxyList { // |scheme_bit_field| is a bunch of ProxyServer::Scheme bitwise ORed together. void RemoveProxiesWithoutScheme(int scheme_bit_field); + // Clear the proxy list. + void Clear(); + // Returns true if there is nothing left in the ProxyList. bool IsEmpty() const; + // Returns the number of proxy servers in this list. + size_t size() const; + // Returns the first proxy server in the list. It is only valid to call // this if !IsEmpty(). const ProxyServer& Get() const; diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc index 35ccfbd..b210bd8 100644 --- a/net/proxy/proxy_service.cc +++ b/net/proxy/proxy_service.cc @@ -167,6 +167,7 @@ class ProxyConfigServiceDirect : public ProxyConfigService { virtual ConfigAvailability GetLatestProxyConfig(ProxyConfig* config) OVERRIDE { *config = ProxyConfig::CreateDirect(); + config->set_source(PROXY_CONFIG_SOURCE_UNKNOWN); return CONFIG_VALID; } }; @@ -802,6 +803,7 @@ class ProxyService::PacRequest url_(url), resolve_job_(NULL), config_id_(ProxyConfig::kInvalidConfigID), + config_source_(PROXY_CONFIG_SOURCE_UNKNOWN), net_log_(net_log) { DCHECK(!user_callback.is_null()); } @@ -814,6 +816,7 @@ class ProxyService::PacRequest DCHECK(service_->config_.is_valid()); config_id_ = service_->config_.id(); + config_source_ = service_->config_.source(); return resolver()->GetProxyForURL( url_, results_, @@ -869,10 +872,13 @@ class ProxyService::PacRequest // Make a note in the results which configuration was in use at the // time of the resolve. results_->config_id_ = config_id_; + results_->config_source_ = config_source_; + results_->did_use_pac_script_ = true; // Reset the state associated with in-progress-resolve. resolve_job_ = NULL; config_id_ = ProxyConfig::kInvalidConfigID; + config_source_ = PROXY_CONFIG_SOURCE_UNKNOWN; return service_->DidFinishResolvingProxy(results_, result_code, net_log_); } @@ -914,6 +920,7 @@ class ProxyService::PacRequest GURL url_; ProxyResolver::RequestHandle resolve_job_; ProxyConfig::ID config_id_; // The config id when the resolve was started. + ProxyConfigSource config_source_; // The source of proxy settings. BoundNetLog net_log_; }; @@ -1116,6 +1123,7 @@ int ProxyService::TryToCompleteSynchronously(const GURL& url, // Use the manual proxy settings. config_.proxy_rules().Apply(url, result); + result->config_source_ = config_.source(); result->config_id_ = config_.id(); return OK; } @@ -1237,6 +1245,7 @@ void ProxyService::OnInitProxyResolverComplete(int result) { // TODO(eroman): Make this ID unique in the case where configuration changed // due to ProxyScriptDeciderPoller. config_.set_id(fetched_config_.id()); + config_.set_source(fetched_config_.source()); // Resume any requests which we had to defer until the PAC script was // downloaded. diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc index abd6d6a..cec0035 100644 --- a/net/proxy/proxy_service_unittest.cc +++ b/net/proxy/proxy_service_unittest.cc @@ -216,6 +216,7 @@ TEST_F(ProxyServiceTest, PAC) { EXPECT_EQ(OK, callback.WaitForResult()); EXPECT_FALSE(info.is_direct()); EXPECT_EQ("foopy:80", info.proxy_server().ToURI()); + EXPECT_TRUE(info.did_use_pac_script()); // Check the NetLog was filled correctly. CapturingNetLog::CapturedEntryList entries; @@ -292,6 +293,7 @@ TEST_F(ProxyServiceTest, PAC_FailoverWithoutDirect) { EXPECT_EQ(OK, callback1.WaitForResult()); EXPECT_FALSE(info.is_direct()); EXPECT_EQ("foopy:8080", info.proxy_server().ToURI()); + EXPECT_TRUE(info.did_use_pac_script()); // Now, imagine that connecting to foopy:8080 fails: there is nothing // left to fallback to, since our proxy list was NOT terminated by @@ -382,6 +384,36 @@ TEST_F(ProxyServiceTest, PAC_FailoverAfterDirect) { EXPECT_TRUE(info.is_empty()); } +TEST_F(ProxyServiceTest, PAC_ConfigSourcePropagates) { + // Test whether the ProxyConfigSource set by the ProxyConfigService is applied + // to ProxyInfo after the proxy is resolved via a PAC script. + ProxyConfig config = + ProxyConfig::CreateFromCustomPacURL(GURL("http://foopy/proxy.pac")); + config.set_source(PROXY_CONFIG_SOURCE_TEST); + + MockProxyConfigService* config_service = new MockProxyConfigService(config); + MockAsyncProxyResolver* resolver = new MockAsyncProxyResolver; + ProxyService service(config_service, resolver, NULL); + + // Resolve something. + GURL url("http://www.google.com/"); + ProxyInfo info; + TestCompletionCallback callback; + int rv = service.ResolveProxy( + url, &info, callback.callback(), NULL, BoundNetLog()); + ASSERT_EQ(ERR_IO_PENDING, rv); + resolver->pending_set_pac_script_request()->CompleteNow(OK); + ASSERT_EQ(1u, resolver->pending_requests().size()); + + // Set the result in proxy resolver. + resolver->pending_requests()[0]->results()->UseNamedProxy("foopy"); + resolver->pending_requests()[0]->CompleteNow(OK); + + EXPECT_EQ(OK, callback.WaitForResult()); + EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source()); + EXPECT_TRUE(info.did_use_pac_script()); +} + TEST_F(ProxyServiceTest, ProxyResolverFails) { // Test what happens when the ProxyResolver fails. The download and setting // of the PAC script have already succeeded, so this corresponds with a @@ -1120,6 +1152,56 @@ TEST_F(ProxyServiceTest, PerProtocolProxyTests) { } } +TEST_F(ProxyServiceTest, ProxyConfigSourcePropagates) { + // Test that the proxy config source is set correctly when resolving proxies + // using manual proxy rules. Namely, the config source should only be set if + // any of the rules were applied. + { + ProxyConfig config; + config.set_source(PROXY_CONFIG_SOURCE_TEST); + config.proxy_rules().ParseFromString("https=foopy2:8080"); + ProxyService service( + new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL); + GURL test_url("http://www.google.com"); + ProxyInfo info; + TestCompletionCallback callback; + int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL, + BoundNetLog()); + ASSERT_EQ(OK, rv); + // Should be SOURCE_TEST, even if there are no HTTP proxies configured. + EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source()); + } + { + ProxyConfig config; + config.set_source(PROXY_CONFIG_SOURCE_TEST); + config.proxy_rules().ParseFromString("https=foopy2:8080"); + ProxyService service( + new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL); + GURL test_url("https://www.google.com"); + ProxyInfo info; + TestCompletionCallback callback; + int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL, + BoundNetLog()); + ASSERT_EQ(OK, rv); + // Used the HTTPS proxy. So source should be TEST. + EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source()); + } + { + ProxyConfig config; + config.set_source(PROXY_CONFIG_SOURCE_TEST); + ProxyService service( + new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL); + GURL test_url("http://www.google.com"); + ProxyInfo info; + TestCompletionCallback callback; + int rv = service.ResolveProxy(test_url, &info, callback.callback(), NULL, + BoundNetLog()); + ASSERT_EQ(OK, rv); + // ProxyConfig is empty. Source should still be TEST. + EXPECT_EQ(PROXY_CONFIG_SOURCE_TEST, info.config_source()); + } +} + // If only HTTP and a SOCKS proxy are specified, check if ftp/https queries // fall back to the SOCKS proxy. TEST_F(ProxyServiceTest, DefaultProxyFallbackToSOCKS) { |