summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/http/http_network_session.cc1
-rw-r--r--net/http/http_network_session.h6
-rw-r--r--net/http/http_network_transaction_unittest.cc65
-rw-r--r--net/http/http_stream_factory.cc33
-rw-r--r--net/http/http_stream_factory.h30
-rw-r--r--net/http/http_stream_factory_unittest.cc236
-rw-r--r--net/http/http_stream_request.cc138
-rw-r--r--net/http/http_stream_request.h31
-rw-r--r--net/http/stream_factory.h19
-rw-r--r--net/net.gyp1
-rw-r--r--net/proxy/proxy_service.cc7
-rw-r--r--net/proxy/proxy_service.h5
-rw-r--r--net/socket/client_socket_pool.h23
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, &params, num_sockets, net_log);
+}
+
} // namespace net
#endif // NET_SOCKET_CLIENT_SOCKET_POOL_H_