summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-10 04:11:27 +0000
committerericroman@google.com <ericroman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-10 04:11:27 +0000
commit63de95b265c665320b776c821f4cc44872c65c87 (patch)
treed60769b5e1907b060870af7d88ed567671a24e4e /net
parentbcdae8c9c9d90889fa0ca6491ae191a9e2f944b4 (diff)
downloadchromium_src-63de95b265c665320b776c821f4cc44872c65c87.zip
chromium_src-63de95b265c665320b776c821f4cc44872c65c87.tar.gz
chromium_src-63de95b265c665320b776c821f4cc44872c65c87.tar.bz2
Misc proxy service changes.
(1) Changed the proxy service ownership model -- rather than being a detail of the HTTP stack, it is now a dependency owned by UrlRequestContext. - ProxyService is owned by UrlRequestContext (before was HttpNetworkSession) - ProxyResolver is owned by ProxyService (before was HttpNetworkSession) Being able to share the proxy service is needed in several places, including incognito mode http context (http://crbug.com/3564), and for proxy resolving in the new FTP stack. (2) Added an IPC for getting of the ProxyResolverWinHttp dependency in the plugin process. Not hooked up yet, but intent is to route the proxy resolve requests through the browser process. (3) Changed some unit tests which were depending on the system proxy settings (this was a sideffect of their calling HttpNetworkLayer::CreateFactory(NULL)). (4) Moved the first-time ProxyService::UpdateConfig out of the constructor and into the initial request. Done to avoid startup perf regressions, since the ProxyService construction is now done earlier (on the startup critical path). BUG=3564 Review URL: http://codereview.chromium.org/12938 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6693 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/http/http_cache.cc8
-rw-r--r--net/http/http_cache.h10
-rw-r--r--net/http/http_network_layer.cc35
-rw-r--r--net/http/http_network_layer.h12
-rw-r--r--net/http/http_network_layer_unittest.cc11
-rw-r--r--net/http/http_network_session.h14
-rw-r--r--net/http/http_network_transaction_unittest.cc55
-rw-r--r--net/http/http_transaction_winhttp.cc24
-rw-r--r--net/http/http_transaction_winhttp.h12
-rw-r--r--net/http/http_transaction_winhttp_unittest.cc10
-rw-r--r--net/proxy/proxy_service.cc55
-rw-r--r--net/proxy/proxy_service.h55
-rw-r--r--net/proxy/proxy_service_unittest.cc197
-rw-r--r--net/url_request/url_request_context.h10
-rw-r--r--net/url_request/url_request_unittest.cc6
-rw-r--r--net/url_request/url_request_unittest.h7
16 files changed, 308 insertions, 213 deletions
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc
index b82795c..fbc2b0f 100644
--- a/net/http/http_cache.cc
+++ b/net/http/http_cache.cc
@@ -916,20 +916,20 @@ void HttpCache::Transaction::OnCacheReadCompleted(int result) {
//-----------------------------------------------------------------------------
-HttpCache::HttpCache(const ProxyInfo* proxy_info,
+HttpCache::HttpCache(ProxyService* proxy_service,
const std::wstring& cache_dir,
int cache_size)
: disk_cache_dir_(cache_dir),
mode_(NORMAL),
- network_layer_(HttpNetworkLayer::CreateFactory(proxy_info)),
+ network_layer_(HttpNetworkLayer::CreateFactory(proxy_service)),
ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
in_memory_cache_(false),
cache_size_(cache_size) {
}
-HttpCache::HttpCache(const ProxyInfo* proxy_info, int cache_size)
+HttpCache::HttpCache(ProxyService* proxy_service, int cache_size)
: mode_(NORMAL),
- network_layer_(HttpNetworkLayer::CreateFactory(proxy_info)),
+ network_layer_(HttpNetworkLayer::CreateFactory(proxy_service)),
ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)),
in_memory_cache_(true),
cache_size_(cache_size) {
diff --git a/net/http/http_cache.h b/net/http/http_cache.h
index 22f0754..9729527 100644
--- a/net/http/http_cache.h
+++ b/net/http/http_cache.h
@@ -31,7 +31,7 @@ namespace net {
class HttpRequestInfo;
class HttpResponseInfo;
-class ProxyInfo;
+class ProxyService;
class HttpCache : public HttpTransactionFactory {
public:
@@ -51,16 +51,14 @@ class HttpCache : public HttpTransactionFactory {
// Initialize the cache from the directory where its data is stored. The
// disk cache is initialized lazily (by CreateTransaction) in this case. If
// |cache_size| is zero, a default value will be calculated automatically.
- // If the proxy information is null, then the system settings will be used.
- HttpCache(const ProxyInfo* proxy_info,
+ HttpCache(ProxyService* proxy_service,
const std::wstring& cache_dir,
int cache_size);
// Initialize using an in-memory cache. The cache is initialized lazily
// (by CreateTransaction) in this case. If |cache_size| is zero, a default
- // value will be calculated automatically. If the proxy information is null,
- // then the system settings will be used.
- HttpCache(const ProxyInfo* proxy_info, int cache_size);
+ // value will be calculated automatically.
+ HttpCache(ProxyService* proxy_service, int cache_size);
// Initialize the cache from its component parts, which is useful for
// testing. The lifetime of the network_layer and disk_cache are managed by
diff --git a/net/http/http_network_layer.cc b/net/http/http_network_layer.cc
index 78b8aa6..2b84682 100644
--- a/net/http/http_network_layer.cc
+++ b/net/http/http_network_layer.cc
@@ -8,13 +8,8 @@
#include "net/base/client_socket_factory.h"
#include "net/http/http_network_session.h"
#include "net/http/http_network_transaction.h"
-#include "net/proxy/proxy_resolver_fixed.h"
-#include "net/proxy/proxy_resolver_null.h"
#if defined(OS_WIN)
#include "net/http/http_transaction_winhttp.h"
-#include "net/proxy/proxy_resolver_winhttp.h"
-#elif defined(OS_MACOSX)
-#include "net/proxy/proxy_resolver_mac.h"
#endif
namespace net {
@@ -28,13 +23,14 @@ bool HttpNetworkLayer::use_winhttp_ = false;
// static
HttpTransactionFactory* HttpNetworkLayer::CreateFactory(
- const ProxyInfo* pi) {
+ ProxyService* proxy_service) {
+ DCHECK(proxy_service);
#if defined(OS_WIN)
if (use_winhttp_)
- return new HttpTransactionWinHttp::Factory(pi);
+ return new HttpTransactionWinHttp::Factory(proxy_service);
#endif
- return new HttpNetworkLayer(pi);
+ return new HttpNetworkLayer(proxy_service);
}
#if defined(OS_WIN)
@@ -46,24 +42,9 @@ void HttpNetworkLayer::UseWinHttp(bool value) {
//-----------------------------------------------------------------------------
-HttpNetworkLayer::HttpNetworkLayer(const ProxyInfo* pi)
- : suspended_(false) {
- if (pi) {
- proxy_resolver_.reset(new ProxyResolverFixed(*pi));
- } else {
-#if defined(OS_WIN)
- proxy_resolver_.reset(new ProxyResolverWinHttp());
-#elif defined(OS_MACOSX)
- proxy_resolver_.reset(new ProxyResolverMac());
-#else
- // This used to be a NOTIMPLEMENTED(), but that logs as an error,
- // screwing up layout tests.
- LOG(WARNING) << "Proxies are not implemented; remove me once that's fixed.";
- // http://code.google.com/p/chromium/issues/detail?id=4523 is the bug
- // to implement this.
- proxy_resolver_.reset(new ProxyResolverNull());
-#endif
- }
+HttpNetworkLayer::HttpNetworkLayer(ProxyService* proxy_service)
+ : proxy_service_(proxy_service), suspended_(false) {
+ DCHECK(proxy_service_);
}
HttpNetworkLayer::~HttpNetworkLayer() {
@@ -74,7 +55,7 @@ HttpTransaction* HttpNetworkLayer::CreateTransaction() {
return NULL;
if (!session_)
- session_ = new HttpNetworkSession(proxy_resolver_.release());
+ session_ = new HttpNetworkSession(proxy_service_);
return new HttpNetworkTransaction(
session_, ClientSocketFactory::GetDefaultFactory());
diff --git a/net/http/http_network_layer.h b/net/http/http_network_layer.h
index 93e7eb4..5364642 100644
--- a/net/http/http_network_layer.h
+++ b/net/http/http_network_layer.h
@@ -13,16 +13,17 @@ namespace net {
class HttpNetworkSession;
class ProxyInfo;
-class ProxyResolver;
+class ProxyService;
class HttpNetworkLayer : public HttpTransactionFactory {
public:
- explicit HttpNetworkLayer(const ProxyInfo* pi);
+ // |proxy_service| must remain valid for the lifetime of HttpNetworkLayer.
+ explicit HttpNetworkLayer(ProxyService* proxy_service);
~HttpNetworkLayer();
// This function hides the details of how a network layer gets instantiated
// and allows other implementations to be substituted.
- static HttpTransactionFactory* CreateFactory(const ProxyInfo* pi);
+ static HttpTransactionFactory* CreateFactory(ProxyService* proxy_service);
#if defined(OS_WIN)
// If value is true, then WinHTTP will be used.
@@ -39,9 +40,8 @@ class HttpNetworkLayer : public HttpTransactionFactory {
static bool use_winhttp_;
#endif
- // The pending proxy resolver to use when lazily creating session_.
- // NULL afterwards.
- scoped_ptr<ProxyResolver> proxy_resolver_;
+ // The proxy service being used for the session.
+ ProxyService* proxy_service_;
scoped_refptr<HttpNetworkSession> session_;
bool suspended_;
diff --git a/net/http/http_network_layer_unittest.cc b/net/http/http_network_layer_unittest.cc
index 2bccd8a..0460947 100644
--- a/net/http/http_network_layer_unittest.cc
+++ b/net/http/http_network_layer_unittest.cc
@@ -5,6 +5,7 @@
#include "net/base/scoped_host_mapper.h"
#include "net/http/http_network_layer.h"
#include "net/http/http_transaction_unittest.h"
+#include "net/proxy/proxy_resolver_null.h"
#include "net/proxy/proxy_service.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -21,13 +22,15 @@ class HttpNetworkLayerTest : public PlatformTest {
};
TEST_F(HttpNetworkLayerTest, CreateAndDestroy) {
- net::HttpNetworkLayer factory(NULL);
+ net::ProxyService proxy_service(new net::ProxyResolverNull);
+ net::HttpNetworkLayer factory(&proxy_service);
scoped_ptr<net::HttpTransaction> trans(factory.CreateTransaction());
}
TEST_F(HttpNetworkLayerTest, Suspend) {
- net::HttpNetworkLayer factory(NULL);
+ net::ProxyService proxy_service(new net::ProxyResolverNull);
+ net::HttpNetworkLayer factory(&proxy_service);
scoped_ptr<net::HttpTransaction> trans(factory.CreateTransaction());
trans.reset();
@@ -43,8 +46,8 @@ TEST_F(HttpNetworkLayerTest, Suspend) {
}
TEST_F(HttpNetworkLayerTest, GoogleGET) {
- net::ProxyInfo no_proxy; // Avoid using a proxy server.
- net::HttpNetworkLayer factory(&no_proxy);
+ net::ProxyService proxy_service(new net::ProxyResolverNull);
+ net::HttpNetworkLayer factory(&proxy_service);
TestCompletionCallback callback;
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index 11ccc26c..d998665 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -9,10 +9,11 @@
#include "net/base/client_socket_pool.h"
#include "net/base/ssl_config_service.h"
#include "net/http/http_auth_cache.h"
-#include "net/proxy/proxy_service.h"
namespace net {
+class ProxyService;
+
// This class holds session objects used by HttpNetworkTransaction objects.
class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> {
public:
@@ -21,15 +22,15 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> {
MAX_SOCKETS_PER_GROUP = 6
};
- explicit HttpNetworkSession(ProxyResolver* proxy_resolver)
+ explicit HttpNetworkSession(ProxyService* proxy_service)
: connection_pool_(new ClientSocketPool(MAX_SOCKETS_PER_GROUP)),
- proxy_resolver_(proxy_resolver),
- proxy_service_(proxy_resolver) {
+ proxy_service_(proxy_service) {
+ DCHECK(proxy_service);
}
HttpAuthCache* auth_cache() { return &auth_cache_; }
ClientSocketPool* connection_pool() { return connection_pool_; }
- ProxyService* proxy_service() { return &proxy_service_; }
+ ProxyService* proxy_service() { return proxy_service_; }
#if defined(OS_WIN)
SSLConfigService* ssl_config_service() { return &ssl_config_service_; }
#endif
@@ -37,8 +38,7 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> {
private:
HttpAuthCache auth_cache_;
scoped_refptr<ClientSocketPool> connection_pool_;
- scoped_ptr<ProxyResolver> proxy_resolver_;
- ProxyService proxy_service_;
+ ProxyService* proxy_service_;
#if defined(OS_WIN)
// TODO(port): Port the SSLConfigService class to Linux and Mac OS X.
SSLConfigService ssl_config_service_;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 68a643e..903f6d9 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -200,15 +200,13 @@ class MockClientSocketFactory : public net::ClientSocketFactory {
MockClientSocketFactory mock_socket_factory;
-net::HttpNetworkSession* CreateSession(net::ProxyResolver* proxy_resolver) {
- if (!proxy_resolver) {
- proxy_resolver = new net::ProxyResolverNull();
- }
- return new net::HttpNetworkSession(proxy_resolver);
+// Create a proxy service which fails on all requests (falls back to direct).
+net::ProxyService* CreateNullProxyService() {
+ return new net::ProxyService(new net::ProxyResolverNull);
}
-net::HttpNetworkSession* CreateSession() {
- return CreateSession(NULL);
+net::HttpNetworkSession* CreateSession(net::ProxyService* proxy_service) {
+ return new net::HttpNetworkSession(proxy_service);
}
class HttpNetworkTransactionTest : public PlatformTest {
@@ -238,8 +236,9 @@ struct SimpleGetHelperResult {
SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[]) {
SimpleGetHelperResult out;
+ scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService());
scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction(
- CreateSession(), &mock_socket_factory));
+ CreateSession(proxy_service.get()), &mock_socket_factory));
net::HttpRequestInfo request;
request.method = "GET";
@@ -290,8 +289,9 @@ void FillLargeHeadersString(std::string* str, int size) {
//-----------------------------------------------------------------------------
TEST_F(HttpNetworkTransactionTest, Basic) {
+ scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService());
scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction(
- CreateSession(), &mock_socket_factory));
+ CreateSession(proxy_service.get()), &mock_socket_factory));
}
TEST_F(HttpNetworkTransactionTest, SimpleGET) {
@@ -398,7 +398,9 @@ TEST_F(HttpNetworkTransactionTest, StopsReading204) {
}
TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
- scoped_refptr<net::HttpNetworkSession> session = CreateSession();
+ scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService());
+ scoped_refptr<net::HttpNetworkSession> session =
+ CreateSession(proxy_service.get());
MockRead data_reads[] = {
MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
@@ -447,8 +449,9 @@ TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
}
TEST_F(HttpNetworkTransactionTest, Ignores100) {
+ scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService());
scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction(
- CreateSession(), &mock_socket_factory));
+ CreateSession(proxy_service.get()), &mock_socket_factory));
net::HttpRequestInfo request;
request.method = "POST";
@@ -492,7 +495,9 @@ TEST_F(HttpNetworkTransactionTest, Ignores100) {
// transaction to resend the request.
void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
const MockRead& read_failure) {
- scoped_refptr<net::HttpNetworkSession> session = CreateSession();
+ scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService());
+ scoped_refptr<net::HttpNetworkSession> session =
+ CreateSession(proxy_service.get());
net::HttpRequestInfo request;
request.method = "GET";
@@ -557,8 +562,9 @@ TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
}
TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
+ scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService());
scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction(
- CreateSession(), &mock_socket_factory));
+ CreateSession(proxy_service.get()), &mock_socket_factory));
net::HttpRequestInfo request;
request.method = "GET";
@@ -611,8 +617,9 @@ TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
// Test the request-challenge-retry sequence for basic auth.
// (basic auth is the easiest to mock, because it has no randomness).
TEST_F(HttpNetworkTransactionTest, BasicAuth) {
+ scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService());
scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction(
- CreateSession(), &mock_socket_factory));
+ CreateSession(proxy_service.get()), &mock_socket_factory));
net::HttpRequestInfo request;
request.method = "GET";
@@ -704,10 +711,11 @@ TEST_F(HttpNetworkTransactionTest, BasicAuth) {
TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
net::ProxyInfo proxy_info;
proxy_info.UseNamedProxy("myproxy:70");
+ net::ProxyService proxy_service(new net::ProxyResolverFixed(proxy_info));
// Configure against proxy server "myproxy:70".
scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction(
- CreateSession(new net::ProxyResolverFixed(proxy_info)),
+ CreateSession(&proxy_service),
&mock_socket_factory));
net::HttpRequestInfo request;
@@ -840,8 +848,9 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
// After some maximum number of bytes is consumed, the transaction should
// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
+ scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService());
scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction(
- CreateSession(), &mock_socket_factory));
+ CreateSession(proxy_service.get()), &mock_socket_factory));
net::HttpRequestInfo request;
request.method = "GET";
@@ -882,9 +891,10 @@ TEST_F(HttpNetworkTransactionTest, DontRecycleTCPSocketForSSLTunnel) {
// Configure against proxy server "myproxy:70".
net::ProxyInfo proxy_info;
proxy_info.UseNamedProxy("myproxy:70");
+ net::ProxyService proxy_service(new net::ProxyResolverFixed(proxy_info));
scoped_refptr<net::HttpNetworkSession> session(
- CreateSession(new net::ProxyResolverFixed(proxy_info)));
+ CreateSession(&proxy_service));
scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction(
session.get(), &mock_socket_factory));
@@ -961,7 +971,9 @@ TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
request[1].upload_data->AppendBytes("foo", 3);
request[1].load_flags = 0;
- scoped_refptr<net::HttpNetworkSession> session = CreateSession();
+ scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService());
+ scoped_refptr<net::HttpNetworkSession> session =
+ CreateSession(proxy_service.get());
// The first socket is used for transaction 1 and the first attempt of
// transaction 2.
@@ -1037,8 +1049,9 @@ TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
// an identity in the URL. The request should be sent as normal, but when
// it fails the identity from the URL is used to answer the challenge.
TEST_F(HttpNetworkTransactionTest, AuthIdentityInUrl) {
+ scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService());
scoped_ptr<net::HttpTransaction> trans(new net::HttpNetworkTransaction(
- CreateSession(), &mock_socket_factory));
+ CreateSession(proxy_service.get()), &mock_socket_factory));
net::HttpRequestInfo request;
request.method = "GET";
@@ -1106,7 +1119,9 @@ TEST_F(HttpNetworkTransactionTest, AuthIdentityInUrl) {
// Test that previously tried username/passwords for a realm get re-used.
TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
- scoped_refptr<net::HttpNetworkSession> session = CreateSession();
+ scoped_ptr<net::ProxyService> proxy_service(CreateNullProxyService());
+ scoped_refptr<net::HttpNetworkSession> session =
+ CreateSession(proxy_service.get());
// Transaction 1: authenticate (foo, bar) on MyRealm1
{
diff --git a/net/http/http_transaction_winhttp.cc b/net/http/http_transaction_winhttp.cc
index 20019ef..b1ecf2a 100644
--- a/net/http/http_transaction_winhttp.cc
+++ b/net/http/http_transaction_winhttp.cc
@@ -172,7 +172,7 @@ class HttpTransactionWinHttp::Session
WINHTTP_FLAG_SECURE_PROTOCOL_TLS1
};
- Session();
+ Session(ProxyService* proxy_service);
// Opens the primary WinHttp session handle.
bool Init(const std::string& user_agent);
@@ -195,7 +195,7 @@ class HttpTransactionWinHttp::Session
// The message loop of the thread where the session was created.
MessageLoop* message_loop() { return message_loop_; }
- ProxyService* proxy_service() { return proxy_service_.get(); }
+ ProxyService* proxy_service() { return proxy_service_; }
// Gets the HTTP authentication cache for the session.
AuthCache* auth_cache() { return &auth_cache_; }
@@ -240,8 +240,7 @@ class HttpTransactionWinHttp::Session
HINTERNET internet_;
HINTERNET internet_no_tls_;
MessageLoop* message_loop_;
- scoped_ptr<ProxyService> proxy_service_;
- scoped_ptr<ProxyResolver> proxy_resolver_;
+ ProxyService* proxy_service_;
AuthCache auth_cache_;
// This event object is used when destroying a transaction. It is given
@@ -296,14 +295,12 @@ class HttpTransactionWinHttp::Session
WinHttpRequestThrottle request_throttle_;
};
-HttpTransactionWinHttp::Session::Session()
+HttpTransactionWinHttp::Session::Session(ProxyService* proxy_service)
: internet_(NULL),
internet_no_tls_(NULL),
+ proxy_service_(proxy_service),
session_callback_ref_count_(0),
quitting_(false) {
- proxy_resolver_.reset(new ProxyResolverWinHttp());
- proxy_service_.reset(new ProxyService(proxy_resolver_.get()));
-
GetSSLConfig();
// Save the current message loop for callback notifications.
@@ -321,13 +318,6 @@ HttpTransactionWinHttp::Session::Session()
}
HttpTransactionWinHttp::Session::~Session() {
- // It is important to shutdown the proxy service before closing the WinHTTP
- // session handle since the proxy service uses the WinHTTP session handle.
- proxy_service_.reset();
-
- // Next, the resolver which also references our session handle.
- proxy_resolver_.reset();
-
if (internet_) {
WinHttpCloseHandle(internet_);
if (internet_no_tls_)
@@ -745,10 +735,10 @@ HttpTransaction* HttpTransactionWinHttp::Factory::CreateTransaction() {
return NULL;
if (!session_) {
- session_ = new Session();
+ session_ = new Session(proxy_service_);
session_->AddRef();
}
- return new HttpTransactionWinHttp(session_, proxy_info_.get());
+ return new HttpTransactionWinHttp(session_, proxy_service_->proxy_info());
}
HttpCache* HttpTransactionWinHttp::Factory::GetCache() {
diff --git a/net/http/http_transaction_winhttp.h b/net/http/http_transaction_winhttp.h
index 3d46306..27ad730 100644
--- a/net/http/http_transaction_winhttp.h
+++ b/net/http/http_transaction_winhttp.h
@@ -28,13 +28,9 @@ class HttpTransactionWinHttp : public HttpTransaction {
// Instantiate this class, and use it to create HttpTransaction objects.
class Factory : public HttpTransactionFactory {
public:
- Factory() : session_(NULL), proxy_info_(NULL), is_suspended_(false) {}
- explicit Factory(const ProxyInfo* info)
- : session_(NULL), proxy_info_(NULL), is_suspended_(false) {
- if (info) {
- proxy_info_.reset(new ProxyInfo());
- proxy_info_->Use(*info);
- }
+ explicit Factory(ProxyService* proxy_service)
+ : session_(NULL), proxy_service_(proxy_service), is_suspended_(false) {
+ DCHECK(proxy_service);
}
~Factory();
@@ -44,7 +40,7 @@ class HttpTransactionWinHttp : public HttpTransaction {
private:
Session* session_;
- scoped_ptr<ProxyInfo> proxy_info_;
+ ProxyService* proxy_service_;
bool is_suspended_;
DISALLOW_EVIL_CONSTRUCTORS(Factory);
};
diff --git a/net/http/http_transaction_winhttp_unittest.cc b/net/http/http_transaction_winhttp_unittest.cc
index cf462e5..acc4e08 100644
--- a/net/http/http_transaction_winhttp_unittest.cc
+++ b/net/http/http_transaction_winhttp_unittest.cc
@@ -4,16 +4,19 @@
#include "net/http/http_transaction_winhttp.h"
#include "net/http/http_transaction_unittest.h"
+#include "net/proxy/proxy_resolver_null.h"
#include "testing/gtest/include/gtest/gtest.h"
TEST(HttpTransactionWinHttp, CreateAndDestroy) {
- net::HttpTransactionWinHttp::Factory factory;
+ net::ProxyService proxy_service(new net::ProxyResolverNull);
+ net::HttpTransactionWinHttp::Factory factory(&proxy_service);
scoped_ptr<net::HttpTransaction> trans(factory.CreateTransaction());
}
TEST(HttpTransactionWinHttp, Suspend) {
- net::HttpTransactionWinHttp::Factory factory;
+ net::ProxyService proxy_service(new net::ProxyResolverNull);
+ net::HttpTransactionWinHttp::Factory factory(&proxy_service);
scoped_ptr<net::HttpTransaction> trans(factory.CreateTransaction());
trans.reset();
@@ -29,7 +32,8 @@ TEST(HttpTransactionWinHttp, Suspend) {
}
TEST(HttpTransactionWinHttp, GoogleGET) {
- net::HttpTransactionWinHttp::Factory factory;
+ net::ProxyService proxy_service(new net::ProxyResolverNull);
+ net::HttpTransactionWinHttp::Factory factory(&proxy_service);
TestCompletionCallback callback;
scoped_ptr<net::HttpTransaction> trans(factory.CreateTransaction());
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc
index 7cfb9ac..5f0f6b2 100644
--- a/net/proxy/proxy_service.cc
+++ b/net/proxy/proxy_service.cc
@@ -17,6 +17,14 @@
#include "base/string_util.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_errors.h"
+#include "net/proxy/proxy_resolver_fixed.h"
+#include "net/proxy/proxy_resolver_null.h"
+#if defined(OS_WIN)
+#include "net/http/http_transaction_winhttp.h"
+#include "net/proxy/proxy_resolver_winhttp.h"
+#elif defined(OS_MACOSX)
+#include "net/proxy/proxy_resolver_mac.h"
+#endif
using base::TimeDelta;
using base::TimeTicks;
@@ -88,13 +96,14 @@ std::string ProxyList::Get() const {
return std::string();
}
-std::string ProxyList::GetList() const {
+std::string ProxyList::GetAnnotatedList() const {
std::string proxy_list;
std::vector<std::string>::const_iterator iter = proxies_.begin();
for (; iter != proxies_.end(); ++iter) {
if (!proxy_list.empty())
- proxy_list += L';';
-
+ proxy_list += ";";
+ // Assume every proxy is an HTTP proxy, as that is all we currently support.
+ proxy_list += "PROXY ";
proxy_list += *iter;
}
@@ -168,6 +177,10 @@ void ProxyInfo::Apply(HINTERNET request_handle) {
}
#endif
+std::string ProxyInfo::GetAnnotatedProxyList() {
+ return is_direct() ? "DIRECT" : proxy_list_.GetAnnotatedList();
+}
+
// ProxyService::PacRequest ---------------------------------------------------
// We rely on the fact that the origin thread (and its message loop) will not
@@ -261,8 +274,35 @@ class ProxyService::PacRequest :
ProxyService::ProxyService(ProxyResolver* resolver)
: resolver_(resolver),
- config_is_bad_(false) {
- UpdateConfig();
+ config_is_bad_(false),
+ config_has_been_updated_(false) {
+}
+
+// static
+ProxyService* ProxyService::Create(const ProxyInfo* pi) {
+ if (pi) {
+ ProxyService* proxy_service =
+ new ProxyService(new ProxyResolverFixed(*pi));
+
+ // TODO(eroman): remove this WinHTTP hack once it is no more.
+ // We keep a copy of the ProxyInfo that was used to create the
+ // proxy service, so we can pass it to WinHTTP.
+ proxy_service->proxy_info_.reset(new ProxyInfo(*pi));
+
+ return proxy_service;
+ }
+#if defined(OS_WIN)
+ return new ProxyService(new ProxyResolverWinHttp());
+#elif defined(OS_MACOSX)
+ return new ProxyService(new ProxyResolverMac());
+#else
+ // This used to be a NOTIMPLEMENTED(), but that logs as an error,
+ // screwing up layout tests.
+ LOG(WARNING) << "Proxies are not implemented; remove me once that's fixed.";
+ // http://code.google.com/p/chromium/issues/detail?id=4523 is the bug
+ // to implement this.
+ return new ProxyService(new ProxyResolverNull());
+#endif
}
int ProxyService::ResolveProxy(const GURL& url, ProxyInfo* result,
@@ -272,7 +312,8 @@ int ProxyService::ResolveProxy(const GURL& url, ProxyInfo* result,
const TimeDelta kProxyConfigMaxAge = TimeDelta::FromSeconds(5);
// Periodically check for a new config.
- if ((TimeTicks::Now() - config_last_update_time_) > kProxyConfigMaxAge)
+ if (!config_has_been_updated_ ||
+ (TimeTicks::Now() - config_last_update_time_) > kProxyConfigMaxAge)
UpdateConfig();
result->config_id_ = config_.id();
@@ -437,6 +478,8 @@ void ProxyService::DidCompletePacRequest(int config_id, int result_code) {
}
void ProxyService::UpdateConfig() {
+ config_has_been_updated_ = true;
+
ProxyConfig latest;
if (resolver_->GetProxyConfig(&latest) != OK)
return;
diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h
index ea83509..bea4aef 100644
--- a/net/proxy/proxy_service.h
+++ b/net/proxy/proxy_service.h
@@ -36,7 +36,7 @@ class ProxyConfig {
enum { INVALID_ID = 0 };
ProxyConfig();
- // Default copy-constructor an assignment operator are OK!
+ // Default copy-constructor and assignment operator are OK!
// Used to numerically identify this configuration.
ID id() const { return id_; }
@@ -55,7 +55,7 @@ class ProxyConfig {
// 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;
@@ -81,12 +81,11 @@ struct ProxyRetryInfo {
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 to the given ProxyResolver to handle the actual proxy
-// resolution. See ProxyResolverWinHttp for example. The consumer of this
-// class is responsible for ensuring that the ProxyResolver instance remains
-// valid for the lifetime of the ProxyService.
+// HTTP(S) URL. It uses the given ProxyResolver to handle the actual proxy
+// resolution. See ProxyResolverWinHttp for example.
class ProxyService {
public:
+ // The instance takes ownership of |resolver|.
explicit ProxyService(ProxyResolver* resolver);
// Used internally to handle PAC queries.
@@ -100,7 +99,8 @@ class ProxyService {
// The caller is responsible for ensuring that |results| and |callback|
// remain valid until the callback is run or until |pac_request| is cancelled
// via CancelPacRequest. |pac_request| is only valid while the completion
- // callback is still pending.
+ // callback is still pending. NULL can be passed for |pac_request| if
+ // the caller will not need to cancel the request.
//
// We use the three possible proxy access types in the following order, and
// we only use one of them (no falling back to other access types if the
@@ -120,6 +120,9 @@ class ProxyService {
// to ResolveProxy. The semantics of this call are otherwise similar to
// ResolveProxy.
//
+ // NULL can be passed for |pac_request| if the caller will not need to
+ // cancel the request.
+ //
// Returns ERR_FAILED if there is not another proxy config to try.
//
int ReconsiderProxyAfterError(const GURL& url,
@@ -130,10 +133,21 @@ class ProxyService {
// Call this method with a non-null |pac_request| to cancel the PAC request.
void CancelPacRequest(PacRequest* pac_request);
+ // 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).
+ static ProxyService* Create(const ProxyInfo* pi);
+
+ // TODO(eroman): remove once WinHTTP is gone.
+ // Get the ProxyInfo used to create this proxy service (only used by WinHTTP).
+ const ProxyInfo* proxy_info() const {
+ return proxy_info_.get();
+ }
+
private:
friend class PacRequest;
- ProxyResolver* resolver() { return resolver_; }
+ ProxyResolver* resolver() { return resolver_.get(); }
base::Thread* pac_thread() { return pac_thread_.get(); }
// Identifies the proxy configuration.
@@ -155,16 +169,22 @@ class ProxyService {
// 2. The URL matches one of the entities in the proxy bypass list.
bool ShouldBypassProxyForURL(const GURL& url);
- ProxyResolver* resolver_;
+ scoped_ptr<ProxyResolver> resolver_;
scoped_ptr<base::Thread> pac_thread_;
- // We store the IE proxy config and a counter that is incremented each time
+ // We store the proxy config and a counter that is incremented each time
// the config changes.
ProxyConfig config_;
+ // TODO(eroman): remove this once WinHTTP stack is gone.
+ scoped_ptr<ProxyInfo> proxy_info_;
+
// Indicates that the configuration is bad and should be ignored.
bool config_is_bad_;
+ // false if the ProxyService has not been initialized yet.
+ bool config_has_been_updated_;
+
// The time when the proxy configuration was last read from the system.
base::TimeTicks config_last_update_time_;
@@ -177,6 +197,8 @@ class 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.
+// TODO(eroman): The proxy list should work for multiple proxy types.
+// See http://crbug.com/469.
class ProxyList {
public:
// Initializes the proxy list to a string containing one or more proxy servers
@@ -193,8 +215,11 @@ class ProxyList {
// Returns the first valid proxy server in the list.
std::string Get() const;
- // Returns all the valid proxies, delimited by a semicolon.
- std::string GetList() const;
+ // Returns a PAC-style semicolon-separated list of valid proxy servers.
+ // For example: "PROXY xxx.xxx.xxx.xxx:xx; SOCKS yyy.yyy.yyy:yy".
+ // Since ProxyList is currently just used for HTTP, this will return only
+ // entries of type "PROXY" or "DIRECT".
+ std::string GetAnnotatedList() 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
@@ -210,6 +235,7 @@ class ProxyList {
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);
@@ -232,6 +258,9 @@ class ProxyInfo {
// Returns the first valid proxy server.
std::string proxy_server() const { return proxy_list_.Get(); }
+ // See description in ProxyList::GetAnnotatedList().
+ std::string GetAnnotatedProxyList();
+
// 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) {
@@ -257,8 +286,6 @@ class ProxyInfo {
// proxy info does not yield a connection that we might want to reconsider
// the proxy config given by config_id_.
bool config_was_tried_;
-
- DISALLOW_COPY_AND_ASSIGN(ProxyInfo);
};
// This interface provides the low-level functions to access the proxy
diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc
index 16a1649..1ad7d32 100644
--- a/net/proxy/proxy_service_unittest.cc
+++ b/net/proxy/proxy_service_unittest.cc
@@ -12,16 +12,18 @@ namespace {
class MockProxyResolver : public net::ProxyResolver {
public:
MockProxyResolver() : fail_get_proxy_for_url(false) {
- config.reset(new net::ProxyConfig);
+ }
+ // Init the MockProxyResolver with the specified ProxyConfig.
+ explicit MockProxyResolver(const net::ProxyConfig& c) : config(c) {
}
virtual int GetProxyConfig(net::ProxyConfig* results) {
- *results = *(config.get());
+ *results = config;
return net::OK;
}
virtual int GetProxyForURL(const GURL& query_url,
const GURL& pac_url,
net::ProxyInfo* results) {
- if (pac_url != config->pac_url)
+ if (pac_url != config.pac_url)
return net::ERR_INVALID_ARGUMENT;
if (fail_get_proxy_for_url)
return net::ERR_FAILED;
@@ -32,7 +34,7 @@ class MockProxyResolver : public net::ProxyResolver {
}
return net::OK;
}
- scoped_ptr<net::ProxyConfig> config;
+ net::ProxyConfig config;
net::ProxyInfo info;
// info is only returned if query_url in GetProxyForURL matches this:
@@ -45,9 +47,22 @@ class MockProxyResolver : public net::ProxyResolver {
} // namespace
+// GetAnnotatedList() is used to generate a string for mozilla's GetProxyForUrl
+// NPAPI extension. Check that it adheres to the expected format.
+TEST(ProxyListTest, GetAnnotatedList) {
+ net::ProxyList proxy_list;
+
+ std::vector<std::string> proxies;
+ proxies.push_back("www.first.com:80");
+ proxies.push_back("www.second.com:80");
+ proxy_list.SetVector(proxies);
+
+ EXPECT_EQ(std::string("PROXY www.first.com:80;PROXY www.second.com:80"),
+ proxy_list.GetAnnotatedList());
+}
+
TEST(ProxyServiceTest, Direct) {
- MockProxyResolver resolver;
- net::ProxyService service(&resolver);
+ net::ProxyService service(new MockProxyResolver);
GURL url("http://www.google.com/");
@@ -58,12 +73,12 @@ TEST(ProxyServiceTest, Direct) {
}
TEST(ProxyServiceTest, PAC) {
- MockProxyResolver resolver;
- resolver.config->pac_url = GURL("http://foopy/proxy.pac");
- resolver.info.UseNamedProxy("foopy");
- resolver.info_predicate_query_host = "www.google.com";
+ MockProxyResolver* resolver = new MockProxyResolver;
+ resolver->config.pac_url = GURL("http://foopy/proxy.pac");
+ resolver->info.UseNamedProxy("foopy");
+ resolver->info_predicate_query_host = "www.google.com";
- net::ProxyService service(&resolver);
+ net::ProxyService service(resolver);
GURL url("http://www.google.com/");
@@ -75,12 +90,12 @@ TEST(ProxyServiceTest, PAC) {
}
TEST(ProxyServiceTest, PAC_FailoverToDirect) {
- MockProxyResolver resolver;
- resolver.config->pac_url = GURL("http://foopy/proxy.pac");
- resolver.info.UseNamedProxy("foopy:8080");
- resolver.info_predicate_query_host = "www.google.com";
+ MockProxyResolver* resolver = new MockProxyResolver;
+ resolver->config.pac_url = GURL("http://foopy/proxy.pac");
+ resolver->info.UseNamedProxy("foopy:8080");
+ resolver->info_predicate_query_host = "www.google.com";
- net::ProxyService service(&resolver);
+ net::ProxyService service(resolver);
GURL url("http://www.google.com/");
@@ -99,13 +114,13 @@ TEST(ProxyServiceTest, PAC_FailoverToDirect) {
TEST(ProxyServiceTest, PAC_FailsToDownload) {
// Test what happens when we fail to download the PAC URL.
- MockProxyResolver resolver;
- resolver.config->pac_url = GURL("http://foopy/proxy.pac");
- resolver.info.UseNamedProxy("foopy:8080");
- resolver.info_predicate_query_host = "www.google.com";
- resolver.fail_get_proxy_for_url = true;
+ MockProxyResolver* resolver = new MockProxyResolver;
+ resolver->config.pac_url = GURL("http://foopy/proxy.pac");
+ resolver->info.UseNamedProxy("foopy:8080");
+ resolver->info_predicate_query_host = "www.google.com";
+ resolver->fail_get_proxy_for_url = true;
- net::ProxyService service(&resolver);
+ net::ProxyService service(resolver);
GURL url("http://www.google.com/");
net::ProxyInfo info;
@@ -117,8 +132,8 @@ TEST(ProxyServiceTest, PAC_FailsToDownload) {
EXPECT_EQ(rv, net::OK);
EXPECT_TRUE(info.is_direct());
- resolver.fail_get_proxy_for_url = false;
- resolver.info.UseNamedProxy("foopy_valid:8080");
+ resolver->fail_get_proxy_for_url = false;
+ resolver->info.UseNamedProxy("foopy_valid:8080");
// But, if that fails, then we should give the proxy config another shot
// since we have never tried it with this URL before.
@@ -132,13 +147,13 @@ TEST(ProxyServiceTest, ProxyFallback) {
// Test what happens when we specify multiple proxy servers and some of them
// are bad.
- MockProxyResolver resolver;
- resolver.config->pac_url = GURL("http://foopy/proxy.pac");
- resolver.info.UseNamedProxy("foopy1:8080;foopy2:9090");
- resolver.info_predicate_query_host = "www.google.com";
- resolver.fail_get_proxy_for_url = false;
+ MockProxyResolver* resolver = new MockProxyResolver;
+ resolver->config.pac_url = GURL("http://foopy/proxy.pac");
+ resolver->info.UseNamedProxy("foopy1:8080;foopy2:9090");
+ resolver->info_predicate_query_host = "www.google.com";
+ resolver->fail_get_proxy_for_url = false;
- net::ProxyService service(&resolver);
+ net::ProxyService service(resolver);
GURL url("http://www.google.com/");
@@ -160,10 +175,10 @@ TEST(ProxyServiceTest, ProxyFallback) {
// Create a new resolver that returns 3 proxies. The second one is already
// known to be bad.
- resolver.config->pac_url = GURL("http://foopy/proxy.pac");
- resolver.info.UseNamedProxy("foopy3:7070;foopy1:8080;foopy2:9090");
- resolver.info_predicate_query_host = "www.google.com";
- resolver.fail_get_proxy_for_url = false;
+ resolver->config.pac_url = GURL("http://foopy/proxy.pac");
+ resolver->info.UseNamedProxy("foopy3:7070;foopy1:8080;foopy2:9090");
+ resolver->info_predicate_query_host = "www.google.com";
+ resolver->fail_get_proxy_for_url = false;
rv = service.ResolveProxy(url, &info, NULL, NULL);
EXPECT_EQ(rv, net::OK);
@@ -190,13 +205,13 @@ TEST(ProxyServiceTest, ProxyFallback) {
TEST(ProxyServiceTest, ProxyFallback_NewSettings) {
// Test proxy failover when new settings are available.
- MockProxyResolver resolver;
- resolver.config->pac_url = GURL("http://foopy/proxy.pac");
- resolver.info.UseNamedProxy("foopy1:8080;foopy2:9090");
- resolver.info_predicate_query_host = "www.google.com";
- resolver.fail_get_proxy_for_url = false;
+ MockProxyResolver* resolver = new MockProxyResolver;
+ resolver->config.pac_url = GURL("http://foopy/proxy.pac");
+ resolver->info.UseNamedProxy("foopy1:8080;foopy2:9090");
+ resolver->info_predicate_query_host = "www.google.com";
+ resolver->fail_get_proxy_for_url = false;
- net::ProxyService service(&resolver);
+ net::ProxyService service(resolver);
GURL url("http://www.google.com/");
@@ -210,8 +225,8 @@ TEST(ProxyServiceTest, ProxyFallback_NewSettings) {
EXPECT_EQ(info.proxy_server(), "foopy1:8080");
// Fake an error on the proxy, and also a new configuration on the proxy.
- resolver.config.reset(new net::ProxyConfig);
- resolver.config->pac_url = GURL("http://foopy-new/proxy.pac");
+ resolver->config = net::ProxyConfig();
+ resolver->config.pac_url = GURL("http://foopy-new/proxy.pac");
rv = service.ReconsiderProxyAfterError(url, &info, NULL, NULL);
EXPECT_EQ(rv, net::OK);
@@ -225,8 +240,8 @@ TEST(ProxyServiceTest, ProxyFallback_NewSettings) {
EXPECT_EQ(info.proxy_server(), "foopy2:9090");
// We simulate a new configuration.
- resolver.config.reset(new net::ProxyConfig);
- resolver.config->pac_url = GURL("http://foopy-new2/proxy.pac");
+ resolver->config = net::ProxyConfig();
+ resolver->config.pac_url = GURL("http://foopy-new2/proxy.pac");
// We fake anothe error. It should go back to the first proxy.
rv = service.ReconsiderProxyAfterError(url, &info, NULL, NULL);
@@ -237,13 +252,13 @@ TEST(ProxyServiceTest, ProxyFallback_NewSettings) {
TEST(ProxyServiceTest, ProxyFallback_BadConfig) {
// Test proxy failover when the configuration is bad.
- MockProxyResolver resolver;
- resolver.config->pac_url = GURL("http://foopy/proxy.pac");
- resolver.info.UseNamedProxy("foopy1:8080;foopy2:9090");
- resolver.info_predicate_query_host = "www.google.com";
- resolver.fail_get_proxy_for_url = false;
+ MockProxyResolver* resolver = new MockProxyResolver;
+ resolver->config.pac_url = GURL("http://foopy/proxy.pac");
+ resolver->info.UseNamedProxy("foopy1:8080;foopy2:9090");
+ resolver->info_predicate_query_host = "www.google.com";
+ resolver->fail_get_proxy_for_url = false;
- net::ProxyService service(&resolver);
+ net::ProxyService service(resolver);
GURL url("http://www.google.com/");
@@ -266,7 +281,7 @@ TEST(ProxyServiceTest, ProxyFallback_BadConfig) {
// Fake a PAC failure.
net::ProxyInfo info2;
- resolver.fail_get_proxy_for_url = true;
+ resolver->fail_get_proxy_for_url = true;
rv = service.ResolveProxy(url, &info2, NULL, NULL);
EXPECT_EQ(rv, net::OK);
@@ -275,7 +290,7 @@ TEST(ProxyServiceTest, ProxyFallback_BadConfig) {
// The PAC is now fixed and will return a proxy server.
// It should also clear the list of bad proxies.
- resolver.fail_get_proxy_for_url = false;
+ resolver->fail_get_proxy_for_url = false;
// Try to resolve, it will still return "direct" because we have no reason
// to check the config since everything works.
@@ -298,12 +313,12 @@ TEST(ProxyServiceTest, ProxyFallback_BadConfig) {
TEST(ProxyServiceTest, ProxyBypassList) {
// Test what happens when a proxy bypass list is specified.
- MockProxyResolver resolver;
- resolver.config->proxy_server = "foopy1:8080;foopy2:9090";
- resolver.config->auto_detect = false;
- resolver.config->proxy_bypass_local_names = true;
-
- net::ProxyService service(&resolver);
+ net::ProxyConfig config;
+ config.proxy_server = "foopy1:8080;foopy2:9090";
+ config.auto_detect = false;
+ config.proxy_bypass_local_names = true;
+
+ net::ProxyService service(new MockProxyResolver(config));
GURL url("http://www.google.com/");
// Get the proxy information.
net::ProxyInfo info;
@@ -311,58 +326,63 @@ TEST(ProxyServiceTest, ProxyBypassList) {
EXPECT_EQ(rv, net::OK);
EXPECT_FALSE(info.is_direct());
- net::ProxyService service1(&resolver);
+ net::ProxyService service1(new MockProxyResolver(config));
GURL test_url1("local");
net::ProxyInfo info1;
rv = service1.ResolveProxy(test_url1, &info1, NULL, NULL);
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;
- net::ProxyService service2(&resolver);
+ config.proxy_bypass.clear();
+ config.proxy_bypass.push_back("*.org");
+ config.proxy_bypass_local_names = true;
+ MockProxyResolver* resolver = new MockProxyResolver(config);
+ net::ProxyService service2(resolver);
GURL test_url2("http://www.webkit.org");
net::ProxyInfo info2;
rv = service2.ResolveProxy(test_url2, &info2, NULL, NULL);
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;
- net::ProxyService service3(&resolver);
+ config.proxy_bypass.clear();
+ config.proxy_bypass.push_back("*.org");
+ config.proxy_bypass.push_back("7*");
+ config.proxy_bypass_local_names = true;
+ resolver = new MockProxyResolver(config);
+ net::ProxyService service3(resolver);
GURL test_url3("http://74.125.19.147");
net::ProxyInfo info3;
rv = service3.ResolveProxy(test_url3, &info3, NULL, NULL);
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;
- net::ProxyService service4(&resolver);
+ config.proxy_bypass.clear();
+ config.proxy_bypass.push_back("*.org");
+ config.proxy_bypass_local_names = true;
+ resolver = new MockProxyResolver(config);
+ net::ProxyService service4(resolver);
GURL test_url4("http://www.msn.com");
net::ProxyInfo info4;
rv = service4.ResolveProxy(test_url4, &info4, NULL, NULL);
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;
- net::ProxyService service5(&resolver);
+ config.proxy_bypass.clear();
+ config.proxy_bypass.push_back("*.MSN.COM");
+ config.proxy_bypass_local_names = true;
+ resolver = new MockProxyResolver(config);
+ net::ProxyService service5(resolver);
GURL test_url5("http://www.msnbc.msn.com");
net::ProxyInfo info5;
rv = service5.ResolveProxy(test_url5, &info5, NULL, NULL);
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;
- net::ProxyService service6(&resolver);
+ config.proxy_bypass.clear();
+ config.proxy_bypass.push_back("*.msn.com");
+ config.proxy_bypass_local_names = true;
+ resolver = new MockProxyResolver(config);
+ net::ProxyService service6(resolver);
GURL test_url6("HTTP://WWW.MSNBC.MSN.COM");
net::ProxyInfo info6;
rv = service6.ResolveProxy(test_url6, &info6, NULL, NULL);
@@ -371,11 +391,11 @@ TEST(ProxyServiceTest, ProxyBypassList) {
}
TEST(ProxyServiceTest, PerProtocolProxyTests) {
- MockProxyResolver resolver;
- resolver.config->proxy_server = "http=foopy1:8080;https=foopy2:8080";
- resolver.config->auto_detect = false;
+ net::ProxyConfig config;
+ config.proxy_server = "http=foopy1:8080;https=foopy2:8080";
+ config.auto_detect = false;
- net::ProxyService service1(&resolver);
+ net::ProxyService service1(new MockProxyResolver(config));
GURL test_url1("http://www.msn.com");
net::ProxyInfo info1;
int rv = service1.ResolveProxy(test_url1, &info1, NULL, NULL);
@@ -383,7 +403,7 @@ TEST(ProxyServiceTest, PerProtocolProxyTests) {
EXPECT_FALSE(info1.is_direct());
EXPECT_TRUE(info1.proxy_server() == "foopy1:8080");
- net::ProxyService service2(&resolver);
+ net::ProxyService service2(new MockProxyResolver(config));
GURL test_url2("ftp://ftp.google.com");
net::ProxyInfo info2;
rv = service2.ResolveProxy(test_url2, &info2, NULL, NULL);
@@ -391,7 +411,7 @@ TEST(ProxyServiceTest, PerProtocolProxyTests) {
EXPECT_TRUE(info2.is_direct());
EXPECT_TRUE(info2.proxy_server() == "");
- net::ProxyService service3(&resolver);
+ net::ProxyService service3(new MockProxyResolver(config));
GURL test_url3("https://webbranch.techcu.com");
net::ProxyInfo info3;
rv = service3.ResolveProxy(test_url3, &info3, NULL, NULL);
@@ -399,8 +419,9 @@ TEST(ProxyServiceTest, PerProtocolProxyTests) {
EXPECT_FALSE(info3.is_direct());
EXPECT_TRUE(info3.proxy_server() == "foopy2:8080");
- resolver.config->proxy_server = "foopy1:8080";
- net::ProxyService service4(&resolver);
+ MockProxyResolver* resolver = new MockProxyResolver(config);
+ resolver->config.proxy_server = "foopy1:8080";
+ net::ProxyService service4(resolver);
GURL test_url4("www.microsoft.com");
net::ProxyInfo info4;
rv = service4.ResolveProxy(test_url4, &info4, NULL, NULL);
diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h
index 2cab534..5ea25db 100644
--- a/net/url_request/url_request_context.h
+++ b/net/url_request/url_request_context.h
@@ -21,6 +21,7 @@
namespace net {
class CookieMonster;
+class ProxyService;
}
// Subclass to provide application-specific context for URLRequest instances.
@@ -28,11 +29,17 @@ class URLRequestContext :
public base::RefCountedThreadSafe<URLRequestContext> {
public:
URLRequestContext()
- : http_transaction_factory_(NULL),
+ : proxy_service_(NULL),
+ http_transaction_factory_(NULL),
cookie_store_(NULL),
is_off_the_record_(false) {
}
+ // Get the proxy service for this context.
+ net::ProxyService* proxy_service() const {
+ return proxy_service_;
+ }
+
// Gets the http transaction factory for this context.
net::HttpTransactionFactory* http_transaction_factory() {
return http_transaction_factory_;
@@ -66,6 +73,7 @@ class URLRequestContext :
protected:
// The following members are expected to be initialized and owned by
// subclasses.
+ net::ProxyService* proxy_service_;
net::HttpTransactionFactory* http_transaction_factory_;
net::CookieMonster* cookie_store_;
net::CookiePolicy cookie_policy_;
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 83d5744..4a82c4e 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -29,6 +29,8 @@
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_cache.h"
#include "net/http/http_network_layer.h"
+#include "net/proxy/proxy_resolver_null.h"
+#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -40,13 +42,15 @@ namespace {
class URLRequestHttpCacheContext : public URLRequestContext {
public:
URLRequestHttpCacheContext() {
+ proxy_service_ = new net::ProxyService(new net::ProxyResolverNull);
http_transaction_factory_ =
- new net::HttpCache(net::HttpNetworkLayer::CreateFactory(NULL),
+ new net::HttpCache(net::HttpNetworkLayer::CreateFactory(proxy_service_),
disk_cache::CreateInMemoryCacheBackend(0));
}
virtual ~URLRequestHttpCacheContext() {
delete http_transaction_factory_;
+ delete proxy_service_;
}
};
diff --git a/net/url_request/url_request_unittest.h b/net/url_request/url_request_unittest.h
index c0c62a3..786f40a 100644
--- a/net/url_request/url_request_unittest.h
+++ b/net/url_request/url_request_unittest.h
@@ -20,6 +20,8 @@
#include "net/base/net_errors.h"
#include "net/http/http_network_layer.h"
#include "net/url_request/url_request.h"
+#include "net/proxy/proxy_resolver_null.h"
+#include "net/proxy/proxy_service.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "googleurl/src/url_util.h"
@@ -30,11 +32,14 @@ const std::string kDefaultHostName("localhost");
class TestURLRequestContext : public URLRequestContext {
public:
TestURLRequestContext() {
- http_transaction_factory_ = net::HttpNetworkLayer::CreateFactory(NULL);
+ proxy_service_ = new net::ProxyService(new net::ProxyResolverNull);
+ http_transaction_factory_ =
+ net::HttpNetworkLayer::CreateFactory(proxy_service_);
}
virtual ~TestURLRequestContext() {
delete http_transaction_factory_;
+ delete proxy_service_;
}
};