summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/automation/automation_provider.cc2
-rw-r--r--chrome/browser/net/chrome_url_request_context.cc2
-rw-r--r--chrome/browser/net/chrome_url_request_context_unittest.cc18
-rw-r--r--chrome/common/chrome_switches.cc3
-rwxr-xr-xnet/net.gyp3
-rw-r--r--net/proxy/proxy_bypass_rules.cc228
-rw-r--r--net/proxy/proxy_bypass_rules.h130
-rw-r--r--net/proxy/proxy_bypass_rules_unittest.cc286
-rw-r--r--net/proxy/proxy_config.cc85
-rw-r--r--net/proxy/proxy_config.h16
-rw-r--r--net/proxy/proxy_config_service_common_unittest.cc9
-rw-r--r--net/proxy/proxy_config_service_common_unittest.h6
-rw-r--r--net/proxy/proxy_config_service_linux.cc14
-rw-r--r--net/proxy/proxy_config_service_linux_unittest.cc55
-rw-r--r--net/proxy/proxy_config_service_mac.cc9
-rw-r--r--net/proxy/proxy_config_service_win.cc5
-rw-r--r--net/proxy/proxy_config_service_win_unittest.cc17
-rw-r--r--net/proxy/proxy_config_unittest.cc74
-rw-r--r--net/proxy/proxy_service.cc86
-rw-r--r--net/proxy/proxy_service.h10
-rw-r--r--net/proxy/proxy_service_unittest.cc256
21 files changed, 729 insertions, 585 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 4fc54ea..52e424b 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -1331,7 +1331,7 @@ class SetProxyConfigTask : public Task {
}
std::string proxy_bypass_list;
if (dict.GetString(automation::kJSONProxyBypassList, &proxy_bypass_list)) {
- pc->ParseNoProxyList(proxy_bypass_list);
+ pc->bypass_rules.ParseFromString(proxy_bypass_list);
}
std::string proxy_server;
if (dict.GetString(automation::kJSONProxyServer, &proxy_server)) {
diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc
index 79a94cd..bb8cba9 100644
--- a/chrome/browser/net/chrome_url_request_context.cc
+++ b/chrome/browser/net/chrome_url_request_context.cc
@@ -948,7 +948,7 @@ net::ProxyConfig* CreateProxyConfig(const CommandLine& command_line) {
}
if (command_line.HasSwitch(switches::kProxyBypassList)) {
- proxy_config->ParseNoProxyList(
+ proxy_config->bypass_rules.ParseFromString(
WideToASCII(command_line.GetSwitchValue(
switches::kProxyBypassList)));
}
diff --git a/chrome/browser/net/chrome_url_request_context_unittest.cc b/chrome/browser/net/chrome_url_request_context_unittest.cc
index e1ac43e..e7d679c 100644
--- a/chrome/browser/net/chrome_url_request_context_unittest.cc
+++ b/chrome/browser/net/chrome_url_request_context_unittest.cc
@@ -59,7 +59,6 @@ TEST(ChromeUrlRequestContextTest, CreateProxyConfigTest) {
GURL pac_url;
net::ProxyConfig::ProxyRules proxy_rules;
const char* proxy_bypass_list; // newline separated
- bool bypass_local_names;
} tests[] = {
{
TEST_DESC("Empty command line"),
@@ -71,7 +70,6 @@ TEST(ChromeUrlRequestContextTest, CreateProxyConfigTest) {
GURL(), // pac_url
net::ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false // bypass_local_names
},
{
TEST_DESC("No proxy"),
@@ -83,7 +81,6 @@ TEST(ChromeUrlRequestContextTest, CreateProxyConfigTest) {
GURL(), // pac_url
net::ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false // bypass_local_names
},
{
TEST_DESC("No proxy with extra parameters."),
@@ -95,7 +92,6 @@ TEST(ChromeUrlRequestContextTest, CreateProxyConfigTest) {
GURL(), // pac_url
net::ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false // bypass_local_names
},
{
TEST_DESC("Single proxy."),
@@ -107,7 +103,6 @@ TEST(ChromeUrlRequestContextTest, CreateProxyConfigTest) {
GURL(), // pac_url
net::MakeSingleProxyRules("http://proxy:8888"), // proxy_rules
"", // proxy_bypass_list
- false // bypass_local_names
},
{
TEST_DESC("Per scheme proxy."),
@@ -121,7 +116,6 @@ TEST(ChromeUrlRequestContextTest, CreateProxyConfigTest) {
"",
"ftpproxy:8889"), // proxy_rules
"", // proxy_bypass_list
- false // bypass_local_names
},
{
TEST_DESC("Per scheme proxy with bypass URLs."),
@@ -134,8 +128,8 @@ TEST(ChromeUrlRequestContextTest, CreateProxyConfigTest) {
net::MakeProxyPerSchemeRules("httpproxy:8888",
"",
"ftpproxy:8889"), // proxy_rules
- "*.google.com\n*foo.com:99\n1.2.3.4:22\n127.0.0.1/8\n",
- false // bypass_local_names
+ // TODO(eroman): 127.0.0.1/8 is unsupported, so it was dropped
+ "*.google.com\nfoo.com:99\n1.2.3.4:22\n",
},
{
TEST_DESC("Pac URL with proxy bypass URLs"),
@@ -146,8 +140,8 @@ TEST(ChromeUrlRequestContextTest, CreateProxyConfigTest) {
false, // auto_detect
GURL("http://wpad/wpad.dat"), // pac_url
net::ProxyConfig::ProxyRules(), // proxy_rules
- "*.google.com\n*foo.com:99\n1.2.3.4:22\n127.0.0.1/8\n",
- false // bypass_local_names
+ // TODO(eroman): 127.0.0.1/8 is unsupported, so it was dropped
+ "*.google.com\nfoo.com:99\n1.2.3.4:22\n",
},
{
TEST_DESC("Autodetect"),
@@ -159,7 +153,6 @@ TEST(ChromeUrlRequestContextTest, CreateProxyConfigTest) {
GURL(), // pac_url
net::ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false // bypass_local_names
}
};
@@ -176,8 +169,7 @@ TEST(ChromeUrlRequestContextTest, CreateProxyConfigTest) {
EXPECT_EQ(tests[i].auto_detect, config->auto_detect);
EXPECT_EQ(tests[i].pac_url, config->pac_url);
EXPECT_EQ(tests[i].proxy_bypass_list,
- net::FlattenProxyBypass(config->proxy_bypass));
- EXPECT_EQ(tests[i].bypass_local_names, config->proxy_bypass_local_names);
+ net::FlattenProxyBypass(config->bypass_rules));
EXPECT_EQ(tests[i].proxy_rules, config->proxy_rules);
}
}
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 2099d95..9f18551 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -537,7 +537,8 @@ const char kProxyAutoDetect[] = "proxy-auto-detect";
// Specify a list of hosts for whom we bypass proxy settings and use direct
// connections. Ignored if --proxy-auto-detect or --no-proxy-server are
// also specified.
-// TODO(robertshield): Specify host format.
+// This is a comma separated list of bypass rules. See:
+// "net/proxy/proxy_bypass_rules.h" for the format of these rules.
const char kProxyBypassList[] = "proxy-bypass-list";
// Use the pac script at the given URL
diff --git a/net/net.gyp b/net/net.gyp
index 4509616..cf0a9c3 100755
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -372,6 +372,8 @@
'ocsp/nss_ocsp.h',
'proxy/init_proxy_resolver.cc',
'proxy/init_proxy_resolver.h',
+ 'proxy/proxy_bypass_rules.cc',
+ 'proxy/proxy_bypass_rules.h',
'proxy/proxy_config.cc',
'proxy/proxy_config.h',
'proxy/proxy_config_service.h',
@@ -659,6 +661,7 @@
'http/http_vary_data_unittest.cc',
'proxy/init_proxy_resolver_unittest.cc',
'proxy/mock_proxy_resolver.h',
+ 'proxy/proxy_bypass_rules_unittest.cc',
'proxy/proxy_config_service_linux_unittest.cc',
'proxy/proxy_config_service_win_unittest.cc',
'proxy/proxy_config_unittest.cc',
diff --git a/net/proxy/proxy_bypass_rules.cc b/net/proxy/proxy_bypass_rules.cc
new file mode 100644
index 0000000..9cf9d94
--- /dev/null
+++ b/net/proxy/proxy_bypass_rules.cc
@@ -0,0 +1,228 @@
+// Copyright (c) 2010 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_bypass_rules.h"
+
+#include "base/logging.h"
+#include "base/string_tokenizer.h"
+#include "base/string_util.h"
+#include "net/base/net_util.h"
+
+namespace net {
+
+namespace {
+
+class HostnamePatternRule : public ProxyBypassRules::Rule {
+ public:
+ HostnamePatternRule(const std::string& optional_scheme,
+ const std::string& hostname_pattern,
+ int optional_port)
+ : optional_scheme_(StringToLowerASCII(optional_scheme)),
+ hostname_pattern_(StringToLowerASCII(hostname_pattern)),
+ optional_port_(optional_port) {
+ }
+
+ virtual bool Matches(const GURL& url) const {
+ if (optional_port_ != -1 && url.EffectiveIntPort() != optional_port_)
+ return false; // Didn't match port expectation.
+
+ if (!optional_scheme_.empty() && url.scheme() != optional_scheme_)
+ return false; // Didn't match scheme expectation.
+
+ // Note it is necessary to lower-case the host, since GURL uses capital
+ // letters for percent-escaped characters.
+ return MatchPatternASCII(StringToLowerASCII(url.host()),
+ hostname_pattern_);
+ }
+
+ virtual std::string ToString() const {
+ std::string str;
+ if (!optional_scheme_.empty())
+ StringAppendF(&str, "%s://", optional_scheme_.c_str());
+ str += hostname_pattern_;
+ if (optional_port_ != -1)
+ StringAppendF(&str, ":%d", optional_port_);
+ return str;
+ }
+
+ private:
+ const std::string optional_scheme_;
+ const std::string hostname_pattern_;
+ const int optional_port_;
+};
+
+class BypassLocalRule : public ProxyBypassRules::Rule {
+ public:
+ virtual bool Matches(const GURL& url) const {
+ const std::string& host = url.host();
+ if (host == "127.0.0.1" || host == "[::1]")
+ return true;
+ return host.find('.') == std::string::npos;
+ }
+
+ virtual std::string ToString() const {
+ return "<local>";
+ }
+};
+
+// Returns true if the given string represents an IP address.
+bool IsIPAddress(const std::string& domain) {
+ // From GURL::HostIsIPAddress()
+ url_canon::RawCanonOutputT<char, 128> ignored_output;
+ url_canon::CanonHostInfo host_info;
+ url_parse::Component domain_comp(0, domain.size());
+ url_canon::CanonicalizeIPAddress(domain.c_str(), domain_comp,
+ &ignored_output, &host_info);
+ return host_info.IsIPAddress();
+}
+
+} // namespace
+
+ProxyBypassRules::~ProxyBypassRules() {
+}
+
+bool ProxyBypassRules::Matches(const GURL& url) const {
+ for (RuleList::const_iterator it = rules_.begin(); it != rules_.end(); ++it) {
+ if ((*it)->Matches(url))
+ return true;
+ }
+ return false;
+}
+
+bool ProxyBypassRules::Equals(const ProxyBypassRules& other) const {
+ if (rules_.size() != other.rules().size())
+ return false;
+
+ for (size_t i = 0; i < rules_.size(); ++i) {
+ if (!rules_[i]->Equals(*other.rules()[i]))
+ return false;
+ }
+ return true;
+}
+
+void ProxyBypassRules::ParseFromString(const std::string& raw) {
+ ParseFromStringInternal(raw, false);
+}
+
+void ProxyBypassRules::ParseFromStringUsingSuffixMatching(
+ const std::string& raw) {
+ ParseFromStringInternal(raw, true);
+}
+
+bool ProxyBypassRules::AddRuleForHostname(const std::string& optional_scheme,
+ const std::string& hostname_pattern,
+ int optional_port) {
+ if (hostname_pattern.empty())
+ return false;
+
+ rules_.push_back(new HostnamePatternRule(optional_scheme,
+ hostname_pattern,
+ optional_port));
+ return true;
+}
+
+void ProxyBypassRules::AddRuleToBypassLocal() {
+ rules_.push_back(new BypassLocalRule);
+}
+
+bool ProxyBypassRules::AddRuleFromString(const std::string& raw) {
+ return AddRuleFromStringInternalWithLogging(raw, false);
+}
+
+void ProxyBypassRules::Clear() {
+ rules_.clear();
+}
+
+void ProxyBypassRules::ParseFromStringInternal(
+ const std::string& raw,
+ bool use_hostname_suffix_matching) {
+ Clear();
+
+ StringTokenizer entries(raw, ",;");
+ while (entries.GetNext()) {
+ AddRuleFromStringInternalWithLogging(entries.token(),
+ use_hostname_suffix_matching);
+ }
+}
+
+bool ProxyBypassRules::AddRuleFromStringInternal(
+ const std::string& raw_untrimmed,
+ bool use_hostname_suffix_matching) {
+ std::string raw;
+ TrimWhitespaceASCII(raw_untrimmed, TRIM_ALL, &raw);
+
+ // This is the special syntax used by WinInet's bypass list -- we allow it
+ // on all platforms and interpret it the same way.
+ if (LowerCaseEqualsASCII(raw, "<local>")) {
+ AddRuleToBypassLocal();
+ return true;
+ }
+
+ // Extract any scheme-restriction.
+ std::string::size_type scheme_pos = raw.find("://");
+ std::string scheme;
+ if (scheme_pos != std::string::npos) {
+ scheme = raw.substr(0, scheme_pos);
+ raw = raw.substr(scheme_pos + 3);
+ if (scheme.empty())
+ return false;
+ }
+
+ if (raw.empty())
+ return false;
+
+ // If there is a forward slash in the input, it is probably a CIDR style
+ // mask.
+ if (raw.find('/') != std::string::npos) {
+ LOG(WARNING) << "TODO: support CIDR-style proxy bypass entries "
+ "(http://crbug.com/9835)";
+ return false;
+ }
+
+ // Check if we have an <ip-address>[:port] input. We need to treat this
+ // separately since the IP literal may not be in a canonical form.
+ std::string host;
+ int port;
+ if (ParseHostAndPort(raw, &host, &port)) {
+ if (IsIPAddress(host)) {
+ // Canonicalize the IP literal before adding it as a string pattern.
+ GURL tmp_url("http://" + host);
+ return AddRuleForHostname(scheme, tmp_url.host(), port);
+ }
+ }
+
+ // Otherwise assume we have <hostname-pattern>[:port].
+ std::string::size_type pos_colon = raw.rfind(':');
+ host = raw;
+ port = -1;
+ if (pos_colon != std::string::npos) {
+ if (!StringToInt(raw.substr(pos_colon + 1), &port) ||
+ (port < 0 || port > 0xFFFF)) {
+ return false; // Port was invalid.
+ }
+ raw = raw.substr(0, pos_colon);
+ }
+
+ // Special-case hostnames that begin with a period.
+ // For example, we remap ".google.com" --> "*.google.com".
+ if (StartsWithASCII(raw, ".", false))
+ raw = "*" + raw;
+
+ // If suffix matching was asked for, make sure the pattern starts with a
+ // wildcard.
+ if (use_hostname_suffix_matching && !StartsWithASCII(raw, "*", false))
+ raw = "*" + raw;
+
+ return AddRuleForHostname(scheme, raw, port);
+}
+
+bool ProxyBypassRules::AddRuleFromStringInternalWithLogging(
+ const std::string& raw,
+ bool use_hostname_suffix_matching) {
+ bool ok = AddRuleFromStringInternal(raw, use_hostname_suffix_matching);
+ LOG_IF(WARNING, !ok) << "Unable to parse proxy bypass rule: " << raw;
+ return ok;
+}
+
+} // namespace net
diff --git a/net/proxy/proxy_bypass_rules.h b/net/proxy/proxy_bypass_rules.h
new file mode 100644
index 0000000..03bb4ae
--- /dev/null
+++ b/net/proxy/proxy_bypass_rules.h
@@ -0,0 +1,130 @@
+// Copyright (c) 2010 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_BYPASS_RULES_H_
+#define NET_PROXY_PROXY_BYPASS_RULES_H_
+
+#include <string>
+#include <vector>
+
+#include "base/ref_counted.h"
+#include "googleurl/src/gurl.h"
+
+namespace net {
+
+// ProxyBypassRules describes the set of URLs that should bypass the proxy
+// settings, as a list of rules. A URL is said to match the bypass rules
+// if it matches any one of these rules.
+class ProxyBypassRules {
+ public:
+ // Interface for an individual proxy bypass rule.
+ class Rule : public base::RefCounted<Rule> {
+ public:
+ Rule() {}
+ virtual ~Rule() {}
+
+ // Returns true if |url| matches the rule.
+ virtual bool Matches(const GURL& url) const = 0;
+
+ // Returns a string representation of this rule. This is used both for
+ // visualizing the rules, and also to test equality of a rules list.
+ virtual std::string ToString() const = 0;
+
+ bool Equals(const Rule& rule) const {
+ return ToString() == rule.ToString();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Rule);
+ };
+
+ typedef std::vector<scoped_refptr<Rule> > RuleList;
+
+ // Note: This class supports copy constructor and assignment.
+
+ ~ProxyBypassRules();
+
+ // Returns the current list of rules.
+ const RuleList& rules() const { return rules_; }
+
+ // Returns true if |url| matches any of the proxy bypass rules.
+ bool Matches(const GURL& url) const;
+
+ // Returns true if |*this| is equal to |other|; in other words, whether they
+ // describe the same set of rules.
+ bool Equals(const ProxyBypassRules& other) const;
+
+ // Initializes the list of rules by parsing the string |raw|. |raw| is a
+ // comma separated list of rules. See AddRuleFromString() to see the list
+ // of supported formats.
+ void ParseFromString(const std::string& raw);
+
+ // This is a variant of ParseFromString, which interprets hostname patterns
+ // as suffix tests rather than hostname tests (so "google.com" would actually
+ // match "*google.com"). This is only currently used for the linux no_proxy
+ // evironment variable. It is less flexible, since with the suffix matching
+ // format you can't match an individual host.
+ // NOTE: Use ParseFromString() unless you truly need this behavior.
+ void ParseFromStringUsingSuffixMatching(const std::string& raw);
+
+ // Adds a rule that matches a URL when all of the following are true:
+ // (a) The URL's scheme matches |optional_scheme|, if
+ // |!optional_scheme.empty()|
+ // (b) The URL's hostname matches |hostname_pattern|.
+ // (c) The URL's (effective) port number matches |optional_port| if
+ // |optional_port != -1|
+ // Returns true if the rule was successfully added.
+ bool AddRuleForHostname(const std::string& optional_scheme,
+ const std::string& hostname_pattern,
+ int optional_port);
+
+ // Adds a rule that bypasses all "local" hostnames.
+ // This matches IE's interpretation of the
+ // "Bypass proxy server for local addresses" settings checkbox. Fully
+ // qualified domain names or IP addresses are considered non-local,
+ // regardless of what they map to (except for the loopback addresses).
+ void AddRuleToBypassLocal();
+
+ // Adds a rule given by the string |raw|. The format of |raw| can be any of
+ // the following:
+ //
+ // [ <scheme> "://" ] <hostname_pattern> [ ":" <port> ]
+ // "." <hostname_suffix_pattern> [ ":" <port> ]
+ // [ <scheme> "://" ] <ip_literal> [ ":" <port> ]
+ // "<local>"
+ //
+ // Note that <ip_literal> can be either an IPv4 literal, or an IPv6 literal
+ // but if it is an IPv6 literal it MUST be surrounded by square brackets,
+ // as in "[::1]".
+ //
+ // Also note that "<local>" means to bypass all local hostnames. (See
+ // AddRuleToBypassLocal() for details).
+ //
+ // Returns true if the rule was successfully added.
+ //
+ // TODO(eroman): support IPv6 literals without brackets.
+ // TODO(eroman): support CIDR-style IP masks. (http://crbug.com/9835).
+ //
+ bool AddRuleFromString(const std::string& raw);
+
+ // Removes all the rules.
+ void Clear();
+
+ private:
+ // The following are variants of ParseFromString() and AddRuleFromString(),
+ // which additionally prefix hostname patterns with a wildcard if
+ // |use_hostname_suffix_matching| was true.
+ void ParseFromStringInternal(const std::string& raw,
+ bool use_hostname_suffix_matching);
+ bool AddRuleFromStringInternal(const std::string& raw,
+ bool use_hostname_suffix_matching);
+ bool AddRuleFromStringInternalWithLogging(const std::string& raw,
+ bool use_hostname_suffix_matching);
+
+ RuleList rules_;
+};
+
+} // namespace net
+
+#endif // NET_PROXY_PROXY_BYPASS_RULES_H_
diff --git a/net/proxy/proxy_bypass_rules_unittest.cc b/net/proxy/proxy_bypass_rules_unittest.cc
new file mode 100644
index 0000000..1bf24cb
--- /dev/null
+++ b/net/proxy/proxy_bypass_rules_unittest.cc
@@ -0,0 +1,286 @@
+// Copyright (c) 2010 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_bypass_rules.h"
+
+#include "base/string_util.h"
+#include "net/proxy/proxy_config_service_common_unittest.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+TEST(ProxyBypassRulesTest, ParseAndMatchBasicHost) {
+ ProxyBypassRules rules;
+ rules.ParseFromString("wWw.gOogle.com");
+ ASSERT_EQ(1u, rules.rules().size());
+ EXPECT_EQ("www.google.com", rules.rules()[0]->ToString());
+
+ // All of these match; port, scheme, and non-hostname components don't
+ // matter.
+ EXPECT_TRUE(rules.Matches(GURL("http://www.google.com")));
+ EXPECT_TRUE(rules.Matches(GURL("ftp://www.google.com:99")));
+ EXPECT_TRUE(rules.Matches(GURL("https://www.google.com:81")));
+
+ // Must be a strict host match to work.
+ EXPECT_FALSE(rules.Matches(GURL("http://foo.www.google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("http://xxx.google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("http://google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("http://www.google.com.baz.org")));
+}
+
+TEST(ProxyBypassRulesTest, ParseAndMatchBasicDomain) {
+ ProxyBypassRules rules;
+ rules.ParseFromString(".gOOgle.com");
+ ASSERT_EQ(1u, rules.rules().size());
+ // Note that we inferred this was an "ends with" test.
+ EXPECT_EQ("*.google.com", rules.rules()[0]->ToString());
+
+ // All of these match; port, scheme, and non-hostname components don't
+ // matter.
+ EXPECT_TRUE(rules.Matches(GURL("http://www.google.com")));
+ EXPECT_TRUE(rules.Matches(GURL("ftp://www.google.com:99")));
+ EXPECT_TRUE(rules.Matches(GURL("https://a.google.com:81")));
+ EXPECT_TRUE(rules.Matches(GURL("http://foo.google.com/x/y?q")));
+ EXPECT_TRUE(rules.Matches(GURL("http://foo:bar@baz.google.com#x")));
+
+ // Must be a strict "ends with" to work.
+ EXPECT_FALSE(rules.Matches(GURL("http://google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("http://foo.google.com.baz.org")));
+}
+
+TEST(ProxyBypassRulesTest, ParseAndMatchBasicDomainWithPort) {
+ ProxyBypassRules rules;
+ rules.ParseFromString("*.GOOGLE.com:80");
+ ASSERT_EQ(1u, rules.rules().size());
+ EXPECT_EQ("*.google.com:80", rules.rules()[0]->ToString());
+
+ // All of these match; scheme, and non-hostname components don't matter.
+ EXPECT_TRUE(rules.Matches(GURL("http://www.google.com")));
+ EXPECT_TRUE(rules.Matches(GURL("ftp://www.google.com:80")));
+ EXPECT_TRUE(rules.Matches(GURL("https://a.google.com:80?x")));
+
+ // Must be a strict "ends with" to work.
+ EXPECT_FALSE(rules.Matches(GURL("http://google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("http://foo.google.com.baz.org")));
+
+ // The ports must match.
+ EXPECT_FALSE(rules.Matches(GURL("http://www.google.com:90")));
+ EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
+}
+
+TEST(ProxyBypassRulesTest, MatchAll) {
+ ProxyBypassRules rules;
+ rules.ParseFromString("*");
+ ASSERT_EQ(1u, rules.rules().size());
+ EXPECT_EQ("*", rules.rules()[0]->ToString());
+
+ EXPECT_TRUE(rules.Matches(GURL("http://www.google.com")));
+ EXPECT_TRUE(rules.Matches(GURL("ftp://www.foobar.com:99")));
+ EXPECT_TRUE(rules.Matches(GURL("https://a.google.com:80?x")));
+}
+
+TEST(ProxyBypassRulesTest, WildcardAtStart) {
+ ProxyBypassRules rules;
+ rules.ParseFromString("*.org:443");
+ ASSERT_EQ(1u, rules.rules().size());
+ EXPECT_EQ("*.org:443", rules.rules()[0]->ToString());
+
+ EXPECT_TRUE(rules.Matches(GURL("http://www.google.org:443")));
+ EXPECT_TRUE(rules.Matches(GURL("https://www.google.org")));
+
+ EXPECT_FALSE(rules.Matches(GURL("http://www.google.org")));
+ EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("https://www.google.org.com")));
+}
+
+TEST(ProxyBypassRulesTest, IPV4Address) {
+ ProxyBypassRules rules;
+ rules.ParseFromString("192.168.1.1");
+ ASSERT_EQ(1u, rules.rules().size());
+ EXPECT_EQ("192.168.1.1", rules.rules()[0]->ToString());
+
+ EXPECT_TRUE(rules.Matches(GURL("http://192.168.1.1")));
+ EXPECT_TRUE(rules.Matches(GURL("https://192.168.1.1:90")));
+
+ EXPECT_FALSE(rules.Matches(GURL("http://www.google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("http://sup.192.168.1.1")));
+}
+
+TEST(ProxyBypassRulesTest, IPV4AddressWithPort) {
+ ProxyBypassRules rules;
+ rules.ParseFromString("192.168.1.1:33");
+ ASSERT_EQ(1u, rules.rules().size());
+ EXPECT_EQ("192.168.1.1:33", rules.rules()[0]->ToString());
+
+ EXPECT_TRUE(rules.Matches(GURL("http://192.168.1.1:33")));
+
+ EXPECT_FALSE(rules.Matches(GURL("http://www.google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("http://192.168.1.1")));
+ EXPECT_FALSE(rules.Matches(GURL("http://sup.192.168.1.1:33")));
+}
+
+TEST(ProxyBypassRulesTest, IPV6Address) {
+ ProxyBypassRules rules;
+ rules.ParseFromString("[3ffe:2a00:100:7031:0:0::1]");
+ ASSERT_EQ(1u, rules.rules().size());
+ // Note that we canonicalized the IP address.
+ EXPECT_EQ("[3ffe:2a00:100:7031::1]", rules.rules()[0]->ToString());
+
+ EXPECT_TRUE(rules.Matches(GURL("http://[3ffe:2a00:100:7031::1]")));
+ EXPECT_TRUE(rules.Matches(GURL("http://[3ffe:2a00:100:7031::1]:33")));
+
+ EXPECT_FALSE(rules.Matches(GURL("http://www.google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("http://sup.192.168.1.1:33")));
+}
+
+TEST(ProxyBypassRulesTest, IPV6AddressWithPort) {
+ ProxyBypassRules rules;
+ rules.ParseFromString("[3ffe:2a00:100:7031::1]:33");
+ ASSERT_EQ(1u, rules.rules().size());
+ EXPECT_EQ("[3ffe:2a00:100:7031::1]:33", rules.rules()[0]->ToString());
+
+ EXPECT_TRUE(rules.Matches(GURL("http://[3ffe:2a00:100:7031::1]:33")));
+
+ EXPECT_FALSE(rules.Matches(GURL("http://[3ffe:2a00:100:7031::1]")));
+ EXPECT_FALSE(rules.Matches(GURL("http://www.google.com")));
+}
+
+TEST(ProxyBypassRulesTest, HTTPOnly) {
+ ProxyBypassRules rules;
+ rules.ParseFromString("http://www.google.com");
+ ASSERT_EQ(1u, rules.rules().size());
+ EXPECT_EQ("http://www.google.com", rules.rules()[0]->ToString());
+
+ EXPECT_TRUE(rules.Matches(GURL("http://www.google.com/foo")));
+ EXPECT_TRUE(rules.Matches(GURL("http://www.google.com:99")));
+
+ EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("ftp://www.google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("http://foo.www.google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("http://www.google.com.org")));
+ EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
+}
+
+TEST(ProxyBypassRulesTest, HTTPOnlyWithWildcard) {
+ ProxyBypassRules rules;
+ rules.ParseFromString("http://*www.google.com");
+ ASSERT_EQ(1u, rules.rules().size());
+ EXPECT_EQ("http://*www.google.com", rules.rules()[0]->ToString());
+
+ EXPECT_TRUE(rules.Matches(GURL("http://www.google.com/foo")));
+ EXPECT_TRUE(rules.Matches(GURL("http://www.google.com:99")));
+ EXPECT_TRUE(rules.Matches(GURL("http://foo.www.google.com")));
+
+ EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("ftp://www.google.com")));
+ EXPECT_FALSE(rules.Matches(GURL("http://www.google.com.org")));
+ EXPECT_FALSE(rules.Matches(GURL("https://www.google.com")));
+}
+
+TEST(ProxyBypassRulesTest, UseSuffixMatching) {
+ ProxyBypassRules rules;
+ rules.ParseFromStringUsingSuffixMatching(
+ "foo1.com, .foo2.com, 192.168.1.1, "
+ "*foobar.com:80, *.foo, http://baz, <local>");
+ ASSERT_EQ(7u, rules.rules().size());
+ EXPECT_EQ("*foo1.com", rules.rules()[0]->ToString());
+ EXPECT_EQ("*.foo2.com", rules.rules()[1]->ToString());
+ EXPECT_EQ("192.168.1.1", rules.rules()[2]->ToString());
+ EXPECT_EQ("*foobar.com:80", rules.rules()[3]->ToString());
+ EXPECT_EQ("*.foo", rules.rules()[4]->ToString());
+ EXPECT_EQ("http://*baz", rules.rules()[5]->ToString());
+ EXPECT_EQ("<local>", rules.rules()[6]->ToString());
+
+ EXPECT_TRUE(rules.Matches(GURL("http://foo1.com")));
+ EXPECT_TRUE(rules.Matches(GURL("http://aaafoo1.com")));
+ EXPECT_FALSE(rules.Matches(GURL("http://aaafoo1.com.net")));
+}
+
+TEST(ProxyBypassRulesTest, MultipleRules) {
+ ProxyBypassRules rules;
+ rules.ParseFromString(".google.com , .foobar.com:30");
+ ASSERT_EQ(2u, rules.rules().size());
+
+ EXPECT_TRUE(rules.Matches(GURL("http://baz.google.com:40")));
+ EXPECT_FALSE(rules.Matches(GURL("http://google.com:40")));
+ EXPECT_TRUE(rules.Matches(GURL("http://bar.foobar.com:30")));
+ EXPECT_FALSE(rules.Matches(GURL("http://bar.foobar.com")));
+ EXPECT_FALSE(rules.Matches(GURL("http://bar.foobar.com:33")));
+}
+
+TEST(ProxyBypassRulesTest, BadInputs) {
+ ProxyBypassRules rules;
+ EXPECT_FALSE(rules.AddRuleFromString("://"));
+ EXPECT_FALSE(rules.AddRuleFromString(" "));
+ EXPECT_FALSE(rules.AddRuleFromString("http://"));
+ EXPECT_FALSE(rules.AddRuleFromString("*.foo.com:-34"));
+ EXPECT_EQ(0u, rules.rules().size());
+}
+
+TEST(ProxyBypassRulesTest, Equals) {
+ ProxyBypassRules rules1;
+ ProxyBypassRules rules2;
+
+ rules1.ParseFromString("foo1.com, .foo2.com");
+ rules2.ParseFromString("foo1.com,.FOo2.com");
+
+ EXPECT_TRUE(rules1.Equals(rules2));
+ EXPECT_TRUE(rules2.Equals(rules1));
+
+ rules1.ParseFromString(".foo2.com");
+ rules2.ParseFromString("foo1.com,.FOo2.com");
+
+ EXPECT_FALSE(rules1.Equals(rules2));
+ EXPECT_FALSE(rules2.Equals(rules1));
+}
+
+TEST(ProxyBypassRulesTest, BypassLocalNames) {
+ const struct {
+ const char* url;
+ bool expected_is_local;
+ } tests[] = {
+ // Single-component hostnames are considered local.
+ {"http://localhost/x", true},
+ {"http://www", true},
+
+ // IPv4 loopback interface.
+ {"http://127.0.0.1/x", true},
+ {"http://127.0.0.1:80/x", true},
+
+ // IPv6 loopback interface.
+ {"http://[::1]:80/x", true},
+ {"http://[0:0::1]:6233/x", true},
+ {"http://[0:0:0:0:0:0:0:1]/x", true},
+
+ // Non-local URLs.
+ {"http://foo.com/", false},
+ {"http://localhost.i/", false},
+ {"http://www.google.com/", false},
+ {"http://192.168.0.1/", false},
+
+ // Try with different protocols.
+ {"ftp://127.0.0.1/x", true},
+ {"ftp://foobar.com/x", false},
+
+ // This is a bit of a gray-area, but GURL does not strip trailing dots
+ // in host-names, so the following are considered non-local.
+ {"http://www./x", false},
+ {"http://localhost./x", false},
+ };
+
+ ProxyBypassRules rules;
+ rules.ParseFromString("<local>");
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ SCOPED_TRACE(StringPrintf(
+ "Test[%d]: %s", static_cast<int>(i), tests[i].url));
+ EXPECT_EQ(tests[i].expected_is_local, rules.Matches(GURL(tests[i].url)));
+ }
+}
+
+} // namespace
+
+} // namespace net
diff --git a/net/proxy/proxy_config.cc b/net/proxy/proxy_config.cc
index 836559e..f8fe9f6 100644
--- a/net/proxy/proxy_config.cc
+++ b/net/proxy/proxy_config.cc
@@ -11,7 +11,6 @@ namespace net {
ProxyConfig::ProxyConfig()
: auto_detect(false),
- proxy_bypass_local_names(false),
id_(INVALID_ID) {
}
@@ -21,8 +20,7 @@ bool ProxyConfig::Equals(const ProxyConfig& other) const {
return auto_detect == other.auto_detect &&
pac_url == other.pac_url &&
proxy_rules == other.proxy_rules &&
- proxy_bypass == other.proxy_bypass &&
- proxy_bypass_local_names == other.proxy_bypass_local_names;
+ bypass_rules.Equals(other.bypass_rules);
}
bool ProxyConfig::MayRequirePACResolver() const {
@@ -98,72 +96,6 @@ ProxyServer* ProxyConfig::ProxyRules::MapSchemeToProxy(
return NULL; // No mapping for this scheme.
}
-namespace {
-
-// Returns true if the given string represents an IP address.
-bool IsIPAddress(const std::string& domain) {
- // From GURL::HostIsIPAddress()
- url_canon::RawCanonOutputT<char, 128> ignored_output;
- url_canon::CanonHostInfo host_info;
- url_parse::Component domain_comp(0, domain.size());
- url_canon::CanonicalizeIPAddress(domain.c_str(), domain_comp,
- &ignored_output, &host_info);
- return host_info.IsIPAddress();
-}
-
-} // namespace
-
-void ProxyConfig::ParseNoProxyList(const std::string& no_proxy) {
- proxy_bypass.clear();
- if (no_proxy.empty())
- return;
- // Traditional semantics:
- // A single "*" is specifically allowed and unproxies anything.
- // "*" wildcards other than a single "*" entry are not universally
- // supported. We will support them, as we get * wildcards for free
- // (see MatchPatternASCII() called from
- // ProxyService::ShouldBypassProxyForURL()).
- // no_proxy is a comma-separated list of <trailing_domain>[:<port>].
- // If no port is specified then any port matches.
- // The historical definition has trailing_domain match using a simple
- // string "endswith" test, so that the match need not correspond to a
- // "." boundary. For example: "google.com" matches "igoogle.com" too.
- // Seems like that could be confusing, but we'll obey tradition.
- // IP CIDR patterns are supposed to be supported too. We intend
- // to do this in proxy_service.cc, but it's currently a TODO.
- // See: http://crbug.com/9835.
- StringTokenizer no_proxy_list(no_proxy, ",");
- while (no_proxy_list.GetNext()) {
- std::string bypass_entry = no_proxy_list.token();
- TrimWhitespaceASCII(bypass_entry, TRIM_ALL, &bypass_entry);
- if (bypass_entry.empty())
- continue;
- if (bypass_entry.at(0) != '*') {
- // Insert a wildcard * to obtain an endsWith match, unless the
- // entry looks like it might be an IP or CIDR.
- // First look for either a :<port> or CIDR mask length suffix.
- std::string::const_iterator begin = bypass_entry.begin();
- std::string::const_iterator scan = bypass_entry.end() - 1;
- while (scan > begin && IsAsciiDigit(*scan))
- --scan;
- std::string potential_ip;
- if (*scan == '/' || *scan == ':')
- potential_ip = std::string(begin, scan - 1);
- else
- potential_ip = bypass_entry;
- if (!IsIPAddress(potential_ip)) {
- // Do insert a wildcard.
- bypass_entry.insert(0, "*");
- }
- // TODO(sdoyon): When CIDR matching is implemented in
- // proxy_service.cc, consider making proxy_bypass more
- // sophisticated to avoid parsing out the string on every
- // request.
- }
- proxy_bypass.push_back(bypass_entry);
- }
-}
-
} // namespace net
namespace {
@@ -247,18 +179,15 @@ std::ostream& operator<<(std::ostream& out, const net::ProxyConfig& config) {
}
out << " Bypass list: ";
- if (config.proxy_bypass.empty()) {
- out << "[None]\n";
+ if (config.bypass_rules.rules().empty()) {
+ out << "[None]";
} else {
- out << "\n";
- std::vector<std::string>::const_iterator it;
- for (it = config.proxy_bypass.begin();
- it != config.proxy_bypass.end(); ++it) {
- out << " " << *it << "\n";
+ net::ProxyBypassRules::RuleList::const_iterator it;
+ for (it = config.bypass_rules.rules().begin();
+ it != config.bypass_rules.rules().end(); ++it) {
+ out << "\n " << (*it)->ToString();
}
}
- out << " Bypass local names: "
- << BoolToYesNoString(config.proxy_bypass_local_names);
return out;
}
diff --git a/net/proxy/proxy_config.h b/net/proxy/proxy_config.h
index c48f74b..bd62465 100644
--- a/net/proxy/proxy_config.h
+++ b/net/proxy/proxy_config.h
@@ -10,6 +10,7 @@
#include <vector>
#include "googleurl/src/gurl.h"
+#include "net/proxy/proxy_bypass_rules.h"
#include "net/proxy/proxy_server.h"
namespace net {
@@ -104,20 +105,7 @@ class ProxyConfig {
};
ProxyRules proxy_rules;
-
- // Parses entries from a comma-separated list of hosts for which proxy
- // configurations should be bypassed. Clears proxy_bypass and sets it to the
- // resulting list.
- void ParseNoProxyList(const std::string& no_proxy);
-
- // Indicates a list of hosts that should bypass any proxy configuration. For
- // these hosts, a direct connection should always be used.
- // The form <host>:<port> is also supported, meaning that only
- // connections on the specified port should be direct.
- std::vector<std::string> proxy_bypass;
-
- // Indicates whether local names (no dots) bypass proxies.
- bool proxy_bypass_local_names;
+ ProxyBypassRules bypass_rules;
// Returns true if the given config is equivalent to this config.
bool Equals(const ProxyConfig& other) const;
diff --git a/net/proxy/proxy_config_service_common_unittest.cc b/net/proxy/proxy_config_service_common_unittest.cc
index 1a61468..74baa49 100644
--- a/net/proxy/proxy_config_service_common_unittest.cc
+++ b/net/proxy/proxy_config_service_common_unittest.cc
@@ -54,11 +54,12 @@ ProxyConfig::ProxyRules MakeProxyPerSchemeRules(
"", proxy_http, proxy_https, proxy_ftp, socks_proxy);
}
-std::string FlattenProxyBypass(const BypassList& proxy_bypass) {
+std::string FlattenProxyBypass(const ProxyBypassRules& bypass_rules) {
std::string flattened_proxy_bypass;
- for (BypassList::const_iterator it = proxy_bypass.begin();
- it != proxy_bypass.end(); ++it) {
- flattened_proxy_bypass += *it + "\n";
+ for (ProxyBypassRules::RuleList::const_iterator it =
+ bypass_rules.rules().begin();
+ it != bypass_rules.rules().end(); ++it) {
+ flattened_proxy_bypass += (*it)->ToString() + "\n";
}
return flattened_proxy_bypass;
}
diff --git a/net/proxy/proxy_config_service_common_unittest.h b/net/proxy/proxy_config_service_common_unittest.h
index 783fc6f..66ddfa6 100644
--- a/net/proxy/proxy_config_service_common_unittest.h
+++ b/net/proxy/proxy_config_service_common_unittest.h
@@ -14,6 +14,8 @@
namespace net {
+class ProxyBypassRules;
+
ProxyConfig::ProxyRules MakeProxyRules(
ProxyConfig::ProxyRules::Type type,
const char* single_proxy,
@@ -35,10 +37,8 @@ ProxyConfig::ProxyRules MakeProxyPerSchemeRules(
const char* proxy_ftp,
const char* socks_proxy);
-typedef std::vector<std::string> BypassList;
-
// Joins the proxy bypass list using "\n" to make it into a single string.
-std::string FlattenProxyBypass(const BypassList& proxy_bypass);
+std::string FlattenProxyBypass(const ProxyBypassRules& bypass_rules);
} // namespace net
diff --git a/net/proxy/proxy_config_service_linux.cc b/net/proxy/proxy_config_service_linux.cc
index 3ca35c5..4eb6779 100644
--- a/net/proxy/proxy_config_service_linux.cc
+++ b/net/proxy/proxy_config_service_linux.cc
@@ -163,7 +163,9 @@ bool ProxyConfigServiceLinux::Delegate::GetConfigFromEnv(ProxyConfig* config) {
// connections.
return !no_proxy.empty();
}
- config->ParseNoProxyList(no_proxy);
+ // Note that this uses "suffix" matching. So a bypass of "google.com"
+ // is understood to mean a bypass of "*google.com".
+ config->bypass_rules.ParseFromStringUsingSuffixMatching(no_proxy);
return true;
}
@@ -943,10 +945,16 @@ bool ProxyConfigServiceLinux::Delegate::GetConfigFromGConf(
}
// Now the bypass list.
+ std::vector<std::string> ignore_hosts_list;
gconf_getter_->GetStringList("/system/http_proxy/ignore_hosts",
- &config->proxy_bypass);
+ &ignore_hosts_list);
+
+ config->bypass_rules.Clear();
+ for (size_t i = 0; i < ignore_hosts_list.size(); ++i)
+ config->bypass_rules.AddRuleFromString(ignore_hosts_list[i]);
+
// Note that there are no settings with semantics corresponding to
- // config->proxy_bypass_local_names.
+ // bypass of local names.
return true;
}
diff --git a/net/proxy/proxy_config_service_linux_unittest.cc b/net/proxy/proxy_config_service_linux_unittest.cc
index 4ebc12e..0940ddf 100644
--- a/net/proxy/proxy_config_service_linux_unittest.cc
+++ b/net/proxy/proxy_config_service_linux_unittest.cc
@@ -367,7 +367,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
GURL pac_url;
ProxyConfig::ProxyRules proxy_rules;
const char* proxy_bypass_list; // newline separated
- bool bypass_local_names;
} tests[] = {
{
TEST_DESC("No proxying"),
@@ -385,7 +384,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -404,7 +402,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -423,7 +420,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
GURL("http://wpad/wpad.dat"), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -442,7 +438,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -461,7 +456,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
GURL(), // pac_url
MakeSingleProxyRules("www.google.com"), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -480,7 +474,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -500,7 +493,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
MakeProxyPerSchemeRules("www.google.com", // proxy_rules
"", ""),
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -519,7 +511,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
GURL(), // pac_url
MakeSingleProxyRules("www.google.com:88"), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -543,7 +534,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
"www.foo.com:110",
"ftp.foo.com:121"),
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -562,7 +552,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
GURL(), // pac_url
MakeSingleProxyRules("socks4://socks.com:99"), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -580,7 +569,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
GURL(), // pac_url
MakeSingleProxyRules("www.google.com"), // proxy_rules
"*.google.com\n", // proxy_bypass_list
- false, // bypass_local_names
},
};
@@ -600,8 +588,7 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) {
EXPECT_EQ(tests[i].auto_detect, config.auto_detect);
EXPECT_EQ(tests[i].pac_url, config.pac_url);
EXPECT_EQ(tests[i].proxy_bypass_list,
- FlattenProxyBypass(config.proxy_bypass));
- EXPECT_EQ(tests[i].bypass_local_names, config.proxy_bypass_local_names);
+ FlattenProxyBypass(config.bypass_rules));
EXPECT_EQ(tests[i].proxy_rules, config.proxy_rules);
}
}
@@ -620,7 +607,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
GURL pac_url;
ProxyConfig::ProxyRules proxy_rules;
const char* proxy_bypass_list; // newline separated
- bool bypass_local_names;
} tests[] = {
{
TEST_DESC("No proxying"),
@@ -639,7 +625,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -659,7 +644,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -679,7 +663,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
GURL("http://wpad/wpad.dat"), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -699,7 +682,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -719,7 +701,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
GURL(), // pac_url
MakeSingleProxyRules("www.google.com"), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -739,7 +720,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
GURL(), // pac_url
MakeSingleProxyRules("www.google.com:99"), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -759,7 +739,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
GURL(), // pac_url
MakeSingleProxyRules("www.google.com:99"), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -780,7 +759,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
MakeProxyPerSchemeRules("www.google.com", "www.foo.com:110",
"ftp.foo.com:121"),
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -800,7 +778,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
GURL(), // pac_url
MakeSingleProxyRules("socks4://socks.com:888"), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -820,7 +797,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
GURL(), // pac_url
MakeSingleProxyRules("socks5://socks.com:888"), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -840,7 +816,6 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
GURL(), // pac_url
MakeSingleProxyRules("socks4://socks.com"), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -859,8 +834,8 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
GURL(), // pac_url
MakeSingleProxyRules("www.google.com"), // proxy_rules
// proxy_bypass_list
- "*.google.com\n*foo.com:99\n1.2.3.4:22\n127.0.0.1/8\n",
- false, // bypass_local_names
+ // TODO(eroman): 127.0.0.1/8 is unsupported, so it was dropped
+ "*.google.com\n*foo.com:99\n1.2.3.4:22\n",
},
};
@@ -880,8 +855,7 @@ TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) {
EXPECT_EQ(tests[i].auto_detect, config.auto_detect);
EXPECT_EQ(tests[i].pac_url, config.pac_url);
EXPECT_EQ(tests[i].proxy_bypass_list,
- FlattenProxyBypass(config.proxy_bypass));
- EXPECT_EQ(tests[i].bypass_local_names, config.proxy_bypass_local_names);
+ FlattenProxyBypass(config.bypass_rules));
EXPECT_EQ(tests[i].proxy_rules, config.proxy_rules);
}
}
@@ -930,7 +904,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
GURL pac_url;
ProxyConfig::ProxyRules proxy_rules;
const char* proxy_bypass_list; // newline separated
- bool bypass_local_names;
} tests[] = {
{
TEST_DESC("No proxying"),
@@ -943,7 +916,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -957,7 +929,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -972,7 +943,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
GURL("http://wpad/wpad.dat"), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -989,7 +959,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
"www.foo.com",
"ftp.foo.com"), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -1005,7 +974,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
MakeProxyPerSchemeRules("www.google.com",
"", ""), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -1021,7 +989,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
MakeProxyPerSchemeRules("www.google.com:88",
"", ""), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -1036,7 +1003,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
MakeProxyPerSchemeRules("www.google.com",
"", ""), // proxy_rules
"*.google.com\n", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -1051,7 +1017,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
MakeProxyPerSchemeRules("www.google.com",
"", ""), // proxy_rules
"*.google.com\n*.kde.org\n", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -1066,7 +1031,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
MakeProxyPerSchemeRules("www.google.com",
"", ""), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -1081,7 +1045,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
MakeProxyPerSchemeRules("www.google.com",
"", ""), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -1096,7 +1059,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
MakeProxyPerSchemeRules("www.google.com",
"", ""), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -1110,7 +1072,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
MakeProxyPerSchemeRules("www.google.com",
"", ""), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -1124,7 +1085,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
MakeProxyPerSchemeRules("www.google.com",
"", ""), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -1138,7 +1098,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
MakeProxyPerSchemeRules("www.google.com",
"", ""), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -1153,7 +1112,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
MakeProxyPerSchemeRules("www.google.com",
"", "ftp.foo.com"), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -1167,7 +1125,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
GURL("http:// foo"), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
{
@@ -1182,7 +1139,6 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
MakeProxyPerSchemeRules("www.google.com",
"", "ftp.foo.com"), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
};
@@ -1206,8 +1162,7 @@ TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) {
EXPECT_EQ(tests[i].auto_detect, config.auto_detect);
EXPECT_EQ(tests[i].pac_url, config.pac_url);
EXPECT_EQ(tests[i].proxy_bypass_list,
- FlattenProxyBypass(config.proxy_bypass));
- EXPECT_EQ(tests[i].bypass_local_names, config.proxy_bypass_local_names);
+ FlattenProxyBypass(config.bypass_rules));
EXPECT_EQ(tests[i].proxy_rules, config.proxy_rules);
}
}
diff --git a/net/proxy/proxy_config_service_mac.cc b/net/proxy/proxy_config_service_mac.cc
index 3359cc3..74b1ea6 100644
--- a/net/proxy/proxy_config_service_mac.cc
+++ b/net/proxy/proxy_config_service_mac.cc
@@ -140,7 +140,7 @@ int ProxyConfigServiceMac::GetProxyConfig(ProxyConfig* config) {
" to be a CFStringRef but it was not";
} else {
- config->proxy_bypass.push_back(
+ config->bypass_rules.AddRuleFromString(
base::SysCFStringRefToUTF8(bypass_item_ref));
}
}
@@ -148,10 +148,11 @@ int ProxyConfigServiceMac::GetProxyConfig(ProxyConfig* config) {
// proxy bypass boolean
- config->proxy_bypass_local_names =
- GetBoolFromDictionary(config_dict.get(),
+ if (GetBoolFromDictionary(config_dict.get(),
kSCPropNetProxiesExcludeSimpleHostnames,
- false);
+ false)) {
+ config->bypass_rules.AddRuleToBypassLocal();
+ }
return OK;
}
diff --git a/net/proxy/proxy_config_service_win.cc b/net/proxy/proxy_config_service_win.cc
index 30c4adb..c39c510 100644
--- a/net/proxy/proxy_config_service_win.cc
+++ b/net/proxy/proxy_config_service_win.cc
@@ -55,10 +55,7 @@ void ProxyConfigServiceWin::SetFromIEConfig(
StringTokenizer proxy_server_bypass_list(proxy_bypass, "; \t\n\r");
while (proxy_server_bypass_list.GetNext()) {
std::string bypass_url_domain = proxy_server_bypass_list.token();
- if (bypass_url_domain == "<local>")
- config->proxy_bypass_local_names = true;
- else
- config->proxy_bypass.push_back(bypass_url_domain);
+ config->bypass_rules.AddRuleFromString(bypass_url_domain);
}
}
if (ie_config.lpszAutoConfigUrl)
diff --git a/net/proxy/proxy_config_service_win_unittest.cc b/net/proxy/proxy_config_service_win_unittest.cc
index 2b0ff66..ffcb0be 100644
--- a/net/proxy/proxy_config_service_win_unittest.cc
+++ b/net/proxy/proxy_config_service_win_unittest.cc
@@ -21,7 +21,6 @@ TEST(ProxyConfigServiceWinTest, SetFromIEConfig) {
GURL pac_url;
ProxyConfig::ProxyRules proxy_rules;
const char* proxy_bypass_list; // newline separated
- bool bypass_local_names;
} tests[] = {
// Auto detect.
{
@@ -37,7 +36,6 @@ TEST(ProxyConfigServiceWinTest, SetFromIEConfig) {
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
// Valid PAC url
@@ -54,7 +52,6 @@ TEST(ProxyConfigServiceWinTest, SetFromIEConfig) {
GURL("http://wpad/wpad.dat"), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
// Invalid PAC url string.
@@ -71,7 +68,6 @@ TEST(ProxyConfigServiceWinTest, SetFromIEConfig) {
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
// Single-host in proxy list.
@@ -88,7 +84,6 @@ TEST(ProxyConfigServiceWinTest, SetFromIEConfig) {
GURL(), // pac_url
MakeSingleProxyRules("www.google.com"), // proxy_rules
"", // proxy_bypass_list
- false, // bypass_local_names
},
// Per-scheme proxy rules.
@@ -105,7 +100,6 @@ TEST(ProxyConfigServiceWinTest, SetFromIEConfig) {
GURL(), // pac_url
MakeProxyPerSchemeRules("www.google.com:80", "www.foo.com:110", ""),
"", // proxy_bypass_list
- false, // bypass_local_names
},
// SOCKS proxy configuration
@@ -124,7 +118,6 @@ TEST(ProxyConfigServiceWinTest, SetFromIEConfig) {
MakeProxyPerSchemeRules("www.google.com:80", "www.foo.com:110",
"ftpproxy:20", "foopy:130"),
"", // proxy_bypass_list
- false, // bypass_local_names
},
// Bypass local names.
@@ -139,8 +132,7 @@ TEST(ProxyConfigServiceWinTest, SetFromIEConfig) {
true, // auto_detect
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
- "", // proxy_bypass_list
- true, // bypass_local_names
+ "<local>\n", // proxy_bypass_list
},
// Bypass "google.com" and local names, using semicolon as delimeter
@@ -157,8 +149,7 @@ TEST(ProxyConfigServiceWinTest, SetFromIEConfig) {
true, // auto_detect
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
- "google.com\n", // proxy_bypass_list
- true, // bypass_local_names
+ "<local>\ngoogle.com\n", // proxy_bypass_list
},
// Bypass "foo.com" and "google.com", using lines as delimeter.
@@ -175,7 +166,6 @@ TEST(ProxyConfigServiceWinTest, SetFromIEConfig) {
GURL(), // pac_url
ProxyConfig::ProxyRules(), // proxy_rules
"foo.com\ngoogle.com\n", // proxy_bypass_list
- false, // bypass_local_names
},
};
@@ -186,8 +176,7 @@ TEST(ProxyConfigServiceWinTest, SetFromIEConfig) {
EXPECT_EQ(tests[i].auto_detect, config.auto_detect);
EXPECT_EQ(tests[i].pac_url, config.pac_url);
EXPECT_EQ(tests[i].proxy_bypass_list,
- FlattenProxyBypass(config.proxy_bypass));
- EXPECT_EQ(tests[i].bypass_local_names, config.proxy_bypass_local_names);
+ FlattenProxyBypass(config.bypass_rules));
EXPECT_EQ(tests[i].proxy_rules, config.proxy_rules);
}
}
diff --git a/net/proxy/proxy_config_unittest.cc b/net/proxy/proxy_config_unittest.cc
index 259f1fa..9f6cbaf 100644
--- a/net/proxy/proxy_config_unittest.cc
+++ b/net/proxy/proxy_config_unittest.cc
@@ -71,26 +71,14 @@ TEST(ProxyConfigTest, Equals) {
EXPECT_TRUE(config1.Equals(config2));
EXPECT_TRUE(config2.Equals(config1));
- // Test |ProxyConfig::proxy_bypass|.
+ // Test |ProxyConfig::bypass_rules|.
- config2.proxy_bypass.push_back("*.google.com");
+ config2.bypass_rules.AddRuleFromString("*.google.com");
EXPECT_FALSE(config1.Equals(config2));
EXPECT_FALSE(config2.Equals(config1));
- config1.proxy_bypass.push_back("*.google.com");
-
- EXPECT_TRUE(config1.Equals(config2));
- EXPECT_TRUE(config2.Equals(config1));
-
- // Test |ProxyConfig::proxy_bypass_local_names|.
-
- config1.proxy_bypass_local_names = true;
-
- EXPECT_FALSE(config1.Equals(config2));
- EXPECT_FALSE(config2.Equals(config1));
-
- config2.proxy_bypass_local_names = true;
+ config1.bypass_rules.AddRuleFromString("*.google.com");
EXPECT_TRUE(config1.Equals(config2));
EXPECT_TRUE(config2.Equals(config1));
@@ -252,39 +240,6 @@ TEST(ProxyConfigTest, ParseProxyRules) {
}
}
-TEST(ProxyConfigTest, ParseProxyBypassList) {
- struct bypass_test {
- const char* proxy_bypass_input;
- const char* flattened_output;
- };
-
- const struct {
- const char* proxy_bypass_input;
- const char* flattened_output;
- } tests[] = {
- {
- "*",
- "*\n"
- },
- {
- ".google.com, .foo.com:42",
- "*.google.com\n*.foo.com:42\n"
- },
- {
- ".google.com, foo.com:99, 1.2.3.4:22, 127.0.0.1/8",
- "*.google.com\n*foo.com:99\n1.2.3.4:22\n127.0.0.1/8\n"
- }
- };
-
- ProxyConfig config;
-
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
- config.ParseNoProxyList(tests[i].proxy_bypass_input);
- EXPECT_EQ(tests[i].flattened_output,
- FlattenProxyBypass(config.proxy_bypass));
- }
-}
-
std::string ProxyConfigToString(const ProxyConfig& config) {
std::ostringstream stream;
stream << config;
@@ -303,8 +258,7 @@ TEST(ProxyConfigTest, ToString) {
" Custom PAC script: [None]\n"
"Manual settings:\n"
" Proxy server: single-proxy:81\n"
- " Bypass list: [None]\n"
- " Bypass local names: No",
+ " Bypass list: [None]",
ProxyConfigToString(config));
}
@@ -320,8 +274,7 @@ TEST(ProxyConfigTest, ToString) {
" Custom PAC script: http://custom/pac.js\n"
"Manual settings:\n"
" Proxy server: single-proxy:81\n"
- " Bypass list: [None]\n"
- " Bypass local names: No",
+ " Bypass list: [None]",
ProxyConfigToString(config));
}
@@ -330,9 +283,9 @@ TEST(ProxyConfigTest, ToString) {
ProxyConfig config;
config.auto_detect = false;
config.proxy_rules.ParseFromString("http://single-proxy:81");
- config.proxy_bypass.push_back("google.com");
- config.proxy_bypass.push_back("bypass2.net:1730");
- config.proxy_bypass_local_names = true;
+ config.bypass_rules.AddRuleFromString("google.com");
+ config.bypass_rules.AddRuleFromString("bypass2.net:1730");
+ config.bypass_rules.AddRuleToBypassLocal();
EXPECT_EQ("Automatic settings:\n"
" Auto-detect: No\n"
@@ -342,7 +295,7 @@ TEST(ProxyConfigTest, ToString) {
" Bypass list: \n"
" google.com\n"
" bypass2.net:1730\n"
- " Bypass local names: Yes",
+ " <local>",
ProxyConfigToString(config));
}
@@ -360,8 +313,7 @@ TEST(ProxyConfigTest, ToString) {
" Proxy server: \n"
" HTTP: proxy-for-http:1801\n"
" HTTPS: proxy-for-https:1802\n"
- " Bypass list: [None]\n"
- " Bypass local names: No",
+ " Bypass list: [None]",
ProxyConfigToString(config));
}
@@ -379,8 +331,7 @@ TEST(ProxyConfigTest, ToString) {
" Proxy server: \n"
" HTTP: proxy-for-http:1801\n"
" SOCKS: socks4://socks-server:6083\n"
- " Bypass list: [None]\n"
- " Bypass local names: No",
+ " Bypass list: [None]",
ProxyConfigToString(config));
}
@@ -394,8 +345,7 @@ TEST(ProxyConfigTest, ToString) {
" Custom PAC script: [None]\n"
"Manual settings:\n"
" Proxy server: [None]\n"
- " Bypass list: [None]\n"
- " Bypass local names: No",
+ " Bypass list: [None]",
ProxyConfigToString(config));
}
}
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
index 90fd297..fa7ba4d 100644
--- a/net/proxy/proxy_service.cc
+++ b/net/proxy/proxy_service.cc
@@ -334,7 +334,7 @@ void ProxyService::ApplyProxyRules(const GURL& url,
ProxyInfo* result) {
DCHECK(!proxy_rules.empty());
- if (ShouldBypassProxyForURL(url)) {
+ if (config_.bypass_rules.Matches(url)) {
result->UseDirect();
return;
}
@@ -692,90 +692,6 @@ void ProxyService::UpdateConfigIfOld(LoadLog* load_log) {
UpdateConfig(load_log);
}
-bool ProxyService::ShouldBypassProxyForURL(const GURL& url) {
- std::string url_domain = url.scheme();
- if (!url_domain.empty())
- url_domain += "://";
-
- url_domain += url.host();
- // This isn't superfluous; GURL case canonicalization doesn't hit the embedded
- // percent-encoded characters.
- StringToLowerASCII(&url_domain);
-
- // TODO(eroman): use GetHostAndPort().
- std::string url_domain_and_port = url_domain + ":"
- + IntToString(url.EffectiveIntPort());
-
- if (config_.proxy_bypass_local_names && IsLocalName(url))
- return true;
-
- for(std::vector<std::string>::const_iterator i = config_.proxy_bypass.begin();
- i != config_.proxy_bypass.end(); ++i) {
- std::string bypass_url_domain = *i;
-
- // The proxy server bypass list can contain entities with http/https
- // If no scheme is specified then it indicates that all schemes are
- // allowed for the current entry. For matching this we just use
- // the protocol scheme of the url passed in.
- size_t scheme_colon = bypass_url_domain.find("://");
- if (scheme_colon == std::string::npos) {
- std::string bypass_url_domain_with_scheme = url.scheme();
- scheme_colon = bypass_url_domain_with_scheme.length();
- bypass_url_domain_with_scheme += "://";
- bypass_url_domain_with_scheme += bypass_url_domain;
-
- bypass_url_domain = bypass_url_domain_with_scheme;
- }
- std::string* url_compare_reference = &url_domain;
- size_t port_colon = bypass_url_domain.rfind(":");
- if (port_colon > scheme_colon) {
- // If our match pattern includes a colon followed by a digit,
- // and either it's preceded by ']' (IPv6 with port)
- // or has no other colon (IPv4),
- // then match against <domain>:<port>.
- // TODO(sdoyon): straighten this out, in particular the IPv6 brackets,
- // and do the parsing in ProxyConfig when we do the CIDR matching
- // mentioned below.
- std::string::const_iterator domain_begin =
- bypass_url_domain.begin() + scheme_colon + 3; // after ://
- std::string::const_iterator port_iter =
- bypass_url_domain.begin() + port_colon;
- std::string::const_iterator end = bypass_url_domain.end();
- if ((port_iter + 1) < end && IsAsciiDigit(*(port_iter + 1)) &&
- (*(port_iter - 1) == ']' ||
- std::find(domain_begin, port_iter, ':') == port_iter))
- url_compare_reference = &url_domain_and_port;
- }
-
- StringToLowerASCII(&bypass_url_domain);
-
- if (MatchPatternASCII(*url_compare_reference, bypass_url_domain))
- return true;
-
- // Some systems (the Mac, for example) allow CIDR-style specification of
- // proxy bypass for IP-specified hosts (e.g. "10.0.0.0/8"; see
- // http://www.tcd.ie/iss/internet/osx_proxy.php for a real-world example).
- // That's kinda cool so we'll provide that for everyone.
- // TODO(avi): implement here. See: http://crbug.com/9835.
- // IP addresses ought to be canonicalized for comparison (whether
- // with CIDR, port, or IP address alone).
- }
-
- return false;
-}
-
-// This matches IE's interpretation of the
-// "Bypass proxy server for local addresses" settings checkbox. Fully
-// qualified domain names or IP addresses are considered non-local,
-// regardless of what they map to.
-//
-// static
-bool ProxyService::IsLocalName(const GURL& url) {
- const std::string& host = url.host();
- if (host == "127.0.0.1" || host == "[::1]")
- return true;
- return host.find('.') == std::string::npos;
-}
void ProxyService::OnIPAddressChanged() {
DCHECK(network_change_notifier_);
diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h
index 8614d555..5798214 100644
--- a/net/proxy/proxy_service.h
+++ b/net/proxy/proxy_service.h
@@ -178,7 +178,6 @@ class ProxyService : public base::RefCountedThreadSafe<ProxyService>,
private:
friend class base::RefCountedThreadSafe<ProxyService>;
- FRIEND_TEST(ProxyServiceTest, IsLocalName);
FRIEND_TEST(ProxyServiceTest, UpdateConfigAfterFailedAutodetect);
FRIEND_TEST(ProxyServiceTest, UpdateConfigFromPACToDirect);
friend class PacRequest;
@@ -253,15 +252,6 @@ class ProxyService : public base::RefCountedThreadSafe<ProxyService>,
int result_code,
LoadLog* load_log);
- // Returns true if the URL passed in should not go through the proxy server.
- // 1. If the proxy settings say to bypass local names, and |IsLocalName(url)|.
- // 2. The URL matches one of the entities in the proxy bypass list.
- bool ShouldBypassProxyForURL(const GURL& url);
-
- // Returns true if |url| is to an intranet site (using non-FQDN as the
- // heuristic).
- static bool IsLocalName(const GURL& url);
-
// NetworkChangeNotifier::Observer methods:
virtual void OnIPAddressChanged();
diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc
index b6804ce..802806c 100644
--- a/net/proxy/proxy_service_unittest.cc
+++ b/net/proxy/proxy_service_unittest.cc
@@ -674,212 +674,33 @@ TEST(ProxyServiceTest, ProxyFallback_BadConfig) {
}
TEST(ProxyServiceTest, ProxyBypassList) {
- // Test what happens when a proxy bypass list is specified.
+ // Test that the proxy bypass rules are consulted.
- ProxyInfo info;
+ TestCompletionCallback callback[2];
+ ProxyInfo info[2];
ProxyConfig config;
config.proxy_rules.ParseFromString("foopy1:8080;foopy2:9090");
config.auto_detect = false;
- config.proxy_bypass_local_names = true;
-
- {
- scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config),
- new MockAsyncProxyResolver(),
- NULL));
- GURL url("http://www.google.com/");
- // Get the proxy information.
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- }
-
- {
- scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config),
- new MockAsyncProxyResolver(),
- NULL));
- GURL test_url("http://local");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
- }
+ config.bypass_rules.ParseFromString("*.org");
- config.proxy_bypass.clear();
- config.proxy_bypass.push_back("*.org");
- config.proxy_bypass_local_names = true;
- {
- scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
- GURL test_url("http://www.webkit.org");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
- }
-
- config.proxy_bypass.clear();
- config.proxy_bypass.push_back("*.org");
- config.proxy_bypass.push_back("7*");
- config.proxy_bypass_local_names = true;
- {
- scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
- GURL test_url("http://74.125.19.147");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
- }
+ scoped_refptr<ProxyService> service(new ProxyService(
+ new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
- config.proxy_bypass.clear();
- config.proxy_bypass.push_back("*.org");
- config.proxy_bypass_local_names = true;
- {
- scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
- GURL test_url("http://www.msn.com");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- }
+ int rv;
+ GURL url1("http://www.webkit.org");
+ GURL url2("http://www.webkit.com");
- config.proxy_bypass.clear();
- config.proxy_bypass.push_back("*.MSN.COM");
- config.proxy_bypass_local_names = true;
- {
- scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
- GURL test_url("http://www.msnbc.msn.com");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
- }
+ // Request for a .org domain should bypass proxy.
+ rv = service->ResolveProxy(url1, &info[0], &callback[0], NULL, NULL);
+ EXPECT_EQ(OK, rv);
+ EXPECT_TRUE(info[0].is_direct());
- config.proxy_bypass.clear();
- config.proxy_bypass.push_back("*.msn.com");
- config.proxy_bypass_local_names = true;
- {
- scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
- GURL test_url("HTTP://WWW.MSNBC.MSN.COM");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
- }
+ // Request for a .com domain hits the proxy.
+ rv = service->ResolveProxy(url2, &info[1], &callback[1], NULL, NULL);
+ EXPECT_EQ(OK, rv);
+ EXPECT_EQ("foopy1:8080", info[1].proxy_server().ToURI());
}
-TEST(ProxyServiceTest, ProxyBypassListWithPorts) {
- // Test port specification in bypass list entries.
- ProxyInfo info;
- ProxyConfig config;
- config.proxy_rules.ParseFromString("foopy1:8080;foopy2:9090");
- config.auto_detect = false;
- config.proxy_bypass_local_names = false;
-
- config.proxy_bypass.clear();
- config.proxy_bypass.push_back("*.example.com:99");
- {
- scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
- {
- GURL test_url("http://www.example.com:99");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
- }
- {
- GURL test_url("http://www.example.com:100");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- }
- {
- GURL test_url("http://www.example.com");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- }
- }
-
- config.proxy_bypass.clear();
- config.proxy_bypass.push_back("*.example.com:80");
- {
- scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
- GURL test_url("http://www.example.com");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
- }
-
- config.proxy_bypass.clear();
- config.proxy_bypass.push_back("*.example.com");
- {
- scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
- GURL test_url("http://www.example.com:99");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
- }
-
- // IPv6 with port.
- config.proxy_bypass.clear();
- config.proxy_bypass.push_back("[3ffe:2a00:100:7031::1]:99");
- {
- scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
- {
- GURL test_url("http://[3ffe:2a00:100:7031::1]:99/");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
- }
- {
- GURL test_url("http://[3ffe:2a00:100:7031::1]/");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_FALSE(info.is_direct());
- }
- }
-
- // IPv6 without port. The bypass entry ought to work without the
- // brackets, but the bypass matching logic in ProxyService is
- // currently limited.
- config.proxy_bypass.clear();
- config.proxy_bypass.push_back("[3ffe:2a00:100:7031::1]");
- {
- scoped_refptr<ProxyService> service(new ProxyService(
- new MockProxyConfigService(config), new MockAsyncProxyResolver, NULL));
- {
- GURL test_url("http://[3ffe:2a00:100:7031::1]:99/");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
- }
- {
- GURL test_url("http://[3ffe:2a00:100:7031::1]/");
- TestCompletionCallback callback;
- int rv = service->ResolveProxy(test_url, &info, &callback, NULL, NULL);
- EXPECT_EQ(OK, rv);
- EXPECT_TRUE(info.is_direct());
- }
- }
-}
TEST(ProxyServiceTest, PerProtocolProxyTests) {
ProxyConfig config;
@@ -1491,7 +1312,7 @@ TEST(ProxyServiceTest, BypassDoesntApplyToPac) {
config.auto_detect = true;
config.pac_url = GURL("http://foopy/proxy.pac");
config.proxy_rules.ParseFromString("http=foopy:80"); // Not used.
- config.proxy_bypass.push_back("www.google.com");
+ config.bypass_rules.ParseFromString("www.google.com");
MockProxyConfigService* config_service = new MockProxyConfigService(config);
MockAsyncProxyResolverExpectsBytes* resolver =
@@ -1644,47 +1465,6 @@ TEST(ProxyServiceTest, ResetProxyConfigService) {
EXPECT_EQ("foopy2:8080", info.proxy_server().ToURI());
}
-TEST(ProxyServiceTest, IsLocalName) {
- const struct {
- const char* url;
- bool expected_is_local;
- } tests[] = {
- // Single-component hostnames are considered local.
- {"http://localhost/x", true},
- {"http://www", true},
-
- // IPv4 loopback interface.
- {"http://127.0.0.1/x", true},
- {"http://127.0.0.1:80/x", true},
-
- // IPv6 loopback interface.
- {"http://[::1]:80/x", true},
- {"http://[0:0::1]:6233/x", true},
- {"http://[0:0:0:0:0:0:0:1]/x", true},
-
- // Non-local URLs.
- {"http://foo.com/", false},
- {"http://localhost.i/", false},
- {"http://www.google.com/", false},
- {"http://192.168.0.1/", false},
-
- // Try with different protocols.
- {"ftp://127.0.0.1/x", true},
- {"ftp://foobar.com/x", false},
-
- // This is a bit of a gray-area, but GURL does not strip trailing dots
- // in host-names, so the following are considered non-local.
- {"http://www./x", false},
- {"http://localhost./x", false},
- };
-
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
- SCOPED_TRACE(StringPrintf("Test[%" PRIuS "]: %s", i, tests[i].url));
- bool is_local = ProxyService::IsLocalName(GURL(tests[i].url));
- EXPECT_EQ(tests[i].expected_is_local, is_local);
- }
-}
-
// Check that after we have done the auto-detect test, and the configuration
// is updated (with no change), we don't re-try the autodetect test.
// Regression test for http://crbug.com/18526 -- the configuration was being