summaryrefslogtreecommitdiffstats
path: root/net/proxy
diff options
context:
space:
mode:
authoravi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-30 18:51:16 +0000
committeravi@google.com <avi@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-10-30 18:51:16 +0000
commit21a52557fc2373e7c3f525072384bb97f7978012 (patch)
tree84539a3aba112abf72b88c644b791c23cdfefe93 /net/proxy
parent074ff16d3029256a9585529cad5487c1ae6eb409 (diff)
downloadchromium_src-21a52557fc2373e7c3f525072384bb97f7978012.zip
chromium_src-21a52557fc2373e7c3f525072384bb97f7978012.tar.gz
chromium_src-21a52557fc2373e7c3f525072384bb97f7978012.tar.bz2
oops; will reland once tree is open
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4223 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/proxy')
-rw-r--r--net/proxy/proxy_resolver_mac.cc342
-rw-r--r--net/proxy/proxy_resolver_mac.h25
-rw-r--r--net/proxy/proxy_resolver_winhttp.cc15
-rw-r--r--net/proxy/proxy_service.cc29
-rw-r--r--net/proxy/proxy_service.h12
-rw-r--r--net/proxy/proxy_service_unittest.cc23
6 files changed, 22 insertions, 424 deletions
diff --git a/net/proxy/proxy_resolver_mac.cc b/net/proxy/proxy_resolver_mac.cc
deleted file mode 100644
index 0bf52b91..0000000
--- a/net/proxy/proxy_resolver_mac.cc
+++ /dev/null
@@ -1,342 +0,0 @@
-// Copyright (c) 2008 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_resolver_mac.h"
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <CoreServices/CoreServices.h>
-#include <SystemConfiguration/SystemConfiguration.h>
-
-#include "base/scoped_cftyperef.h"
-#include "base/string_util.h"
-#include "base/sys_string_conversions.h"
-#include "net/base/net_errors.h"
-
-namespace {
-
-// Utility function to pull out a value from a dictionary, check its type, and
-// return it. Returns NULL if the key is not present or of the wrong type.
-CFTypeRef GetValueFromDictionary(CFDictionaryRef dict,
- CFStringRef key,
- CFTypeID expected_type) {
- CFTypeRef value = CFDictionaryGetValue(dict, key);
- if (!value)
- return value;
-
- if (CFGetTypeID(value) != expected_type) {
- scoped_cftyperef<CFStringRef> expected_type_ref(
- CFCopyTypeIDDescription(expected_type));
- scoped_cftyperef<CFStringRef> actual_type_ref(
- CFCopyTypeIDDescription(CFGetTypeID(value)));
- LOG(WARNING) << "Expected value for key "
- << base::SysCFStringRefToUTF8(key)
- << " to be "
- << base::SysCFStringRefToUTF8(expected_type_ref)
- << " but it was "
- << base::SysCFStringRefToUTF8(actual_type_ref)
- << " instead";
- return NULL;
- }
-
- return value;
-}
-
-// Utility function to pull out a boolean value from a dictionary and return it,
-// returning a default value if the key is not present.
-bool GetBoolFromDictionary(CFDictionaryRef dict,
- CFStringRef key,
- bool default_value) {
- CFNumberRef number = (CFNumberRef)GetValueFromDictionary(dict, key,
- CFNumberGetTypeID());
- if (!number)
- return default_value;
-
- int int_value;
- if (CFNumberGetValue(number, kCFNumberIntType, &int_value))
- return int_value;
- else
- return default_value;
-}
-
-// Utility function to pull out a host/port pair from a dictionary and format
-// them into a "<host>[:<port>]" style string. Pass in a dictionary that has a
-// value for the host key and optionally a value for the port key. Returns a
-// formatted string. In the error condition where the host value is especially
-// malformed, returns an empty string. (You may still want to check for that
-// result anyway.)
-std::string GetHostPortFromDictionary(CFDictionaryRef dict,
- CFStringRef host_key,
- CFStringRef port_key) {
- std::string result;
-
- CFStringRef host_ref =
- (CFStringRef)GetValueFromDictionary(dict, host_key,
- CFStringGetTypeID());
- if (!host_ref) {
- LOG(WARNING) << "Could not find expected key "
- << base::SysCFStringRefToUTF8(host_key)
- << " in the proxy dictionary";
- return result;
- }
- result = base::SysCFStringRefToUTF8(host_ref);
-
- CFNumberRef port_ref =
- (CFNumberRef)GetValueFromDictionary(dict, port_key,
- CFNumberGetTypeID());
- if (port_ref) {
- int port;
- CFNumberGetValue(port_ref, kCFNumberIntType, &port);
- result += ":";
- result += IntToString(port);
- }
-
- return result;
-}
-
-// Callback for CFNetworkExecuteProxyAutoConfigurationURL. |client| is a pointer
-// to a CFTypeRef. This stashes either |error| or |proxies| in that location.
-void ResultCallback(void* client, CFArrayRef proxies, CFErrorRef error) {
- DCHECK((proxies != NULL) == (error == NULL));
-
- CFTypeRef* result_ptr = (CFTypeRef*)client;
- DCHECK(result_ptr != NULL);
- DCHECK(*result_ptr == NULL);
-
- if (error != NULL) {
- *result_ptr = CFRetain(error);
- } else {
- *result_ptr = CFRetain(proxies);
- }
- CFRunLoopStop(CFRunLoopGetCurrent());
-}
-
-} // namespace
-
-namespace net {
-
-int ProxyResolverMac::GetProxyConfig(ProxyConfig* config) {
- scoped_cftyperef<CFDictionaryRef> config_dict(
- SCDynamicStoreCopyProxies(NULL));
- DCHECK(config_dict);
-
- // auto-detect
-
- // There appears to be no UI for this configuration option, and we're not sure
- // if Apple's proxy code even takes it into account. But the constant is in
- // the header file so we'll use it.
- config->auto_detect =
- GetBoolFromDictionary(config_dict.get(),
- kSCPropNetProxiesProxyAutoDiscoveryEnable,
- false);
-
- // PAC file
-
- if (GetBoolFromDictionary(config_dict.get(),
- kSCPropNetProxiesProxyAutoConfigEnable,
- false)) {
- CFStringRef pac_url_ref =
- (CFStringRef)GetValueFromDictionary(
- config_dict.get(),
- kSCPropNetProxiesProxyAutoConfigURLString,
- CFStringGetTypeID());
- if (pac_url_ref)
- config->pac_url = base::SysCFStringRefToUTF8(pac_url_ref);
- }
-
- // proxies (for now only ftp, http and https)
-
- if (GetBoolFromDictionary(config_dict.get(),
- kSCPropNetProxiesFTPEnable,
- false)) {
- std::string host_port =
- GetHostPortFromDictionary(config_dict.get(),
- kSCPropNetProxiesFTPProxy,
- kSCPropNetProxiesFTPPort);
- if (!host_port.empty()) {
- config->proxy_server += "ftp=";
- config->proxy_server += host_port;
- }
- }
- if (GetBoolFromDictionary(config_dict.get(),
- kSCPropNetProxiesHTTPEnable,
- false)) {
- std::string host_port =
- GetHostPortFromDictionary(config_dict.get(),
- kSCPropNetProxiesHTTPProxy,
- kSCPropNetProxiesHTTPPort);
- if (!host_port.empty()) {
- if (!config->proxy_server.empty())
- config->proxy_server += ";";
- config->proxy_server += "http=";
- config->proxy_server += host_port;
- }
- }
- if (GetBoolFromDictionary(config_dict.get(),
- kSCPropNetProxiesHTTPSEnable,
- false)) {
- std::string host_port =
- GetHostPortFromDictionary(config_dict.get(),
- kSCPropNetProxiesHTTPSProxy,
- kSCPropNetProxiesHTTPSPort);
- if (!host_port.empty()) {
- if (!config->proxy_server.empty())
- config->proxy_server += ";";
- config->proxy_server += "https=";
- config->proxy_server += host_port;
- }
- }
-
- // proxy bypass list
-
- CFArrayRef bypass_array_ref =
- (CFArrayRef)GetValueFromDictionary(config_dict.get(),
- kSCPropNetProxiesExceptionsList,
- CFArrayGetTypeID());
- if (bypass_array_ref) {
- CFIndex bypass_array_count = CFArrayGetCount(bypass_array_ref);
- for (CFIndex i = 0; i < bypass_array_count; ++i) {
- CFStringRef bypass_item_ref =
- (CFStringRef)CFArrayGetValueAtIndex(bypass_array_ref, i);
- if (CFGetTypeID(bypass_item_ref) != CFStringGetTypeID()) {
- LOG(WARNING) << "Expected value for item " << i
- << " in the kSCPropNetProxiesExceptionsList"
- " to be a CFStringRef but it was not";
-
- } else {
- config->proxy_bypass.push_back(
- base::SysCFStringRefToUTF8(bypass_item_ref));
- }
- }
- }
-
- // proxy bypass boolean
-
- config->proxy_bypass_local_names =
- GetBoolFromDictionary(config_dict.get(),
- kSCPropNetProxiesExcludeSimpleHostnames,
- false);
-
- return OK;
-}
-
-// Gets the proxy information for a query URL from a PAC. Implementation
-// inspired by http://developer.apple.com/samplecode/CFProxySupportTool/
-int ProxyResolverMac::GetProxyForURL(const std::string& query_url,
- const std::string& pac_url,
- ProxyInfo* results) {
- scoped_cftyperef<CFStringRef> query_ref(
- base::SysUTF8ToCFStringRef(query_url));
- scoped_cftyperef<CFStringRef> pac_ref(
- base::SysUTF8ToCFStringRef(pac_url));
- scoped_cftyperef<CFURLRef> query_url_ref(
- CFURLCreateWithString(kCFAllocatorDefault,
- query_ref.get(),
- NULL));
- scoped_cftyperef<CFURLRef> pac_url_ref(
- CFURLCreateWithString(kCFAllocatorDefault,
- pac_ref.get(),
- NULL));
-
- // Work around <rdar://problem/5530166>. This dummy call to
- // CFNetworkCopyProxiesForURL initializes some state within CFNetwork that is
- // required by CFNetworkExecuteProxyAutoConfigurationURL.
-
- CFArrayRef dummy_result = CFNetworkCopyProxiesForURL(query_url_ref.get(),
- NULL);
- if (dummy_result)
- CFRelease(dummy_result);
-
- // We cheat here. We need to act as if we were synchronous, so we pump the
- // runloop ourselves. Our caller moved us to a new thread anyway, so this is
- // OK to do. (BTW, CFNetworkExecuteProxyAutoConfigurationURL returns a
- // runloop source we need to release despite its name.)
-
- CFTypeRef result;
- CFStreamClientContext context = { 0, &result, NULL, NULL, NULL };
- scoped_cftyperef<CFRunLoopSourceRef> runloop_source(
- CFNetworkExecuteProxyAutoConfigurationURL(pac_url_ref.get(),
- query_url_ref.get(),
- ResultCallback,
- &context));
- if (!runloop_source)
- return ERR_FAILED;
-
- const CFStringRef private_runloop_mode =
- CFSTR("org.chromium.ProxyResolverMac");
-
- CFRunLoopAddSource(CFRunLoopGetCurrent(), runloop_source.get(),
- private_runloop_mode);
- CFRunLoopRunInMode(private_runloop_mode, DBL_MAX, false);
- CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runloop_source.get(),
- private_runloop_mode);
- DCHECK(result != NULL);
-
- if (CFGetTypeID(result) == CFErrorGetTypeID()) {
- // TODO(avi): do something better than this
- CFRelease(result);
- return ERR_FAILED;
- }
- DCHECK(CFGetTypeID(result) == CFArrayGetTypeID());
- scoped_cftyperef<CFArrayRef> proxy_array_ref((CFArrayRef)result);
-
- // Proxy information. If we're allowed to contact the site directly, we set
- // allow_direct to true. If we've found proxies to use, apart from
- // accumulating them in proxy_list, we set found_proxy to true. These
- // bool results are orthogonal.
- bool allow_direct = false;
- std::string proxy_list;
- bool found_proxy = false;
-
- CFIndex proxy_array_count = CFArrayGetCount(proxy_array_ref.get());
- for (CFIndex i = 0; i < proxy_array_count; ++i) {
- CFDictionaryRef proxy_dictionary =
- (CFDictionaryRef)CFArrayGetValueAtIndex(proxy_array_ref.get(), i);
- DCHECK(CFGetTypeID(proxy_dictionary) == CFDictionaryGetTypeID());
-
- // The dictionary may have the following keys:
- // - kCFProxyTypeKey : The type of the proxy. We're assuming that it's of
- // the type we asked for (e.g. kCFProxyTypeHTTP for
- // http://... ) if it's not kCFProxyTypeNone.
- // - kCFProxyHostNameKey
- // - kCFProxyPortNumberKey : The meat we're after.
- // - kCFProxyUsernameKey
- // - kCFProxyPasswordKey : Despite the existence of these keys in the
- // documentation, they're never populated. Even if a
- // username/password were to be set in the network
- // proxy system preferences, we'd need to fetch it
- // from the Keychain ourselves. CFProxy is such a
- // tease.
- // - kCFProxyAutoConfigurationURLKey : If the PAC file specifies another
- // PAC file, I'm going home.
-
- CFStringRef proxy_type =
- (CFStringRef)GetValueFromDictionary(proxy_dictionary,
- kCFProxyTypeKey,
- CFStringGetTypeID());
- if (CFEqual(proxy_type, kCFProxyTypeNone))
- allow_direct = true;
- if (CFEqual(proxy_type, kCFProxyTypeNone) ||
- CFEqual(proxy_type, kCFProxyTypeSOCKS) ||
- CFEqual(proxy_type, kCFProxyTypeAutoConfigurationURL))
- continue;
-
- if (found_proxy)
- proxy_list += ";";
- else
- found_proxy = true;
-
- proxy_list += GetHostPortFromDictionary(proxy_dictionary,
- kCFProxyHostNameKey,
- kCFProxyPortNumberKey);
- }
-
- if (found_proxy)
- results->UseNamedProxy(proxy_list);
- if (allow_direct)
- results->UseDirect();
-
- return OK;
-}
-
-} // namespace net
diff --git a/net/proxy/proxy_resolver_mac.h b/net/proxy/proxy_resolver_mac.h
deleted file mode 100644
index 3063866..0000000
--- a/net/proxy/proxy_resolver_mac.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2008 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_RESOLVER_MAC_H_
-#define NET_PROXY_PROXY_RESOLVER_MAC_H_
-
-#include "net/proxy/proxy_service.h"
-
-namespace net {
-
-// Implementation of ProxyResolver that uses the Mac CFProxySupport to implement
-// proxies.
-class ProxyResolverMac : public ProxyResolver {
- public:
- // ProxyResolver methods:
- virtual int GetProxyConfig(ProxyConfig* config);
- virtual int GetProxyForURL(const std::string& query_url,
- const std::string& pac_url,
- ProxyInfo* results);
-};
-
-} // namespace net
-
-#endif // NET_PROXY_PROXY_RESOLVER_MAC_H_
diff --git a/net/proxy/proxy_resolver_winhttp.cc b/net/proxy/proxy_resolver_winhttp.cc
index 19dd0b0..5a16df5 100644
--- a/net/proxy/proxy_resolver_winhttp.cc
+++ b/net/proxy/proxy_resolver_winhttp.cc
@@ -8,7 +8,6 @@
#include <winhttp.h>
#include "base/histogram.h"
-#include "base/string_tokenizer.h"
#include "net/base/net_errors.h"
#pragma comment(lib, "winhttp.lib")
@@ -71,18 +70,8 @@ int ProxyResolverWinHttp::GetProxyConfig(ProxyConfig* config) {
config->auto_detect = true;
if (ie_config.lpszProxy)
config->proxy_server = WideToASCII(ie_config.lpszProxy);
- if (ie_config.lpszProxyBypass) {
- std::string proxy_bypass = WideToASCII(ie_config.lpszProxyBypass);
-
- 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);
- }
- }
+ if (ie_config.lpszProxyBypass)
+ config->proxy_bypass = WideToASCII(ie_config.lpszProxyBypass);
if (ie_config.lpszAutoConfigUrl)
config->pac_url = WideToASCII(ie_config.lpszAutoConfigUrl);
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
index 394a97f..52d8491 100644
--- a/net/proxy/proxy_service.cc
+++ b/net/proxy/proxy_service.cc
@@ -30,7 +30,6 @@ ProxyConfig::ID ProxyConfig::last_id_ = ProxyConfig::INVALID_ID;
ProxyConfig::ProxyConfig()
: auto_detect(false),
- proxy_bypass_local_names(false),
id_(++last_id_) {
}
@@ -40,8 +39,7 @@ bool ProxyConfig::Equals(const ProxyConfig& other) const {
return auto_detect == other.auto_detect &&
pac_url == other.pac_url &&
proxy_server == other.proxy_server &&
- proxy_bypass == other.proxy_bypass &&
- proxy_bypass_local_names == other.proxy_bypass_local_names;
+ proxy_bypass == other.proxy_bypass;
}
// ProxyList ------------------------------------------------------------------
@@ -447,18 +445,17 @@ bool ProxyService::ShouldBypassProxyForURL(const GURL& url) {
url_domain += "://";
url_domain += url.host();
- // This isn't superfluous; GURL case canonicalization doesn't hit the embedded
- // percent-encoded characters.
StringToLowerASCII(&url_domain);
- if (config_.proxy_bypass_local_names) {
- if (url.host().find('.') == std::string::npos)
- 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;
+ StringTokenizer proxy_server_bypass_list(config_.proxy_bypass, ";");
+ while (proxy_server_bypass_list.GetNext()) {
+ std::string bypass_url_domain = proxy_server_bypass_list.token();
+ if (bypass_url_domain == "<local>") {
+ // Any name without a DOT (.) is considered to be local.
+ if (url.host().find('.') == std::string::npos)
+ return true;
+ continue;
+ }
// The proxy server bypass list can contain entities with http/https
// If no scheme is specified then it indicates that all schemes are
@@ -476,12 +473,6 @@ bool ProxyService::ShouldBypassProxyForURL(const GURL& url) {
if (MatchPattern(url_domain, 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
}
return false;
diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h
index 8ea3653..c596aab 100644
--- a/net/proxy/proxy_service.h
+++ b/net/proxy/proxy_service.h
@@ -47,16 +47,12 @@ class ProxyConfig {
std::string pac_url;
// If non-empty, indicates the proxy server to use (of the form host:port).
- // If proxies depend on the scheme, a string of the format
- // "scheme1=url[:port];scheme2=url[:port]" may be provided here.
std::string proxy_server;
- // Indicates a list of hosts that should bypass any proxy configuration. For
- // these hosts, a direct connection should always be used.
- std::vector<std::string> proxy_bypass;
-
- // Indicates whether local names (no dots) bypass proxies.
- bool proxy_bypass_local_names;
+ // If non-empty, indicates a comma-delimited list of hosts that should bypass
+ // any proxy configuration. For these hosts, a direct connection should
+ // always be used.
+ std::string proxy_bypass;
// Returns true if the given config is equivalent to this config.
bool Equals(const ProxyConfig& other) const;
diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc
index 8166a42..d33ac6d 100644
--- a/net/proxy/proxy_service_unittest.cc
+++ b/net/proxy/proxy_service_unittest.cc
@@ -301,7 +301,7 @@ TEST(ProxyServiceTest, ProxyBypassList) {
MockProxyResolver resolver;
resolver.config->proxy_server = "foopy1:8080;foopy2:9090";
resolver.config->auto_detect = false;
- resolver.config->proxy_bypass_local_names = true;
+ resolver.config->proxy_bypass = "<local>";
net::ProxyService service(&resolver);
GURL url("http://www.google.com/");
@@ -318,9 +318,7 @@ TEST(ProxyServiceTest, ProxyBypassList) {
EXPECT_EQ(rv, net::OK);
EXPECT_TRUE(info1.is_direct());
- resolver.config->proxy_bypass.clear();
- resolver.config->proxy_bypass.push_back("*.org");
- resolver.config->proxy_bypass_local_names = true;
+ resolver.config->proxy_bypass = "<local>;*.org";
net::ProxyService service2(&resolver);
GURL test_url2("http://www.webkit.org");
net::ProxyInfo info2;
@@ -328,10 +326,7 @@ TEST(ProxyServiceTest, ProxyBypassList) {
EXPECT_EQ(rv, net::OK);
EXPECT_TRUE(info2.is_direct());
- resolver.config->proxy_bypass.clear();
- resolver.config->proxy_bypass.push_back("*.org");
- resolver.config->proxy_bypass.push_back("7*");
- resolver.config->proxy_bypass_local_names = true;
+ resolver.config->proxy_bypass = "<local>;*.org;7*";
net::ProxyService service3(&resolver);
GURL test_url3("http://74.125.19.147");
net::ProxyInfo info3;
@@ -339,9 +334,7 @@ TEST(ProxyServiceTest, ProxyBypassList) {
EXPECT_EQ(rv, net::OK);
EXPECT_TRUE(info3.is_direct());
- resolver.config->proxy_bypass.clear();
- resolver.config->proxy_bypass.push_back("*.org");
- resolver.config->proxy_bypass_local_names = true;
+ resolver.config->proxy_bypass = "<local>;*.org;";
net::ProxyService service4(&resolver);
GURL test_url4("http://www.msn.com");
net::ProxyInfo info4;
@@ -349,9 +342,7 @@ TEST(ProxyServiceTest, ProxyBypassList) {
EXPECT_EQ(rv, net::OK);
EXPECT_FALSE(info4.is_direct());
- resolver.config->proxy_bypass.clear();
- resolver.config->proxy_bypass.push_back("*.MSN.COM");
- resolver.config->proxy_bypass_local_names = true;
+ resolver.config->proxy_bypass = "<local>;*.MSN.COM;";
net::ProxyService service5(&resolver);
GURL test_url5("http://www.msnbc.msn.com");
net::ProxyInfo info5;
@@ -359,9 +350,7 @@ TEST(ProxyServiceTest, ProxyBypassList) {
EXPECT_EQ(rv, net::OK);
EXPECT_TRUE(info5.is_direct());
- resolver.config->proxy_bypass.clear();
- resolver.config->proxy_bypass.push_back("*.msn.com");
- resolver.config->proxy_bypass_local_names = true;
+ resolver.config->proxy_bypass = "<local>;*.msn.com;";
net::ProxyService service6(&resolver);
GURL test_url6("HTTP://WWW.MSNBC.MSN.COM");
net::ProxyInfo info6;