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.
5 #include "net/http/http_proxy_client_socket_pool.h"
7 #include "base/callback.h"
8 #include "base/compiler_specific.h"
9 #include "base/string_util.h"
10 #include "base/time.h"
11 #include "base/utf_string_conversions.h"
12 #include "net/base/auth.h"
13 #include "net/base/load_timing_info.h"
14 #include "net/base/load_timing_info_test_util.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/test_completion_callback.h"
17 #include "net/cert/cert_verifier.h"
18 #include "net/dns/mock_host_resolver.h"
19 #include "net/http/http_auth_handler_factory.h"
20 #include "net/http/http_network_session.h"
21 #include "net/http/http_request_headers.h"
22 #include "net/http/http_response_headers.h"
23 #include "net/http/http_server_properties_impl.h"
24 #include "net/proxy/proxy_service.h"
25 #include "net/socket/client_socket_handle.h"
26 #include "net/socket/client_socket_pool_histograms.h"
27 #include "net/socket/socket_test_util.h"
28 #include "net/spdy/spdy_session.h"
29 #include "net/spdy/spdy_session_pool.h"
30 #include "net/spdy/spdy_test_util_spdy2.h"
31 #include "net/ssl/ssl_config_service_defaults.h"
32 #include "net/test/test_certificate_data.h"
33 #include "testing/gtest/include/gtest/gtest.h"
35 using namespace net::test_spdy2
;
41 const int kMaxSockets
= 32;
42 const int kMaxSocketsPerGroup
= 6;
44 // Make sure |handle|'s load times are set correctly. DNS and connect start
45 // times comes from mock client sockets in these tests, so primarily serves to
46 // check those times were copied, and ssl times / connect end are set correctly.
47 void TestLoadTimingInfo(const ClientSocketHandle
& handle
) {
48 LoadTimingInfo load_timing_info
;
49 EXPECT_TRUE(handle
.GetLoadTimingInfo(false, &load_timing_info
));
51 EXPECT_FALSE(load_timing_info
.socket_reused
);
52 // None of these tests use a NetLog.
53 EXPECT_EQ(NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
55 ExpectConnectTimingHasTimes(
56 load_timing_info
.connect_timing
,
57 CONNECT_TIMING_HAS_SSL_TIMES
| CONNECT_TIMING_HAS_DNS_TIMES
);
58 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info
);
61 // Just like TestLoadTimingInfo, except DNS times are expected to be null, for
62 // tests over proxies that do DNS lookups themselves.
63 void TestLoadTimingInfoNoDns(const ClientSocketHandle
& handle
) {
64 LoadTimingInfo load_timing_info
;
65 EXPECT_TRUE(handle
.GetLoadTimingInfo(false, &load_timing_info
));
67 // None of these tests use a NetLog.
68 EXPECT_EQ(NetLog::Source::kInvalidId
, load_timing_info
.socket_log_id
);
70 EXPECT_FALSE(load_timing_info
.socket_reused
);
72 ExpectConnectTimingHasTimes(load_timing_info
.connect_timing
,
73 CONNECT_TIMING_HAS_SSL_TIMES
);
74 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info
);
77 class SSLClientSocketPoolTest
: public testing::Test
{
79 SSLClientSocketPoolTest()
80 : proxy_service_(ProxyService::CreateDirect()),
81 ssl_config_service_(new SSLConfigServiceDefaults
),
82 http_auth_handler_factory_(
83 HttpAuthHandlerFactory::CreateDefault(&host_resolver_
)),
84 session_(CreateNetworkSession()),
85 direct_transport_socket_params_(
86 new TransportSocketParams(HostPortPair("host", 443),
90 OnHostResolutionCallback())),
91 transport_histograms_("MockTCP"),
92 transport_socket_pool_(kMaxSockets
,
94 &transport_histograms_
,
96 proxy_transport_socket_params_(
97 new TransportSocketParams(HostPortPair("proxy", 443),
101 OnHostResolutionCallback())),
102 socks_socket_params_(
103 new SOCKSSocketParams(proxy_transport_socket_params_
,
105 HostPortPair("sockshost", 443),
107 socks_histograms_("MockSOCKS"),
108 socks_socket_pool_(kMaxSockets
,
111 &transport_socket_pool_
),
112 http_proxy_socket_params_(
113 new HttpProxySocketParams(proxy_transport_socket_params_
,
117 HostPortPair("host", 80),
118 session_
->http_auth_cache(),
119 session_
->http_auth_handler_factory(),
120 session_
->spdy_session_pool(),
122 http_proxy_histograms_("MockHttpProxy"),
123 http_proxy_socket_pool_(kMaxSockets
,
125 &http_proxy_histograms_
,
127 &transport_socket_pool_
,
130 scoped_refptr
<SSLConfigService
> ssl_config_service(
131 new SSLConfigServiceDefaults
);
132 ssl_config_service
->GetSSLConfig(&ssl_config_
);
135 void CreatePool(bool transport_pool
, bool http_proxy_pool
, bool socks_pool
) {
136 ssl_histograms_
.reset(new ClientSocketPoolHistograms("SSLUnitTest"));
137 pool_
.reset(new SSLClientSocketPool(
140 ssl_histograms_
.get(),
141 NULL
/* host_resolver */,
142 NULL
/* cert_verifier */,
143 NULL
/* server_bound_cert_service */,
144 NULL
/* transport_security_state */,
145 std::string() /* ssl_session_cache_shard */,
147 transport_pool
? &transport_socket_pool_
: NULL
,
148 socks_pool
? &socks_socket_pool_
: NULL
,
149 http_proxy_pool
? &http_proxy_socket_pool_
: NULL
,
154 scoped_refptr
<SSLSocketParams
> SSLParams(ProxyServer::Scheme proxy
,
155 bool want_spdy_over_npn
) {
156 return make_scoped_refptr(new SSLSocketParams(
157 proxy
== ProxyServer::SCHEME_DIRECT
?
158 direct_transport_socket_params_
: NULL
,
159 proxy
== ProxyServer::SCHEME_SOCKS5
? socks_socket_params_
: NULL
,
160 proxy
== ProxyServer::SCHEME_HTTP
? http_proxy_socket_params_
: NULL
,
162 HostPortPair("host", 443),
166 want_spdy_over_npn
));
169 void AddAuthToCache() {
170 const base::string16
kFoo(ASCIIToUTF16("foo"));
171 const base::string16
kBar(ASCIIToUTF16("bar"));
172 session_
->http_auth_cache()->Add(GURL("http://proxy:443/"),
174 HttpAuth::AUTH_SCHEME_BASIC
,
175 "Basic realm=MyRealm1",
176 AuthCredentials(kFoo
, kBar
),
180 HttpNetworkSession
* CreateNetworkSession() {
181 HttpNetworkSession::Params params
;
182 params
.host_resolver
= &host_resolver_
;
183 params
.cert_verifier
= cert_verifier_
.get();
184 params
.proxy_service
= proxy_service_
.get();
185 params
.client_socket_factory
= &socket_factory_
;
186 params
.ssl_config_service
= ssl_config_service_
;
187 params
.http_auth_handler_factory
= http_auth_handler_factory_
.get();
188 params
.http_server_properties
= &http_server_properties_
;
189 params
.enable_spdy_compression
= false;
190 return new HttpNetworkSession(params
);
193 void TestIPPoolingDisabled(SSLSocketDataProvider
* ssl
);
195 MockClientSocketFactory socket_factory_
;
196 MockCachingHostResolver host_resolver_
;
197 scoped_ptr
<CertVerifier
> cert_verifier_
;
198 const scoped_ptr
<ProxyService
> proxy_service_
;
199 const scoped_refptr
<SSLConfigService
> ssl_config_service_
;
200 const scoped_ptr
<HttpAuthHandlerFactory
> http_auth_handler_factory_
;
201 HttpServerPropertiesImpl http_server_properties_
;
202 const scoped_refptr
<HttpNetworkSession
> session_
;
204 scoped_refptr
<TransportSocketParams
> direct_transport_socket_params_
;
205 ClientSocketPoolHistograms transport_histograms_
;
206 MockTransportClientSocketPool transport_socket_pool_
;
208 scoped_refptr
<TransportSocketParams
> proxy_transport_socket_params_
;
210 scoped_refptr
<SOCKSSocketParams
> socks_socket_params_
;
211 ClientSocketPoolHistograms socks_histograms_
;
212 MockSOCKSClientSocketPool socks_socket_pool_
;
214 scoped_refptr
<HttpProxySocketParams
> http_proxy_socket_params_
;
215 ClientSocketPoolHistograms http_proxy_histograms_
;
216 HttpProxyClientSocketPool http_proxy_socket_pool_
;
218 SSLConfig ssl_config_
;
219 scoped_ptr
<ClientSocketPoolHistograms
> ssl_histograms_
;
220 scoped_ptr
<SSLClientSocketPool
> pool_
;
223 TEST_F(SSLClientSocketPoolTest
, TCPFail
) {
224 StaticSocketDataProvider data
;
225 data
.set_connect_data(MockConnect(SYNCHRONOUS
, ERR_CONNECTION_FAILED
));
226 socket_factory_
.AddSocketDataProvider(&data
);
228 CreatePool(true /* tcp pool */, false, false);
229 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_DIRECT
,
232 ClientSocketHandle handle
;
233 int rv
= handle
.Init("a", params
, MEDIUM
, CompletionCallback(), pool_
.get(),
235 EXPECT_EQ(ERR_CONNECTION_FAILED
, rv
);
236 EXPECT_FALSE(handle
.is_initialized());
237 EXPECT_FALSE(handle
.socket());
238 EXPECT_FALSE(handle
.is_ssl_error());
241 TEST_F(SSLClientSocketPoolTest
, TCPFailAsync
) {
242 StaticSocketDataProvider data
;
243 data
.set_connect_data(MockConnect(ASYNC
, ERR_CONNECTION_FAILED
));
244 socket_factory_
.AddSocketDataProvider(&data
);
246 CreatePool(true /* tcp pool */, false, false);
247 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_DIRECT
,
250 ClientSocketHandle handle
;
251 TestCompletionCallback callback
;
252 int rv
= handle
.Init(
253 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
254 EXPECT_EQ(ERR_IO_PENDING
, rv
);
255 EXPECT_FALSE(handle
.is_initialized());
256 EXPECT_FALSE(handle
.socket());
258 EXPECT_EQ(ERR_CONNECTION_FAILED
, callback
.WaitForResult());
259 EXPECT_FALSE(handle
.is_initialized());
260 EXPECT_FALSE(handle
.socket());
261 EXPECT_FALSE(handle
.is_ssl_error());
264 TEST_F(SSLClientSocketPoolTest
, BasicDirect
) {
265 StaticSocketDataProvider data
;
266 data
.set_connect_data(MockConnect(SYNCHRONOUS
, OK
));
267 socket_factory_
.AddSocketDataProvider(&data
);
268 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
269 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
271 CreatePool(true /* tcp pool */, false, false);
272 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_DIRECT
,
275 ClientSocketHandle handle
;
276 TestCompletionCallback callback
;
277 int rv
= handle
.Init(
278 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
280 EXPECT_TRUE(handle
.is_initialized());
281 EXPECT_TRUE(handle
.socket());
282 TestLoadTimingInfo(handle
);
285 TEST_F(SSLClientSocketPoolTest
, BasicDirectAsync
) {
286 StaticSocketDataProvider data
;
287 socket_factory_
.AddSocketDataProvider(&data
);
288 SSLSocketDataProvider
ssl(ASYNC
, OK
);
289 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
291 CreatePool(true /* tcp pool */, false, false);
292 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_DIRECT
,
295 ClientSocketHandle handle
;
296 TestCompletionCallback callback
;
297 int rv
= handle
.Init(
298 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
299 EXPECT_EQ(ERR_IO_PENDING
, rv
);
300 EXPECT_FALSE(handle
.is_initialized());
301 EXPECT_FALSE(handle
.socket());
303 EXPECT_EQ(OK
, callback
.WaitForResult());
304 EXPECT_TRUE(handle
.is_initialized());
305 EXPECT_TRUE(handle
.socket());
306 TestLoadTimingInfo(handle
);
309 TEST_F(SSLClientSocketPoolTest
, DirectCertError
) {
310 StaticSocketDataProvider data
;
311 socket_factory_
.AddSocketDataProvider(&data
);
312 SSLSocketDataProvider
ssl(ASYNC
, ERR_CERT_COMMON_NAME_INVALID
);
313 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
315 CreatePool(true /* tcp pool */, false, false);
316 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_DIRECT
,
319 ClientSocketHandle handle
;
320 TestCompletionCallback callback
;
321 int rv
= handle
.Init(
322 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
323 EXPECT_EQ(ERR_IO_PENDING
, rv
);
324 EXPECT_FALSE(handle
.is_initialized());
325 EXPECT_FALSE(handle
.socket());
327 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID
, callback
.WaitForResult());
328 EXPECT_TRUE(handle
.is_initialized());
329 EXPECT_TRUE(handle
.socket());
330 TestLoadTimingInfo(handle
);
333 TEST_F(SSLClientSocketPoolTest
, DirectSSLError
) {
334 StaticSocketDataProvider data
;
335 socket_factory_
.AddSocketDataProvider(&data
);
336 SSLSocketDataProvider
ssl(ASYNC
, ERR_SSL_PROTOCOL_ERROR
);
337 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
339 CreatePool(true /* tcp pool */, false, false);
340 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_DIRECT
,
343 ClientSocketHandle handle
;
344 TestCompletionCallback callback
;
345 int rv
= handle
.Init(
346 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
347 EXPECT_EQ(ERR_IO_PENDING
, rv
);
348 EXPECT_FALSE(handle
.is_initialized());
349 EXPECT_FALSE(handle
.socket());
351 EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR
, callback
.WaitForResult());
352 EXPECT_FALSE(handle
.is_initialized());
353 EXPECT_FALSE(handle
.socket());
354 EXPECT_TRUE(handle
.is_ssl_error());
357 TEST_F(SSLClientSocketPoolTest
, DirectWithNPN
) {
358 StaticSocketDataProvider data
;
359 socket_factory_
.AddSocketDataProvider(&data
);
360 SSLSocketDataProvider
ssl(ASYNC
, OK
);
361 ssl
.SetNextProto(kProtoHTTP11
);
362 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
364 CreatePool(true /* tcp pool */, false, false);
365 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_DIRECT
,
368 ClientSocketHandle handle
;
369 TestCompletionCallback callback
;
370 int rv
= handle
.Init(
371 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
372 EXPECT_EQ(ERR_IO_PENDING
, rv
);
373 EXPECT_FALSE(handle
.is_initialized());
374 EXPECT_FALSE(handle
.socket());
376 EXPECT_EQ(OK
, callback
.WaitForResult());
377 EXPECT_TRUE(handle
.is_initialized());
378 EXPECT_TRUE(handle
.socket());
379 TestLoadTimingInfo(handle
);
380 SSLClientSocket
* ssl_socket
= static_cast<SSLClientSocket
*>(handle
.socket());
381 EXPECT_TRUE(ssl_socket
->WasNpnNegotiated());
384 TEST_F(SSLClientSocketPoolTest
, DirectNoSPDY
) {
385 StaticSocketDataProvider data
;
386 socket_factory_
.AddSocketDataProvider(&data
);
387 SSLSocketDataProvider
ssl(ASYNC
, OK
);
388 ssl
.SetNextProto(kProtoHTTP11
);
389 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
391 CreatePool(true /* tcp pool */, false, false);
392 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_DIRECT
,
395 ClientSocketHandle handle
;
396 TestCompletionCallback callback
;
397 int rv
= handle
.Init(
398 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
399 EXPECT_EQ(ERR_IO_PENDING
, rv
);
400 EXPECT_FALSE(handle
.is_initialized());
401 EXPECT_FALSE(handle
.socket());
403 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED
, callback
.WaitForResult());
404 EXPECT_FALSE(handle
.is_initialized());
405 EXPECT_FALSE(handle
.socket());
406 EXPECT_TRUE(handle
.is_ssl_error());
409 TEST_F(SSLClientSocketPoolTest
, DirectGotSPDY
) {
410 StaticSocketDataProvider data
;
411 socket_factory_
.AddSocketDataProvider(&data
);
412 SSLSocketDataProvider
ssl(ASYNC
, OK
);
413 ssl
.SetNextProto(kProtoSPDY2
);
414 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
416 CreatePool(true /* tcp pool */, false, false);
417 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_DIRECT
,
420 ClientSocketHandle handle
;
421 TestCompletionCallback callback
;
422 int rv
= handle
.Init(
423 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
424 EXPECT_EQ(ERR_IO_PENDING
, rv
);
425 EXPECT_FALSE(handle
.is_initialized());
426 EXPECT_FALSE(handle
.socket());
428 EXPECT_EQ(OK
, callback
.WaitForResult());
429 EXPECT_TRUE(handle
.is_initialized());
430 EXPECT_TRUE(handle
.socket());
431 TestLoadTimingInfo(handle
);
433 SSLClientSocket
* ssl_socket
= static_cast<SSLClientSocket
*>(handle
.socket());
434 EXPECT_TRUE(ssl_socket
->WasNpnNegotiated());
436 std::string server_protos
;
437 ssl_socket
->GetNextProto(&proto
, &server_protos
);
438 EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto
),
442 TEST_F(SSLClientSocketPoolTest
, DirectGotBonusSPDY
) {
443 StaticSocketDataProvider data
;
444 socket_factory_
.AddSocketDataProvider(&data
);
445 SSLSocketDataProvider
ssl(ASYNC
, OK
);
446 ssl
.SetNextProto(kProtoSPDY2
);
447 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
449 CreatePool(true /* tcp pool */, false, false);
450 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_DIRECT
,
453 ClientSocketHandle handle
;
454 TestCompletionCallback callback
;
455 int rv
= handle
.Init(
456 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
457 EXPECT_EQ(ERR_IO_PENDING
, rv
);
458 EXPECT_FALSE(handle
.is_initialized());
459 EXPECT_FALSE(handle
.socket());
461 EXPECT_EQ(OK
, callback
.WaitForResult());
462 EXPECT_TRUE(handle
.is_initialized());
463 EXPECT_TRUE(handle
.socket());
464 TestLoadTimingInfo(handle
);
466 SSLClientSocket
* ssl_socket
= static_cast<SSLClientSocket
*>(handle
.socket());
467 EXPECT_TRUE(ssl_socket
->WasNpnNegotiated());
469 std::string server_protos
;
470 ssl_socket
->GetNextProto(&proto
, &server_protos
);
471 EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto
),
475 TEST_F(SSLClientSocketPoolTest
, SOCKSFail
) {
476 StaticSocketDataProvider data
;
477 data
.set_connect_data(MockConnect(SYNCHRONOUS
, ERR_CONNECTION_FAILED
));
478 socket_factory_
.AddSocketDataProvider(&data
);
480 CreatePool(false, true /* http proxy pool */, true /* socks pool */);
481 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_SOCKS5
,
484 ClientSocketHandle handle
;
485 TestCompletionCallback callback
;
486 int rv
= handle
.Init(
487 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
488 EXPECT_EQ(ERR_CONNECTION_FAILED
, rv
);
489 EXPECT_FALSE(handle
.is_initialized());
490 EXPECT_FALSE(handle
.socket());
491 EXPECT_FALSE(handle
.is_ssl_error());
494 TEST_F(SSLClientSocketPoolTest
, SOCKSFailAsync
) {
495 StaticSocketDataProvider data
;
496 data
.set_connect_data(MockConnect(ASYNC
, ERR_CONNECTION_FAILED
));
497 socket_factory_
.AddSocketDataProvider(&data
);
499 CreatePool(false, true /* http proxy pool */, true /* socks pool */);
500 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_SOCKS5
,
503 ClientSocketHandle handle
;
504 TestCompletionCallback callback
;
505 int rv
= handle
.Init(
506 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
507 EXPECT_EQ(ERR_IO_PENDING
, rv
);
508 EXPECT_FALSE(handle
.is_initialized());
509 EXPECT_FALSE(handle
.socket());
511 EXPECT_EQ(ERR_CONNECTION_FAILED
, callback
.WaitForResult());
512 EXPECT_FALSE(handle
.is_initialized());
513 EXPECT_FALSE(handle
.socket());
514 EXPECT_FALSE(handle
.is_ssl_error());
517 TEST_F(SSLClientSocketPoolTest
, SOCKSBasic
) {
518 StaticSocketDataProvider data
;
519 data
.set_connect_data(MockConnect(SYNCHRONOUS
, OK
));
520 socket_factory_
.AddSocketDataProvider(&data
);
521 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
522 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
524 CreatePool(false, true /* http proxy pool */, true /* socks pool */);
525 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_SOCKS5
,
528 ClientSocketHandle handle
;
529 TestCompletionCallback callback
;
530 int rv
= handle
.Init(
531 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
533 EXPECT_TRUE(handle
.is_initialized());
534 EXPECT_TRUE(handle
.socket());
535 // SOCKS5 generally has no DNS times, but the mock SOCKS5 sockets used here
536 // don't go through the real logic, unlike in the HTTP proxy tests.
537 TestLoadTimingInfo(handle
);
540 TEST_F(SSLClientSocketPoolTest
, SOCKSBasicAsync
) {
541 StaticSocketDataProvider data
;
542 socket_factory_
.AddSocketDataProvider(&data
);
543 SSLSocketDataProvider
ssl(ASYNC
, OK
);
544 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
546 CreatePool(false, true /* http proxy pool */, true /* socks pool */);
547 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_SOCKS5
,
550 ClientSocketHandle handle
;
551 TestCompletionCallback callback
;
552 int rv
= handle
.Init(
553 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
554 EXPECT_EQ(ERR_IO_PENDING
, rv
);
555 EXPECT_FALSE(handle
.is_initialized());
556 EXPECT_FALSE(handle
.socket());
558 EXPECT_EQ(OK
, callback
.WaitForResult());
559 EXPECT_TRUE(handle
.is_initialized());
560 EXPECT_TRUE(handle
.socket());
561 // SOCKS5 generally has no DNS times, but the mock SOCKS5 sockets used here
562 // don't go through the real logic, unlike in the HTTP proxy tests.
563 TestLoadTimingInfo(handle
);
566 TEST_F(SSLClientSocketPoolTest
, HttpProxyFail
) {
567 StaticSocketDataProvider data
;
568 data
.set_connect_data(MockConnect(SYNCHRONOUS
, ERR_CONNECTION_FAILED
));
569 socket_factory_
.AddSocketDataProvider(&data
);
571 CreatePool(false, true /* http proxy pool */, true /* socks pool */);
572 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_HTTP
,
575 ClientSocketHandle handle
;
576 TestCompletionCallback callback
;
577 int rv
= handle
.Init(
578 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
579 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED
, rv
);
580 EXPECT_FALSE(handle
.is_initialized());
581 EXPECT_FALSE(handle
.socket());
582 EXPECT_FALSE(handle
.is_ssl_error());
585 TEST_F(SSLClientSocketPoolTest
, HttpProxyFailAsync
) {
586 StaticSocketDataProvider data
;
587 data
.set_connect_data(MockConnect(ASYNC
, ERR_CONNECTION_FAILED
));
588 socket_factory_
.AddSocketDataProvider(&data
);
590 CreatePool(false, true /* http proxy pool */, true /* socks pool */);
591 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_HTTP
,
594 ClientSocketHandle handle
;
595 TestCompletionCallback callback
;
596 int rv
= handle
.Init(
597 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
598 EXPECT_EQ(ERR_IO_PENDING
, rv
);
599 EXPECT_FALSE(handle
.is_initialized());
600 EXPECT_FALSE(handle
.socket());
602 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED
, callback
.WaitForResult());
603 EXPECT_FALSE(handle
.is_initialized());
604 EXPECT_FALSE(handle
.socket());
605 EXPECT_FALSE(handle
.is_ssl_error());
608 TEST_F(SSLClientSocketPoolTest
, HttpProxyBasic
) {
609 MockWrite writes
[] = {
610 MockWrite(SYNCHRONOUS
,
611 "CONNECT host:80 HTTP/1.1\r\n"
613 "Proxy-Connection: keep-alive\r\n"
614 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
617 MockRead(SYNCHRONOUS
, "HTTP/1.1 200 Connection Established\r\n\r\n"),
619 StaticSocketDataProvider
data(reads
, arraysize(reads
), writes
,
621 data
.set_connect_data(MockConnect(SYNCHRONOUS
, OK
));
622 socket_factory_
.AddSocketDataProvider(&data
);
624 SSLSocketDataProvider
ssl(SYNCHRONOUS
, OK
);
625 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
627 CreatePool(false, true /* http proxy pool */, true /* socks pool */);
628 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_HTTP
,
631 ClientSocketHandle handle
;
632 TestCompletionCallback callback
;
633 int rv
= handle
.Init(
634 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
636 EXPECT_TRUE(handle
.is_initialized());
637 EXPECT_TRUE(handle
.socket());
638 TestLoadTimingInfoNoDns(handle
);
641 TEST_F(SSLClientSocketPoolTest
, HttpProxyBasicAsync
) {
642 MockWrite writes
[] = {
643 MockWrite("CONNECT host:80 HTTP/1.1\r\n"
645 "Proxy-Connection: keep-alive\r\n"
646 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
649 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
651 StaticSocketDataProvider
data(reads
, arraysize(reads
), writes
,
653 socket_factory_
.AddSocketDataProvider(&data
);
655 SSLSocketDataProvider
ssl(ASYNC
, OK
);
656 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
658 CreatePool(false, true /* http proxy pool */, true /* socks pool */);
659 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_HTTP
,
662 ClientSocketHandle handle
;
663 TestCompletionCallback callback
;
664 int rv
= handle
.Init(
665 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
666 EXPECT_EQ(ERR_IO_PENDING
, rv
);
667 EXPECT_FALSE(handle
.is_initialized());
668 EXPECT_FALSE(handle
.socket());
670 EXPECT_EQ(OK
, callback
.WaitForResult());
671 EXPECT_TRUE(handle
.is_initialized());
672 EXPECT_TRUE(handle
.socket());
673 TestLoadTimingInfoNoDns(handle
);
676 TEST_F(SSLClientSocketPoolTest
, NeedProxyAuth
) {
677 MockWrite writes
[] = {
678 MockWrite("CONNECT host:80 HTTP/1.1\r\n"
680 "Proxy-Connection: keep-alive\r\n\r\n"),
683 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
684 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
685 MockRead("Content-Length: 10\r\n\r\n"),
686 MockRead("0123456789"),
688 StaticSocketDataProvider
data(reads
, arraysize(reads
), writes
,
690 socket_factory_
.AddSocketDataProvider(&data
);
691 SSLSocketDataProvider
ssl(ASYNC
, OK
);
692 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
694 CreatePool(false, true /* http proxy pool */, true /* socks pool */);
695 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_HTTP
,
698 ClientSocketHandle handle
;
699 TestCompletionCallback callback
;
700 int rv
= handle
.Init(
701 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
702 EXPECT_EQ(ERR_IO_PENDING
, rv
);
703 EXPECT_FALSE(handle
.is_initialized());
704 EXPECT_FALSE(handle
.socket());
706 EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED
, callback
.WaitForResult());
707 EXPECT_FALSE(handle
.is_initialized());
708 EXPECT_FALSE(handle
.socket());
709 EXPECT_FALSE(handle
.is_ssl_error());
710 const HttpResponseInfo
& tunnel_info
= handle
.ssl_error_response_info();
711 EXPECT_EQ(tunnel_info
.headers
->response_code(), 407);
712 scoped_ptr
<ClientSocketHandle
> tunnel_handle(
713 handle
.release_pending_http_proxy_connection());
714 EXPECT_TRUE(tunnel_handle
->socket());
715 EXPECT_FALSE(tunnel_handle
->socket()->IsConnected());
718 TEST_F(SSLClientSocketPoolTest
, IPPooling
) {
719 const int kTestPort
= 80;
723 HostPortProxyPair pair
;
724 AddressList addresses
;
726 { "www.webkit.org", "192.0.2.33,192.168.0.1,192.168.0.5" },
727 { "code.google.com", "192.168.0.2,192.168.0.3,192.168.0.5" },
728 { "js.webkit.org", "192.168.0.4,192.168.0.1,192.0.2.33" },
731 host_resolver_
.set_synchronous_mode(true);
732 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(test_hosts
); i
++) {
733 host_resolver_
.rules()->AddIPLiteralRule(
734 test_hosts
[i
].name
, test_hosts
[i
].iplist
, std::string());
736 // This test requires that the HostResolver cache be populated. Normal
737 // code would have done this already, but we do it manually.
738 HostResolver::RequestInfo
info(HostPortPair(test_hosts
[i
].name
, kTestPort
));
739 host_resolver_
.Resolve(info
, &test_hosts
[i
].addresses
, CompletionCallback(),
740 NULL
, BoundNetLog());
742 // Setup a HostPortProxyPair
743 test_hosts
[i
].pair
= HostPortProxyPair(
744 HostPortPair(test_hosts
[i
].name
, kTestPort
), ProxyServer::Direct());
748 MockRead(ASYNC
, ERR_IO_PENDING
),
750 StaticSocketDataProvider
data(reads
, arraysize(reads
), NULL
, 0);
751 socket_factory_
.AddSocketDataProvider(&data
);
752 SSLSocketDataProvider
ssl(ASYNC
, OK
);
753 ssl
.cert
= X509Certificate::CreateFromBytes(
754 reinterpret_cast<const char*>(webkit_der
), sizeof(webkit_der
));
755 ssl
.SetNextProto(kProtoSPDY2
);
756 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
758 CreatePool(true /* tcp pool */, false, false);
759 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_DIRECT
,
762 scoped_ptr
<ClientSocketHandle
> handle(new ClientSocketHandle());
763 TestCompletionCallback callback
;
764 int rv
= handle
->Init(
765 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
766 EXPECT_EQ(ERR_IO_PENDING
, rv
);
767 EXPECT_FALSE(handle
->is_initialized());
768 EXPECT_FALSE(handle
->socket());
770 EXPECT_EQ(OK
, callback
.WaitForResult());
771 EXPECT_TRUE(handle
->is_initialized());
772 EXPECT_TRUE(handle
->socket());
774 SSLClientSocket
* ssl_socket
= static_cast<SSLClientSocket
*>(handle
->socket());
775 EXPECT_TRUE(ssl_socket
->WasNpnNegotiated());
777 std::string server_protos
;
778 ssl_socket
->GetNextProto(&proto
, &server_protos
);
779 EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto
),
782 // TODO(rtenneti): MockClientSocket::GetPeerAddress returns 0 as the port
783 // number. Fix it to return port 80 and then use GetPeerAddress to AddAlias.
784 SpdySessionPoolPeer
pool_peer(session_
->spdy_session_pool());
785 pool_peer
.AddAlias(test_hosts
[0].addresses
.front(), test_hosts
[0].pair
);
787 scoped_refptr
<SpdySession
> spdy_session
;
788 rv
= session_
->spdy_session_pool()->GetSpdySessionFromSocket(
789 test_hosts
[0].pair
, handle
.release(), BoundNetLog(), 0,
790 &spdy_session
, true);
793 EXPECT_TRUE(session_
->spdy_session_pool()->HasSession(test_hosts
[0].pair
));
794 EXPECT_FALSE(session_
->spdy_session_pool()->HasSession(test_hosts
[1].pair
));
795 EXPECT_TRUE(session_
->spdy_session_pool()->HasSession(test_hosts
[2].pair
));
797 session_
->spdy_session_pool()->CloseAllSessions();
800 void SSLClientSocketPoolTest::TestIPPoolingDisabled(
801 SSLSocketDataProvider
* ssl
) {
802 const int kTestPort
= 80;
806 HostPortProxyPair pair
;
807 AddressList addresses
;
809 { "www.webkit.org", "192.0.2.33,192.168.0.1,192.168.0.5" },
810 { "js.webkit.com", "192.168.0.4,192.168.0.1,192.0.2.33" },
813 TestCompletionCallback callback
;
815 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(test_hosts
); i
++) {
816 host_resolver_
.rules()->AddIPLiteralRule(
817 test_hosts
[i
].name
, test_hosts
[i
].iplist
, std::string());
819 // This test requires that the HostResolver cache be populated. Normal
820 // code would have done this already, but we do it manually.
821 HostResolver::RequestInfo
info(HostPortPair(test_hosts
[i
].name
, kTestPort
));
822 rv
= host_resolver_
.Resolve(info
, &test_hosts
[i
].addresses
,
823 callback
.callback(), NULL
, BoundNetLog());
824 EXPECT_EQ(OK
, callback
.GetResult(rv
));
826 // Setup a HostPortProxyPair
827 test_hosts
[i
].pair
= HostPortProxyPair(
828 HostPortPair(test_hosts
[i
].name
, kTestPort
), ProxyServer::Direct());
832 MockRead(ASYNC
, ERR_IO_PENDING
),
834 StaticSocketDataProvider
data(reads
, arraysize(reads
), NULL
, 0);
835 socket_factory_
.AddSocketDataProvider(&data
);
836 socket_factory_
.AddSSLSocketDataProvider(ssl
);
838 CreatePool(true /* tcp pool */, false, false);
839 scoped_refptr
<SSLSocketParams
> params
= SSLParams(ProxyServer::SCHEME_DIRECT
,
842 scoped_ptr
<ClientSocketHandle
> handle(new ClientSocketHandle());
844 "a", params
, MEDIUM
, callback
.callback(), pool_
.get(), BoundNetLog());
845 EXPECT_EQ(ERR_IO_PENDING
, rv
);
846 EXPECT_FALSE(handle
->is_initialized());
847 EXPECT_FALSE(handle
->socket());
849 EXPECT_EQ(OK
, callback
.WaitForResult());
850 EXPECT_TRUE(handle
->is_initialized());
851 EXPECT_TRUE(handle
->socket());
853 SSLClientSocket
* ssl_socket
= static_cast<SSLClientSocket
*>(handle
->socket());
854 EXPECT_TRUE(ssl_socket
->WasNpnNegotiated());
856 std::string server_protos
;
857 ssl_socket
->GetNextProto(&proto
, &server_protos
);
858 EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto
),
861 // TODO(rtenneti): MockClientSocket::GetPeerAddress returns 0 as the port
862 // number. Fix it to return port 80 and then use GetPeerAddress to AddAlias.
863 SpdySessionPoolPeer
pool_peer(session_
->spdy_session_pool());
864 pool_peer
.AddAlias(test_hosts
[0].addresses
.front(), test_hosts
[0].pair
);
866 scoped_refptr
<SpdySession
> spdy_session
;
867 rv
= session_
->spdy_session_pool()->GetSpdySessionFromSocket(
868 test_hosts
[0].pair
, handle
.release(), BoundNetLog(), 0,
869 &spdy_session
, true);
872 EXPECT_TRUE(session_
->spdy_session_pool()->HasSession(test_hosts
[0].pair
));
873 EXPECT_FALSE(session_
->spdy_session_pool()->HasSession(test_hosts
[1].pair
));
875 session_
->spdy_session_pool()->CloseAllSessions();
878 // Verifies that an SSL connection with client authentication disables SPDY IP
880 TEST_F(SSLClientSocketPoolTest
, IPPoolingClientCert
) {
881 SSLSocketDataProvider
ssl(ASYNC
, OK
);
882 ssl
.cert
= X509Certificate::CreateFromBytes(
883 reinterpret_cast<const char*>(webkit_der
), sizeof(webkit_der
));
884 ssl
.client_cert_sent
= true;
885 ssl
.SetNextProto(kProtoSPDY2
);
886 TestIPPoolingDisabled(&ssl
);
889 // Verifies that an SSL connection with channel ID disables SPDY IP pooling.
890 TEST_F(SSLClientSocketPoolTest
, IPPoolingChannelID
) {
891 SSLSocketDataProvider
ssl(ASYNC
, OK
);
892 ssl
.channel_id_sent
= true;
893 ssl
.SetNextProto(kProtoSPDY2
);
894 TestIPPoolingDisabled(&ssl
);
897 // It would be nice to also test the timeouts in SSLClientSocketPool.