diff options
-rw-r--r-- | net/http/http_network_session.cc | 1 | ||||
-rw-r--r-- | net/http/http_network_session.h | 6 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 65 | ||||
-rw-r--r-- | net/http/http_stream_factory.cc | 33 | ||||
-rw-r--r-- | net/http/http_stream_factory.h | 30 | ||||
-rw-r--r-- | net/http/http_stream_factory_unittest.cc | 236 | ||||
-rw-r--r-- | net/http/http_stream_request.cc | 138 | ||||
-rw-r--r-- | net/http/http_stream_request.h | 31 | ||||
-rw-r--r-- | net/http/stream_factory.h | 19 | ||||
-rw-r--r-- | net/net.gyp | 1 | ||||
-rw-r--r-- | net/proxy/proxy_service.cc | 7 | ||||
-rw-r--r-- | net/proxy/proxy_service.h | 5 | ||||
-rw-r--r-- | net/socket/client_socket_pool.h | 23 |
13 files changed, 497 insertions, 98 deletions
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index 056feaf..410d9e6 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc @@ -40,7 +40,6 @@ HttpNetworkSession::HttpNetworkSession( proxy_service, ssl_config_service), spdy_session_pool_(spdy_session_pool), - http_stream_factory_(new HttpStreamFactory()), http_auth_handler_factory_(http_auth_handler_factory), network_delegate_(network_delegate), net_log_(net_log) { diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index e23ecd6..bf5e98b 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h @@ -116,8 +116,8 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession>, return network_delegate_; } - const scoped_refptr<HttpStreamFactory>& http_stream_factory() { - return http_stream_factory_; + HttpStreamFactory* http_stream_factory() { + return &http_stream_factory_; } // Creates a Value summary of the state of the socket pools. The caller is @@ -152,7 +152,7 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession>, // TODO(willchan): Move this out to IOThread so it can be shared across // URLRequestContexts. scoped_ptr<SpdySessionPool> spdy_session_pool_; - scoped_refptr<HttpStreamFactory> http_stream_factory_; + HttpStreamFactory http_stream_factory_; HttpAuthHandlerFactory* http_auth_handler_factory_; HttpNetworkDelegate* const network_delegate_; NetLog* net_log_; diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index e37eea6..a935df9 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -96,12 +96,6 @@ struct SessionDependencies { NetLog* net_log; }; -ProxyService* CreateFixedProxyService(const std::string& proxy) { - net::ProxyConfig proxy_config; - proxy_config.proxy_rules().ParseFromString(proxy); - return ProxyService::CreateFixed(proxy_config); -} - HttpNetworkSession* CreateSession(SessionDependencies* session_deps) { return new HttpNetworkSession(session_deps->host_resolver.get(), NULL /* dnsrr_resolver */, @@ -260,9 +254,6 @@ class CaptureGroupNameSocketPool : public ParentPool { virtual void ReleaseSocket(const std::string& group_name, ClientSocket* socket) {} virtual void CloseIdleSockets() {} - virtual HostResolver* GetHostResolver() const { - return NULL; - } virtual int IdleSocketCount() const { return 0; } @@ -1401,7 +1392,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) { // that requires a restart when setting up an SSL tunnel. TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { // Configure against proxy server "myproxy:70". - SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); CapturingBoundNetLog log(CapturingNetLog::kUnbounded); session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); @@ -1509,7 +1500,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) { // proxy connection, when setting up an SSL tunnel. TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) { // Configure against proxy server "myproxy:70". - SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); CapturingBoundNetLog log(CapturingNetLog::kUnbounded); session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); @@ -1621,7 +1612,7 @@ TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) { // even if the user cancels the proxy's auth attempt. TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) { // Configure against proxy server "myproxy:70". - SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); @@ -1719,7 +1710,7 @@ TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) { // Test a simple get through an HTTPS Proxy. TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) { // Configure against https proxy server "proxy:70". - SessionDependencies session_deps(CreateFixedProxyService("https://proxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); CapturingBoundNetLog log(CapturingNetLog::kUnbounded); session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); @@ -1773,7 +1764,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) { // Test a SPDY get through an HTTPS Proxy. TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) { // Configure against https proxy server "proxy:70". - SessionDependencies session_deps(CreateFixedProxyService("https://proxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); CapturingBoundNetLog log(CapturingNetLog::kUnbounded); session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); @@ -1832,7 +1823,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) { // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server. TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) { // Configure against https proxy server "proxy:70". - SessionDependencies session_deps(CreateFixedProxyService("https://proxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); CapturingBoundNetLog log(CapturingNetLog::kUnbounded); session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); @@ -1910,7 +1901,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) { // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server. TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) { // Configure against https proxy server "proxy:70". - SessionDependencies session_deps(CreateFixedProxyService("https://proxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); CapturingBoundNetLog log(CapturingNetLog::kUnbounded); session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); @@ -1984,7 +1975,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) { // Test a SPDY CONNECT failure through an HTTPS Proxy. TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) { // Configure against https proxy server "proxy:70". - SessionDependencies session_deps(CreateFixedProxyService("https://proxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); CapturingBoundNetLog log(CapturingNetLog::kUnbounded); session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); @@ -2044,7 +2035,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) { // Test the challenge-response-retry sequence through an HTTPS Proxy TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) { // Configure against https proxy server "proxy:70". - SessionDependencies session_deps(CreateFixedProxyService("https://proxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); CapturingBoundNetLog log(CapturingNetLog::kUnbounded); session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); @@ -2136,7 +2127,7 @@ TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) { void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus( const MockRead& status, int expected_status) { // Configure against proxy server "myproxy:70". - SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); @@ -2347,7 +2338,7 @@ TEST_F(HttpNetworkTransactionTest, ConnectStatus505) { // authentication. Again, this uses basic auth for both since that is // the simplest to mock. TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) { - SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); // Configure against proxy server "myproxy:70". scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction( @@ -2858,7 +2849,7 @@ TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) { // http://code.google.com/p/chromium/issues/detail?id=3772 TEST_F(HttpNetworkTransactionTest, DontRecycleTCPSocketForSSLTunnel) { // Configure against proxy server "myproxy:70". - SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); @@ -4090,7 +4081,7 @@ TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) { // Test HTTPS connections to a site with a bad certificate, going through a // proxy TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) { - SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); HttpRequestInfo request; request.method = "GET"; @@ -4168,7 +4159,7 @@ TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) { // Test HTTPS connections to a site, going through an HTTPS proxy TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) { - SessionDependencies session_deps(CreateFixedProxyService("https://proxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); HttpRequestInfo request; request.method = "GET"; @@ -4224,7 +4215,7 @@ TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) { // Test HTTPS connections to a site with a bad certificate, going through an // HTTPS proxy TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) { - SessionDependencies session_deps(CreateFixedProxyService("https://proxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70")); HttpRequestInfo request; request.method = "GET"; @@ -4342,7 +4333,7 @@ TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) { } TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) { - SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(CreateSession(&session_deps))); @@ -4688,7 +4679,7 @@ TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) { TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) { SessionDependencies session_deps( - CreateFixedProxyService("socks4://myproxy:1080")); + ProxyService::CreateFixed("socks4://myproxy:1080")); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(CreateSession(&session_deps))); @@ -4739,7 +4730,7 @@ TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) { TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) { SessionDependencies session_deps( - CreateFixedProxyService("socks4://myproxy:1080")); + ProxyService::CreateFixed("socks4://myproxy:1080")); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(CreateSession(&session_deps))); @@ -4795,7 +4786,7 @@ TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) { TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) { SessionDependencies session_deps( - CreateFixedProxyService("socks5://myproxy:1080")); + ProxyService::CreateFixed("socks5://myproxy:1080")); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(CreateSession(&session_deps))); @@ -4860,7 +4851,7 @@ TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) { TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) { SessionDependencies session_deps( - CreateFixedProxyService("socks5://myproxy:1080")); + ProxyService::CreateFixed("socks5://myproxy:1080")); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(CreateSession(&session_deps))); @@ -4939,7 +4930,7 @@ struct GroupNameTest { scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests( const std::string& proxy_server) { - SessionDependencies session_deps(CreateFixedProxyService(proxy_server)); + SessionDependencies session_deps(ProxyService::CreateFixed(proxy_server)); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); HttpAlternateProtocols* alternate_protocols = @@ -5151,7 +5142,7 @@ TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) { TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) { SessionDependencies session_deps( - CreateFixedProxyService("myproxy:70;foobar:80")); + ProxyService::CreateFixed("myproxy:70;foobar:80")); // This simulates failure resolving all hostnames; that means we will fail // connecting to both proxies (myproxy:70 and foobar:80). @@ -5477,7 +5468,7 @@ TEST_F(HttpNetworkTransactionTest, DrainResetOK) { // Test HTTPS connections going through a proxy that sends extra data. TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) { - SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); HttpRequestInfo request; request.method = "GET"; @@ -6801,7 +6792,7 @@ TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) { } if (test_config.proxy_url) { session_deps.proxy_service = - CreateFixedProxyService(test_config.proxy_url); + ProxyService::CreateFixed(test_config.proxy_url); } else { session_deps.proxy_service = ProxyService::CreateDirect(); } @@ -7218,7 +7209,7 @@ TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) { HttpStreamFactory::set_next_protos( "\x08http/1.1\x07http1.1\x06spdy/2\x04spdy"); - SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); HttpAuthHandlerMock::Factory* auth_factory = new HttpAuthHandlerMock::Factory(); HttpAuthHandlerMock* auth_handler = new HttpAuthHandlerMock(); @@ -7394,7 +7385,7 @@ TEST_F(HttpNetworkTransactionTest, SimpleCancel) { // Test a basic GET request through a proxy. TEST_F(HttpNetworkTransactionTest, ProxyGet) { - SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); CapturingBoundNetLog log(CapturingNetLog::kUnbounded); session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); @@ -7442,7 +7433,7 @@ TEST_F(HttpNetworkTransactionTest, ProxyGet) { // Test a basic HTTPS GET request through a proxy. TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) { - SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); CapturingBoundNetLog log(CapturingNetLog::kUnbounded); session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); @@ -7507,7 +7498,7 @@ TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) { // Test a basic HTTPS GET request through a proxy, but the server hangs up // while establishing the tunnel. TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) { - SessionDependencies session_deps(CreateFixedProxyService("myproxy:70")); + SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70")); CapturingBoundNetLog log(CapturingNetLog::kUnbounded); session_deps.net_log = log.bound().net_log(); scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); diff --git a/net/http/http_stream_factory.cc b/net/http/http_stream_factory.cc index 9342564..1ddd1c2 100644 --- a/net/http/http_stream_factory.cc +++ b/net/http/http_stream_factory.cc @@ -42,6 +42,13 @@ HttpStreamFactory::HttpStreamFactory() { } HttpStreamFactory::~HttpStreamFactory() { + RequestCallbackMap request_callback_map; + request_callback_map.swap(request_callback_map_); + for (RequestCallbackMap::iterator it = request_callback_map.begin(); + it != request_callback_map.end(); ++it) { + delete it->first; + // We don't invoke the callback in the destructor. + } } StreamRequest* HttpStreamFactory::RequestStream( @@ -56,6 +63,22 @@ StreamRequest* HttpStreamFactory::RequestStream( return stream; } +int HttpStreamFactory::PreconnectStreams( + int num_streams, + const HttpRequestInfo* request_info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + HttpNetworkSession* session, + const BoundNetLog& net_log, + CompletionCallback* callback) { + HttpStreamRequest* stream = new HttpStreamRequest(this, session); + int rv = stream->Preconnect(num_streams, request_info, ssl_config, + proxy_info, this, net_log); + DCHECK_EQ(ERR_IO_PENDING, rv); + request_callback_map_[stream] = callback; + return rv; +} + void HttpStreamFactory::AddTLSIntolerantServer(const GURL& url) { tls_intolerant_servers_.insert(GetHostAndPort(url)); } @@ -131,4 +154,14 @@ GURL HttpStreamFactory::ApplyHostMappingRules(const GURL& url, return url; } +void HttpStreamFactory::OnPreconnectsComplete( + HttpStreamRequest* request, int result) { + RequestCallbackMap::iterator it = request_callback_map_.find(request); + DCHECK(it != request_callback_map_.end()); + CompletionCallback* callback = it->second; + request_callback_map_.erase(it); + delete request; + callback->Run(result); +} + } // namespace net diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h index b9f5586..b619add 100644 --- a/net/http/http_stream_factory.h +++ b/net/http/http_stream_factory.h @@ -5,6 +5,7 @@ #ifndef NET_HTTP_HTTP_STREAM_FACTORY_H_ #define NET_HTTP_HTTP_STREAM_FACTORY_H_ +#include <map> #include <set> #include <string> @@ -14,6 +15,7 @@ #include "net/base/ssl_config_service.h" #include "net/http/http_auth.h" #include "net/http/http_auth_controller.h" +#include "net/http/http_stream_request.h" #include "net/http/stream_factory.h" #include "net/proxy/proxy_service.h" #include "net/socket/client_socket_handle.h" @@ -22,9 +24,10 @@ namespace net { class HttpNetworkSession; struct HttpRequestInfo; +class HttpStreamRequest; class HttpStreamFactory : public StreamFactory, - public base::RefCounted<HttpStreamFactory> { + public HttpStreamRequest::PreconnectDelegate { public: HttpStreamFactory(); virtual ~HttpStreamFactory(); @@ -37,17 +40,26 @@ class HttpStreamFactory : public StreamFactory, StreamRequest::Delegate* delegate, const BoundNetLog& net_log); - // TLS Intolerant Server API + virtual int PreconnectStreams(int num_streams, + const HttpRequestInfo* info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + HttpNetworkSession* session, + const BoundNetLog& net_log, + CompletionCallback* callback); + void AddTLSIntolerantServer(const GURL& url); bool IsTLSIntolerantServer(const GURL& url); - // Alternate Protocol API - void ProcessAlternateProtocol(HttpAlternateProtocols* alternate_protocols, - const std::string& alternate_protocol_str, - const HostPortPair& http_host_port_pair); + virtual void ProcessAlternateProtocol( + HttpAlternateProtocols* alternate_protocols, + const std::string& alternate_protocol_str, + const HostPortPair& http_host_port_pair); + + virtual GURL ApplyHostMappingRules(const GURL& url, HostPortPair* endpoint); - // Host Mapping Rules API - GURL ApplyHostMappingRules(const GURL& url, HostPortPair* endpoint); + // HttpStreamRequest::PreconnectDelegate API + virtual void OnPreconnectsComplete(HttpStreamRequest* request, int result); // Static settings @@ -98,6 +110,8 @@ class HttpStreamFactory : public StreamFactory, static void SetHostMappingRules(const std::string& rules); private: + typedef std::map<HttpStreamRequest*, CompletionCallback*> RequestCallbackMap; + RequestCallbackMap request_callback_map_; std::set<std::string> tls_intolerant_servers_; static const HostMappingRules* host_mapping_rules_; diff --git a/net/http/http_stream_factory_unittest.cc b/net/http/http_stream_factory_unittest.cc new file mode 100644 index 0000000..db72024 --- /dev/null +++ b/net/http/http_stream_factory_unittest.cc @@ -0,0 +1,236 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/http/http_stream_factory.h" + +#include <string> + +#include "base/basictypes.h" +#include "net/base/mock_host_resolver.h" +#include "net/base/net_log.h" +#include "net/base/ssl_config_service_defaults.h" +#include "net/base/test_completion_callback.h" +#include "net/http/http_auth_handler_factory.h" +#include "net/http/http_network_session.h" +#include "net/http/http_network_session_peer.h" +#include "net/http/http_request_info.h" +#include "net/socket/socket_test_util.h" +#include "net/spdy/spdy_session_pool.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { + +namespace { + +struct SessionDependencies { + // Custom proxy service dependency. + explicit SessionDependencies(ProxyService* proxy_service) + : host_resolver(new MockHostResolver), + proxy_service(proxy_service), + ssl_config_service(new SSLConfigServiceDefaults), + http_auth_handler_factory( + HttpAuthHandlerFactory::CreateDefault(host_resolver.get())), + net_log(NULL) {} + + scoped_ptr<MockHostResolverBase> host_resolver; + scoped_refptr<ProxyService> proxy_service; + scoped_refptr<SSLConfigService> ssl_config_service; + MockClientSocketFactory socket_factory; + scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory; + NetLog* net_log; +}; + +HttpNetworkSession* CreateSession(SessionDependencies* session_deps) { + return new HttpNetworkSession(session_deps->host_resolver.get(), + NULL /* dnsrr_resolver */, + session_deps->proxy_service, + &session_deps->socket_factory, + session_deps->ssl_config_service, + new SpdySessionPool(NULL), + session_deps->http_auth_handler_factory.get(), + NULL, + session_deps->net_log); +} + +struct TestCase { + int num_streams; + bool ssl; +}; + +TestCase kTests[] = { + { 1, false }, + { 2, false }, + { 1, true}, + { 2, true}, +}; + +int PreconnectHelper(const TestCase& test, + HttpNetworkSession* session) { + SSLConfig ssl_config; + session->ssl_config_service()->GetSSLConfig(&ssl_config); + + HttpRequestInfo request; + request.method = "GET"; + request.url = test.ssl ? GURL("https://www.google.com") : + GURL("http://www.google.com"); + request.load_flags = 0; + + ProxyInfo proxy_info; + TestCompletionCallback callback; + + int rv = session->http_stream_factory()->PreconnectStreams( + test.num_streams, &request, &ssl_config, &proxy_info, session, + BoundNetLog(), &callback); + if (rv != ERR_IO_PENDING) + return ERR_UNEXPECTED; + return callback.WaitForResult(); +}; + +template<typename ParentPool> +class CapturePreconnectsSocketPool : public ParentPool { + public: + explicit CapturePreconnectsSocketPool(HttpNetworkSession* session); + + int last_num_streams() const { + return last_num_streams_; + } + + virtual int RequestSocket(const std::string& group_name, + const void* socket_params, + RequestPriority priority, + ClientSocketHandle* handle, + CompletionCallback* callback, + const BoundNetLog& net_log) { + ADD_FAILURE(); + return ERR_UNEXPECTED; + } + + virtual void RequestSockets(const std::string& group_name, + const void* socket_params, + int num_sockets, + const BoundNetLog& net_log) { + last_num_streams_ = num_sockets; + } + + virtual void CancelRequest(const std::string& group_name, + ClientSocketHandle* handle) { + ADD_FAILURE(); + } + virtual void ReleaseSocket(const std::string& group_name, + ClientSocket* socket) { + ADD_FAILURE(); + } + virtual void CloseIdleSockets() { + ADD_FAILURE(); + } + virtual int IdleSocketCount() const { + ADD_FAILURE(); + return 0; + } + virtual int IdleSocketCountInGroup(const std::string& group_name) const { + ADD_FAILURE(); + return 0; + } + virtual LoadState GetLoadState(const std::string& group_name, + const ClientSocketHandle* handle) const { + ADD_FAILURE(); + return LOAD_STATE_IDLE; + } + virtual base::TimeDelta ConnectionTimeout() const { + return base::TimeDelta(); + } + + private: + int last_num_streams_; +}; + +typedef CapturePreconnectsSocketPool<TCPClientSocketPool> +CapturePreconnectsTCPSocketPool; +typedef CapturePreconnectsSocketPool<HttpProxyClientSocketPool> +CapturePreconnectsHttpProxySocketPool; +typedef CapturePreconnectsSocketPool<SOCKSClientSocketPool> +CapturePreconnectsSOCKSSocketPool; +typedef CapturePreconnectsSocketPool<SSLClientSocketPool> +CapturePreconnectsSSLSocketPool; + +template<typename ParentPool> +CapturePreconnectsSocketPool<ParentPool>::CapturePreconnectsSocketPool( + HttpNetworkSession* session) + : ParentPool(0, 0, NULL, session->host_resolver(), NULL, NULL) {} + +template<> +CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool( + HttpNetworkSession* session) + : HttpProxyClientSocketPool(0, 0, NULL, session->host_resolver(), NULL, + NULL, NULL) {} + +template<> +CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool( + HttpNetworkSession* session) + : SSLClientSocketPool(0, 0, NULL, session->host_resolver(), NULL, NULL, + NULL, NULL, NULL, NULL, NULL) {} + +TEST(HttpStreamFactoryTest, PreconnectDirect) { + for (size_t i = 0; i < arraysize(kTests); ++i) { + SessionDependencies session_deps(ProxyService::CreateDirect()); + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + HttpNetworkSessionPeer peer(session); + CapturePreconnectsTCPSocketPool* tcp_conn_pool = + new CapturePreconnectsTCPSocketPool(session); + peer.SetTCPSocketPool(tcp_conn_pool); + CapturePreconnectsSSLSocketPool* ssl_conn_pool = + new CapturePreconnectsSSLSocketPool(session.get()); + peer.SetSSLSocketPool(ssl_conn_pool); + EXPECT_EQ(OK, PreconnectHelper(kTests[i], session)); + if (kTests[i].ssl) + EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); + else + EXPECT_EQ(kTests[i].num_streams, tcp_conn_pool->last_num_streams()); + } +} + +TEST(HttpStreamFactoryTest, PreconnectHttpProxy) { + for (size_t i = 0; i < arraysize(kTests); ++i) { + SessionDependencies session_deps(ProxyService::CreateFixed("http_proxy")); + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + HttpNetworkSessionPeer peer(session); + HostPortPair proxy_host("http_proxy", 80); + CapturePreconnectsHttpProxySocketPool* http_proxy_pool = + new CapturePreconnectsHttpProxySocketPool(session); + peer.SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool); + CapturePreconnectsSSLSocketPool* ssl_conn_pool = + new CapturePreconnectsSSLSocketPool(session); + peer.SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); + EXPECT_EQ(OK, PreconnectHelper(kTests[i], session)); + if (kTests[i].ssl) + EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); + else + EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams()); + } +} + +TEST(HttpStreamFactoryTest, PreconnectSocksProxy) { + for (size_t i = 0; i < arraysize(kTests); ++i) { + SessionDependencies session_deps( + ProxyService::CreateFixed("socks4://socks_proxy:1080")); + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); + HttpNetworkSessionPeer peer(session); + HostPortPair proxy_host("socks_proxy", 1080); + CapturePreconnectsSOCKSSocketPool* socks_proxy_pool = + new CapturePreconnectsSOCKSSocketPool(session); + peer.SetSocketPoolForSOCKSProxy(proxy_host, socks_proxy_pool); + CapturePreconnectsSSLSocketPool* ssl_conn_pool = + new CapturePreconnectsSSLSocketPool(session); + peer.SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); + EXPECT_EQ(OK, PreconnectHelper(kTests[i], session)); + if (kTests[i].ssl) + EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); + else + EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams()); + } +} + +} // namespace + +} // namespace net diff --git a/net/http/http_stream_request.cc b/net/http/http_stream_request.cc index f43037e..dd079a4 100644 --- a/net/http/http_stream_request.cc +++ b/net/http/http_stream_request.cc @@ -18,7 +18,7 @@ #include "net/http/http_proxy_client_socket_pool.h" #include "net/http/http_request_info.h" #include "net/socket/client_socket_handle.h" -#include "net/socket/client_socket_handle.h" +#include "net/socket/client_socket_pool.h" #include "net/socket/socks_client_socket_pool.h" #include "net/socket/ssl_client_socket.h" #include "net/socket/ssl_client_socket.h" @@ -46,7 +46,7 @@ GURL UpgradeUrlToHttps(const GURL& original_url) { } // namespace HttpStreamRequest::HttpStreamRequest( - HttpStreamFactory* factory, + StreamFactory* factory, HttpNetworkSession* session) : request_info_(NULL), proxy_info_(NULL), @@ -61,14 +61,16 @@ HttpStreamRequest::HttpStreamRequest( pac_request_(NULL), using_ssl_(false), using_spdy_(false), - force_spdy_always_(factory->force_spdy_always()), - force_spdy_over_ssl_(factory->force_spdy_over_ssl()), + force_spdy_always_(HttpStreamFactory::force_spdy_always()), + force_spdy_over_ssl_(HttpStreamFactory::force_spdy_over_ssl()), spdy_certificate_error_(OK), establishing_tunnel_(false), was_alternate_protocol_available_(false), was_npn_negotiated_(false), + preconnect_delegate_(NULL), + num_streams_(0), ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { - if (factory->use_alternate_protocols()) + if (HttpStreamFactory::use_alternate_protocols()) alternate_protocol_mode_ = kUnspecified; else alternate_protocol_mode_ = kDoNotUseAlternateProtocol; @@ -87,9 +89,8 @@ HttpStreamRequest::~HttpStreamRequest() { session_->proxy_service()->CancelPacRequest(pac_request_); // The stream could be in a partial state. It is not reusable. - if (stream_.get() && next_state_ != STATE_DONE) { + if (stream_.get() && next_state_ != STATE_DONE) stream_->Close(true /* not reusable */); - } } void HttpStreamRequest::Start(const HttpRequestInfo* request_info, @@ -97,16 +98,23 @@ void HttpStreamRequest::Start(const HttpRequestInfo* request_info, ProxyInfo* proxy_info, Delegate* delegate, const BoundNetLog& net_log) { - CHECK_EQ(STATE_NONE, next_state_); - - request_info_ = request_info; - ssl_config_ = ssl_config; - proxy_info_ = proxy_info; + DCHECK(preconnect_delegate_ == NULL && delegate_ == NULL); + DCHECK(delegate); delegate_ = delegate; - net_log_ = net_log; - next_state_ = STATE_RESOLVE_PROXY; - int rv = RunLoop(OK); - DCHECK_EQ(ERR_IO_PENDING, rv); + StartInternal(request_info, ssl_config, proxy_info, net_log); +} + +int HttpStreamRequest::Preconnect(int num_streams, + const HttpRequestInfo* request_info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + PreconnectDelegate* delegate, + const BoundNetLog& net_log) { + DCHECK(preconnect_delegate_ == NULL && delegate_ == NULL); + DCHECK(delegate); + num_streams_ = num_streams; + preconnect_delegate_ = delegate; + return StartInternal(request_info, ssl_config, proxy_info, net_log); } int HttpStreamRequest::RestartWithCertificate(X509Certificate* client_cert) { @@ -186,6 +194,10 @@ void HttpStreamRequest::OnNeedsClientAuthCallback( delegate_->OnNeedsClientAuth(cert_info); } +void HttpStreamRequest::OnPreconnectsComplete(int result) { + preconnect_delegate_->OnPreconnectsComplete(this, result); +} + void HttpStreamRequest::OnIOComplete(int result) { RunLoop(result); } @@ -193,7 +205,18 @@ void HttpStreamRequest::OnIOComplete(int result) { int HttpStreamRequest::RunLoop(int result) { result = DoLoop(result); - DCHECK(delegate_); + DCHECK(delegate_ || preconnect_delegate_); + + if (result == ERR_IO_PENDING) + return result; + + if (preconnect_delegate_) { + MessageLoop::current()->PostTask( + FROM_HERE, + method_factory_.NewRunnableMethod( + &HttpStreamRequest::OnPreconnectsComplete, result)); + return ERR_IO_PENDING; + } if (IsCertificateError(result)) { // Retrieve SSL information from the socket. @@ -238,9 +261,6 @@ int HttpStreamRequest::RunLoop(int result) { connection_->ssl_error_response_info().cert_request_info)); return ERR_IO_PENDING; - case ERR_IO_PENDING: - break; - case OK: next_state_ = STATE_DONE; MessageLoop::current()->PostTask( @@ -261,7 +281,7 @@ int HttpStreamRequest::RunLoop(int result) { } int HttpStreamRequest::DoLoop(int result) { - DCHECK(next_state_ != STATE_NONE); + DCHECK_NE(next_state_, STATE_NONE); int rv = result; do { State state = next_state_; @@ -307,6 +327,21 @@ int HttpStreamRequest::DoLoop(int result) { return rv; } +int HttpStreamRequest::StartInternal(const HttpRequestInfo* request_info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + const BoundNetLog& net_log) { + CHECK_EQ(STATE_NONE, next_state_); + request_info_ = request_info; + ssl_config_ = ssl_config; + proxy_info_ = proxy_info; + net_log_ = net_log; + next_state_ = STATE_RESOLVE_PROXY; + int rv = RunLoop(OK); + DCHECK_EQ(ERR_IO_PENDING, rv); + return rv; +} + int HttpStreamRequest::DoResolveProxy() { DCHECK(!pac_request_); @@ -377,7 +412,7 @@ int HttpStreamRequest::DoResolveProxyComplete(int result) { } HostPortProxyPair pair(endpoint_, proxy_info()->proxy_server()); - if (!factory_->create_new_spdy_session_for_http() && + if (!HttpStreamFactory::create_new_spdy_session_for_http() && alternate_protocol_mode_ == kUsingAlternateProtocol && !session_->spdy_session_pool()->HasSession(pair)) { // If we don't already have a SpdySession, then don't pay the SSL handshake @@ -405,9 +440,10 @@ int HttpStreamRequest::DoInitConnection() { using_spdy_ = false; // Check first if we have a spdy session for this group. If so, then go - // straight to using that. + // straight to using that. Unless we are preconnecting. HostPortProxyPair pair(endpoint_, proxy_info()->proxy_server()); - if (session_->spdy_session_pool()->HasSession(pair)) { + if (!preconnect_delegate_ && + session_->spdy_session_pool()->HasSession(pair)) { using_spdy_ = true; next_state_ = STATE_CREATE_STREAM; return OK; @@ -525,6 +561,12 @@ int HttpStreamRequest::DoInitConnection() { else ssl_pool = session_->GetSocketPoolForSSLWithProxy(*proxy_host_port); + if (preconnect_delegate_) { + RequestSocketsForPool(ssl_pool, connection_group, ssl_params, + num_streams_, net_log_); + return OK; + } + return connection_->Init(connection_group, ssl_params, request_info().priority, &io_callback_, ssl_pool, net_log_); @@ -532,25 +574,53 @@ int HttpStreamRequest::DoInitConnection() { // Finally, get the connection started. if (proxy_info()->is_http() || proxy_info()->is_https()) { - return connection_->Init( - connection_group, http_proxy_params, request_info().priority, - &io_callback_, session_->GetSocketPoolForHTTPProxy(*proxy_host_port), - net_log_); + HttpProxyClientSocketPool* pool = + session_->GetSocketPoolForHTTPProxy(*proxy_host_port); + if (preconnect_delegate_) { + RequestSocketsForPool(pool, connection_group, http_proxy_params, + num_streams_, net_log_); + return OK; + } + + return connection_->Init(connection_group, http_proxy_params, + request_info().priority, &io_callback_, + pool, net_log_); } if (proxy_info()->is_socks()) { - return connection_->Init( - connection_group, socks_params, request_info().priority, &io_callback_, - session_->GetSocketPoolForSOCKSProxy(*proxy_host_port), net_log_); + SOCKSClientSocketPool* pool = + session_->GetSocketPoolForSOCKSProxy(*proxy_host_port); + if (preconnect_delegate_) { + RequestSocketsForPool(pool, connection_group, socks_params, + num_streams_, net_log_); + return OK; + } + + return connection_->Init(connection_group, socks_params, + request_info().priority, &io_callback_, pool, + net_log_); } DCHECK(proxy_info()->is_direct()); + + TCPClientSocketPool* pool = session_->tcp_socket_pool(); + if (preconnect_delegate_) { + RequestSocketsForPool(pool, connection_group, tcp_params, + num_streams_, net_log_); + return OK; + } + return connection_->Init(connection_group, tcp_params, request_info().priority, &io_callback_, - session_->tcp_socket_pool(), net_log_); + pool, net_log_); } int HttpStreamRequest::DoInitConnectionComplete(int result) { + if (preconnect_delegate_) { + DCHECK_EQ(OK, result); + return OK; + } + // |result| may be the result of any of the stacked pools. The following // logic is used when determining how to interpret an error. // If |result| < 0: @@ -781,7 +851,7 @@ scoped_refptr<SSLSocketParams> HttpStreamRequest::GenerateSslParams( static_cast<int>(ssl_config()->ssl3_fallback), 2); int load_flags = request_info().load_flags; - if (factory_->ignore_certificate_errors()) + if (HttpStreamFactory::ignore_certificate_errors()) load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; if (request_info().load_flags & LOAD_VERIFY_EV_CERT) ssl_config()->verify_ev_cert = true; @@ -904,7 +974,7 @@ int HttpStreamRequest::HandleCertificateError(int error) { ssl_config()->allowed_bad_certs.push_back(bad_cert); int load_flags = request_info().load_flags; - if (factory_->ignore_certificate_errors()) + if (HttpStreamFactory::ignore_certificate_errors()) load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; if (ssl_socket->IgnoreCertError(error, load_flags)) return OK; diff --git a/net/http/http_stream_request.h b/net/http/http_stream_request.h index 0933272..4769f55 100644 --- a/net/http/http_stream_request.h +++ b/net/http/http_stream_request.h @@ -13,7 +13,6 @@ #include "net/http/http_auth.h" #include "net/http/http_auth_controller.h" #include "net/http/http_alternate_protocols.h" -#include "net/http/http_stream_factory.h" #include "net/http/stream_factory.h" #include "net/proxy/proxy_service.h" #include "net/socket/client_socket_handle.h" @@ -24,7 +23,6 @@ class ClientSocketHandle; class HttpAuthController; class HttpNetworkSession; class HttpProxySocketParams; -class HttpStreamFactory; class SOCKSSocketParams; class SSLSocketParams; class StreamRequestDelegate; @@ -35,7 +33,15 @@ struct HttpRequestInfo; // created for the StreamFactory. class HttpStreamRequest : public StreamRequest { public: - HttpStreamRequest(HttpStreamFactory* factory, + class PreconnectDelegate { + public: + virtual ~PreconnectDelegate() {} + + virtual void OnPreconnectsComplete(HttpStreamRequest* request, + int result) = 0; + }; + + HttpStreamRequest(StreamFactory* factory, HttpNetworkSession* session); virtual ~HttpStreamRequest(); @@ -50,6 +56,13 @@ class HttpStreamRequest : public StreamRequest { Delegate* delegate, const BoundNetLog& net_log); + int Preconnect(int num_streams, + const HttpRequestInfo* request_info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + PreconnectDelegate* delegate, + const BoundNetLog& net_log); + // StreamRequest interface virtual int RestartWithCertificate(X509Certificate* client_cert); virtual int RestartTunnelWithProxyAuth(const string16& username, @@ -96,10 +109,15 @@ class HttpStreamRequest : public StreamRequest { void OnNeedsProxyAuthCallback(const HttpResponseInfo& response_info, HttpAuthController* auth_controller); void OnNeedsClientAuthCallback(SSLCertRequestInfo* cert_info); + void OnPreconnectsComplete(int result); void OnIOComplete(int result); int RunLoop(int result); int DoLoop(int result); + int StartInternal(const HttpRequestInfo* request_info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + const BoundNetLog& net_log); // Each of these methods corresponds to a State value. Those with an input // argument receive the result from the previous state. If a method returns @@ -169,7 +187,7 @@ class HttpStreamRequest : public StreamRequest { scoped_refptr<HttpNetworkSession> session_; CompletionCallbackImpl<HttpStreamRequest> io_callback_; scoped_ptr<ClientSocketHandle> connection_; - scoped_refptr<HttpStreamFactory> factory_; + StreamFactory* const factory_; Delegate* delegate_; BoundNetLog net_log_; State next_state_; @@ -215,6 +233,11 @@ class HttpStreamRequest : public StreamRequest { // True if we negotiated NPN. bool was_npn_negotiated_; + PreconnectDelegate* preconnect_delegate_; + + // Only used if |preconnect_delegate_| is non-NULL. + int num_streams_; + ScopedRunnableMethodFactory<HttpStreamRequest> method_factory_; DISALLOW_COPY_AND_ASSIGN(HttpStreamRequest); diff --git a/net/http/stream_factory.h b/net/http/stream_factory.h index 592ce5a..480df06 100644 --- a/net/http/stream_factory.h +++ b/net/http/stream_factory.h @@ -8,6 +8,7 @@ #include <string> #include "base/ref_counted.h" +#include "net/base/completion_callback.h" #include "net/base/load_states.h" namespace net { @@ -110,7 +111,7 @@ class StreamFactory { // Request a stream. // Will callback to the StreamRequestDelegate upon completion. - // |info|, |ssl_config|, and |proxy_info| must been kept alive until + // |info|, |ssl_config|, and |proxy_info| must be kept alive until // |delegate| is called. virtual StreamRequest* RequestStream(const HttpRequestInfo* info, SSLConfig* ssl_config, @@ -119,15 +120,27 @@ class StreamFactory { StreamRequest::Delegate* delegate, const BoundNetLog& net_log) = 0; - // TLS Intolerant Server API + // Requests that enough connections for |num_streams| be opened. If + // ERR_IO_PENDING is returned, |info|, |ssl_config|, and |proxy_info| must + // be kept alive until |callback| is invoked. + virtual int PreconnectStreams(int num_streams, + const HttpRequestInfo* info, + SSLConfig* ssl_config, + ProxyInfo* proxy_info, + HttpNetworkSession* session, + const BoundNetLog& net_log, + CompletionCallback* callback) = 0; + virtual void AddTLSIntolerantServer(const GURL& url) = 0; virtual bool IsTLSIntolerantServer(const GURL& url) = 0; - // Alternate Protocol API virtual void ProcessAlternateProtocol( HttpAlternateProtocols* alternate_protocols, const std::string& alternate_protocol_str, const HostPortPair& http_host_port_pair) = 0; + + virtual GURL ApplyHostMappingRules(const GURL& url, + HostPortPair* endpoint) = 0; }; } // namespace net diff --git a/net/net.gyp b/net/net.gyp index 7aaf9ed..768cb6e 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -873,6 +873,7 @@ 'http/http_request_headers_unittest.cc', 'http/http_response_body_drainer_unittest.cc', 'http/http_response_headers_unittest.cc', + 'http/http_stream_factory_unittest.cc', 'http/http_transaction_unittest.cc', 'http/http_transaction_unittest.h', 'http/http_util_unittest.cc', diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc index 644daad..8584a25 100644 --- a/net/proxy/proxy_service.cc +++ b/net/proxy/proxy_service.cc @@ -460,6 +460,13 @@ ProxyService* ProxyService::CreateFixed(const ProxyConfig& pc) { } // static +ProxyService* ProxyService::CreateFixed(const std::string& proxy) { + net::ProxyConfig proxy_config; + proxy_config.proxy_rules().ParseFromString(proxy); + return ProxyService::CreateFixed(proxy_config); +} + +// static ProxyService* ProxyService::CreateDirect() { // Use direct connections. return new ProxyService(new ProxyConfigServiceDirect, new ProxyResolverNull, diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h index 0b8f873..951cd2a 100644 --- a/net/proxy/proxy_service.h +++ b/net/proxy/proxy_service.h @@ -181,9 +181,10 @@ class ProxyService : public base::RefCountedThreadSafe<ProxyService>, ProxyConfigService* proxy_config_service, NetLog* net_log); - // Convenience method that creates a proxy service using the - // specified fixed settings. |pc| must not be NULL. + // Convenience methods that creates a proxy service using the + // specified fixed settings. static ProxyService* CreateFixed(const ProxyConfig& pc); + static ProxyService* CreateFixed(const std::string& proxy); // Creates a proxy service that uses a DIRECT connection for all requests. static ProxyService* CreateDirect(); diff --git a/net/socket/client_socket_pool.h b/net/socket/client_socket_pool.h index d097c0f..23bb63f 100644 --- a/net/socket/client_socket_pool.h +++ b/net/socket/client_socket_pool.h @@ -149,12 +149,13 @@ class ClientSocketPool { DISALLOW_COPY_AND_ASSIGN(ClientSocketPool); }; -// Declaration, but no definition. ClientSocketPool subclasses should indicate -// valid SocketParams via the REGISTER_SOCKET_PARAMS_FOR_POOL macro below, which -// will provide a definition of CheckIsValidSocketParamsForPool for the -// ClientSocketPool subtype and SocketParams pair. Trying to use a SocketParams -// type that has not been registered with the corresponding ClientSocketPool -// subtype will result in a compile-time error. +// ClientSocketPool subclasses should indicate valid SocketParams via the +// REGISTER_SOCKET_PARAMS_FOR_POOL macro below. By default, any given +// <PoolType,SocketParams> pair will have its SocketParamsTrait inherit from +// base::false_type, but REGISTER_SOCKET_PARAMS_FOR_POOL will specialize that +// pairing to inherit from base::true_type. This provides compile time +// verification that the correct SocketParams type is used with the appropriate +// PoolType. template <typename PoolType, typename SocketParams> struct SocketParamTraits : public base::false_type { }; @@ -176,6 +177,16 @@ struct SocketParamTraits<pool_type, scoped_refptr<socket_params> > \ : public base::true_type { \ } +template <typename PoolType, typename SocketParams> +void RequestSocketsForPool(PoolType* pool, + const std::string& group_name, + const scoped_refptr<SocketParams>& params, + int num_sockets, + const BoundNetLog& net_log) { + CheckIsValidSocketParamsForPool<PoolType, SocketParams>(); + pool->RequestSockets(group_name, ¶ms, num_sockets, net_log); +} + } // namespace net #endif // NET_SOCKET_CLIENT_SOCKET_POOL_H_ |