Index: net/socket/client_socket_pool_manager.cc |
diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc |
index 71b9d6d6f5895230a0d7bae8083c930f3372e911..942543c1b438ad0e57742969c8b4519da32d916e 100644 |
--- a/net/socket/client_socket_pool_manager.cc |
+++ b/net/socket/client_socket_pool_manager.cc |
@@ -64,61 +64,18 @@ COMPILE_ASSERT(arraysize(g_max_sockets_per_proxy_server) == |
HttpNetworkSession::NUM_SOCKET_POOL_TYPES, |
max_sockets_per_proxy_server_length_mismatch); |
-// The meat of the implementation for the InitSocketHandleForHttpRequest, |
-// InitSocketHandleForRawConnect and PreconnectSocketsForHttpRequest methods. |
-int InitSocketPoolHelper(const GURL& request_url, |
- const HttpRequestHeaders& request_extra_headers, |
- int request_load_flags, |
- RequestPriority request_priority, |
- HttpNetworkSession* session, |
- const ProxyInfo& proxy_info, |
- bool force_spdy_over_ssl, |
- bool want_spdy_over_npn, |
- const SSLConfig& ssl_config_for_origin, |
- const SSLConfig& ssl_config_for_proxy, |
- bool force_tunnel, |
- const BoundNetLog& net_log, |
- int num_preconnect_streams, |
- ClientSocketHandle* socket_handle, |
- const OnHostResolutionCallback& resolution_callback, |
- const CompletionCallback& callback) { |
- scoped_refptr<TransportSocketParams> tcp_params; |
- scoped_refptr<HttpProxySocketParams> http_proxy_params; |
- scoped_refptr<SOCKSSocketParams> socks_params; |
- scoped_ptr<HostPortPair> proxy_host_port; |
- |
- bool using_ssl = request_url.SchemeIs("https") || force_spdy_over_ssl; |
- |
- HostPortPair origin_host_port = |
- HostPortPair(request_url.HostNoBrackets(), |
- request_url.EffectiveIntPort()); |
- |
- if (!using_ssl && session->params().testing_fixed_http_port != 0) { |
- origin_host_port.set_port(session->params().testing_fixed_http_port); |
- } else if (using_ssl && session->params().testing_fixed_https_port != 0) { |
- origin_host_port.set_port(session->params().testing_fixed_https_port); |
- } |
- |
- bool disable_resolver_cache = |
- request_load_flags & LOAD_BYPASS_CACHE || |
- request_load_flags & LOAD_VALIDATE_CACHE || |
- request_load_flags & LOAD_DISABLE_CACHE; |
- |
- int load_flags = request_load_flags; |
- if (session->params().ignore_certificate_errors) |
- load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; |
- |
+std::string ConnectionGroupForUrl(const GURL& request_url, |
+ bool force_ssl, |
+ const HostPortPair& host_port, |
+ uint16 ssl_version_max, |
+ ProxyServer::Scheme proxy_scheme) { |
// Build the string used to uniquely identify connections of this type. |
// Determine the host and port to connect to. |
- std::string connection_group = origin_host_port.ToString(); |
+ std::string connection_group = host_port.ToString(); |
DCHECK(!connection_group.empty()); |
if (request_url.SchemeIs("ftp")) { |
- // Combining FTP with forced SPDY over SSL would be a "path to madness". |
- // Make sure we never do that. |
- DCHECK(!using_ssl); |
connection_group = "ftp/" + connection_group; |
- } |
- if (using_ssl) { |
+ } else if (force_ssl || request_url.SchemeIs("https")) { |
// All connections in a group should use the same SSLConfig settings. |
// Encode version_max in the connection group's name, unless it's the |
// default version_max. (We want the common case to use the shortest |
@@ -129,9 +86,9 @@ int InitSocketPoolHelper(const GURL& request_url, |
// should be the same for all connections, whereas version_max may |
// change for version fallbacks. |
std::string prefix = "ssl/"; |
- if (ssl_config_for_origin.version_max != |
+ if (ssl_version_max != |
SSLConfigService::default_version_max()) { |
- switch (ssl_config_for_origin.version_max) { |
+ switch (ssl_version_max) { |
case SSL_PROTOCOL_VERSION_TLS1_2: |
prefix = "ssl(max:3.3)/"; |
break; |
@@ -152,150 +109,247 @@ int InitSocketPoolHelper(const GURL& request_url, |
connection_group = prefix + connection_group; |
} |
- bool ignore_limits = (request_load_flags & LOAD_IGNORE_LIMITS) != 0; |
+ char socks_version = 0; |
+ if (proxy_scheme == ProxyServer::SCHEME_SOCKS4) |
+ socks_version = '4'; |
+ else if (proxy_scheme == ProxyServer::SCHEME_SOCKS5) |
+ socks_version = '5'; |
+ |
+ if (socks_version) |
+ connection_group = base::StringPrintf("socks%c/%s", socks_version, |
+ connection_group.c_str()); |
+ |
+ return connection_group; |
+} |
+ |
+HostPortPair HostPortPairFromUrlForSession(const GURL& request_url, |
+ bool using_ssl, |
+ HttpNetworkSession* session) { |
+ HostPortPair host_port(request_url.HostNoBrackets(), |
+ request_url.EffectiveIntPort()); |
+ |
+ if (!using_ssl && session->params().testing_fixed_http_port != 0) { |
+ host_port.set_port(session->params().testing_fixed_http_port); |
+ } else if (using_ssl && session->params().testing_fixed_https_port != 0) { |
+ host_port.set_port(session->params().testing_fixed_https_port); |
+ } |
+ |
+ return host_port; |
+} |
+ |
+template<typename Callback> |
+int |
+InvokeWithSocketParamsAndPool( |
+ const GURL& request_url, |
+ const HttpRequestHeaders& request_extra_headers, |
+ int request_load_flags, |
+ RequestPriority request_priority, |
+ HttpNetworkSession* session, |
+ const ProxyInfo& proxy_info, |
+ bool force_spdy_over_ssl, |
+ bool want_spdy_over_npn, |
+ const SSLConfig& ssl_config_for_origin, |
+ const SSLConfig& ssl_config_for_proxy, |
+ bool force_tunnel, |
+ const OnHostResolutionCallback& resolution_callback, |
+ const Callback& callback) { |
+ bool using_ssl = request_url.SchemeIs("https") || force_spdy_over_ssl; |
+ // Combining FTP with forced SPDY over SSL would be a "path to madness". |
+ // Make sure we never do that. |
+ DCHECK(!(using_ssl && request_url.SchemeIs("ftp"))); |
+ |
+ HostPortPair origin_host_port = |
+ HostPortPairFromUrlForSession(request_url, using_ssl, session); |
+ |
+ ProxyServer::Scheme proxy_scheme = proxy_info.proxy_server().scheme(); |
+ std::string connection_group = |
+ ConnectionGroupForUrl(request_url, force_spdy_over_ssl, origin_host_port, |
+ using_ssl ? ssl_config_for_origin.version_max : 0, |
+ proxy_scheme); |
+ |
+ scoped_ptr<HostPortPair> proxy_host_port; |
+ HostPortPair* target_host_port = NULL; |
if (proxy_info.is_direct()) { |
- tcp_params = new TransportSocketParams(origin_host_port, |
- request_priority, |
- disable_resolver_cache, |
- ignore_limits, |
- resolution_callback); |
+ target_host_port = &origin_host_port; |
} else { |
- ProxyServer proxy_server = proxy_info.proxy_server(); |
- proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair())); |
- scoped_refptr<TransportSocketParams> proxy_tcp_params( |
- new TransportSocketParams(*proxy_host_port, |
- request_priority, |
- disable_resolver_cache, |
- ignore_limits, |
- resolution_callback)); |
- |
- if (proxy_info.is_http() || proxy_info.is_https()) { |
- std::string user_agent; |
- request_extra_headers.GetHeader(HttpRequestHeaders::kUserAgent, |
- &user_agent); |
- scoped_refptr<SSLSocketParams> ssl_params; |
- if (proxy_info.is_https()) { |
- // Set ssl_params, and unset proxy_tcp_params |
- ssl_params = new SSLSocketParams(proxy_tcp_params, |
- NULL, |
- NULL, |
- ProxyServer::SCHEME_DIRECT, |
- *proxy_host_port.get(), |
- ssl_config_for_proxy, |
- load_flags, |
- force_spdy_over_ssl, |
- want_spdy_over_npn); |
- proxy_tcp_params = NULL; |
- } |
- |
- http_proxy_params = |
- new HttpProxySocketParams(proxy_tcp_params, |
- ssl_params, |
- request_url, |
- user_agent, |
- origin_host_port, |
- session->http_auth_cache(), |
- session->http_auth_handler_factory(), |
- session->spdy_session_pool(), |
- force_tunnel || using_ssl); |
- } else { |
- DCHECK(proxy_info.is_socks()); |
- char socks_version; |
- if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5) |
- socks_version = '5'; |
- else |
- socks_version = '4'; |
- connection_group = base::StringPrintf( |
- "socks%c/%s", socks_version, connection_group.c_str()); |
- |
- socks_params = new SOCKSSocketParams(proxy_tcp_params, |
- socks_version == '5', |
- origin_host_port, |
- request_priority); |
- } |
+ proxy_host_port.reset( |
+ new HostPortPair(proxy_info.proxy_server().host_port_pair())); |
+ target_host_port = proxy_host_port.get(); |
} |
- // Deal with SSL - which layers on top of any given proxy. |
+ SSLClientSocketPool* ssl_pool = NULL; |
if (using_ssl) { |
- scoped_refptr<SSLSocketParams> ssl_params = |
- new SSLSocketParams(tcp_params, |
- socks_params, |
- http_proxy_params, |
- proxy_info.proxy_server().scheme(), |
- origin_host_port, |
- ssl_config_for_origin, |
- load_flags, |
- force_spdy_over_ssl, |
- want_spdy_over_npn); |
- SSLClientSocketPool* ssl_pool = NULL; |
- if (proxy_info.is_direct()) { |
+ if (proxy_info.is_direct()) |
ssl_pool = session->GetSSLSocketPool( |
HttpNetworkSession::NORMAL_SOCKET_POOL); |
- } else { |
+ else |
ssl_pool = session->GetSocketPoolForSSLWithProxy( |
HttpNetworkSession::NORMAL_SOCKET_POOL, |
*proxy_host_port); |
- } |
+ } |
- if (num_preconnect_streams) { |
- RequestSocketsForPool(ssl_pool, connection_group, ssl_params, |
- num_preconnect_streams, net_log); |
- return OK; |
- } |
+ int load_flags = request_load_flags; |
+ if (session->params().ignore_certificate_errors) |
+ load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; |
- return socket_handle->Init(connection_group, ssl_params, |
- request_priority, callback, ssl_pool, |
- net_log); |
+ scoped_refptr<TransportSocketParams> tcp_params; |
+ { |
+ bool disable_resolver_cache = |
+ request_load_flags & LOAD_BYPASS_CACHE || |
+ request_load_flags & LOAD_VALIDATE_CACHE || |
+ request_load_flags & LOAD_DISABLE_CACHE; |
+ bool ignore_limits = (request_load_flags & LOAD_IGNORE_LIMITS) != 0; |
+ tcp_params = new TransportSocketParams(*target_host_port, |
+ request_priority, |
+ disable_resolver_cache, |
+ ignore_limits, |
+ resolution_callback); |
} |
- // Finally, get the connection started. |
- |
- if (proxy_info.is_http() || proxy_info.is_https()) { |
- HttpProxyClientSocketPool* pool = |
- session->GetSocketPoolForHTTPProxy( |
- HttpNetworkSession::NORMAL_SOCKET_POOL, |
- *proxy_host_port); |
- if (num_preconnect_streams) { |
- RequestSocketsForPool(pool, connection_group, http_proxy_params, |
- num_preconnect_streams, net_log); |
- return OK; |
+ if (proxy_info.is_direct()) { |
+ if (using_ssl) { |
+ scoped_refptr<SSLSocketParams> ssl_params = |
+ new SSLSocketParams(tcp_params, |
+ origin_host_port, |
+ ssl_config_for_origin, |
+ load_flags, |
+ force_spdy_over_ssl, |
+ want_spdy_over_npn); |
+ |
+ return callback(ssl_pool, connection_group, ssl_params, request_priority); |
+ } else { |
+ TransportClientSocketPool* pool = session->GetTransportSocketPool( |
+ HttpNetworkSession::NORMAL_SOCKET_POOL); |
+ |
+ return callback(pool, connection_group, tcp_params, request_priority); |
+ } |
+ } else if (proxy_info.is_http() || proxy_info.is_https()) { |
+ std::string user_agent; |
+ request_extra_headers.GetHeader(HttpRequestHeaders::kUserAgent, |
+ &user_agent); |
+ scoped_refptr<SSLSocketParams> ssl_params; |
+ if (proxy_info.is_https()) { |
+ ssl_params = new SSLSocketParams(tcp_params, |
+ *proxy_host_port.get(), |
+ ssl_config_for_proxy, |
+ load_flags, |
+ force_spdy_over_ssl, |
+ want_spdy_over_npn); |
} |
- return socket_handle->Init(connection_group, http_proxy_params, |
- request_priority, callback, |
- pool, net_log); |
- } |
+ scoped_refptr<HttpProxySocketParams> http_proxy_params = |
+ new HttpProxySocketParams(proxy_info.is_https() ? NULL : tcp_params, |
+ ssl_params, |
+ request_url, |
+ user_agent, |
+ origin_host_port, |
+ session->http_auth_cache(), |
+ session->http_auth_handler_factory(), |
+ session->spdy_session_pool(), |
+ force_tunnel || using_ssl); |
+ |
+ if (using_ssl) { |
+ scoped_refptr<SSLSocketParams> ssl_params = |
+ new SSLSocketParams(http_proxy_params, |
+ proxy_scheme, |
+ origin_host_port, |
+ ssl_config_for_origin, |
+ load_flags, |
+ force_spdy_over_ssl, |
+ want_spdy_over_npn); |
+ |
+ return callback(ssl_pool, connection_group, ssl_params, request_priority); |
+ } else { |
+ HttpProxyClientSocketPool* pool = |
+ session->GetSocketPoolForHTTPProxy( |
+ HttpNetworkSession::NORMAL_SOCKET_POOL, |
+ *proxy_host_port); |
+ |
+ return callback(pool, connection_group, |
+ http_proxy_params, request_priority); |
+ } |
+ } else { |
+ DCHECK(proxy_info.is_socks()); |
+ |
+ scoped_refptr<SOCKSSocketParams> socks_params = |
+ new SOCKSSocketParams(tcp_params, |
+ proxy_scheme == ProxyServer::SCHEME_SOCKS5, |
+ origin_host_port, |
+ request_priority); |
+ |
+ if (using_ssl) { |
+ scoped_refptr<SSLSocketParams> ssl_params = |
+ new SSLSocketParams(socks_params, |
+ proxy_scheme, |
+ origin_host_port, |
+ ssl_config_for_origin, |
+ load_flags, |
+ force_spdy_over_ssl, |
+ want_spdy_over_npn); |
+ |
+ return callback(ssl_pool, connection_group, ssl_params, request_priority); |
+ } else { |
+ SOCKSClientSocketPool* pool = session->GetSocketPoolForSOCKSProxy( |
+ HttpNetworkSession::NORMAL_SOCKET_POOL, |
+ *proxy_host_port); |
- if (proxy_info.is_socks()) { |
- SOCKSClientSocketPool* pool = |
- session->GetSocketPoolForSOCKSProxy( |
- HttpNetworkSession::NORMAL_SOCKET_POOL, |
- *proxy_host_port); |
- if (num_preconnect_streams) { |
- RequestSocketsForPool(pool, connection_group, socks_params, |
- num_preconnect_streams, net_log); |
- return OK; |
+ return callback(pool, connection_group, socks_params, request_priority); |
} |
+ } |
+ |
+ NOTREACHED(); |
+ return ERR_UNEXPECTED; |
+} |
- return socket_handle->Init(connection_group, socks_params, |
- request_priority, callback, pool, |
- net_log); |
+class RequestSocketForPool { |
+public: |
+ RequestSocketForPool(ClientSocketHandle* socket_handle, |
+ const CompletionCallback& callback, |
+ const BoundNetLog& net_log) |
+ : socket_handle_(socket_handle), |
+ callback_(callback), |
+ net_log_(net_log) {} |
+ |
+ template <typename PoolType, typename SocketParams> |
+ int operator()(PoolType* pool, |
+ const std::string& group_name, |
+ const scoped_refptr<SocketParams>& params, |
+ RequestPriority request_priority) const { |
+ CheckIsValidSocketParamsForPool<PoolType, SocketParams>(); |
+ |
+ return socket_handle_->Init(group_name, params, request_priority, |
+ callback_, pool, net_log_); |
} |
- DCHECK(proxy_info.is_direct()); |
+private: |
+ ClientSocketHandle* socket_handle_; |
+ const CompletionCallback& callback_; |
+ const BoundNetLog& net_log_; |
+}; |
- TransportClientSocketPool* pool = |
- session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL); |
- if (num_preconnect_streams) { |
- RequestSocketsForPool(pool, connection_group, tcp_params, |
- num_preconnect_streams, net_log); |
+class RequestSocketsForPool { |
+public: |
+ RequestSocketsForPool(int num_preconnect_streams, |
+ const BoundNetLog& net_log) |
+ : num_preconnect_streams_(num_preconnect_streams), |
+ net_log_(net_log) {} |
+ |
+ template <typename PoolType, typename SocketParams> |
+ int operator()(PoolType* pool, |
+ const std::string& group_name, |
+ const scoped_refptr<SocketParams>& params, |
+ RequestPriority request_priority) const { |
+ CheckIsValidSocketParamsForPool<PoolType, SocketParams>(); |
+ |
+ pool->RequestSockets( |
+ group_name, ¶ms, num_preconnect_streams_, net_log_); |
return OK; |
} |
- return socket_handle->Init(connection_group, tcp_params, |
- request_priority, callback, |
- pool, net_log); |
-} |
+private: |
+ int num_preconnect_streams_; |
+ const BoundNetLog& net_log_; |
+}; |
} // namespace |
@@ -380,11 +434,14 @@ int InitSocketHandleForHttpRequest( |
const OnHostResolutionCallback& resolution_callback, |
const CompletionCallback& callback) { |
DCHECK(socket_handle); |
- return InitSocketPoolHelper( |
+ |
+ RequestSocketForPool socketRequest(socket_handle, callback, net_log); |
+ |
+ return InvokeWithSocketParamsAndPool( |
request_url, request_extra_headers, request_load_flags, request_priority, |
session, proxy_info, force_spdy_over_ssl, want_spdy_over_npn, |
- ssl_config_for_origin, ssl_config_for_proxy, false, net_log, 0, |
- socket_handle, resolution_callback, callback); |
+ ssl_config_for_origin, ssl_config_for_proxy, false, |
+ resolution_callback, socketRequest); |
} |
int InitSocketHandleForRawConnect( |
@@ -397,17 +454,20 @@ int InitSocketHandleForRawConnect( |
ClientSocketHandle* socket_handle, |
const CompletionCallback& callback) { |
DCHECK(socket_handle); |
+ |
+ RequestSocketForPool socketRequest(socket_handle, callback, net_log); |
+ |
// Synthesize an HttpRequestInfo. |
GURL request_url = GURL("http://" + host_port_pair.ToString()); |
HttpRequestHeaders request_extra_headers; |
int request_load_flags = 0; |
RequestPriority request_priority = MEDIUM; |
- return InitSocketPoolHelper( |
+ return InvokeWithSocketParamsAndPool( |
request_url, request_extra_headers, request_load_flags, request_priority, |
- session, proxy_info, false, false, ssl_config_for_origin, |
- ssl_config_for_proxy, true, net_log, 0, socket_handle, |
- OnHostResolutionCallback(), callback); |
+ session, proxy_info, false, false, |
+ ssl_config_for_origin, ssl_config_for_proxy, true, |
+ OnHostResolutionCallback(), socketRequest); |
} |
int PreconnectSocketsForHttpRequest( |
@@ -423,12 +483,13 @@ int PreconnectSocketsForHttpRequest( |
const SSLConfig& ssl_config_for_proxy, |
const BoundNetLog& net_log, |
int num_preconnect_streams) { |
- return InitSocketPoolHelper( |
+ RequestSocketsForPool socketsRequest(num_preconnect_streams, net_log); |
+ |
+ return InvokeWithSocketParamsAndPool( |
request_url, request_extra_headers, request_load_flags, request_priority, |
session, proxy_info, force_spdy_over_ssl, want_spdy_over_npn, |
- ssl_config_for_origin, ssl_config_for_proxy, false, net_log, |
- num_preconnect_streams, NULL, OnHostResolutionCallback(), |
- CompletionCallback()); |
+ ssl_config_for_origin, ssl_config_for_proxy, false, |
+ OnHostResolutionCallback(), socketsRequest); |
} |
} // namespace net |