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
28namespace net {
29
30namespace {
31
32// Total limit of sockets.
33int 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.
38int 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.
43int g_max_sockets_per_proxy_server = 32;
44
45// Appends information about all |socket_pools| to the end of |list|.
46template <class MapType>
47static 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.
61int 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
247ClientSocketPoolManager::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
298ClientSocketPoolManager::~ClientSocketPoolManager() {
299  CertDatabase::RemoveObserver(this);
300}
301
302void 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
352void 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
401SOCKSClientSocketPool* 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
435HttpProxyClientSocketPool* 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
508SSLClientSocketPool* 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
538int ClientSocketPoolManager::max_sockets_per_group() {
539  return g_max_sockets_per_group;
540}
541
542// static
543void 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
554void 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
564Value* 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
593void ClientSocketPoolManager::OnUserCertAdded(const X509Certificate* cert) {
594  FlushSocketPools();
595}
596
597void 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
612int 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
639int 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
667int 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