diff options
author | sanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-29 01:09:41 +0000 |
---|---|---|
committer | sanjeevr@chromium.org <sanjeevr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-29 01:09:41 +0000 |
commit | 5483d30448876fd7c7c08db0517be1123b5be8f1 (patch) | |
tree | cad62333b823fcbcd04726d4c7ab51c71c80c2c5 /net/socket/client_socket_pool_manager.cc | |
parent | 34338254f776be94d79ca184c4eb2ea5b3f62318 (diff) | |
download | chromium_src-5483d30448876fd7c7c08db0517be1123b5be8f1.zip chromium_src-5483d30448876fd7c7c08db0517be1123b5be8f1.tar.gz chromium_src-5483d30448876fd7c7c08db0517be1123b5be8f1.tar.bz2 |
Moved the logic to initialize a ClientSocketHandle with the relevant socket pool based on the proxy information to static helpers in ClientSocketPoolManager from HttpStreamFactoryImpl::Job::DoInitConnection. This will allow us to reuse this logic for raw socket connections that need to tunnel through the proxies (for example the XMPP connection made by jingle).
BUG=None
TEST=net_unittests, Test with proxy servers.
R=willchan@chromium.org
Review URL: http://codereview.chromium.org/6733042
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79641 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket/client_socket_pool_manager.cc')
-rw-r--r-- | net/socket/client_socket_pool_manager.cc | 257 |
1 files changed, 256 insertions, 1 deletions
diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc index 3d12256..68ff4ec 100644 --- a/net/socket/client_socket_pool_manager.cc +++ b/net/socket/client_socket_pool_manager.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. // @@ -11,11 +11,15 @@ #include <string> #include "base/logging.h" +#include "base/stringprintf.h" #include "base/values.h" #include "net/base/ssl_config_service.h" +#include "net/http/http_network_session.h" #include "net/http/http_proxy_client_socket_pool.h" +#include "net/http/http_request_info.h" #include "net/proxy/proxy_service.h" #include "net/socket/client_socket_factory.h" +#include "net/socket/client_socket_handle.h" #include "net/socket/client_socket_pool_histograms.h" #include "net/socket/socks_client_socket_pool.h" #include "net/socket/ssl_client_socket_pool.h" @@ -52,6 +56,179 @@ static void AddSocketPoolsToList(ListValue* list, } } +// The meat of the implementation for the InitSocketHandleForHttpRequest, +// InitSocketHandleForRawConnect and PreconnectSocketsForHttpRequest methods. +int InitSocketPoolHelper(const HttpRequestInfo& request_info, + 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, + const BoundNetLog& net_log, + int num_preconnect_streams, + ClientSocketHandle* socket_handle, + CompletionCallback* callback) { + scoped_refptr<TCPSocketParams> tcp_params; + scoped_refptr<HttpProxySocketParams> http_proxy_params; + scoped_refptr<SOCKSSocketParams> socks_params; + scoped_ptr<HostPortPair> proxy_host_port; + + bool using_ssl = request_info.url.SchemeIs("https") || force_spdy_over_ssl; + + HostPortPair origin_host_port = + HostPortPair(request_info.url.HostNoBrackets(), + request_info.url.EffectiveIntPort()); + + bool disable_resolver_cache = + request_info.load_flags & LOAD_BYPASS_CACHE || + request_info.load_flags & LOAD_VALIDATE_CACHE || + request_info.load_flags & LOAD_DISABLE_CACHE; + + int load_flags = request_info.load_flags; + if (HttpStreamFactory::ignore_certificate_errors()) + load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS; + + // 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(); + DCHECK(!connection_group.empty()); + if (using_ssl) + connection_group = base::StringPrintf("ssl/%s", connection_group.c_str()); + + if (proxy_info.is_direct()) { + tcp_params = new TCPSocketParams(origin_host_port, + request_info.priority, + request_info.referrer, + disable_resolver_cache); + } else { + ProxyServer proxy_server = proxy_info.proxy_server(); + proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair())); + scoped_refptr<TCPSocketParams> proxy_tcp_params( + new TCPSocketParams(*proxy_host_port, + request_info.priority, + request_info.referrer, + disable_resolver_cache)); + + if (proxy_info.is_http() || proxy_info.is_https()) { + std::string user_agent; + request_info.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_info.url, + user_agent, + origin_host_port, + session->http_auth_cache(), + session->http_auth_handler_factory(), + session->spdy_session_pool(), + 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_info.priority, + request_info.referrer); + } + } + + // Deal with SSL - which layers on top of any given proxy. + 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()) + ssl_pool = session->ssl_socket_pool(); + else + ssl_pool = session->GetSocketPoolForSSLWithProxy(*proxy_host_port); + + if (num_preconnect_streams) { + RequestSocketsForPool(ssl_pool, connection_group, ssl_params, + num_preconnect_streams, net_log); + return OK; + } + + return socket_handle->Init(connection_group, ssl_params, + request_info.priority, callback, ssl_pool, + net_log); + } + + // Finally, get the connection started. + if (proxy_info.is_http() || proxy_info.is_https()) { + HttpProxyClientSocketPool* pool = + session->GetSocketPoolForHTTPProxy(*proxy_host_port); + if (num_preconnect_streams) { + RequestSocketsForPool(pool, connection_group, http_proxy_params, + num_preconnect_streams, net_log); + return OK; + } + + return socket_handle->Init(connection_group, http_proxy_params, + request_info.priority, callback, + pool, net_log); + } + + if (proxy_info.is_socks()) { + SOCKSClientSocketPool* pool = + session->GetSocketPoolForSOCKSProxy(*proxy_host_port); + if (num_preconnect_streams) { + RequestSocketsForPool(pool, connection_group, socks_params, + num_preconnect_streams, net_log); + return OK; + } + + return socket_handle->Init(connection_group, socks_params, + request_info.priority, callback, pool, + net_log); + } + + DCHECK(proxy_info.is_direct()); + + TCPClientSocketPool* pool = session->tcp_socket_pool(); + if (num_preconnect_streams) { + RequestSocketsForPool(pool, connection_group, tcp_params, + num_preconnect_streams, net_log); + return OK; + } + + return socket_handle->Init(connection_group, tcp_params, + request_info.priority, callback, + pool, net_log); +} + } // namespace ClientSocketPoolManager::ClientSocketPoolManager( @@ -403,4 +580,82 @@ void ClientSocketPoolManager::OnUserCertAdded(X509Certificate* cert) { FlushSocketPools(); } +// static +int ClientSocketPoolManager::InitSocketHandleForHttpRequest( + const HttpRequestInfo& request_info, + 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, + const BoundNetLog& net_log, + ClientSocketHandle* socket_handle, + CompletionCallback* callback) { + DCHECK(socket_handle); + return InitSocketPoolHelper(request_info, + session, + proxy_info, + force_spdy_over_ssl, + want_spdy_over_npn, + ssl_config_for_origin, + ssl_config_for_proxy, + net_log, + 0, + socket_handle, + callback); +} + +// static +int ClientSocketPoolManager::InitSocketHandleForRawConnect( + const HostPortPair& host_port_pair, + HttpNetworkSession* session, + const ProxyInfo& proxy_info, + const SSLConfig& ssl_config_for_origin, + const SSLConfig& ssl_config_for_proxy, + const BoundNetLog& net_log, + ClientSocketHandle* socket_handle, + CompletionCallback* callback) { + DCHECK(socket_handle); + // Synthesize an HttpRequestInfo. + HttpRequestInfo request_info; + request_info.url = GURL("http://" + host_port_pair.ToString()); + return InitSocketPoolHelper(request_info, + session, + proxy_info, + false, + false, + ssl_config_for_origin, + ssl_config_for_proxy, + net_log, + 0, + socket_handle, + callback); +} + +// static +int ClientSocketPoolManager::PreconnectSocketsForHttpRequest( + const HttpRequestInfo& request_info, + 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, + const BoundNetLog& net_log, + int num_preconnect_streams) { + return InitSocketPoolHelper(request_info, + session, + proxy_info, + force_spdy_over_ssl, + want_spdy_over_npn, + ssl_config_for_origin, + ssl_config_for_proxy, + net_log, + num_preconnect_streams, + NULL, + NULL); +} + + } // namespace net |