summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorasanka@chromium.org <asanka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-12 23:32:51 +0000
committerasanka@chromium.org <asanka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-12 23:32:51 +0000
commitdb8ff912c0325d5bbff4b989de637ee371d09406 (patch)
treed76d169b88f42e8a53e193afddc851012bb5d122 /net
parent72cf3215b9359e1f7c454e9d3f281edef5bf3fc7 (diff)
downloadchromium_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.gyp3
-rw-r--r--net/proxy/proxy_config.cc18
-rw-r--r--net/proxy/proxy_config.h19
-rw-r--r--net/proxy/proxy_config_service_linux.cc24
-rw-r--r--net/proxy/proxy_config_service_linux.h5
-rw-r--r--net/proxy/proxy_config_service_linux_unittest.cc4
-rw-r--r--net/proxy/proxy_config_service_mac.cc3
-rw-r--r--net/proxy/proxy_config_service_win.cc4
-rw-r--r--net/proxy/proxy_config_service_win_unittest.cc3
-rw-r--r--net/proxy/proxy_config_source.cc35
-rw-r--r--net/proxy/proxy_config_source.h38
-rw-r--r--net/proxy/proxy_config_unittest.cc31
-rw-r--r--net/proxy/proxy_info.cc32
-rw-r--r--net/proxy/proxy_info.h36
-rw-r--r--net/proxy/proxy_info_unittest.cc41
-rw-r--r--net/proxy/proxy_list.cc10
-rw-r--r--net/proxy/proxy_list.h8
-rw-r--r--net/proxy/proxy_service.cc9
-rw-r--r--net/proxy/proxy_service_unittest.cc82
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) {