• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 #include "net/socket/client_socket_pool_manager.h"
6 
7 #include <string>
8 
9 #include "base/basictypes.h"
10 #include "base/logging.h"
11 #include "base/strings/stringprintf.h"
12 #include "net/base/load_flags.h"
13 #include "net/http/http_proxy_client_socket_pool.h"
14 #include "net/http/http_request_info.h"
15 #include "net/http/http_stream_factory.h"
16 #include "net/proxy/proxy_info.h"
17 #include "net/socket/client_socket_handle.h"
18 #include "net/socket/socks_client_socket_pool.h"
19 #include "net/socket/ssl_client_socket_pool.h"
20 #include "net/socket/transport_client_socket_pool.h"
21 
22 namespace net {
23 
24 namespace {
25 
26 // Limit of sockets of each socket pool.
27 int g_max_sockets_per_pool[] = {
28   256,  // NORMAL_SOCKET_POOL
29   256   // WEBSOCKET_SOCKET_POOL
30 };
31 
32 COMPILE_ASSERT(arraysize(g_max_sockets_per_pool) ==
33                    HttpNetworkSession::NUM_SOCKET_POOL_TYPES,
34                max_sockets_per_pool_length_mismatch);
35 
36 // Default to allow up to 6 connections per host. Experiment and tuning may
37 // try other values (greater than 0).  Too large may cause many problems, such
38 // as home routers blocking the connections!?!?  See http://crbug.com/12066.
39 //
40 // WebSocket connections are long-lived, and should be treated differently
41 // than normal other connections. 6 connections per group sounded too small
42 // for such use, thus we use a larger limit which was determined somewhat
43 // arbitrarily.
44 // TODO(yutak): Look at the usage and determine the right value after
45 // WebSocket protocol stack starts to work.
46 int g_max_sockets_per_group[] = {
47   6,  // NORMAL_SOCKET_POOL
48   30  // WEBSOCKET_SOCKET_POOL
49 };
50 
51 COMPILE_ASSERT(arraysize(g_max_sockets_per_group) ==
52                    HttpNetworkSession::NUM_SOCKET_POOL_TYPES,
53                max_sockets_per_group_length_mismatch);
54 
55 // The max number of sockets to allow per proxy server.  This applies both to
56 // http and SOCKS proxies.  See http://crbug.com/12066 and
57 // http://crbug.com/44501 for details about proxy server connection limits.
58 int g_max_sockets_per_proxy_server[] = {
59   kDefaultMaxSocketsPerProxyServer,  // NORMAL_SOCKET_POOL
60   kDefaultMaxSocketsPerProxyServer   // WEBSOCKET_SOCKET_POOL
61 };
62 
63 COMPILE_ASSERT(arraysize(g_max_sockets_per_proxy_server) ==
64                    HttpNetworkSession::NUM_SOCKET_POOL_TYPES,
65                max_sockets_per_proxy_server_length_mismatch);
66 
67 // The meat of the implementation for the InitSocketHandleForHttpRequest,
68 // InitSocketHandleForRawConnect and PreconnectSocketsForHttpRequest methods.
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,PrivacyMode privacy_mode,const BoundNetLog & net_log,int num_preconnect_streams,ClientSocketHandle * socket_handle,HttpNetworkSession::SocketPoolType socket_pool_type,const OnHostResolutionCallback & resolution_callback,const CompletionCallback & callback)69 int InitSocketPoolHelper(const GURL& request_url,
70                          const HttpRequestHeaders& request_extra_headers,
71                          int request_load_flags,
72                          RequestPriority request_priority,
73                          HttpNetworkSession* session,
74                          const ProxyInfo& proxy_info,
75                          bool force_spdy_over_ssl,
76                          bool want_spdy_over_npn,
77                          const SSLConfig& ssl_config_for_origin,
78                          const SSLConfig& ssl_config_for_proxy,
79                          bool force_tunnel,
80                          PrivacyMode privacy_mode,
81                          const BoundNetLog& net_log,
82                          int num_preconnect_streams,
83                          ClientSocketHandle* socket_handle,
84                          HttpNetworkSession::SocketPoolType socket_pool_type,
85                          const OnHostResolutionCallback& resolution_callback,
86                          const CompletionCallback& callback) {
87   scoped_refptr<HttpProxySocketParams> http_proxy_params;
88   scoped_refptr<SOCKSSocketParams> socks_params;
89   scoped_ptr<HostPortPair> proxy_host_port;
90 
91   bool using_ssl = request_url.SchemeIs("https") ||
92       request_url.SchemeIs("wss") || force_spdy_over_ssl;
93 
94   HostPortPair origin_host_port =
95       HostPortPair(request_url.HostNoBrackets(),
96                    request_url.EffectiveIntPort());
97 
98   if (!using_ssl && session->params().testing_fixed_http_port != 0) {
99     origin_host_port.set_port(session->params().testing_fixed_http_port);
100   } else if (using_ssl && session->params().testing_fixed_https_port != 0) {
101     origin_host_port.set_port(session->params().testing_fixed_https_port);
102   }
103 
104   bool disable_resolver_cache =
105       request_load_flags & LOAD_BYPASS_CACHE ||
106       request_load_flags & LOAD_VALIDATE_CACHE ||
107       request_load_flags & LOAD_DISABLE_CACHE;
108 
109   int load_flags = request_load_flags;
110   if (session->params().ignore_certificate_errors)
111     load_flags |= LOAD_IGNORE_ALL_CERT_ERRORS;
112 
113   // Build the string used to uniquely identify connections of this type.
114   // Determine the host and port to connect to.
115   std::string connection_group = origin_host_port.ToString();
116   DCHECK(!connection_group.empty());
117   if (request_url.SchemeIs("ftp")) {
118     // Combining FTP with forced SPDY over SSL would be a "path to madness".
119     // Make sure we never do that.
120     DCHECK(!using_ssl);
121     connection_group = "ftp/" + connection_group;
122   }
123   if (using_ssl) {
124     // All connections in a group should use the same SSLConfig settings.
125     // Encode version_max in the connection group's name, unless it's the
126     // default version_max. (We want the common case to use the shortest
127     // encoding). A version_max of TLS 1.1 is encoded as "ssl(max:3.2)/"
128     // rather than "tlsv1.1/" because the actual protocol version, which
129     // is selected by the server, may not be TLS 1.1. Do not encode
130     // version_min in the connection group's name because version_min
131     // should be the same for all connections, whereas version_max may
132     // change for version fallbacks.
133     std::string prefix = "ssl/";
134     if (ssl_config_for_origin.version_max != kDefaultSSLVersionMax) {
135       switch (ssl_config_for_origin.version_max) {
136         case SSL_PROTOCOL_VERSION_TLS1_2:
137           prefix = "ssl(max:3.3)/";
138           break;
139         case SSL_PROTOCOL_VERSION_TLS1_1:
140           prefix = "ssl(max:3.2)/";
141           break;
142         case SSL_PROTOCOL_VERSION_TLS1:
143           prefix = "ssl(max:3.1)/";
144           break;
145         case SSL_PROTOCOL_VERSION_SSL3:
146           prefix = "sslv3/";
147           break;
148         default:
149           CHECK(false);
150           break;
151       }
152     }
153     connection_group = prefix + connection_group;
154   }
155 
156   bool ignore_limits = (request_load_flags & LOAD_IGNORE_LIMITS) != 0;
157   if (!proxy_info.is_direct()) {
158     ProxyServer proxy_server = proxy_info.proxy_server();
159     proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair()));
160     scoped_refptr<TransportSocketParams> proxy_tcp_params(
161         new TransportSocketParams(
162             *proxy_host_port,
163             disable_resolver_cache,
164             ignore_limits,
165             resolution_callback,
166             TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
167 
168     if (proxy_info.is_http() || proxy_info.is_https()) {
169       std::string user_agent;
170       request_extra_headers.GetHeader(HttpRequestHeaders::kUserAgent,
171                                       &user_agent);
172       scoped_refptr<SSLSocketParams> ssl_params;
173       if (proxy_info.is_https()) {
174         // Combine connect and write for SSL sockets in TCP FastOpen
175         // field trial.
176         TransportSocketParams::CombineConnectAndWritePolicy
177             combine_connect_and_write =
178                 session->params().enable_tcp_fast_open_for_ssl ?
179                     TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DESIRED :
180                     TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT;
181         proxy_tcp_params = new TransportSocketParams(*proxy_host_port,
182                                                      disable_resolver_cache,
183                                                      ignore_limits,
184                                                      resolution_callback,
185                                                      combine_connect_and_write);
186         // Set ssl_params, and unset proxy_tcp_params
187         ssl_params = new SSLSocketParams(proxy_tcp_params,
188                                          NULL,
189                                          NULL,
190                                          *proxy_host_port.get(),
191                                          ssl_config_for_proxy,
192                                          PRIVACY_MODE_DISABLED,
193                                          load_flags,
194                                          force_spdy_over_ssl,
195                                          want_spdy_over_npn);
196         proxy_tcp_params = NULL;
197       }
198 
199       http_proxy_params =
200           new HttpProxySocketParams(proxy_tcp_params,
201                                     ssl_params,
202                                     request_url,
203                                     user_agent,
204                                     origin_host_port,
205                                     session->http_auth_cache(),
206                                     session->http_auth_handler_factory(),
207                                     session->spdy_session_pool(),
208                                     force_tunnel || using_ssl,
209                                     session->params().proxy_delegate);
210     } else {
211       DCHECK(proxy_info.is_socks());
212       char socks_version;
213       if (proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5)
214         socks_version = '5';
215       else
216         socks_version = '4';
217       connection_group = base::StringPrintf(
218           "socks%c/%s", socks_version, connection_group.c_str());
219 
220       socks_params = new SOCKSSocketParams(proxy_tcp_params,
221                                            socks_version == '5',
222                                            origin_host_port);
223     }
224   }
225 
226   // Change group name if privacy mode is enabled.
227   if (privacy_mode == PRIVACY_MODE_ENABLED)
228     connection_group = "pm/" + connection_group;
229 
230   // Deal with SSL - which layers on top of any given proxy.
231   if (using_ssl) {
232     scoped_refptr<TransportSocketParams> ssl_tcp_params;
233     if (proxy_info.is_direct()) {
234       // Setup TCP params if non-proxied SSL connection.
235       // Combine connect and write for SSL sockets in TCP FastOpen field trial.
236       TransportSocketParams::CombineConnectAndWritePolicy
237           combine_connect_and_write =
238               session->params().enable_tcp_fast_open_for_ssl ?
239                   TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DESIRED :
240                   TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT;
241       ssl_tcp_params = new TransportSocketParams(origin_host_port,
242                                                  disable_resolver_cache,
243                                                  ignore_limits,
244                                                  resolution_callback,
245                                                  combine_connect_and_write);
246     }
247     scoped_refptr<SSLSocketParams> ssl_params =
248         new SSLSocketParams(ssl_tcp_params,
249                             socks_params,
250                             http_proxy_params,
251                             origin_host_port,
252                             ssl_config_for_origin,
253                             privacy_mode,
254                             load_flags,
255                             force_spdy_over_ssl,
256                             want_spdy_over_npn);
257     SSLClientSocketPool* ssl_pool = NULL;
258     if (proxy_info.is_direct()) {
259       ssl_pool = session->GetSSLSocketPool(socket_pool_type);
260     } else {
261       ssl_pool = session->GetSocketPoolForSSLWithProxy(socket_pool_type,
262                                                        *proxy_host_port);
263     }
264 
265     if (num_preconnect_streams) {
266       RequestSocketsForPool(ssl_pool, connection_group, ssl_params,
267                             num_preconnect_streams, net_log);
268       return OK;
269     }
270 
271     return socket_handle->Init(connection_group, ssl_params,
272                                request_priority, callback, ssl_pool,
273                                net_log);
274   }
275 
276   // Finally, get the connection started.
277 
278   if (proxy_info.is_http() || proxy_info.is_https()) {
279     HttpProxyClientSocketPool* pool =
280         session->GetSocketPoolForHTTPProxy(socket_pool_type, *proxy_host_port);
281     if (num_preconnect_streams) {
282       RequestSocketsForPool(pool, connection_group, http_proxy_params,
283                             num_preconnect_streams, net_log);
284       return OK;
285     }
286 
287     return socket_handle->Init(connection_group, http_proxy_params,
288                                request_priority, callback,
289                                pool, net_log);
290   }
291 
292   if (proxy_info.is_socks()) {
293     SOCKSClientSocketPool* pool =
294         session->GetSocketPoolForSOCKSProxy(socket_pool_type, *proxy_host_port);
295     if (num_preconnect_streams) {
296       RequestSocketsForPool(pool, connection_group, socks_params,
297                             num_preconnect_streams, net_log);
298       return OK;
299     }
300 
301     return socket_handle->Init(connection_group, socks_params,
302                                request_priority, callback, pool,
303                                net_log);
304   }
305 
306   DCHECK(proxy_info.is_direct());
307   scoped_refptr<TransportSocketParams> tcp_params =
308       new TransportSocketParams(
309           origin_host_port,
310           disable_resolver_cache,
311           ignore_limits,
312           resolution_callback,
313           TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT);
314   TransportClientSocketPool* pool =
315       session->GetTransportSocketPool(socket_pool_type);
316   if (num_preconnect_streams) {
317     RequestSocketsForPool(pool, connection_group, tcp_params,
318                           num_preconnect_streams, net_log);
319     return OK;
320   }
321 
322   return socket_handle->Init(connection_group, tcp_params,
323                              request_priority, callback,
324                              pool, net_log);
325 }
326 
327 }  // namespace
328 
ClientSocketPoolManager()329 ClientSocketPoolManager::ClientSocketPoolManager() {}
~ClientSocketPoolManager()330 ClientSocketPoolManager::~ClientSocketPoolManager() {}
331 
332 // static
max_sockets_per_pool(HttpNetworkSession::SocketPoolType pool_type)333 int ClientSocketPoolManager::max_sockets_per_pool(
334     HttpNetworkSession::SocketPoolType pool_type) {
335   DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
336   return g_max_sockets_per_pool[pool_type];
337 }
338 
339 // static
set_max_sockets_per_pool(HttpNetworkSession::SocketPoolType pool_type,int socket_count)340 void ClientSocketPoolManager::set_max_sockets_per_pool(
341     HttpNetworkSession::SocketPoolType pool_type,
342     int socket_count) {
343   DCHECK_LT(0, socket_count);
344   DCHECK_GT(1000, socket_count);  // Sanity check.
345   DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
346   g_max_sockets_per_pool[pool_type] = socket_count;
347   DCHECK_GE(g_max_sockets_per_pool[pool_type],
348             g_max_sockets_per_group[pool_type]);
349 }
350 
351 // static
max_sockets_per_group(HttpNetworkSession::SocketPoolType pool_type)352 int ClientSocketPoolManager::max_sockets_per_group(
353     HttpNetworkSession::SocketPoolType pool_type) {
354   DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
355   return g_max_sockets_per_group[pool_type];
356 }
357 
358 // static
set_max_sockets_per_group(HttpNetworkSession::SocketPoolType pool_type,int socket_count)359 void ClientSocketPoolManager::set_max_sockets_per_group(
360     HttpNetworkSession::SocketPoolType pool_type,
361     int socket_count) {
362   DCHECK_LT(0, socket_count);
363   // The following is a sanity check... but we should NEVER be near this value.
364   DCHECK_GT(100, socket_count);
365   DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
366   g_max_sockets_per_group[pool_type] = socket_count;
367 
368   DCHECK_GE(g_max_sockets_per_pool[pool_type],
369             g_max_sockets_per_group[pool_type]);
370   DCHECK_GE(g_max_sockets_per_proxy_server[pool_type],
371             g_max_sockets_per_group[pool_type]);
372 }
373 
374 // static
max_sockets_per_proxy_server(HttpNetworkSession::SocketPoolType pool_type)375 int ClientSocketPoolManager::max_sockets_per_proxy_server(
376     HttpNetworkSession::SocketPoolType pool_type) {
377   DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
378   return g_max_sockets_per_proxy_server[pool_type];
379 }
380 
381 // static
set_max_sockets_per_proxy_server(HttpNetworkSession::SocketPoolType pool_type,int socket_count)382 void ClientSocketPoolManager::set_max_sockets_per_proxy_server(
383     HttpNetworkSession::SocketPoolType pool_type,
384     int socket_count) {
385   DCHECK_LT(0, socket_count);
386   DCHECK_GT(100, socket_count);  // Sanity check.
387   DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
388   // Assert this case early on. The max number of sockets per group cannot
389   // exceed the max number of sockets per proxy server.
390   DCHECK_LE(g_max_sockets_per_group[pool_type], socket_count);
391   g_max_sockets_per_proxy_server[pool_type] = socket_count;
392 }
393 
InitSocketHandleForHttpRequest(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,PrivacyMode privacy_mode,const BoundNetLog & net_log,ClientSocketHandle * socket_handle,const OnHostResolutionCallback & resolution_callback,const CompletionCallback & callback)394 int InitSocketHandleForHttpRequest(
395     const GURL& request_url,
396     const HttpRequestHeaders& request_extra_headers,
397     int request_load_flags,
398     RequestPriority request_priority,
399     HttpNetworkSession* session,
400     const ProxyInfo& proxy_info,
401     bool force_spdy_over_ssl,
402     bool want_spdy_over_npn,
403     const SSLConfig& ssl_config_for_origin,
404     const SSLConfig& ssl_config_for_proxy,
405     PrivacyMode privacy_mode,
406     const BoundNetLog& net_log,
407     ClientSocketHandle* socket_handle,
408     const OnHostResolutionCallback& resolution_callback,
409     const CompletionCallback& callback) {
410   DCHECK(socket_handle);
411   return InitSocketPoolHelper(
412       request_url, request_extra_headers, request_load_flags, request_priority,
413       session, proxy_info, force_spdy_over_ssl, want_spdy_over_npn,
414       ssl_config_for_origin, ssl_config_for_proxy, false, privacy_mode, net_log,
415       0, socket_handle, HttpNetworkSession::NORMAL_SOCKET_POOL,
416       resolution_callback, callback);
417 }
418 
InitSocketHandleForWebSocketRequest(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,PrivacyMode privacy_mode,const BoundNetLog & net_log,ClientSocketHandle * socket_handle,const OnHostResolutionCallback & resolution_callback,const CompletionCallback & callback)419 int InitSocketHandleForWebSocketRequest(
420     const GURL& request_url,
421     const HttpRequestHeaders& request_extra_headers,
422     int request_load_flags,
423     RequestPriority request_priority,
424     HttpNetworkSession* session,
425     const ProxyInfo& proxy_info,
426     bool force_spdy_over_ssl,
427     bool want_spdy_over_npn,
428     const SSLConfig& ssl_config_for_origin,
429     const SSLConfig& ssl_config_for_proxy,
430     PrivacyMode privacy_mode,
431     const BoundNetLog& net_log,
432     ClientSocketHandle* socket_handle,
433     const OnHostResolutionCallback& resolution_callback,
434     const CompletionCallback& callback) {
435   DCHECK(socket_handle);
436   return InitSocketPoolHelper(
437       request_url, request_extra_headers, request_load_flags, request_priority,
438       session, proxy_info, force_spdy_over_ssl, want_spdy_over_npn,
439       ssl_config_for_origin, ssl_config_for_proxy, true, privacy_mode, net_log,
440       0, socket_handle, HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
441       resolution_callback, callback);
442 }
443 
InitSocketHandleForRawConnect(const HostPortPair & host_port_pair,HttpNetworkSession * session,const ProxyInfo & proxy_info,const SSLConfig & ssl_config_for_origin,const SSLConfig & ssl_config_for_proxy,PrivacyMode privacy_mode,const BoundNetLog & net_log,ClientSocketHandle * socket_handle,const CompletionCallback & callback)444 int InitSocketHandleForRawConnect(
445     const HostPortPair& host_port_pair,
446     HttpNetworkSession* session,
447     const ProxyInfo& proxy_info,
448     const SSLConfig& ssl_config_for_origin,
449     const SSLConfig& ssl_config_for_proxy,
450     PrivacyMode privacy_mode,
451     const BoundNetLog& net_log,
452     ClientSocketHandle* socket_handle,
453     const CompletionCallback& callback) {
454   DCHECK(socket_handle);
455   // Synthesize an HttpRequestInfo.
456   GURL request_url = GURL("http://" + host_port_pair.ToString());
457   HttpRequestHeaders request_extra_headers;
458   int request_load_flags = 0;
459   RequestPriority request_priority = MEDIUM;
460 
461   return InitSocketPoolHelper(
462       request_url, request_extra_headers, request_load_flags, request_priority,
463       session, proxy_info, false, false, ssl_config_for_origin,
464       ssl_config_for_proxy, true, privacy_mode, net_log, 0, socket_handle,
465       HttpNetworkSession::NORMAL_SOCKET_POOL, OnHostResolutionCallback(),
466       callback);
467 }
468 
InitSocketHandleForTlsConnect(const HostPortPair & host_port_pair,HttpNetworkSession * session,const ProxyInfo & proxy_info,const SSLConfig & ssl_config_for_origin,const SSLConfig & ssl_config_for_proxy,PrivacyMode privacy_mode,const BoundNetLog & net_log,ClientSocketHandle * socket_handle,const CompletionCallback & callback)469 int InitSocketHandleForTlsConnect(
470     const HostPortPair& host_port_pair,
471     HttpNetworkSession* session,
472     const ProxyInfo& proxy_info,
473     const SSLConfig& ssl_config_for_origin,
474     const SSLConfig& ssl_config_for_proxy,
475     PrivacyMode privacy_mode,
476     const BoundNetLog& net_log,
477     ClientSocketHandle* socket_handle,
478     const CompletionCallback& callback) {
479   DCHECK(socket_handle);
480   // Synthesize an HttpRequestInfo.
481   GURL request_url = GURL("https://" + host_port_pair.ToString());
482   HttpRequestHeaders request_extra_headers;
483   int request_load_flags = 0;
484   RequestPriority request_priority = MEDIUM;
485 
486   return InitSocketPoolHelper(
487       request_url, request_extra_headers, request_load_flags, request_priority,
488       session, proxy_info, false, false, ssl_config_for_origin,
489       ssl_config_for_proxy, true, privacy_mode, net_log, 0, socket_handle,
490       HttpNetworkSession::NORMAL_SOCKET_POOL, OnHostResolutionCallback(),
491       callback);
492 }
493 
PreconnectSocketsForHttpRequest(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,PrivacyMode privacy_mode,const BoundNetLog & net_log,int num_preconnect_streams)494 int PreconnectSocketsForHttpRequest(
495     const GURL& request_url,
496     const HttpRequestHeaders& request_extra_headers,
497     int request_load_flags,
498     RequestPriority request_priority,
499     HttpNetworkSession* session,
500     const ProxyInfo& proxy_info,
501     bool force_spdy_over_ssl,
502     bool want_spdy_over_npn,
503     const SSLConfig& ssl_config_for_origin,
504     const SSLConfig& ssl_config_for_proxy,
505     PrivacyMode privacy_mode,
506     const BoundNetLog& net_log,
507     int num_preconnect_streams) {
508   return InitSocketPoolHelper(
509       request_url, request_extra_headers, request_load_flags, request_priority,
510       session, proxy_info, force_spdy_over_ssl, want_spdy_over_npn,
511       ssl_config_for_origin, ssl_config_for_proxy, false, privacy_mode, net_log,
512       num_preconnect_streams, NULL, HttpNetworkSession::NORMAL_SOCKET_POOL,
513       OnHostResolutionCallback(), CompletionCallback());
514 }
515 
516 }  // namespace net
517