summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobertshield@google.com <robertshield@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-12 15:07:50 +0000
committerrobertshield@google.com <robertshield@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-12 15:07:50 +0000
commitab501a6a67596eb43d233f91f7500779dcbe8740 (patch)
tree90bfc9f94bf80c4ed7081d8d54454f02075c3c26
parent481fe3bfb2359849d1d3fc9d0ceba4161fbb5a3e (diff)
downloadchromium_src-ab501a6a67596eb43d233f91f7500779dcbe8740.zip
chromium_src-ab501a6a67596eb43d233f91f7500779dcbe8740.tar.gz
chromium_src-ab501a6a67596eb43d233f91f7500779dcbe8740.tar.bz2
Making command-line specified proxy settings more flexible - allowing for setting of auto-detect, pac url, per-schema proxy settings, proxy bypass urls.
BUG=http://crbug.com/266 Review URL: http://codereview.chromium.org/115029 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15855 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/net/chrome_url_request_context.cc64
-rw-r--r--chrome/browser/net/chrome_url_request_context.h8
-rw-r--r--chrome/browser/net/chrome_url_request_context_unittest.cc181
-rw-r--r--chrome/chrome.gyp2
-rw-r--r--chrome/chrome.sln3
-rw-r--r--chrome/common/chrome_switches.cc18
-rw-r--r--chrome/common/chrome_switches.h4
-rw-r--r--chrome/test/unit/unittests.vcproj4
-rw-r--r--net/http/http_network_transaction_unittest.cc6
-rw-r--r--net/net.gyp3
-rw-r--r--net/proxy/proxy_config.cc69
-rw-r--r--net/proxy/proxy_config.h11
-rw-r--r--net/proxy/proxy_config_service_fixed.h9
-rw-r--r--net/proxy/proxy_config_service_linux.cc67
-rw-r--r--net/proxy/proxy_config_service_linux.h4
-rw-r--r--net/proxy/proxy_config_unittest.cc34
-rw-r--r--net/proxy/proxy_script_fetcher_unittest.cc2
-rw-r--r--net/proxy/proxy_service.cc60
-rw-r--r--net/proxy/proxy_service.h10
-rw-r--r--net/url_request/url_request_unittest.h7
-rw-r--r--webkit/tools/test_shell/test_shell_request_context.cc5
21 files changed, 444 insertions, 127 deletions
diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc
index b15db26..85a33c9 100644
--- a/chrome/browser/net/chrome_url_request_context.cc
+++ b/chrome/browser/net/chrome_url_request_context.cc
@@ -23,26 +23,68 @@
#include "net/proxy/proxy_service.h"
#include "webkit/glue/webkit_glue.h"
-// Sets up proxy info if overrides were specified on the command line.
-// Otherwise returns NULL (meaning we should use the system defaults).
-// The caller is responsible for deleting returned pointer.
-static net::ProxyInfo* CreateProxyInfo(const CommandLine& command_line) {
- net::ProxyInfo* proxy_info = NULL;
+net::ProxyConfig* CreateProxyConfig(const CommandLine& command_line) {
+ // Scan for all "enable" type proxy switches.
+ static const wchar_t* proxy_switches[] = {
+ switches::kProxyServer,
+ switches::kProxyServerPacUrl,
+ switches::kProxyServerAutoDetect,
+ switches::kProxyServerBypassUrls
+ };
+
+ bool found_enable_proxy_switch = false;
+ for (size_t i = 0; i < arraysize(proxy_switches); i++) {
+ if (command_line.HasSwitch(proxy_switches[i])) {
+ found_enable_proxy_switch = true;
+ break;
+ }
+ }
+
+ if (!found_enable_proxy_switch &&
+ !command_line.HasSwitch(switches::kNoProxyServer)) {
+ return NULL;
+ }
+
+ net::ProxyConfig* proxy_config = new net::ProxyConfig();
+ if (command_line.HasSwitch(switches::kNoProxyServer)) {
+ // Ignore (and warn about) all the other proxy config switches we get if
+ // the no-proxy-server command line argument is present.
+ if (found_enable_proxy_switch) {
+ LOG(WARNING) << "Additional command line proxy switches found when --"
+ << switches::kNoProxyServer << " was specified.";
+ }
+ return proxy_config;
+ }
if (command_line.HasSwitch(switches::kProxyServer)) {
- proxy_info = new net::ProxyInfo();
const std::wstring& proxy_server =
command_line.GetSwitchValue(switches::kProxyServer);
- proxy_info->UseNamedProxy(WideToASCII(proxy_server));
+ proxy_config->proxy_rules.ParseFromString(WideToASCII(proxy_server));
+ }
+
+ if (command_line.HasSwitch(switches::kProxyServerPacUrl)) {
+ proxy_config->pac_url =
+ GURL(WideToASCII(command_line.GetSwitchValue(
+ switches::kProxyServerPacUrl)));
+ }
+
+ if (command_line.HasSwitch(switches::kProxyServerAutoDetect)) {
+ proxy_config->auto_detect = true;
+ }
+
+ if (command_line.HasSwitch(switches::kProxyServerBypassUrls)) {
+ proxy_config->ParseNoProxyList(
+ WideToASCII(command_line.GetSwitchValue(
+ switches::kProxyServerBypassUrls)));
}
- return proxy_info;
+ return proxy_config;
}
// Create a proxy service according to the options on command line.
static net::ProxyService* CreateProxyService(URLRequestContext* context,
const CommandLine& command_line) {
- scoped_ptr<net::ProxyInfo> proxy_info(CreateProxyInfo(command_line));
+ scoped_ptr<net::ProxyConfig> proxy_config(CreateProxyConfig(command_line));
bool use_v8 = !command_line.HasSwitch(switches::kWinHttpProxyResolver);
if (use_v8 && command_line.HasSwitch(switches::kSingleProcess)) {
@@ -53,8 +95,8 @@ static net::ProxyService* CreateProxyService(URLRequestContext* context,
}
return use_v8 ?
- net::ProxyService::CreateUsingV8Resolver(proxy_info.get(), context) :
- net::ProxyService::Create(proxy_info.get());
+ net::ProxyService::CreateUsingV8Resolver(proxy_config.get(), context) :
+ net::ProxyService::Create(proxy_config.get());
}
// static
diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h
index 34b3d97..6f392a7 100644
--- a/chrome/browser/net/chrome_url_request_context.h
+++ b/chrome/browser/net/chrome_url_request_context.h
@@ -9,6 +9,10 @@
#include "net/url_request/url_request_context.h"
class Profile;
+class CommandLine;
+namespace net {
+class ProxyConfig;
+}
// A URLRequestContext subclass used by the browser. This can be used to store
// extra information about requests, beyond what is supported by the base
@@ -96,3 +100,7 @@ class ChromeURLRequestContext : public URLRequestContext,
bool is_media_;
bool is_off_the_record_;
};
+
+// Creates a proxy configuration using the overrides specified on the command
+// line. Returns NULL if the system defaults should be used instead.
+net::ProxyConfig* CreateProxyConfig(const CommandLine& command_line);
diff --git a/chrome/browser/net/chrome_url_request_context_unittest.cc b/chrome/browser/net/chrome_url_request_context_unittest.cc
new file mode 100644
index 0000000..e74e7a8
--- /dev/null
+++ b/chrome/browser/net/chrome_url_request_context_unittest.cc
@@ -0,0 +1,181 @@
+// Copyright (c) 2006-2009 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 "base/command_line.h"
+#include "chrome/browser/net/chrome_url_request_context.h"
+#include "chrome/common/chrome_switches.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service_common_unittest.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+// Builds an identifier for each test in an array.
+#define TEST_DESC(desc) StringPrintf("at line %d <%s>", __LINE__, desc)
+
+TEST(ChromeUrlRequestContextTest, CreateProxyConfigTest) {
+ // Build the input command lines here.
+ CommandLine empty(L"foo.exe");
+ CommandLine no_proxy(L"foo.exe");
+ no_proxy.AppendSwitch(switches::kNoProxyServer);
+ CommandLine no_proxy_extra_params(L"foo.exe");
+ no_proxy_extra_params.AppendSwitch(switches::kNoProxyServer);
+ no_proxy_extra_params.AppendSwitchWithValue(switches::kProxyServer,
+ L"http://proxy:8888");
+ CommandLine single_proxy(L"foo.exe");
+ single_proxy.AppendSwitchWithValue(switches::kProxyServer,
+ L"http://proxy:8888");
+ CommandLine per_scheme_proxy(L"foo.exe");
+ per_scheme_proxy.AppendSwitchWithValue(switches::kProxyServer,
+ L"http=httpproxy:8888;ftp=ftpproxy:8889");
+ CommandLine per_scheme_proxy_bypass(L"foo.exe");
+ per_scheme_proxy_bypass.AppendSwitchWithValue(switches::kProxyServer,
+ L"http=httpproxy:8888;ftp=ftpproxy:8889");
+ per_scheme_proxy_bypass.AppendSwitchWithValue(
+ switches::kProxyServerBypassUrls,
+ L".google.com, foo.com:99, 1.2.3.4:22, 127.0.0.1/8");
+ CommandLine with_pac_url(L"foo.exe");
+ with_pac_url.AppendSwitchWithValue(switches::kProxyServerPacUrl,
+ L"http://wpad/wpad.dat");
+ with_pac_url.AppendSwitchWithValue(
+ switches::kProxyServerBypassUrls,
+ L".google.com, foo.com:99, 1.2.3.4:22, 127.0.0.1/8");
+ CommandLine with_auto_detect(L"foo.exe");
+ with_auto_detect.AppendSwitch(switches::kProxyServerAutoDetect);
+
+ // Inspired from proxy_config_service_win_unittest.cc.
+ const struct {
+ // Short description to identify the test
+ std::string description;
+
+ // The command line to build a ProxyConfig from.
+ const CommandLine& command_line;
+
+ // Expected outputs (fields of the ProxyConfig).
+ bool is_null;
+ bool auto_detect;
+ 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"),
+ // Input
+ empty,
+ // Expected result
+ true, // is_null
+ false, // auto_detect
+ GURL(), // pac_url
+ net::ProxyConfig::ProxyRules(), // proxy_rules
+ "", // proxy_bypass_list
+ false // bypass_local_names
+ },
+ {
+ TEST_DESC("No proxy"),
+ // Input
+ no_proxy,
+ // Expected result
+ false, // is_null
+ false, // auto_detect
+ GURL(), // pac_url
+ net::ProxyConfig::ProxyRules(), // proxy_rules
+ "", // proxy_bypass_list
+ false // bypass_local_names
+ },
+ {
+ TEST_DESC("No proxy with extra parameters."),
+ // Input
+ no_proxy_extra_params,
+ // Expected result
+ false, // is_null
+ false, // auto_detect
+ GURL(), // pac_url
+ net::ProxyConfig::ProxyRules(), // proxy_rules
+ "", // proxy_bypass_list
+ false // bypass_local_names
+ },
+ {
+ TEST_DESC("Single proxy."),
+ // Input
+ single_proxy,
+ // Expected result
+ false, // is_null
+ false, // auto_detect
+ GURL(), // pac_url
+ net::MakeSingleProxyRules("http://proxy:8888"), // proxy_rules
+ "", // proxy_bypass_list
+ false // bypass_local_names
+ },
+ {
+ TEST_DESC("Per scheme proxy."),
+ // Input
+ per_scheme_proxy,
+ // Expected result
+ false, // is_null
+ false, // auto_detect
+ GURL(), // pac_url
+ net::MakeProxyPerSchemeRules("httpproxy:8888",
+ "",
+ "ftpproxy:8889"), // proxy_rules
+ "", // proxy_bypass_list
+ false // bypass_local_names
+ },
+ {
+ TEST_DESC("Per scheme proxy with bypass URLs."),
+ // Input
+ per_scheme_proxy_bypass,
+ // Expected result
+ false, // is_null
+ false, // auto_detect
+ GURL(), // pac_url
+ 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
+ },
+ {
+ TEST_DESC("Pac URL with proxy bypass URLs"),
+ // Input
+ with_pac_url,
+ // Expected result
+ false, // is_null
+ 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
+ },
+ {
+ TEST_DESC("Autodetect"),
+ // Input
+ with_auto_detect,
+ // Expected result
+ false, // is_null
+ true, // auto_detect
+ GURL(), // pac_url
+ net::ProxyConfig::ProxyRules(), // proxy_rules
+ "", // proxy_bypass_list
+ false // bypass_local_names
+ }
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); i++) {
+ SCOPED_TRACE(StringPrintf("Test[%d] %s", i, tests[i].description.c_str()));
+ scoped_ptr<net::ProxyConfig> config(CreateProxyConfig(
+ CommandLine(tests[i].command_line)));
+
+ if (tests[i].is_null) {
+ EXPECT_TRUE(config == NULL);
+ } else {
+ EXPECT_TRUE(config != NULL);
+ 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);
+ EXPECT_EQ(tests[i].proxy_rules, config->proxy_rules);
+ }
+ }
+}
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 2bb811b..79d9be2 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -2584,6 +2584,7 @@
'chrome_resources',
'chrome_strings',
'test_support_unit',
+ '../net/net.gyp:net_test_support',
'../printing/printing.gyp:printing',
'../webkit/webkit.gyp:webkit',
'../skia/skia.gyp:skia',
@@ -2685,6 +2686,7 @@
'browser/metrics/metrics_response_unittest.cc',
'browser/navigation_controller_unittest.cc',
'browser/navigation_entry_unittest.cc',
+ 'browser/net/chrome_url_request_context_unittest.cc',
'browser/net/dns_host_info_unittest.cc',
'browser/net/dns_master_unittest.cc',
'browser/net/resolve_proxy_msg_helper_unittest.cc',
diff --git a/chrome/chrome.sln b/chrome/chrome.sln
index ce4d621..ca346ed 100644
--- a/chrome/chrome.sln
+++ b/chrome/chrome.sln
@@ -304,7 +304,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit_tests", "test\unit\uni
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D} = {CD9CA56E-4E94-444C-87D4-58CA1E6F300D}
{D5E8DCB2-9C61-446F-8BEE-B18CA0E0936E} = {D5E8DCB2-9C61-446F-8BEE-B18CA0E0936E}
{D9DDAF60-663F-49CC-90DC-3D08CC3D1B28} = {D9DDAF60-663F-49CC-90DC-3D08CC3D1B28}
+ {E99DA267-BE90-4F45-88A1-6919DB2C7567} = {E99DA267-BE90-4F45-88A1-6919DB2C7567}
{EC8B7909-62AF-470D-A75D-E1D89C837142} = {EC8B7909-62AF-470D-A75D-E1D89C837142}
+ {ED19720A-8F14-D3FC-9C6D-EEB5AE4D5BD7} = {ED19720A-8F14-D3FC-9C6D-EEB5AE4D5BD7}
{EF5E94AB-B646-4E5B-A058-52EF07B8351C} = {EF5E94AB-B646-4E5B-A058-52EF07B8351C}
{EFBB1436-A63F-4CD8-9E99-B89226E782EC} = {EFBB1436-A63F-4CD8-9E99-B89226E782EC}
{F4F4BCAA-EA59-445C-A119-3E6C29647A51} = {F4F4BCAA-EA59-445C-A119-3E6C29647A51}
@@ -1223,6 +1225,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "memory_test", "test\memory_
{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B} = {BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}
{C564F145-9172-42C3-BFCB-6014CA97DBCD} = {C564F145-9172-42C3-BFCB-6014CA97DBCD}
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D} = {CD9CA56E-4E94-444C-87D4-58CA1E6F300D}
+ {ED19720A-8F14-D3FC-9C6D-EEB5AE4D5BD7} = {ED19720A-8F14-D3FC-9C6D-EEB5AE4D5BD7}
{EF5E94AB-B646-4E5B-A058-52EF07B8351C} = {EF5E94AB-B646-4E5B-A058-52EF07B8351C}
{FA537565-7B03-4FFC-AF15-F7A979B72E22} = {FA537565-7B03-4FFC-AF15-F7A979B72E22}
EndProjectSection
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index ff0522a..3e1a7d1 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -233,9 +233,25 @@ const wchar_t kMakeDefaultBrowser[] = L"make-default-browser";
// affects HTTP and HTTPS requests.
const wchar_t kProxyServer[] = L"proxy-server";
+// Don't use a proxy server, always make direct connections. Overrides any
+// other proxy server flags that are passed.
+const wchar_t kNoProxyServer[] = L"no-proxy-server";
+
+// Specify a list of URLs for whom we bypass proxy settings and use direct
+// connections. Ignored if proxy-server-auto-detect or no-proxy-server are
+// also specified.
+// TODO(robertshield): Specify URL format.
+const wchar_t kProxyServerBypassUrls[] = L"proxy-server-bypass-urls";
+
+// Force proxy auto-detection.
+const wchar_t kProxyServerAutoDetect[] = L"proxy-server-auto-detect";
+
+// Use the pac script at the given URL
+const wchar_t kProxyServerPacUrl[] = L"proxy-server-pac-url";
+
// Use WinHTTP to fetch and evaluate PAC scripts. Otherwise the default is
// to use Chromium's network stack to fetch, and V8 to evaluate.
-const wchar_t kWinHttpProxyResolver[] = L"winhttp-proxy-resolver";
+const wchar_t kWinHttpProxyResolver[] = L"winhttp-proxy-resolver";
// Chrome will support prefetching of DNS information. Until this becomes
// the default, we'll provide a command line switch.
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 83682d0..e1d0243 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -77,6 +77,10 @@ extern const wchar_t kShowIcons[];
extern const wchar_t kMakeDefaultBrowser[];
extern const wchar_t kProxyServer[];
+extern const wchar_t kNoProxyServer[];
+extern const wchar_t kProxyServerBypassUrls[];
+extern const wchar_t kProxyServerAutoDetect[];
+extern const wchar_t kProxyServerPacUrl[];
extern const wchar_t kWinHttpProxyResolver[];
extern const wchar_t kDebugPrint[];
diff --git a/chrome/test/unit/unittests.vcproj b/chrome/test/unit/unittests.vcproj
index f36c673..b3fa491 100644
--- a/chrome/test/unit/unittests.vcproj
+++ b/chrome/test/unit/unittests.vcproj
@@ -456,6 +456,10 @@
>
</File>
<File
+ RelativePath="..\..\browser\net\chrome_url_request_context_unittest.cc"
+ >
+ </File>
+ <File
RelativePath="..\..\browser\safe_browsing\chunk_range_unittest.cc"
>
</File>
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 514ee38..007f0fb 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -345,9 +345,9 @@ ProxyService* CreateNullProxyService() {
}
ProxyService* CreateFixedProxyService(const std::string& proxy) {
- ProxyInfo proxy_info;
- proxy_info.UseNamedProxy(proxy);
- return ProxyService::Create(&proxy_info);
+ net::ProxyConfig proxy_config;
+ proxy_config.proxy_rules.ParseFromString(proxy);
+ return ProxyService::Create(&proxy_config);
}
diff --git a/net/net.gyp b/net/net.gyp
index a87029c..8c11266 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -444,7 +444,6 @@
'http/http_transaction_unittest.h',
'http/http_util_unittest.cc',
'http/http_vary_data_unittest.cc',
- 'proxy/proxy_config_service_common_unittest.cc',
'proxy/proxy_config_service_common_unittest.h',
'proxy/proxy_config_service_linux_unittest.cc',
'proxy/proxy_config_service_win_unittest.cc',
@@ -570,6 +569,8 @@
'sources': [
'disk_cache/disk_cache_test_util.cc',
'disk_cache/disk_cache_test_util.h',
+ 'proxy/proxy_config_service_common_unittest.cc',
+ 'proxy/proxy_config_service_common_unittest.h',
],
},
{
diff --git a/net/proxy/proxy_config.cc b/net/proxy/proxy_config.cc
index a860c99..751049b 100644
--- a/net/proxy/proxy_config.cc
+++ b/net/proxy/proxy_config.cc
@@ -25,6 +25,10 @@ bool ProxyConfig::Equals(const ProxyConfig& other) const {
proxy_bypass_local_names == other.proxy_bypass_local_names;
}
+bool ProxyConfig::MayRequirePACResolver() const {
+ return auto_detect || !pac_url.is_empty();
+}
+
void ProxyConfig::ProxyRules::ParseFromString(const std::string& proxy_rules) {
// Reset.
type = TYPE_NO_RULES;
@@ -76,6 +80,71 @@ const 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_parse::Component ignored_component;
+ url_parse::Component domain_comp(0, domain.size());
+ return url_canon::CanonicalizeIPAddress(domain.c_str(), domain_comp,
+ &ignored_output,
+ &ignored_component);
+}
+
+} // 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 MatchPattern() 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 {
diff --git a/net/proxy/proxy_config.h b/net/proxy/proxy_config.h
index 868fba9..b90e9b7 100644
--- a/net/proxy/proxy_config.h
+++ b/net/proxy/proxy_config.h
@@ -42,6 +42,8 @@ class ProxyConfig {
TYPE_PROXY_PER_SCHEME,
};
+ // Note that the default of TYPE_NO_RULES results in direct connections
+ // being made when using this ProxyConfig.
ProxyRules() : type(TYPE_NO_RULES) {}
bool empty() const {
@@ -91,6 +93,11 @@ 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
@@ -103,6 +110,10 @@ class ProxyConfig {
// Returns true if the given config is equivalent to this config.
bool Equals(const ProxyConfig& other) const;
+ // Returns true if this config could possibly require the proxy service to
+ // use a PAC resolver.
+ bool MayRequirePACResolver() const;
+
private:
int id_;
};
diff --git a/net/proxy/proxy_config_service_fixed.h b/net/proxy/proxy_config_service_fixed.h
index dfa9351..361c2b4 100644
--- a/net/proxy/proxy_config_service_fixed.h
+++ b/net/proxy/proxy_config_service_fixed.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2009 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.
@@ -12,17 +12,16 @@ namespace net {
// Implementation of ProxyConfigService that returns a fixed result.
class ProxyConfigServiceFixed : public ProxyConfigService {
public:
- explicit ProxyConfigServiceFixed(const ProxyInfo& pi) { pi_.Use(pi); }
+ explicit ProxyConfigServiceFixed(const ProxyConfig& pc) : pc_(pc) {}
// ProxyConfigService methods:
virtual int GetProxyConfig(ProxyConfig* config) {
- config->proxy_rules.type = ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY;
- config->proxy_rules.single_proxy = pi_.proxy_server();
+ *config = pc_;
return OK;
}
private:
- ProxyInfo pi_;
+ ProxyConfig pc_;
};
} // namespace net
diff --git a/net/proxy/proxy_config_service_linux.cc b/net/proxy/proxy_config_service_linux.cc
index 3c94cdf..cce5835 100644
--- a/net/proxy/proxy_config_service_linux.cc
+++ b/net/proxy/proxy_config_service_linux.cc
@@ -114,71 +114,6 @@ bool ProxyConfigServiceLinux::GetProxyFromEnvVar(
result_server);
}
-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_parse::Component ignored_component;
- url_parse::Component domain_comp(0, domain.size());
- return url_canon::CanonicalizeIPAddress(domain.c_str(), domain_comp,
- &ignored_output,
- &ignored_component);
-}
-
-} // namespace
-
-void ProxyConfigServiceLinux::ParseNoProxyList(const std::string& no_proxy,
- ProxyConfig* config) {
- 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 MatchPattern() 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 config->proxy_bypass more
- // sophisticated to avoid parsing out the string on every
- // request.
- }
- config->proxy_bypass.push_back(bypass_entry);
- }
-}
-
bool ProxyConfigServiceLinux::GetConfigFromEnv(ProxyConfig* config) {
// Check for automatic configuration first, in
// "auto_proxy". Possibly only the "environment_proxy" firefox
@@ -242,7 +177,7 @@ bool ProxyConfigServiceLinux::GetConfigFromEnv(ProxyConfig* config) {
// connections.
return !no_proxy.empty();
}
- ParseNoProxyList(no_proxy, config);
+ config->ParseNoProxyList(no_proxy);
return true;
}
diff --git a/net/proxy/proxy_config_service_linux.h b/net/proxy/proxy_config_service_linux.h
index 51436af..354bd29 100644
--- a/net/proxy/proxy_config_service_linux.h
+++ b/net/proxy/proxy_config_service_linux.h
@@ -81,9 +81,7 @@ class ProxyConfigServiceLinux : public ProxyConfigService {
ProxyServer* result_server);
// As above but with scheme set to HTTP, for convenience.
bool GetProxyFromEnvVar(const char* variable, ProxyServer* result_server);
- // Parses entries from the value of the no_proxy env var, and stuffs
- // them into config->proxy_bypass.
- void ParseNoProxyList(const std::string& no_proxy, ProxyConfig* config);
+
// Fills proxy config from environment variables. Returns true if
// variables were found and the configuration is valid.
bool GetConfigFromEnv(ProxyConfig* config);
diff --git a/net/proxy/proxy_config_unittest.cc b/net/proxy/proxy_config_unittest.cc
index 9e50e3b..a4192df 100644
--- a/net/proxy/proxy_config_unittest.cc
+++ b/net/proxy/proxy_config_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_config_service_common_unittest.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -197,3 +198,36 @@ TEST(ProxyConfigTest, ParseProxyRules) {
config.proxy_rules.proxy_for_ftp);
}
}
+
+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"
+ }
+ };
+
+ net::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,
+ net::FlattenProxyBypass(config.proxy_bypass));
+ }
+}
diff --git a/net/proxy/proxy_script_fetcher_unittest.cc b/net/proxy/proxy_script_fetcher_unittest.cc
index fae8c2d..e1c4179 100644
--- a/net/proxy/proxy_script_fetcher_unittest.cc
+++ b/net/proxy/proxy_script_fetcher_unittest.cc
@@ -27,7 +27,7 @@ struct FetchResult {
class RequestContext : public URLRequestContext {
public:
RequestContext() {
- net::ProxyInfo no_proxy;
+ net::ProxyConfig no_proxy;
proxy_service_ = net::ProxyService::Create(&no_proxy);
http_transaction_factory_ = net::HttpNetworkLayer::CreateFactory(
proxy_service_);
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
index 0919f45..c2ae532 100644
--- a/net/proxy/proxy_service.cc
+++ b/net/proxy/proxy_service.cc
@@ -71,8 +71,8 @@ class NotifyFetchCompletionTask : public Task {
// We rely on the fact that the origin thread (and its message loop) will not
// be destroyed until after the PAC thread is destroyed.
-class ProxyService::PacRequest :
- public base::RefCountedThreadSafe<ProxyService::PacRequest> {
+class ProxyService::PacRequest
+ : public base::RefCountedThreadSafe<ProxyService::PacRequest> {
public:
// |service| -- the ProxyService that owns this request.
// |url| -- the url of the query.
@@ -193,46 +193,58 @@ ProxyService::ProxyService(ProxyConfigService* config_service,
}
// static
-ProxyService* ProxyService::Create(const ProxyInfo* pi) {
- if (pi) {
- // The ProxyResolver is set to NULL, since it should never be called
- // (because the configuration will never require PAC).
- return new ProxyService(new ProxyConfigServiceFixed(*pi), NULL);
+ProxyService* ProxyService::Create(const ProxyConfig* pc) {
+ scoped_ptr<ProxyConfigService> proxy_config_service;
+ scoped_ptr<ProxyResolver> proxy_resolver;
+ if (pc) {
+ proxy_config_service.reset(new ProxyConfigServiceFixed(*pc));
}
+
#if defined(OS_WIN)
- return new ProxyService(new ProxyConfigServiceWin(),
- new ProxyResolverWinHttp());
+ if (proxy_config_service == NULL)
+ proxy_config_service.reset(new ProxyConfigServiceWin());
+ proxy_resolver.reset(new ProxyResolverWinHttp());
#elif defined(OS_MACOSX)
- return new ProxyService(new ProxyConfigServiceMac(),
- new ProxyResolverMac());
+ if (proxy_config_service == NULL)
+ proxy_config_service.reset(new ProxyConfigServiceMac());
+ proxy_resolver.reset(new ProxyResolverMac());
#elif defined(OS_LINUX)
// On Linux we use the V8Resolver, no fallback implementation.
- return CreateNull();
+ // This means that if we got called with a ProxyConfig that could require a
+ // resolver, or if the caller is trying to create a regular ProxyService via
+ // this method instead of CreateUsingV8Resolver() we have to return a
+ // nulled-out ProxyService.
+ if (!pc || pc->MayRequirePACResolver()) {
+ LOG(WARNING) << "Attempting to create a ProxyService with a non-v8 "
+ << "resolver using an invalid ProxyConfig.";
+ return CreateNull();
+ }
#else
return CreateNull();
#endif
+
+ return new ProxyService(proxy_config_service.release(),
+ proxy_resolver.release());
}
// static
ProxyService* ProxyService::CreateUsingV8Resolver(
- const ProxyInfo* pi, URLRequestContext* url_request_context) {
- if (pi) {
- // The ProxyResolver is set to NULL, since it should never be called
- // (because the configuration will never require PAC).
- return new ProxyService(new ProxyConfigServiceFixed(*pi), NULL);
- }
-
+ const ProxyConfig* pc, URLRequestContext* url_request_context) {
// Choose the system configuration service appropriate for each platform.
- ProxyConfigService* config_service;
+ ProxyConfigService* config_service = NULL;
+ if (pc) {
+ config_service = new ProxyConfigServiceFixed(*pc);
+ } else {
#if defined(OS_WIN)
- config_service = new ProxyConfigServiceWin();
+ config_service = new ProxyConfigServiceWin();
#elif defined(OS_MACOSX)
- config_service = new ProxyConfigServiceMac();
+ config_service = new ProxyConfigServiceMac();
#elif defined(OS_LINUX)
- config_service = new ProxyConfigServiceLinux();
+ config_service = new ProxyConfigServiceLinux();
#else
- return CreateNull();
+ return CreateNull();
#endif
+ }
// Create a ProxyService that uses V8 to evaluate PAC scripts.
ProxyService* proxy_service = new ProxyService(
diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h
index 3ebee8d..f2fbbe7 100644
--- a/net/proxy/proxy_service.h
+++ b/net/proxy/proxy_service.h
@@ -86,14 +86,14 @@ class ProxyService {
// |proxy_script_fetcher|.
void SetProxyScriptFetcher(ProxyScriptFetcher* proxy_script_fetcher);
- // Creates a proxy service using the specified settings. If |pi| is NULL then
+ // Creates a proxy service using the specified settings. If |pc| is NULL then
// the system's default proxy settings will be used (on Windows this will
// use IE's settings).
- static ProxyService* Create(const ProxyInfo* pi);
+ static ProxyService* Create(const ProxyConfig* pc);
- // Creates a proxy service using the specified settings. If |pi| is NULL then
+ // Creates a proxy service using the specified settings. If |pc| is NULL then
// the system's default proxy settings will be used. This is basically the
- // same as Create(const ProxyInfo*), however under the hood it uses a
+ // same as Create(const ProxyConfig*), however under the hood it uses a
// different implementation (V8). |url_request_context| is the URL request
// context that will be used if a PAC script needs to be fetched.
// ##########################################################################
@@ -102,7 +102,7 @@ class ProxyService {
// # other V8's running in the process must use v8::Locker.
// ##########################################################################
static ProxyService* CreateUsingV8Resolver(
- const ProxyInfo* pi,
+ const ProxyConfig* pc,
URLRequestContext* url_request_context);
// Creates a proxy service that always fails to fetch the proxy configuration,
diff --git a/net/url_request/url_request_unittest.h b/net/url_request/url_request_unittest.h
index e661153..37e6439 100644
--- a/net/url_request/url_request_unittest.h
+++ b/net/url_request/url_request_unittest.h
@@ -48,9 +48,9 @@ class TestURLRequestContext : public URLRequestContext {
}
explicit TestURLRequestContext(const std::string& proxy) {
- net::ProxyInfo proxy_info;
- proxy_info.UseNamedProxy(proxy);
- proxy_service_ = net::ProxyService::Create(&proxy_info);
+ net::ProxyConfig proxy_config;
+ proxy_config.proxy_rules.ParseFromString(proxy);
+ proxy_service_ = net::ProxyService::Create(&proxy_config);
http_transaction_factory_ =
net::HttpNetworkLayer::CreateFactory(proxy_service_);
}
@@ -548,7 +548,6 @@ class FTPTestServer : public BaseTestServer {
return true;
}
-
};
#endif // NET_URL_REQUEST_URL_REQUEST_UNITTEST_H_
diff --git a/webkit/tools/test_shell/test_shell_request_context.cc b/webkit/tools/test_shell/test_shell_request_context.cc
index 2597f77..6a58104 100644
--- a/webkit/tools/test_shell/test_shell_request_context.cc
+++ b/webkit/tools/test_shell/test_shell_request_context.cc
@@ -29,9 +29,8 @@ void TestShellRequestContext::Init(
accept_language_ = "en-us,en";
accept_charset_ = "iso-8859-1,*,utf-8";
- net::ProxyInfo proxy_info;
- proxy_info.UseDirect();
- proxy_service_ = net::ProxyService::Create(no_proxy ? &proxy_info : NULL);
+ net::ProxyConfig proxy_config;
+ proxy_service_ = net::ProxyService::Create(no_proxy ? &proxy_config : NULL);
net::HttpCache *cache;
if (cache_path.empty()) {