summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-02 22:37:18 +0000
committerericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-02 22:37:18 +0000
commit7dc52f27b89ea2ab8b82a127fc899efef70fc613 (patch)
tree7ff99224862492b729312a8847f432ea661d635e
parentc8bab10c787854885375ac3c4d98c0d8b51a94c9 (diff)
downloadchromium_src-7dc52f27b89ea2ab8b82a127fc899efef70fc613.zip
chromium_src-7dc52f27b89ea2ab8b82a127fc899efef70fc613.tar.gz
chromium_src-7dc52f27b89ea2ab8b82a127fc899efef70fc613.tar.bz2
split up proxy_service into several files (one per class).
Review URL: http://codereview.chromium.org/28278 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10739 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--net/build/net.vcproj36
-rw-r--r--net/build/net_unittests.vcproj4
-rw-r--r--net/net.gyp10
-rw-r--r--net/net_lib.scons9
-rw-r--r--net/net_unittests.scons1
-rw-r--r--net/proxy/proxy_config.cc29
-rw-r--r--net/proxy/proxy_config.h70
-rw-r--r--net/proxy/proxy_config_service.h27
-rw-r--r--net/proxy/proxy_config_service_fixed.h2
-rw-r--r--net/proxy/proxy_config_service_win.cc3
-rw-r--r--net/proxy/proxy_config_service_win.h2
-rw-r--r--net/proxy/proxy_info.cc31
-rw-r--r--net/proxy/proxy_info.h86
-rw-r--r--net/proxy/proxy_list.cc118
-rw-r--r--net/proxy/proxy_list.h59
-rw-r--r--net/proxy/proxy_list_unittest.cc73
-rw-r--r--net/proxy/proxy_resolver.h54
-rw-r--r--net/proxy/proxy_resolver_mac.cc3
-rw-r--r--net/proxy/proxy_resolver_mac.h3
-rw-r--r--net/proxy/proxy_resolver_v8.cc3
-rw-r--r--net/proxy/proxy_resolver_v8.h2
-rw-r--r--net/proxy/proxy_resolver_v8_unittest.cc5
-rw-r--r--net/proxy/proxy_resolver_winhttp.cc3
-rw-r--r--net/proxy/proxy_resolver_winhttp.h4
-rw-r--r--net/proxy/proxy_retry_info.h31
-rw-r--r--net/proxy/proxy_service.cc160
-rw-r--r--net/proxy/proxy_service.h236
-rw-r--r--net/proxy/proxy_service_unittest.cc69
28 files changed, 677 insertions, 456 deletions
diff --git a/net/build/net.vcproj b/net/build/net.vcproj
index a24ebda..ffe5699 100644
--- a/net/build/net.vcproj
+++ b/net/build/net.vcproj
@@ -1010,6 +1010,18 @@
Name="proxy"
>
<File
+ RelativePath="..\proxy\proxy_config.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\proxy\proxy_config.h"
+ >
+ </File>
+ <File
+ RelativePath="..\proxy\proxy_config_service.h"
+ >
+ </File>
+ <File
RelativePath="..\proxy\proxy_config_service_fixed.h"
>
</File>
@@ -1022,6 +1034,26 @@
>
</File>
<File
+ RelativePath="..\proxy\proxy_info.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\proxy\proxy_info.h"
+ >
+ </File>
+ <File
+ RelativePath="..\proxy\proxy_list.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\proxy\proxy_list.h"
+ >
+ </File>
+ <File
+ RelativePath="..\proxy\proxy_resolver.h"
+ >
+ </File>
+ <File
RelativePath="..\proxy\proxy_resolver_v8.cc"
>
</File>
@@ -1042,6 +1074,10 @@
>
</File>
<File
+ RelativePath="..\proxy\proxy_retry_info.h"
+ >
+ </File>
+ <File
RelativePath="..\proxy\proxy_script_fetcher.cc"
>
</File>
diff --git a/net/build/net_unittests.vcproj b/net/build/net_unittests.vcproj
index 36624d7..6c79cb3 100644
--- a/net/build/net_unittests.vcproj
+++ b/net/build/net_unittests.vcproj
@@ -419,6 +419,10 @@
Name="proxy"
>
<File
+ RelativePath="..\proxy\proxy_list_unittest.cc"
+ >
+ </File>
+ <File
RelativePath="..\proxy\proxy_script_fetcher_unittest.cc"
>
</File>
diff --git a/net/net.gyp b/net/net.gyp
index e1c73d4..fc2ad65 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -228,15 +228,24 @@
'http/http_vary_data.h',
'http/md4.cc',
'http/md4.h',
+ 'proxy/proxy_config.cc',
+ 'proxy/proxy_config.h',
+ 'proxy/proxy_config_service.h',
'proxy/proxy_config_service_fixed.h',
'proxy/proxy_config_service_win.cc',
'proxy/proxy_config_service_win.h',
+ 'proxy/proxy_info.cc',
+ 'proxy/proxy_info.h',
+ 'proxy/proxy_list.cc',
+ 'proxy/proxy_list.h',
+ 'proxy/proxy_resolver.h',
'proxy/proxy_resolver_mac.cc',
'proxy/proxy_resolver_script.h',
'proxy/proxy_resolver_v8.cc',
'proxy/proxy_resolver_v8.h',
'proxy/proxy_resolver_winhttp.cc',
'proxy/proxy_resolver_winhttp.h',
+ 'proxy/proxy_retry_info.h',
'proxy/proxy_script_fetcher.cc',
'proxy/proxy_script_fetcher.h',
'proxy/proxy_server.cc',
@@ -423,6 +432,7 @@
'http/http_transaction_unittest.h',
'http/http_util_unittest.cc',
'http/http_vary_data_unittest.cc',
+ 'proxy/proxy_list_unittest.cc',
'proxy/proxy_resolver_v8_unittest.cc',
'proxy/proxy_script_fetcher_unittest.cc',
'proxy/proxy_server_unittest.cc',
diff --git a/net/net_lib.scons b/net/net_lib.scons
index 6a06759..669928a 100644
--- a/net/net_lib.scons
+++ b/net/net_lib.scons
@@ -244,11 +244,20 @@ input_files = ChromeFileList([
'disk_cache/trace.h',
]),
MSVSFilter('proxy', [
+ 'proxy/proxy_config.cc',
+ 'proxy/proxy_config.h',
+ 'proxy/proxy_config_service.h',
'proxy/proxy_config_service_fixed.h',
'proxy/proxy_config_service_win.cc',
'proxy/proxy_config_service_win.h',
+ 'proxy/proxy_info.cc',
+ 'proxy/proxy_info.h',
+ 'proxy/proxy_list.cc',
+ 'proxy/proxy_list.h',
+ 'proxy/proxy_resolver.h',
'proxy/proxy_resolver_winhttp.cc',
'proxy/proxy_resolver_winhttp.h',
+ 'proxy/proxy_retry_info.h',
'proxy/proxy_script_fetcher.cc',
'proxy/proxy_script_fetcher.h',
'proxy/proxy_server.cc',
diff --git a/net/net_unittests.scons b/net/net_unittests.scons
index ce469f9..e2beaac 100644
--- a/net/net_unittests.scons
+++ b/net/net_unittests.scons
@@ -110,6 +110,7 @@ input_files = ChromeFileList([
'url_request/url_request_unittest.h',
]),
MSVSFilter('proxy', [
+ 'proxy/proxy_list_unittest.cc',
'proxy/proxy_script_fetcher_unittest.cc',
'proxy/proxy_server_unittest.cc',
'proxy/proxy_service_unittest.cc',
diff --git a/net/proxy/proxy_config.cc b/net/proxy/proxy_config.cc
new file mode 100644
index 0000000..b30cb9e
--- /dev/null
+++ b/net/proxy/proxy_config.cc
@@ -0,0 +1,29 @@
+// Copyright (c) 2006-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_config.h"
+
+namespace net {
+
+// static
+ProxyConfig::ID ProxyConfig::last_id_ = ProxyConfig::INVALID_ID;
+
+ProxyConfig::ProxyConfig()
+ : auto_detect(false),
+ proxy_bypass_local_names(false),
+ id_(++last_id_) {
+}
+
+bool ProxyConfig::Equals(const ProxyConfig& other) const {
+ // The two configs can have different IDs. We are just interested in if they
+ // have the same settings.
+ 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;
+}
+
+} // namespace net
+
diff --git a/net/proxy/proxy_config.h b/net/proxy/proxy_config.h
new file mode 100644
index 0000000..53fdcb2
--- /dev/null
+++ b/net/proxy/proxy_config.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2006-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_CONFIG_H_
+#define NET_PROXY_PROXY_CONFIG_H_
+
+#include <string>
+#include <vector>
+
+#include "googleurl/src/gurl.h"
+
+namespace net {
+
+// Proxy configuration used to by the ProxyService.
+class ProxyConfig {
+ public:
+ typedef int ID;
+
+ // Indicates an invalid proxy config.
+ enum { INVALID_ID = 0 };
+
+ ProxyConfig();
+ // Default copy-constructor and assignment operator are OK!
+
+ // Used to numerically identify this configuration.
+ ID id() const { return id_; }
+
+ // True if the proxy configuration should be auto-detected.
+ bool auto_detect;
+
+ // If non-empty, indicates the URL of the proxy auto-config file to use.
+ GURL pac_url;
+
+ // If non-empty, indicates the proxy server to use, given by:
+ //
+ // proxy-uri = [<proxy-scheme>://]<proxy-host>[:"<proxy-port>]
+ //
+ // If the proxy to use depends on the scheme of the URL, can instead specify
+ // a semicolon separated list of:
+ //
+ // <url-scheme>"="<proxy-uri>
+ //
+ // For example:
+ // "http=foopy:80;ftp=foopy2" -- use HTTP proxy "foopy:80" for http URLs,
+ // and HTTP proxy "foopy2:80" for ftp URLs.
+ // "foopy:80" -- use HTTP proxy "foopy:80" for all URLs.
+ // "socks4://foopy" -- use SOCKS v4 proxy "foopy:1080" for all
+ // URLs.
+ std::string proxy_rules;
+
+ // 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;
+
+ // Returns true if the given config is equivalent to this config.
+ bool Equals(const ProxyConfig& other) const;
+
+ private:
+ static int last_id_;
+ int id_;
+};
+
+} // namespace net
+
+#endif // NET_PROXY_PROXY_CONFIG_H_
+
diff --git a/net/proxy/proxy_config_service.h b/net/proxy/proxy_config_service.h
new file mode 100644
index 0000000..4a802c9
--- /dev/null
+++ b/net/proxy/proxy_config_service.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2006-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_CONFIG_SERVICE_H_
+#define NET_PROXY_PROXY_CONFIG_SERVICE_H_
+
+namespace net {
+
+class ProxyConfig;
+
+// Synchronously fetch the system's proxy configuration settings. Called on
+// the IO Thread.
+class ProxyConfigService {
+ public:
+ virtual ~ProxyConfigService() {}
+
+ // Get the proxy configuration. Returns OK if successful or an error code if
+ // otherwise. |config| should be in its initial state when this method is
+ // called.
+ virtual int GetProxyConfig(ProxyConfig* config) = 0;
+};
+
+} // namespace net
+
+#endif // NET_PROXY_PROXY_CONFIG_SERVICE_H_
+
diff --git a/net/proxy/proxy_config_service_fixed.h b/net/proxy/proxy_config_service_fixed.h
index ea0d8a1..5120093 100644
--- a/net/proxy/proxy_config_service_fixed.h
+++ b/net/proxy/proxy_config_service_fixed.h
@@ -5,7 +5,7 @@
#ifndef NET_PROXY_PROXY_CONFIG_SERVICE_FIXED_H_
#define NET_PROXY_PROXY_CONFIG_SERVICE_FIXED_H_
-#include "net/proxy/proxy_service.h"
+#include "net/proxy/proxy_config_service.h"
namespace net {
diff --git a/net/proxy/proxy_config_service_win.cc b/net/proxy/proxy_config_service_win.cc
index 9779928..e3dc95e 100644
--- a/net/proxy/proxy_config_service_win.cc
+++ b/net/proxy/proxy_config_service_win.cc
@@ -7,8 +7,11 @@
#include <windows.h>
#include <winhttp.h>
+#include "base/logging.h"
#include "base/string_tokenizer.h"
+#include "base/string_util.h"
#include "net/base/net_errors.h"
+#include "net/proxy/proxy_config.h"
#pragma comment(lib, "winhttp.lib")
diff --git a/net/proxy/proxy_config_service_win.h b/net/proxy/proxy_config_service_win.h
index f2a5e47..f9f0366 100644
--- a/net/proxy/proxy_config_service_win.h
+++ b/net/proxy/proxy_config_service_win.h
@@ -5,7 +5,7 @@
#ifndef NET_PROXY_PROXY_CONFIG_SERVICE_WIN_H_
#define NET_PROXY_PROXY_CONFIG_SERVICE_WIN_H_
-#include "net/proxy/proxy_service.h"
+#include "net/proxy/proxy_config_service.h"
namespace net {
diff --git a/net/proxy/proxy_info.cc b/net/proxy/proxy_info.cc
new file mode 100644
index 0000000..c1ef588
--- /dev/null
+++ b/net/proxy/proxy_info.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2006-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_info.h"
+
+namespace net {
+
+ProxyInfo::ProxyInfo()
+ : config_id_(ProxyConfig::INVALID_ID),
+ config_was_tried_(false) {
+}
+
+void ProxyInfo::Use(const ProxyInfo& other) {
+ proxy_list_ = other.proxy_list_;
+}
+
+void ProxyInfo::UseDirect() {
+ proxy_list_.Set(std::string());
+}
+
+void ProxyInfo::UseNamedProxy(const std::string& proxy_uri_list) {
+ proxy_list_.Set(proxy_uri_list);
+}
+
+std::string ProxyInfo::ToPacString() {
+ return proxy_list_.ToPacString();
+}
+
+} // namespace net
+
diff --git a/net/proxy/proxy_info.h b/net/proxy/proxy_info.h
new file mode 100644
index 0000000..e66f9ec
--- /dev/null
+++ b/net/proxy/proxy_info.h
@@ -0,0 +1,86 @@
+// Copyright (c) 2006-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_INFO_H_
+#define NET_PROXY_PROXY_INFO_H_
+
+#include <string>
+
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_list.h"
+#include "net/proxy/proxy_retry_info.h"
+#include "net/proxy/proxy_server.h"
+
+class GURL;
+
+namespace net {
+
+// This object holds proxy information returned by ResolveProxy.
+class ProxyInfo {
+ public:
+ ProxyInfo();
+ // Default copy-constructor and assignment operator are OK!
+
+ // Use the same proxy server as the given |proxy_info|.
+ void Use(const ProxyInfo& proxy_info);
+
+ // Use a direct connection.
+ void UseDirect();
+
+ // Use a specific proxy server, of the form:
+ // proxy-uri = [<scheme> "://"] <hostname> [":" <port>]
+ // This may optionally be a semi-colon delimited list of <proxy-uri>.
+ // It is OK to have LWS between entries.
+ void UseNamedProxy(const std::string& proxy_uri_list);
+
+ // Parse from the given PAC result.
+ void UsePacString(const std::string& pac_string) {
+ proxy_list_.SetFromPacString(pac_string);
+ }
+
+ // Returns true if this proxy info specifies a direct connection.
+ bool is_direct() const { return proxy_list_.Get().is_direct(); }
+
+ // Returns the first valid proxy server.
+ ProxyServer proxy_server() const { return proxy_list_.Get(); }
+
+ // See description in ProxyList::ToPacString().
+ std::string ToPacString();
+
+ // Marks the current proxy as bad. Returns true if there is another proxy
+ // available to try in proxy list_.
+ bool Fallback(ProxyRetryInfoMap* proxy_retry_info) {
+ return proxy_list_.Fallback(proxy_retry_info);
+ }
+
+ // Remove all proxies known to be bad from the proxy list.
+ void RemoveBadProxies(const ProxyRetryInfoMap& proxy_retry_info) {
+ proxy_list_.RemoveBadProxies(proxy_retry_info);
+ }
+
+ // Delete any entry which doesn't have one of the specified proxy schemes.
+ void RemoveProxiesWithoutScheme(int scheme_bit_field) {
+ proxy_list_.RemoveProxiesWithoutScheme(scheme_bit_field);
+ }
+
+ private:
+ friend class ProxyService;
+
+ // If proxy_list_ is set to empty, then a "direct" connection is indicated.
+ ProxyList proxy_list_;
+
+ // This value identifies the proxy config used to initialize this object.
+ ProxyConfig::ID config_id_;
+
+ // This flag is false when the proxy configuration was known to be bad when
+ // this proxy info was initialized. In such cases, we know that if this
+ // proxy info does not yield a connection that we might want to reconsider
+ // the proxy config given by config_id_.
+ bool config_was_tried_;
+};
+
+} // namespace net
+
+#endif // NET_PROXY_PROXY_INFO_H_
+
diff --git a/net/proxy/proxy_list.cc b/net/proxy/proxy_list.cc
new file mode 100644
index 0000000..2313896
--- /dev/null
+++ b/net/proxy/proxy_list.cc
@@ -0,0 +1,118 @@
+// Copyright (c) 2006-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_list.h"
+
+#include "base/logging.h"
+#include "base/string_tokenizer.h"
+#include "base/time.h"
+
+using base::TimeDelta;
+using base::TimeTicks;
+
+namespace net {
+
+void ProxyList::Set(const std::string& proxy_uri_list) {
+ proxies_.clear();
+ StringTokenizer str_tok(proxy_uri_list, ";");
+ while (str_tok.GetNext()) {
+ ProxyServer uri = ProxyServer::FromURI(
+ str_tok.token_begin(), str_tok.token_end());
+ // Silently discard malformed inputs.
+ if (uri.is_valid())
+ proxies_.push_back(uri);
+ }
+}
+
+void ProxyList::RemoveBadProxies(const ProxyRetryInfoMap& proxy_retry_info) {
+ std::vector<ProxyServer> new_proxy_list;
+ std::vector<ProxyServer>::const_iterator iter = proxies_.begin();
+ for (; iter != proxies_.end(); ++iter) {
+ ProxyRetryInfoMap::const_iterator bad_proxy =
+ proxy_retry_info.find(iter->ToURI());
+ if (bad_proxy != proxy_retry_info.end()) {
+ // This proxy is bad. Check if it's time to retry.
+ if (bad_proxy->second.bad_until >= TimeTicks::Now()) {
+ // still invalid.
+ continue;
+ }
+ }
+ new_proxy_list.push_back(*iter);
+ }
+
+ proxies_ = new_proxy_list;
+}
+
+void ProxyList::RemoveProxiesWithoutScheme(int scheme_bit_field) {
+ for (std::vector<ProxyServer>::iterator it = proxies_.begin();
+ it != proxies_.end(); ) {
+ if (!(scheme_bit_field & it->scheme())) {
+ it = proxies_.erase(it);
+ continue;
+ }
+ ++it;
+ }
+}
+
+ProxyServer ProxyList::Get() const {
+ if (!proxies_.empty())
+ return proxies_[0];
+ return ProxyServer(ProxyServer::SCHEME_DIRECT, std::string(), -1);
+}
+
+std::string ProxyList::ToPacString() const {
+ std::string proxy_list;
+ std::vector<ProxyServer>::const_iterator iter = proxies_.begin();
+ for (; iter != proxies_.end(); ++iter) {
+ if (!proxy_list.empty())
+ proxy_list += ";";
+ proxy_list += iter->ToPacString();
+ }
+ return proxy_list.empty() ? "DIRECT" : proxy_list;
+}
+
+void ProxyList::SetFromPacString(const std::string& pac_string) {
+ StringTokenizer entry_tok(pac_string, ";");
+ proxies_.clear();
+ while (entry_tok.GetNext()) {
+ ProxyServer uri = ProxyServer::FromPacString(
+ entry_tok.token_begin(), entry_tok.token_end());
+ // Silently discard malformed inputs.
+ if (uri.is_valid())
+ proxies_.push_back(uri);
+ }
+}
+
+bool ProxyList::Fallback(ProxyRetryInfoMap* proxy_retry_info) {
+ // Number of minutes to wait before retrying a bad proxy server.
+ const TimeDelta kProxyRetryDelay = TimeDelta::FromMinutes(5);
+
+ if (proxies_.empty()) {
+ NOTREACHED();
+ return false;
+ }
+
+ std::string key = proxies_[0].ToURI();
+
+ // Mark this proxy as bad.
+ ProxyRetryInfoMap::iterator iter = proxy_retry_info->find(key);
+ if (iter != proxy_retry_info->end()) {
+ // TODO(nsylvain): This is not the first time we get this. We should
+ // double the retry time. Bug 997660.
+ iter->second.bad_until = TimeTicks::Now() + iter->second.current_delay;
+ } else {
+ ProxyRetryInfo retry_info;
+ retry_info.current_delay = kProxyRetryDelay;
+ retry_info.bad_until = TimeTicks().Now() + retry_info.current_delay;
+ (*proxy_retry_info)[key] = retry_info;
+ }
+
+ // Remove this proxy from our list.
+ proxies_.erase(proxies_.begin());
+
+ return !proxies_.empty();
+}
+
+} // namespace net
+
diff --git a/net/proxy/proxy_list.h b/net/proxy/proxy_list.h
new file mode 100644
index 0000000..ac46671
--- /dev/null
+++ b/net/proxy/proxy_list.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2006-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_LIST_H_
+#define NET_PROXY_PROXY_LIST_H_
+
+#include <string>
+#include <vector>
+
+#include "net/proxy/proxy_retry_info.h"
+#include "net/proxy/proxy_server.h"
+
+namespace net {
+
+// This class is used to hold a list of proxies returned by GetProxyForUrl or
+// manually configured. It handles proxy fallback if multiple servers are
+// specified.
+class ProxyList {
+ public:
+ // Initializes the proxy list to a string containing one or more proxy servers
+ // delimited by a semicolon.
+ void Set(const std::string& proxy_uri_list);
+
+ // Remove all proxies known to be bad from the proxy list.
+ void RemoveBadProxies(const ProxyRetryInfoMap& proxy_retry_info);
+
+ // Delete any entry which doesn't have one of the specified proxy schemes.
+ // |scheme_bit_field| is a bunch of ProxyServer::Scheme bitwise ORed together.
+ void RemoveProxiesWithoutScheme(int scheme_bit_field);
+
+ // Returns the first valid proxy server in the list.
+ ProxyServer Get() const;
+
+ // Set the list by parsing the pac result |pac_string|.
+ // Some examples for |pac_string|:
+ // "DIRECT"
+ // "PROXY foopy1"
+ // "PROXY foopy1; SOCKS4 foopy2:1188"
+ void SetFromPacString(const std::string& pac_string);
+
+ // Returns a PAC-style semicolon-separated list of valid proxy servers.
+ // For example: "PROXY xxx.xxx.xxx.xxx:xx; SOCKS yyy.yyy.yyy:yy".
+ std::string ToPacString() const;
+
+ // Marks the current proxy server as bad and deletes it from the list. The
+ // list of known bad proxies is given by proxy_retry_info. Returns true if
+ // there is another server available in the list.
+ bool Fallback(ProxyRetryInfoMap* proxy_retry_info);
+
+ private:
+ // List of proxies.
+ std::vector<ProxyServer> proxies_;
+};
+
+} // namespace net
+
+#endif // NET_PROXY_PROXY_LIST_H_
+
diff --git a/net/proxy/proxy_list_unittest.cc b/net/proxy/proxy_list_unittest.cc
new file mode 100644
index 0000000..c604d0a
--- /dev/null
+++ b/net/proxy/proxy_list_unittest.cc
@@ -0,0 +1,73 @@
+// Copyright (c) 2006-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_list.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// Test parsing from a PAC string.
+TEST(ProxyListTest, SetFromPacString) {
+ const struct {
+ const char* pac_input;
+ const char* pac_output;
+ } tests[] = {
+ // Valid inputs:
+ { "PROXY foopy:10",
+ "PROXY foopy:10",
+ },
+ { " DIRECT", // leading space.
+ "DIRECT",
+ },
+ { "PROXY foopy1 ; proxy foopy2;\t DIRECT",
+ "PROXY foopy1:80;PROXY foopy2:80;DIRECT",
+ },
+ { "proxy foopy1 ; SOCKS foopy2",
+ "PROXY foopy1:80;SOCKS foopy2:1080",
+ },
+
+ // Invalid inputs (parts which aren't understood get
+ // silently discarded):
+ { "PROXY-foopy:10",
+ "DIRECT",
+ },
+ { "PROXY",
+ "DIRECT",
+ },
+ { "PROXY foopy1 ; JUNK ; JUNK ; SOCKS5 foopy2 ; ;",
+ "PROXY foopy1:80;SOCKS5 foopy2:1080",
+ },
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ net::ProxyList list;
+ list.SetFromPacString(tests[i].pac_input);
+ EXPECT_EQ(tests[i].pac_output, list.ToPacString());
+ }
+}
+
+TEST(ProxyListTest, RemoveProxiesWithoutScheme) {
+ const struct {
+ const char* pac_input;
+ int filter;
+ const char* filtered_pac_output;
+ } tests[] = {
+ { "PROXY foopy:10 ; SOCKS5 foopy2 ; SOCKS foopy11 ; PROXY foopy3 ; DIRECT",
+ // Remove anything that isn't HTTP or DIRECT.
+ net::ProxyServer::SCHEME_DIRECT | net::ProxyServer::SCHEME_HTTP,
+ "PROXY foopy:10;PROXY foopy3:80;DIRECT",
+ },
+ { "PROXY foopy:10 | SOCKS5 foopy2",
+ // Remove anything that isn't HTTP or SOCKS5.
+ net::ProxyServer::SCHEME_DIRECT | net::ProxyServer::SCHEME_SOCKS4,
+ "DIRECT",
+ },
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
+ net::ProxyList list;
+ list.SetFromPacString(tests[i].pac_input);
+ list.RemoveProxiesWithoutScheme(tests[i].filter);
+ EXPECT_EQ(tests[i].filtered_pac_output, list.ToPacString());
+ }
+}
+
diff --git a/net/proxy/proxy_resolver.h b/net/proxy/proxy_resolver.h
new file mode 100644
index 0000000..254b250
--- /dev/null
+++ b/net/proxy/proxy_resolver.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2006-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_H_
+#define NET_PROXY_PROXY_RESOLVER_H_
+
+#include <string>
+
+#include "base/logging.h"
+
+class GURL;
+
+namespace net {
+
+class ProxyInfo;
+
+// Synchronously resolve the proxy for a URL, using a PAC script. Called on the
+// PAC Thread.
+class ProxyResolver {
+ public:
+
+ // If a subclass sets |does_fetch| to false, then the owning ProxyResolver
+ // will download PAC scripts on our behalf, and notify changes with
+ // SetPacScript(). Otherwise the subclass is expected to fetch the
+ // PAC script internally, and SetPacScript() will go unused.
+ ProxyResolver(bool does_fetch) : does_fetch_(does_fetch) {}
+
+ virtual ~ProxyResolver() {}
+
+ // Query the proxy auto-config file (specified by |pac_url|) for the proxy to
+ // use to load the given |query_url|. Returns OK if successful or an error
+ // code otherwise.
+ virtual int GetProxyForURL(const GURL& query_url,
+ const GURL& pac_url,
+ ProxyInfo* results) = 0;
+
+ // Called whenever the PAC script has changed, with the contents of the
+ // PAC script. |bytes| may be empty string if there was a fetch error.
+ virtual void SetPacScript(const std::string& bytes) {
+ // Must override SetPacScript() if |does_fetch_ = true|.
+ NOTREACHED();
+ }
+
+ bool does_fetch() const { return does_fetch_; }
+
+ protected:
+ bool does_fetch_;
+};
+
+} // namespace net
+
+#endif // NET_PROXY_PROXY_RESOLVER_H_
+
diff --git a/net/proxy/proxy_resolver_mac.cc b/net/proxy/proxy_resolver_mac.cc
index a2e8788..796847d 100644
--- a/net/proxy/proxy_resolver_mac.cc
+++ b/net/proxy/proxy_resolver_mac.cc
@@ -12,6 +12,9 @@
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "net/base/net_errors.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_info.h"
+#include "net/proxy/proxy_server.h"
namespace {
diff --git a/net/proxy/proxy_resolver_mac.h b/net/proxy/proxy_resolver_mac.h
index 8796d45..8413624 100644
--- a/net/proxy/proxy_resolver_mac.h
+++ b/net/proxy/proxy_resolver_mac.h
@@ -5,7 +5,8 @@
#ifndef NET_PROXY_PROXY_RESOLVER_MAC_H_
#define NET_PROXY_PROXY_RESOLVER_MAC_H_
-#include "net/proxy/proxy_service.h"
+#include "net/proxy/proxy_config_service.h"
+#include "net/proxy/proxy_resolver.h"
namespace net {
diff --git a/net/proxy/proxy_resolver_v8.cc b/net/proxy/proxy_resolver_v8.cc
index 09472e9..81c1138 100644
--- a/net/proxy/proxy_resolver_v8.cc
+++ b/net/proxy/proxy_resolver_v8.cc
@@ -5,10 +5,13 @@
#include "net/proxy/proxy_resolver_v8.h"
#include "base/logging.h"
+#include "base/string_util.h"
+#include "googleurl/src/gurl.h"
#include "net/base/address_list.h"
#include "net/base/host_resolver.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
+#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_resolver_script.h"
#include "v8/include/v8.h"
diff --git a/net/proxy/proxy_resolver_v8.h b/net/proxy/proxy_resolver_v8.h
index ec765fb..a0275c8 100644
--- a/net/proxy/proxy_resolver_v8.h
+++ b/net/proxy/proxy_resolver_v8.h
@@ -8,7 +8,7 @@
#include <string>
#include "base/scoped_ptr.h"
-#include "net/proxy/proxy_service.h"
+#include "net/proxy/proxy_resolver.h"
namespace net {
diff --git a/net/proxy/proxy_resolver_v8_unittest.cc b/net/proxy/proxy_resolver_v8_unittest.cc
index 5f8bef2..c2ddb9f 100644
--- a/net/proxy/proxy_resolver_v8_unittest.cc
+++ b/net/proxy/proxy_resolver_v8_unittest.cc
@@ -3,11 +3,12 @@
// found in the LICENSE file.
#include "base/file_util.h"
-#include "base/logging.h"
+#include "base/string_util.h"
#include "base/path_service.h"
+#include "googleurl/src/gurl.h"
#include "net/base/net_errors.h"
-#include "net/base/net_util.h"
#include "net/proxy/proxy_resolver_v8.h"
+#include "net/proxy/proxy_info.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
diff --git a/net/proxy/proxy_resolver_winhttp.cc b/net/proxy/proxy_resolver_winhttp.cc
index 6065846..a3ed9fe 100644
--- a/net/proxy/proxy_resolver_winhttp.cc
+++ b/net/proxy/proxy_resolver_winhttp.cc
@@ -8,7 +8,10 @@
#include <winhttp.h>
#include "base/histogram.h"
+#include "base/string_util.h"
+#include "googleurl/src/gurl.h"
#include "net/base/net_errors.h"
+#include "net/proxy/proxy_info.h"
#pragma comment(lib, "winhttp.lib")
diff --git a/net/proxy/proxy_resolver_winhttp.h b/net/proxy/proxy_resolver_winhttp.h
index 032cab7..b709702 100644
--- a/net/proxy/proxy_resolver_winhttp.h
+++ b/net/proxy/proxy_resolver_winhttp.h
@@ -5,9 +5,9 @@
#ifndef NET_PROXY_PROXY_RESOLVER_WINHTTP_H_
#define NET_PROXY_PROXY_RESOLVER_WINHTTP_H_
-#include "net/proxy/proxy_service.h"
+#include "net/proxy/proxy_resolver.h"
-typedef LPVOID HINTERNET; // From winhttp.h
+typedef void* HINTERNET; // From winhttp.h
namespace net {
diff --git a/net/proxy/proxy_retry_info.h b/net/proxy/proxy_retry_info.h
new file mode 100644
index 0000000..3e5149e
--- /dev/null
+++ b/net/proxy/proxy_retry_info.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2006-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_RETRY_INFO_H_
+#define NET_PROXY_PROXY_RETRY_INFO_H_
+
+#include <map>
+
+#include "base/time.h"
+
+namespace net {
+
+// Contains the information about when to retry a proxy server.
+struct ProxyRetryInfo {
+ // We should not retry until this time.
+ base::TimeTicks bad_until;
+
+ // This is the current delay. If the proxy is still bad, we need to increase
+ // this delay.
+ base::TimeDelta current_delay;
+};
+
+// Map of proxy servers with the associated RetryInfo structures.
+// The key is a proxy URI string [<scheme>"://"]<host>":"<port>.
+typedef std::map<std::string, ProxyRetryInfo> ProxyRetryInfoMap;
+
+} // namespace net
+
+#endif // NET_PROXY_PROXY_RETRY_INFO_H_
+
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
index 438f147..9b1462f 100644
--- a/net/proxy/proxy_service.cc
+++ b/net/proxy/proxy_service.cc
@@ -4,20 +4,16 @@
#include "net/proxy/proxy_service.h"
-#if defined(OS_WIN)
-#include <windows.h>
-#include <winhttp.h>
-#endif
-
#include <algorithm>
#include "base/compiler_specific.h"
#include "base/logging.h"
-#include "base/message_loop.h"
#include "base/string_tokenizer.h"
+#include "base/string_util.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_errors.h"
#include "net/proxy/proxy_config_service_fixed.h"
+#include "net/proxy/proxy_script_fetcher.h"
#if defined(OS_WIN)
#include "net/proxy/proxy_config_service_win.h"
#include "net/proxy/proxy_resolver_winhttp.h"
@@ -67,153 +63,6 @@ class NotifyFetchCompletionTask : public Task {
std::string bytes_;
};
-// ProxyConfig ----------------------------------------------------------------
-
-// static
-ProxyConfig::ID ProxyConfig::last_id_ = ProxyConfig::INVALID_ID;
-
-ProxyConfig::ProxyConfig()
- : auto_detect(false),
- proxy_bypass_local_names(false),
- id_(++last_id_) {
-}
-
-bool ProxyConfig::Equals(const ProxyConfig& other) const {
- // The two configs can have different IDs. We are just interested in if they
- // have the same settings.
- 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;
-}
-
-// ProxyList ------------------------------------------------------------------
-
-void ProxyList::Set(const std::string& proxy_uri_list) {
- proxies_.clear();
- StringTokenizer str_tok(proxy_uri_list, ";");
- while (str_tok.GetNext()) {
- ProxyServer uri = ProxyServer::FromURI(
- str_tok.token_begin(), str_tok.token_end());
- // Silently discard malformed inputs.
- if (uri.is_valid())
- proxies_.push_back(uri);
- }
-}
-
-void ProxyList::RemoveBadProxies(const ProxyRetryInfoMap& proxy_retry_info) {
- std::vector<ProxyServer> new_proxy_list;
- std::vector<ProxyServer>::const_iterator iter = proxies_.begin();
- for (; iter != proxies_.end(); ++iter) {
- ProxyRetryInfoMap::const_iterator bad_proxy =
- proxy_retry_info.find(iter->ToURI());
- if (bad_proxy != proxy_retry_info.end()) {
- // This proxy is bad. Check if it's time to retry.
- if (bad_proxy->second.bad_until >= TimeTicks::Now()) {
- // still invalid.
- continue;
- }
- }
- new_proxy_list.push_back(*iter);
- }
-
- proxies_ = new_proxy_list;
-}
-
-void ProxyList::RemoveProxiesWithoutScheme(int scheme_bit_field) {
- for (std::vector<ProxyServer>::iterator it = proxies_.begin();
- it != proxies_.end(); ) {
- if (!(scheme_bit_field & it->scheme())) {
- it = proxies_.erase(it);
- continue;
- }
- ++it;
- }
-}
-
-ProxyServer ProxyList::Get() const {
- if (!proxies_.empty())
- return proxies_[0];
- return ProxyServer(ProxyServer::SCHEME_DIRECT, std::string(), -1);
-}
-
-std::string ProxyList::ToPacString() const {
- std::string proxy_list;
- std::vector<ProxyServer>::const_iterator iter = proxies_.begin();
- for (; iter != proxies_.end(); ++iter) {
- if (!proxy_list.empty())
- proxy_list += ";";
- proxy_list += iter->ToPacString();
- }
- return proxy_list.empty() ? "DIRECT" : proxy_list;
-}
-
-void ProxyList::SetFromPacString(const std::string& pac_string) {
- StringTokenizer entry_tok(pac_string, ";");
- proxies_.clear();
- while (entry_tok.GetNext()) {
- ProxyServer uri = ProxyServer::FromPacString(
- entry_tok.token_begin(), entry_tok.token_end());
- // Silently discard malformed inputs.
- if (uri.is_valid())
- proxies_.push_back(uri);
- }
-}
-
-bool ProxyList::Fallback(ProxyRetryInfoMap* proxy_retry_info) {
- // Number of minutes to wait before retrying a bad proxy server.
- const TimeDelta kProxyRetryDelay = TimeDelta::FromMinutes(5);
-
- if (proxies_.empty()) {
- NOTREACHED();
- return false;
- }
-
- std::string key = proxies_[0].ToURI();
-
- // Mark this proxy as bad.
- ProxyRetryInfoMap::iterator iter = proxy_retry_info->find(key);
- if (iter != proxy_retry_info->end()) {
- // TODO(nsylvain): This is not the first time we get this. We should
- // double the retry time. Bug 997660.
- iter->second.bad_until = TimeTicks::Now() + iter->second.current_delay;
- } else {
- ProxyRetryInfo retry_info;
- retry_info.current_delay = kProxyRetryDelay;
- retry_info.bad_until = TimeTicks().Now() + retry_info.current_delay;
- (*proxy_retry_info)[key] = retry_info;
- }
-
- // Remove this proxy from our list.
- proxies_.erase(proxies_.begin());
-
- return !proxies_.empty();
-}
-
-// ProxyInfo ------------------------------------------------------------------
-
-ProxyInfo::ProxyInfo()
- : config_id_(ProxyConfig::INVALID_ID),
- config_was_tried_(false) {
-}
-
-void ProxyInfo::Use(const ProxyInfo& other) {
- proxy_list_ = other.proxy_list_;
-}
-
-void ProxyInfo::UseDirect() {
- proxy_list_.Set(std::string());
-}
-
-void ProxyInfo::UseNamedProxy(const std::string& proxy_uri_list) {
- proxy_list_.Set(proxy_uri_list);
-}
-
-std::string ProxyInfo::ToPacString() {
- return proxy_list_.ToPacString();
-}
-
// ProxyService::PacRequest ---------------------------------------------------
// We rely on the fact that the origin thread (and its message loop) will not
@@ -633,6 +482,11 @@ void ProxyService::CancelPacRequest(PacRequest* req) {
}
}
+void ProxyService::SetProxyScriptFetcher(
+ ProxyScriptFetcher* proxy_script_fetcher) {
+ proxy_script_fetcher_.reset(proxy_script_fetcher);
+}
+
void ProxyService::DidCompletePacRequest(int config_id, int result_code) {
// If we get an error that indicates a bad PAC config, then we should
// remember that, and not try the PAC config again for a while.
diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h
index 3c29195..21b0e07 100644
--- a/net/proxy/proxy_service.h
+++ b/net/proxy/proxy_service.h
@@ -6,95 +6,24 @@
#define NET_PROXY_PROXY_SERVICE_H_
#include <deque>
-#include <map>
#include <string>
-#include <vector>
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
-#include "base/string_util.h"
#include "base/thread.h"
-#include "base/time.h"
#include "base/waitable_event.h"
-#include "googleurl/src/gurl.h"
#include "net/base/completion_callback.h"
-#include "net/proxy/proxy_script_fetcher.h"
#include "net/proxy/proxy_server.h"
+#include "net/proxy/proxy_info.h"
class GURL;
namespace net {
+class ProxyScriptFetcher;
class ProxyConfigService;
-class ProxyInfo;
class ProxyResolver;
-// Proxy configuration used to by the ProxyService.
-class ProxyConfig {
- public:
- typedef int ID;
-
- // Indicates an invalid proxy config.
- enum { INVALID_ID = 0 };
-
- ProxyConfig();
- // Default copy-constructor and assignment operator are OK!
-
- // Used to numerically identify this configuration.
- ID id() const { return id_; }
-
- // True if the proxy configuration should be auto-detected.
- bool auto_detect;
-
- // If non-empty, indicates the URL of the proxy auto-config file to use.
- GURL pac_url;
-
- // If non-empty, indicates the proxy server to use, given by:
- //
- // proxy-uri = [<proxy-scheme>://]<proxy-host>[:"<proxy-port>]
- //
- // If the proxy to use depends on the scheme of the URL, can instead specify
- // a semicolon separated list of:
- //
- // <url-scheme>"="<proxy-uri>
- //
- // For example:
- // "http=foopy:80;ftp=foopy2" -- use HTTP proxy "foopy:80" for http URLs,
- // and HTTP proxy "foopy2:80" for ftp URLs.
- // "foopy:80" -- use HTTP proxy "foopy:80" for all URLs.
- // "socks4://foopy" -- use SOCKS v4 proxy "foopy:1080" for all
- // URLs.
- std::string proxy_rules;
-
- // 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;
-
- // Returns true if the given config is equivalent to this config.
- bool Equals(const ProxyConfig& other) const;
-
- private:
- static int last_id_;
- int id_;
-};
-
-// Contains the information about when to retry a proxy server.
-struct ProxyRetryInfo {
- // We should not retry until this time.
- base::TimeTicks bad_until;
-
- // This is the current delay. If the proxy is still bad, we need to increase
- // this delay.
- base::TimeDelta current_delay;
-};
-
-// Map of proxy servers with the associated RetryInfo structures.
-// The key is a proxy URI string [<scheme>"://"]<host>":"<port>.
-typedef std::map<std::string, ProxyRetryInfo> ProxyRetryInfoMap;
-
// This class can be used to resolve the proxy server to use when loading a
// HTTP(S) URL. It uses the given ProxyResolver to handle the actual proxy
// resolution. See ProxyResolverWinHttp for example.
@@ -151,6 +80,11 @@ class ProxyService {
// Call this method with a non-null |pac_request| to cancel the PAC request.
void CancelPacRequest(PacRequest* pac_request);
+ // Set the ProxyScriptFetcher dependency. This is needed if the ProxyResolver
+ // is of type ProxyResolverWithoutFetch. ProxyService takes ownership of
+ // |proxy_script_fetcher|.
+ void SetProxyScriptFetcher(ProxyScriptFetcher* proxy_script_fetcher);
+
// Create a proxy service using the specified settings. If |pi| is NULL then
// the system's default proxy settings will be used (on Windows this will
// use IE's settings).
@@ -160,13 +94,6 @@ class ProxyService {
// so it falls back to direct connect.
static ProxyService* CreateNull();
- // Set the ProxyScriptFetcher dependency. This is needed if the ProxyResolver
- // is of type ProxyResolverWithoutFetch. ProxyService takes ownership of
- // |proxy_script_fetcher|.
- void SetProxyScriptFetcher(ProxyScriptFetcher* proxy_script_fetcher) {
- proxy_script_fetcher_.reset(proxy_script_fetcher);
- }
-
private:
friend class PacRequest;
@@ -272,155 +199,6 @@ class ProxyService {
DISALLOW_COPY_AND_ASSIGN(ProxyService);
};
-// This class is used to hold a list of proxies returned by GetProxyForUrl or
-// manually configured. It handles proxy fallback if multiple servers are
-// specified.
-class ProxyList {
- public:
- // Initializes the proxy list to a string containing one or more proxy servers
- // delimited by a semicolon.
- void Set(const std::string& proxy_uri_list);
-
- // Remove all proxies known to be bad from the proxy list.
- void RemoveBadProxies(const ProxyRetryInfoMap& proxy_retry_info);
-
- // Delete any entry which doesn't have one of the specified proxy schemes.
- // |scheme_bit_field| is a bunch of ProxyServer::Scheme bitwise ORed together.
- void RemoveProxiesWithoutScheme(int scheme_bit_field);
-
- // Returns the first valid proxy server in the list.
- ProxyServer Get() const;
-
- // Set the list by parsing the pac result |pac_string|.
- // Some examples for |pac_string|:
- // "DIRECT"
- // "PROXY foopy1"
- // "PROXY foopy1; SOCKS4 foopy2:1188"
- void SetFromPacString(const std::string& pac_string);
-
- // Returns a PAC-style semicolon-separated list of valid proxy servers.
- // For example: "PROXY xxx.xxx.xxx.xxx:xx; SOCKS yyy.yyy.yyy:yy".
- std::string ToPacString() const;
-
- // Marks the current proxy server as bad and deletes it from the list. The
- // list of known bad proxies is given by proxy_retry_info. Returns true if
- // there is another server available in the list.
- bool Fallback(ProxyRetryInfoMap* proxy_retry_info);
-
- private:
- // List of proxies.
- std::vector<ProxyServer> proxies_;
-};
-
-// This object holds proxy information returned by ResolveProxy.
-class ProxyInfo {
- public:
- ProxyInfo();
- // Default copy-constructor and assignment operator are OK!
-
- // Use the same proxy server as the given |proxy_info|.
- void Use(const ProxyInfo& proxy_info);
-
- // Use a direct connection.
- void UseDirect();
-
- // Use a specific proxy server, of the form:
- // proxy-uri = [<scheme> "://"] <hostname> [":" <port>]
- // This may optionally be a semi-colon delimited list of <proxy-uri>.
- // It is OK to have LWS between entries.
- void UseNamedProxy(const std::string& proxy_uri_list);
-
- // Parse from the given PAC result.
- void UsePacString(const std::string& pac_string) {
- proxy_list_.SetFromPacString(pac_string);
- }
-
- // Returns true if this proxy info specifies a direct connection.
- bool is_direct() const { return proxy_list_.Get().is_direct(); }
-
- // Returns the first valid proxy server.
- ProxyServer proxy_server() const { return proxy_list_.Get(); }
-
- // See description in ProxyList::ToPacString().
- std::string ToPacString();
-
- // Marks the current proxy as bad. Returns true if there is another proxy
- // available to try in proxy list_.
- bool Fallback(ProxyRetryInfoMap* proxy_retry_info) {
- return proxy_list_.Fallback(proxy_retry_info);
- }
-
- // Remove all proxies known to be bad from the proxy list.
- void RemoveBadProxies(const ProxyRetryInfoMap& proxy_retry_info) {
- proxy_list_.RemoveBadProxies(proxy_retry_info);
- }
-
- // Delete any entry which doesn't have one of the specified proxy schemes.
- void RemoveProxiesWithoutScheme(int scheme_bit_field) {
- proxy_list_.RemoveProxiesWithoutScheme(scheme_bit_field);
- }
-
- private:
- friend class ProxyService;
-
- // If proxy_list_ is set to empty, then a "direct" connection is indicated.
- ProxyList proxy_list_;
-
- // This value identifies the proxy config used to initialize this object.
- ProxyConfig::ID config_id_;
-
- // This flag is false when the proxy configuration was known to be bad when
- // this proxy info was initialized. In such cases, we know that if this
- // proxy info does not yield a connection that we might want to reconsider
- // the proxy config given by config_id_.
- bool config_was_tried_;
-};
-
-// Synchronously fetch the system's proxy configuration settings. Called on
-// the IO Thread.
-class ProxyConfigService {
- public:
- virtual ~ProxyConfigService() {}
-
- // Get the proxy configuration. Returns OK if successful or an error code if
- // otherwise. |config| should be in its initial state when this method is
- // called.
- virtual int GetProxyConfig(ProxyConfig* config) = 0;
-};
-
-// Synchronously resolve the proxy for a URL, using a PAC script. Called on the
-// PAC Thread.
-class ProxyResolver {
- public:
-
- // If a subclass sets |does_fetch| to false, then the owning ProxyResolver
- // will download PAC scripts on our behalf, and notify changes with
- // SetPacScript(). Otherwise the subclass is expected to fetch the
- // PAC script internally, and SetPacScript() will go unused.
- ProxyResolver(bool does_fetch) : does_fetch_(does_fetch) {}
-
- virtual ~ProxyResolver() {}
-
- // Query the proxy auto-config file (specified by |pac_url|) for the proxy to
- // use to load the given |query_url|. Returns OK if successful or an error
- // code otherwise.
- virtual int GetProxyForURL(const GURL& query_url,
- const GURL& pac_url,
- ProxyInfo* results) = 0;
-
- // Called whenever the PAC script has changed, with the contents of the
- // PAC script. |bytes| may be empty string if there was a fetch error.
- virtual void SetPacScript(const std::string& bytes) {
- // Must override SetPacScript() if |does_fetch_ = true|.
- NOTREACHED();
- }
-
- bool does_fetch() const { return does_fetch_; }
-
- protected:
- bool does_fetch_;
-};
-
// Wrapper for invoking methods on a ProxyService synchronously.
class SyncProxyServiceHelper
: public base::RefCountedThreadSafe<SyncProxyServiceHelper> {
diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc
index 84a9395..ea1d56b 100644
--- a/net/proxy/proxy_service_unittest.cc
+++ b/net/proxy/proxy_service_unittest.cc
@@ -5,6 +5,9 @@
#include "base/compiler_specific.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_errors.h"
+#include "net/proxy/proxy_config_service.h"
+#include "net/proxy/proxy_resolver.h"
+#include "net/proxy/proxy_script_fetcher.h"
#include "net/proxy/proxy_service.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -348,72 +351,6 @@ template<>
void RunnableMethodTraits<MockProxyScriptFetcher>::ReleaseCallee(
MockProxyScriptFetcher* remover) {}
-// Test parsing from a PAC string.
-TEST(ProxyListTest, SetFromPacString) {
- const struct {
- const char* pac_input;
- const char* pac_output;
- } tests[] = {
- // Valid inputs:
- { "PROXY foopy:10",
- "PROXY foopy:10",
- },
- { " DIRECT", // leading space.
- "DIRECT",
- },
- { "PROXY foopy1 ; proxy foopy2;\t DIRECT",
- "PROXY foopy1:80;PROXY foopy2:80;DIRECT",
- },
- { "proxy foopy1 ; SOCKS foopy2",
- "PROXY foopy1:80;SOCKS foopy2:1080",
- },
-
- // Invalid inputs (parts which aren't understood get
- // silently discarded):
- { "PROXY-foopy:10",
- "DIRECT",
- },
- { "PROXY",
- "DIRECT",
- },
- { "PROXY foopy1 ; JUNK ; JUNK ; SOCKS5 foopy2 ; ;",
- "PROXY foopy1:80;SOCKS5 foopy2:1080",
- },
- };
-
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
- net::ProxyList list;
- list.SetFromPacString(tests[i].pac_input);
- EXPECT_EQ(tests[i].pac_output, list.ToPacString());
- }
-}
-
-TEST(ProxyListTest, RemoveProxiesWithoutScheme) {
- const struct {
- const char* pac_input;
- int filter;
- const char* filtered_pac_output;
- } tests[] = {
- { "PROXY foopy:10 ; SOCKS5 foopy2 ; SOCKS foopy11 ; PROXY foopy3 ; DIRECT",
- // Remove anything that isn't HTTP or DIRECT.
- net::ProxyServer::SCHEME_DIRECT | net::ProxyServer::SCHEME_HTTP,
- "PROXY foopy:10;PROXY foopy3:80;DIRECT",
- },
- { "PROXY foopy:10 | SOCKS5 foopy2",
- // Remove anything that isn't HTTP or SOCKS5.
- net::ProxyServer::SCHEME_DIRECT | net::ProxyServer::SCHEME_SOCKS4,
- "DIRECT",
- },
- };
-
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
- net::ProxyList list;
- list.SetFromPacString(tests[i].pac_input);
- list.RemoveProxiesWithoutScheme(tests[i].filter);
- EXPECT_EQ(tests[i].filtered_pac_output, list.ToPacString());
- }
-}
-
TEST(ProxyServiceTest, Direct) {
SyncProxyService service(new MockProxyConfigService,
new MockProxyResolver);