Home | History | Annotate | Download | only in socket
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 //
      5 // ClientSocketPoolManager manages access to all ClientSocketPools.  It's a
      6 // simple container for all of them.  Most importantly, it handles the lifetime
      7 // and destruction order properly.
      8 
      9 #include "net/socket/client_socket_pool_manager.h"
     10 
     11 #include <string>
     12 
     13 #include "base/logging.h"
     14 #include "base/stringprintf.h"
     15 #include "base/values.h"
     16 #include "net/base/ssl_config_service.h"
     17 #include "net/http/http_network_session.h"
     18 #include "net/http/http_proxy_client_socket_pool.h"
     19 #include "net/http/http_request_info.h"
     20 #include "net/proxy/proxy_service.h"
     21 #include "net/socket/client_socket_factory.h"
     22 #include "net/socket/client_socket_handle.h"
     23 #include "net/socket/client_socket_pool_histograms.h"
     24 #include "net/socket/socks_client_socket_pool.h"
     25 #include "net/socket/ssl_client_socket_pool.h"
     26 #include "net/socket/transport_client_socket_pool.h"
     27 
     28 namespace net {
     29 
     30 namespace {
     31 
     32 // Total limit of sockets.
     33 int g_max_sockets = 256;
     34 
     35 // Default to allow up to 6 connections per host. Experiment and tuning may
     36 // try other values (greater than 0).  Too large may cause many problems, such
     37 // as home routers blocking the connections!?!?  See http://crbug.com/12066.
     38 int g_max_sockets_per_group = 6;
     39 
     40 // The max number of sockets to allow per proxy server.  This applies both to
     41 // http and SOCKS proxies.  See http://crbug.com/12066 and
     42 // http://crbug.com/44501 for details about proxy server connection limits.
     43 int g_max_sockets_per_proxy_server = 32;
     44 
     45 // Appends information about all |socket_pools| to the end of |list|.
     46 template <class MapType>
     47 static void AddSocketPoolsToList(ListValue* list,
     48                                  const MapType& socket_pools,
     49                                  const std::string& type,
     50                                  bool include_nested_pools) {
     51   for (typename MapType::const_iterator it = socket_pools.begin();
     52        it != socket_pools.end(); it++) {
     53     list->Append(it->second->GetInfoAsValue(it->first.ToString(),
     54                                             type,
     55                                             include_nested_pools));
     56   }
     57 }
     58 
     59 // The meat of the implementation for the InitSocketHandleForHttpRequest,
     60 // InitSocketHandleForRawConnect and PreconnectSocketsForHttpRequest methods.
     61 int InitSocketPoolHelper(const HttpRequestInfo& request_info,
     62                          HttpNetworkSession* session,
     63                          const ProxyInfo& proxy_info,
     64                          bool force_spdy_over_ssl,
     65                          bool want_spdy_over_npn,
     66                          const SSLConfig& ssl_config_for_origin,
     67                          const SSLConfig& ssl_config_for_proxy,
     68                          bool force_tunnel,
     69                          const BoundNetLog& net_log,
     70                          int num_preconnect_streams,
     71                          ClientSocketHandle* socket_handle,
     72                          CompletionCallback* callback) {
     73   scoped_refptr<TransportSocketParams> tcp_params;
     74   scoped_refptr<HttpProxySocketParams> http_proxy_params;
     75   scoped_refptr<SOCKSSocketParams> socks_params;
     76   scoped_ptr<HostPortPair> proxy_host_port;
     77 
     78   bool using_ssl = request_info.url.SchemeIs("https") || force_spdy_over_ssl;
     79 
     80   HostPortPair origin_host_port =
     81       HostPortPair(request_info.url.HostNoBrackets(),
     82                    request_info.url.EffectiveIntPort());
     83 
     84   bool disable_resolver_cache =
     85       request_info.load_flags & LOAD_BYPASS_CACHE ||
     86       request_info.load_flags & LOAD_VALIDATE_CACHE ||
     87       request_info.load_flags & LOAD_DISABLE_CACHE;
     88 
     89   int load_flags = request_info.load_flags;
     90   if (HttpStreamFactory::ignore_certificate_errors())
     91     load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS;
     92 
     93   // Build the string used to uniquely identify connections of this type.
     94   // Determine the host and port to connect to.
     95   std::string connection_group = origin_host_port.ToString();
     96   DCHECK(!connection_group.empty());
     97   if (using_ssl)
     98     connection_group = base::StringPrintf("ssl/%s", connection_group.c_str());
     99 
    100   bool ignore_limits = (request_info.load_flags & LOAD_IGNORE_LIMITS) != 0;
    101   if (proxy_info.is_direct()) {
    102     tcp_params = new TransportSocketParams(origin_host_port,
    103                                      request_info.priority,
    104                                      request_info.referrer,
    105                                      disable_resolver_cache,
    106                                      ignore_limits);
    107 #ifdef ANDROID
    108     if (request_info.valid_uid)
    109       tcp_params->setUID(request_info.calling_uid);
    110 #endif
    111   } else {
    112     ProxyServer proxy_server = proxy_info.proxy_server();
    113     proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair()));
    114     scoped_refptr<TransportSocketParams> proxy_tcp_params(
    115         new TransportSocketParams(*proxy_host_port,
    116                             request_info.priority,
    117                             request_info.referrer,
    118                             disable_resolver_cache,
    119                             ignore_limits));
    120 
    121 #ifdef ANDROID
    122     if (request_info.valid_uid)
    123       proxy_tcp_params->setUID(request_info.calling_uid);
    124 #endif
    125 
    126     if (proxy_info.is_http() || proxy_info.is_https()) {
    127       std::string user_agent;
    128       request_info.extra_headers.GetHeader(HttpRequestHeaders::kUserAgent,
    129                                            &user_agent);
    130       scoped_refptr<SSLSocketParams> ssl_params;
    131       if (proxy_info.is_https()) {
    132         // Set ssl_params, and unset proxy_tcp_params
    133         ssl_params = new SSLSocketParams(proxy_tcp_params,
    134                                          NULL,
    135                                          NULL,
    136                                          ProxyServer::SCHEME_DIRECT,
    137                                          *proxy_host_port.get(),
    138                                          ssl_config_for_proxy,
    139                                          load_flags,
    140                                          force_spdy_over_ssl,
    141                                          want_spdy_over_npn);
    142         proxy_tcp_params = NULL;
    143       }
    144 
    145       http_proxy_params =
    146           new HttpProxySocketParams(proxy_tcp_params,
    147                                     ssl_params,
    148                                     request_info.url,
    149                                     user_agent,
    150                                     origin_host_port,
    151                                     session->http_auth_cache(),
    152                                     session->http_auth_handler_factory(),
    153                                     session->spdy_session_pool(),
    154                                     force_tunnel || using_ssl);
    155     } else {
    156       DCHECK(proxy_info.is_socks());
    157       char socks_version;
    158       if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5)
    159         socks_version = '5';
    160       else
    161         socks_version = '4';
    162       connection_group = base::StringPrintf(
    163           "socks%c/%s", socks_version, connection_group.c_str());
    164 
    165       socks_params = new SOCKSSocketParams(proxy_tcp_params,
    166                                            socks_version == '5',
    167                                            origin_host_port,
    168                                            request_info.priority,
    169                                            request_info.referrer);
    170     }
    171   }
    172 
    173   // Deal with SSL - which layers on top of any given proxy.
    174   if (using_ssl) {
    175     scoped_refptr<SSLSocketParams> ssl_params =
    176         new SSLSocketParams(tcp_params,
    177                             socks_params,
    178                             http_proxy_params,
    179                             proxy_info.proxy_server().scheme(),
    180                             origin_host_port,
    181                             ssl_config_for_origin,
    182                             load_flags,
    183                             force_spdy_over_ssl,
    184                             want_spdy_over_npn);
    185     SSLClientSocketPool* ssl_pool = NULL;
    186     if (proxy_info.is_direct())
    187       ssl_pool = session->ssl_socket_pool();
    188     else
    189       ssl_pool = session->GetSocketPoolForSSLWithProxy(*proxy_host_port);
    190 
    191     if (num_preconnect_streams) {
    192       RequestSocketsForPool(ssl_pool, connection_group, ssl_params,
    193                             num_preconnect_streams, net_log);
    194       return OK;
    195     }
    196 
    197     return socket_handle->Init(connection_group, ssl_params,
    198                                request_info.priority, callback, ssl_pool,
    199                                net_log);
    200   }
    201 
    202   // Finally, get the connection started.
    203   if (proxy_info.is_http() || proxy_info.is_https()) {
    204     HttpProxyClientSocketPool* pool =
    205         session->GetSocketPoolForHTTPProxy(*proxy_host_port);
    206     if (num_preconnect_streams) {
    207       RequestSocketsForPool(pool, connection_group, http_proxy_params,
    208                             num_preconnect_streams, net_log);
    209       return OK;
    210     }
    211 
    212     return socket_handle->Init(connection_group, http_proxy_params,
    213                                request_info.priority, callback,
    214                                pool, net_log);
    215   }
    216 
    217   if (proxy_info.is_socks()) {
    218     SOCKSClientSocketPool* pool =
    219         session->GetSocketPoolForSOCKSProxy(*proxy_host_port);
    220     if (num_preconnect_streams) {
    221       RequestSocketsForPool(pool, connection_group, socks_params,
    222                             num_preconnect_streams, net_log);
    223       return OK;
    224     }
    225 
    226     return socket_handle->Init(connection_group, socks_params,
    227                                request_info.priority, callback, pool,
    228                                net_log);
    229   }
    230 
    231   DCHECK(proxy_info.is_direct());
    232 
    233   TransportClientSocketPool* pool = session->transport_socket_pool();
    234   if (num_preconnect_streams) {
    235     RequestSocketsForPool(pool, connection_group, tcp_params,
    236                           num_preconnect_streams, net_log);
    237     return OK;
    238   }
    239 
    240   return socket_handle->Init(connection_group, tcp_params,
    241                              request_info.priority, callback,
    242                              pool, net_log);
    243 }
    244 
    245 }  // namespace
    246 
    247 ClientSocketPoolManager::ClientSocketPoolManager(
    248     NetLog* net_log,
    249     ClientSocketFactory* socket_factory,
    250     HostResolver* host_resolver,
    251     CertVerifier* cert_verifier,
    252     DnsRRResolver* dnsrr_resolver,
    253     DnsCertProvenanceChecker* dns_cert_checker,
    254     SSLHostInfoFactory* ssl_host_info_factory,
    255     ProxyService* proxy_service,
    256     SSLConfigService* ssl_config_service)
    257     : net_log_(net_log),
    258       socket_factory_(socket_factory),
    259       host_resolver_(host_resolver),
    260       cert_verifier_(cert_verifier),
    261       dnsrr_resolver_(dnsrr_resolver),
    262       dns_cert_checker_(dns_cert_checker),
    263       ssl_host_info_factory_(ssl_host_info_factory),
    264       proxy_service_(proxy_service),
    265       ssl_config_service_(ssl_config_service),
    266       transport_pool_histograms_("TCP"),
    267       transport_socket_pool_(new TransportClientSocketPool(
    268           g_max_sockets, g_max_sockets_per_group,
    269           &transport_pool_histograms_,
    270           host_resolver,
    271           socket_factory_,
    272           net_log)),
    273       ssl_pool_histograms_("SSL2"),
    274       ssl_socket_pool_(new SSLClientSocketPool(
    275           g_max_sockets, g_max_sockets_per_group,
    276           &ssl_pool_histograms_,
    277           host_resolver,
    278           cert_verifier,
    279           dnsrr_resolver,
    280           dns_cert_checker,
    281           ssl_host_info_factory,
    282           socket_factory,
    283           transport_socket_pool_.get(),
    284           NULL /* no socks proxy */,
    285           NULL /* no http proxy */,
    286           ssl_config_service,
    287           net_log)),
    288       transport_for_socks_pool_histograms_("TCPforSOCKS"),
    289       socks_pool_histograms_("SOCK"),
    290       transport_for_http_proxy_pool_histograms_("TCPforHTTPProxy"),
    291       transport_for_https_proxy_pool_histograms_("TCPforHTTPSProxy"),
    292       ssl_for_https_proxy_pool_histograms_("SSLforHTTPSProxy"),
    293       http_proxy_pool_histograms_("HTTPProxy"),
    294       ssl_socket_pool_for_proxies_histograms_("SSLForProxies") {
    295   CertDatabase::AddObserver(this);
    296 }
    297 
    298 ClientSocketPoolManager::~ClientSocketPoolManager() {
    299   CertDatabase::RemoveObserver(this);
    300 }
    301 
    302 void ClientSocketPoolManager::FlushSocketPools() {
    303   // Flush the highest level pools first, since higher level pools may release
    304   // stuff to the lower level pools.
    305 
    306   for (SSLSocketPoolMap::const_iterator it =
    307        ssl_socket_pools_for_proxies_.begin();
    308        it != ssl_socket_pools_for_proxies_.end();
    309        ++it)
    310     it->second->Flush();
    311 
    312   for (HTTPProxySocketPoolMap::const_iterator it =
    313        http_proxy_socket_pools_.begin();
    314        it != http_proxy_socket_pools_.end();
    315        ++it)
    316     it->second->Flush();
    317 
    318   for (SSLSocketPoolMap::const_iterator it =
    319        ssl_socket_pools_for_https_proxies_.begin();
    320        it != ssl_socket_pools_for_https_proxies_.end();
    321        ++it)
    322     it->second->Flush();
    323 
    324   for (TransportSocketPoolMap::const_iterator it =
    325        transport_socket_pools_for_https_proxies_.begin();
    326        it != transport_socket_pools_for_https_proxies_.end();
    327        ++it)
    328     it->second->Flush();
    329 
    330   for (TransportSocketPoolMap::const_iterator it =
    331        transport_socket_pools_for_http_proxies_.begin();
    332        it != transport_socket_pools_for_http_proxies_.end();
    333        ++it)
    334     it->second->Flush();
    335 
    336   for (SOCKSSocketPoolMap::const_iterator it =
    337        socks_socket_pools_.begin();
    338        it != socks_socket_pools_.end();
    339        ++it)
    340     it->second->Flush();
    341 
    342   for (TransportSocketPoolMap::const_iterator it =
    343        transport_socket_pools_for_socks_proxies_.begin();
    344        it != transport_socket_pools_for_socks_proxies_.end();
    345        ++it)
    346     it->second->Flush();
    347 
    348   ssl_socket_pool_->Flush();
    349   transport_socket_pool_->Flush();
    350 }
    351 
    352 void ClientSocketPoolManager::CloseIdleSockets() {
    353   // Close sockets in the highest level pools first, since higher level pools'
    354   // sockets may release stuff to the lower level pools.
    355   for (SSLSocketPoolMap::const_iterator it =
    356        ssl_socket_pools_for_proxies_.begin();
    357        it != ssl_socket_pools_for_proxies_.end();
    358        ++it)
    359     it->second->CloseIdleSockets();
    360 
    361   for (HTTPProxySocketPoolMap::const_iterator it =
    362        http_proxy_socket_pools_.begin();
    363        it != http_proxy_socket_pools_.end();
    364        ++it)
    365     it->second->CloseIdleSockets();
    366 
    367   for (SSLSocketPoolMap::const_iterator it =
    368        ssl_socket_pools_for_https_proxies_.begin();
    369        it != ssl_socket_pools_for_https_proxies_.end();
    370        ++it)
    371     it->second->CloseIdleSockets();
    372 
    373   for (TransportSocketPoolMap::const_iterator it =
    374        transport_socket_pools_for_https_proxies_.begin();
    375        it != transport_socket_pools_for_https_proxies_.end();
    376        ++it)
    377     it->second->CloseIdleSockets();
    378 
    379   for (TransportSocketPoolMap::const_iterator it =
    380        transport_socket_pools_for_http_proxies_.begin();
    381        it != transport_socket_pools_for_http_proxies_.end();
    382        ++it)
    383     it->second->CloseIdleSockets();
    384 
    385   for (SOCKSSocketPoolMap::const_iterator it =
    386        socks_socket_pools_.begin();
    387        it != socks_socket_pools_.end();
    388        ++it)
    389     it->second->CloseIdleSockets();
    390 
    391   for (TransportSocketPoolMap::const_iterator it =
    392        transport_socket_pools_for_socks_proxies_.begin();
    393        it != transport_socket_pools_for_socks_proxies_.end();
    394        ++it)
    395     it->second->CloseIdleSockets();
    396 
    397   ssl_socket_pool_->CloseIdleSockets();
    398   transport_socket_pool_->CloseIdleSockets();
    399 }
    400 
    401 SOCKSClientSocketPool* ClientSocketPoolManager::GetSocketPoolForSOCKSProxy(
    402     const HostPortPair& socks_proxy) {
    403   SOCKSSocketPoolMap::const_iterator it = socks_socket_pools_.find(socks_proxy);
    404   if (it != socks_socket_pools_.end()) {
    405     DCHECK(ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
    406     return it->second;
    407   }
    408 
    409   DCHECK(!ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy));
    410 
    411   std::pair<TransportSocketPoolMap::iterator, bool> tcp_ret =
    412       transport_socket_pools_for_socks_proxies_.insert(
    413           std::make_pair(
    414               socks_proxy,
    415               new TransportClientSocketPool(
    416                   g_max_sockets_per_proxy_server, g_max_sockets_per_group,
    417                   &transport_for_socks_pool_histograms_,
    418                   host_resolver_,
    419                   socket_factory_,
    420                   net_log_)));
    421   DCHECK(tcp_ret.second);
    422 
    423   std::pair<SOCKSSocketPoolMap::iterator, bool> ret =
    424       socks_socket_pools_.insert(
    425           std::make_pair(socks_proxy, new SOCKSClientSocketPool(
    426               g_max_sockets_per_proxy_server, g_max_sockets_per_group,
    427               &socks_pool_histograms_,
    428               host_resolver_,
    429               tcp_ret.first->second,
    430               net_log_)));
    431 
    432   return ret.first->second;
    433 }
    434 
    435 HttpProxyClientSocketPool* ClientSocketPoolManager::GetSocketPoolForHTTPProxy(
    436     const HostPortPair& http_proxy) {
    437   HTTPProxySocketPoolMap::const_iterator it =
    438       http_proxy_socket_pools_.find(http_proxy);
    439   if (it != http_proxy_socket_pools_.end()) {
    440     DCHECK(ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
    441     DCHECK(ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
    442     DCHECK(ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
    443     return it->second;
    444   }
    445 
    446   DCHECK(!ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy));
    447   DCHECK(!ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy));
    448   DCHECK(!ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy));
    449 
    450   std::pair<TransportSocketPoolMap::iterator, bool> tcp_http_ret =
    451       transport_socket_pools_for_http_proxies_.insert(
    452           std::make_pair(
    453               http_proxy,
    454               new TransportClientSocketPool(
    455                   g_max_sockets_per_proxy_server, g_max_sockets_per_group,
    456                   &transport_for_http_proxy_pool_histograms_,
    457                   host_resolver_,
    458                   socket_factory_,
    459                   net_log_)));
    460   DCHECK(tcp_http_ret.second);
    461 
    462   std::pair<TransportSocketPoolMap::iterator, bool> tcp_https_ret =
    463       transport_socket_pools_for_https_proxies_.insert(
    464           std::make_pair(
    465               http_proxy,
    466               new TransportClientSocketPool(
    467                   g_max_sockets_per_proxy_server, g_max_sockets_per_group,
    468                   &transport_for_https_proxy_pool_histograms_,
    469                   host_resolver_,
    470                   socket_factory_,
    471                   net_log_)));
    472   DCHECK(tcp_https_ret.second);
    473 
    474   std::pair<SSLSocketPoolMap::iterator, bool> ssl_https_ret =
    475       ssl_socket_pools_for_https_proxies_.insert(
    476           std::make_pair(
    477               http_proxy,
    478               new SSLClientSocketPool(
    479                   g_max_sockets_per_proxy_server, g_max_sockets_per_group,
    480                   &ssl_for_https_proxy_pool_histograms_,
    481                   host_resolver_,
    482                   cert_verifier_,
    483                   dnsrr_resolver_,
    484                   dns_cert_checker_,
    485                   ssl_host_info_factory_,
    486                   socket_factory_,
    487                   tcp_https_ret.first->second /* https proxy */,
    488                   NULL /* no socks proxy */,
    489                   NULL /* no http proxy */,
    490                   ssl_config_service_, net_log_)));
    491   DCHECK(tcp_https_ret.second);
    492 
    493   std::pair<HTTPProxySocketPoolMap::iterator, bool> ret =
    494       http_proxy_socket_pools_.insert(
    495           std::make_pair(
    496               http_proxy,
    497               new HttpProxyClientSocketPool(
    498                   g_max_sockets_per_proxy_server, g_max_sockets_per_group,
    499                   &http_proxy_pool_histograms_,
    500                   host_resolver_,
    501                   tcp_http_ret.first->second,
    502                   ssl_https_ret.first->second,
    503                   net_log_)));
    504 
    505   return ret.first->second;
    506 }
    507 
    508 SSLClientSocketPool* ClientSocketPoolManager::GetSocketPoolForSSLWithProxy(
    509     const HostPortPair& proxy_server) {
    510   SSLSocketPoolMap::const_iterator it =
    511       ssl_socket_pools_for_proxies_.find(proxy_server);
    512   if (it != ssl_socket_pools_for_proxies_.end())
    513     return it->second;
    514 
    515   SSLClientSocketPool* new_pool = new SSLClientSocketPool(
    516       g_max_sockets_per_proxy_server, g_max_sockets_per_group,
    517       &ssl_pool_histograms_,
    518       host_resolver_,
    519       cert_verifier_,
    520       dnsrr_resolver_,
    521       dns_cert_checker_,
    522       ssl_host_info_factory_,
    523       socket_factory_,
    524       NULL, /* no tcp pool, we always go through a proxy */
    525       GetSocketPoolForSOCKSProxy(proxy_server),
    526       GetSocketPoolForHTTPProxy(proxy_server),
    527       ssl_config_service_,
    528       net_log_);
    529 
    530   std::pair<SSLSocketPoolMap::iterator, bool> ret =
    531       ssl_socket_pools_for_proxies_.insert(std::make_pair(proxy_server,
    532                                                           new_pool));
    533 
    534   return ret.first->second;
    535 }
    536 
    537 // static
    538 int ClientSocketPoolManager::max_sockets_per_group() {
    539   return g_max_sockets_per_group;
    540 }
    541 
    542 // static
    543 void ClientSocketPoolManager::set_max_sockets_per_group(int socket_count) {
    544   DCHECK_LT(0, socket_count);
    545   // The following is a sanity check... but we should NEVER be near this value.
    546   DCHECK_GT(100, socket_count);
    547   g_max_sockets_per_group = socket_count;
    548 
    549   DCHECK_GE(g_max_sockets, g_max_sockets_per_group);
    550   DCHECK_GE(g_max_sockets_per_proxy_server, g_max_sockets_per_group);
    551 }
    552 
    553 // static
    554 void ClientSocketPoolManager::set_max_sockets_per_proxy_server(
    555     int socket_count) {
    556   DCHECK_LT(0, socket_count);
    557   DCHECK_GT(100, socket_count);  // Sanity check.
    558   // Assert this case early on. The max number of sockets per group cannot
    559   // exceed the max number of sockets per proxy server.
    560   DCHECK_LE(g_max_sockets_per_group, socket_count);
    561   g_max_sockets_per_proxy_server = socket_count;
    562 }
    563 
    564 Value* ClientSocketPoolManager::SocketPoolInfoToValue() const {
    565   ListValue* list = new ListValue();
    566   list->Append(transport_socket_pool_->GetInfoAsValue("transport_socket_pool",
    567                                                 "transport_socket_pool",
    568                                                 false));
    569   // Third parameter is false because |ssl_socket_pool_| uses
    570   // |transport_socket_pool_| internally, and do not want to add it a second
    571   // time.
    572   list->Append(ssl_socket_pool_->GetInfoAsValue("ssl_socket_pool",
    573                                                 "ssl_socket_pool",
    574                                                 false));
    575   AddSocketPoolsToList(list,
    576                        http_proxy_socket_pools_,
    577                        "http_proxy_socket_pool",
    578                        true);
    579   AddSocketPoolsToList(list,
    580                        socks_socket_pools_,
    581                        "socks_socket_pool",
    582                        true);
    583 
    584   // Third parameter is false because |ssl_socket_pools_for_proxies_| use
    585   // socket pools in |http_proxy_socket_pools_| and |socks_socket_pools_|.
    586   AddSocketPoolsToList(list,
    587                        ssl_socket_pools_for_proxies_,
    588                        "ssl_socket_pool_for_proxies",
    589                        false);
    590   return list;
    591 }
    592 
    593 void ClientSocketPoolManager::OnUserCertAdded(const X509Certificate* cert) {
    594   FlushSocketPools();
    595 }
    596 
    597 void ClientSocketPoolManager::OnCertTrustChanged(const X509Certificate* cert) {
    598   // We should flush the socket pools if we removed trust from a
    599   // cert, because a previously trusted server may have become
    600   // untrusted.
    601   //
    602   // We should not flush the socket pools if we added trust to a
    603   // cert.
    604   //
    605   // Since the OnCertTrustChanged method doesn't tell us what
    606   // kind of trust change it is, we have to flush the socket
    607   // pools to be safe.
    608   FlushSocketPools();
    609 }
    610 
    611 // static
    612 int ClientSocketPoolManager::InitSocketHandleForHttpRequest(
    613     const HttpRequestInfo& request_info,
    614     HttpNetworkSession* session,
    615     const ProxyInfo& proxy_info,
    616     bool force_spdy_over_ssl,
    617     bool want_spdy_over_npn,
    618     const SSLConfig& ssl_config_for_origin,
    619     const SSLConfig& ssl_config_for_proxy,
    620     const BoundNetLog& net_log,
    621     ClientSocketHandle* socket_handle,
    622     CompletionCallback* callback) {
    623   DCHECK(socket_handle);
    624   return InitSocketPoolHelper(request_info,
    625                               session,
    626                               proxy_info,
    627                               force_spdy_over_ssl,
    628                               want_spdy_over_npn,
    629                               ssl_config_for_origin,
    630                               ssl_config_for_proxy,
    631                               false,
    632                               net_log,
    633                               0,
    634                               socket_handle,
    635                               callback);
    636 }
    637 
    638 // static
    639 int ClientSocketPoolManager::InitSocketHandleForRawConnect(
    640     const HostPortPair& host_port_pair,
    641     HttpNetworkSession* session,
    642     const ProxyInfo& proxy_info,
    643     const SSLConfig& ssl_config_for_origin,
    644     const SSLConfig& ssl_config_for_proxy,
    645     const BoundNetLog& net_log,
    646     ClientSocketHandle* socket_handle,
    647     CompletionCallback* callback) {
    648   DCHECK(socket_handle);
    649   // Synthesize an HttpRequestInfo.
    650   HttpRequestInfo request_info;
    651   request_info.url = GURL("http://" + host_port_pair.ToString());
    652   return InitSocketPoolHelper(request_info,
    653                               session,
    654                               proxy_info,
    655                               false,
    656                               false,
    657                               ssl_config_for_origin,
    658                               ssl_config_for_proxy,
    659                               true,
    660                               net_log,
    661                               0,
    662                               socket_handle,
    663                               callback);
    664 }
    665 
    666 // static
    667 int ClientSocketPoolManager::PreconnectSocketsForHttpRequest(
    668     const HttpRequestInfo& request_info,
    669     HttpNetworkSession* session,
    670     const ProxyInfo& proxy_info,
    671     bool force_spdy_over_ssl,
    672     bool want_spdy_over_npn,
    673     const SSLConfig& ssl_config_for_origin,
    674     const SSLConfig& ssl_config_for_proxy,
    675     const BoundNetLog& net_log,
    676     int num_preconnect_streams) {
    677   return InitSocketPoolHelper(request_info,
    678                               session,
    679                               proxy_info,
    680                               force_spdy_over_ssl,
    681                               want_spdy_over_npn,
    682                               ssl_config_for_origin,
    683                               ssl_config_for_proxy,
    684                               false,
    685                               net_log,
    686                               num_preconnect_streams,
    687                               NULL,
    688                               NULL);
    689 }
    690 
    691 
    692 }  // namespace net
    693