ssl_client_socket_pool_unittest.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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/http/http_proxy_client_socket_pool.h" 6 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" 34 35using namespace net::test_spdy2; 36 37namespace net { 38 39namespace { 40 41const int kMaxSockets = 32; 42const int kMaxSocketsPerGroup = 6; 43 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. 47void TestLoadTimingInfo(const ClientSocketHandle& handle) { 48 LoadTimingInfo load_timing_info; 49 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info)); 50 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); 54 55 ExpectConnectTimingHasTimes( 56 load_timing_info.connect_timing, 57 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES); 58 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info); 59} 60 61// Just like TestLoadTimingInfo, except DNS times are expected to be null, for 62// tests over proxies that do DNS lookups themselves. 63void TestLoadTimingInfoNoDns(const ClientSocketHandle& handle) { 64 LoadTimingInfo load_timing_info; 65 EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info)); 66 67 // None of these tests use a NetLog. 68 EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 69 70 EXPECT_FALSE(load_timing_info.socket_reused); 71 72 ExpectConnectTimingHasTimes(load_timing_info.connect_timing, 73 CONNECT_TIMING_HAS_SSL_TIMES); 74 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info); 75} 76 77class SSLClientSocketPoolTest : public testing::Test { 78 protected: 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), 87 MEDIUM, 88 false, 89 false, 90 OnHostResolutionCallback())), 91 transport_histograms_("MockTCP"), 92 transport_socket_pool_(kMaxSockets, 93 kMaxSocketsPerGroup, 94 &transport_histograms_, 95 &socket_factory_), 96 proxy_transport_socket_params_( 97 new TransportSocketParams(HostPortPair("proxy", 443), 98 MEDIUM, 99 false, 100 false, 101 OnHostResolutionCallback())), 102 socks_socket_params_( 103 new SOCKSSocketParams(proxy_transport_socket_params_, 104 true, 105 HostPortPair("sockshost", 443), 106 MEDIUM)), 107 socks_histograms_("MockSOCKS"), 108 socks_socket_pool_(kMaxSockets, 109 kMaxSocketsPerGroup, 110 &socks_histograms_, 111 &transport_socket_pool_), 112 http_proxy_socket_params_( 113 new HttpProxySocketParams(proxy_transport_socket_params_, 114 NULL, 115 GURL("http://host"), 116 std::string(), 117 HostPortPair("host", 80), 118 session_->http_auth_cache(), 119 session_->http_auth_handler_factory(), 120 session_->spdy_session_pool(), 121 true)), 122 http_proxy_histograms_("MockHttpProxy"), 123 http_proxy_socket_pool_(kMaxSockets, 124 kMaxSocketsPerGroup, 125 &http_proxy_histograms_, 126 &host_resolver_, 127 &transport_socket_pool_, 128 NULL, 129 NULL) { 130 scoped_refptr<SSLConfigService> ssl_config_service( 131 new SSLConfigServiceDefaults); 132 ssl_config_service->GetSSLConfig(&ssl_config_); 133 } 134 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( 138 kMaxSockets, 139 kMaxSocketsPerGroup, 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 */, 146 &socket_factory_, 147 transport_pool ? &transport_socket_pool_ : NULL, 148 socks_pool ? &socks_socket_pool_ : NULL, 149 http_proxy_pool ? &http_proxy_socket_pool_ : NULL, 150 NULL, 151 NULL)); 152 } 153 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, 161 proxy, 162 HostPortPair("host", 443), 163 ssl_config_, 164 0, 165 false, 166 want_spdy_over_npn)); 167 } 168 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/"), 173 "MyRealm1", 174 HttpAuth::AUTH_SCHEME_BASIC, 175 "Basic realm=MyRealm1", 176 AuthCredentials(kFoo, kBar), 177 "/"); 178 } 179 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); 191 } 192 193 void TestIPPoolingDisabled(SSLSocketDataProvider* ssl); 194 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_; 203 204 scoped_refptr<TransportSocketParams> direct_transport_socket_params_; 205 ClientSocketPoolHistograms transport_histograms_; 206 MockTransportClientSocketPool transport_socket_pool_; 207 208 scoped_refptr<TransportSocketParams> proxy_transport_socket_params_; 209 210 scoped_refptr<SOCKSSocketParams> socks_socket_params_; 211 ClientSocketPoolHistograms socks_histograms_; 212 MockSOCKSClientSocketPool socks_socket_pool_; 213 214 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_; 215 ClientSocketPoolHistograms http_proxy_histograms_; 216 HttpProxyClientSocketPool http_proxy_socket_pool_; 217 218 SSLConfig ssl_config_; 219 scoped_ptr<ClientSocketPoolHistograms> ssl_histograms_; 220 scoped_ptr<SSLClientSocketPool> pool_; 221}; 222 223TEST_F(SSLClientSocketPoolTest, TCPFail) { 224 StaticSocketDataProvider data; 225 data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED)); 226 socket_factory_.AddSocketDataProvider(&data); 227 228 CreatePool(true /* tcp pool */, false, false); 229 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, 230 false); 231 232 ClientSocketHandle handle; 233 int rv = handle.Init("a", params, MEDIUM, CompletionCallback(), pool_.get(), 234 BoundNetLog()); 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()); 239} 240 241TEST_F(SSLClientSocketPoolTest, TCPFailAsync) { 242 StaticSocketDataProvider data; 243 data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED)); 244 socket_factory_.AddSocketDataProvider(&data); 245 246 CreatePool(true /* tcp pool */, false, false); 247 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, 248 false); 249 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()); 257 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()); 262} 263 264TEST_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); 270 271 CreatePool(true /* tcp pool */, false, false); 272 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, 273 false); 274 275 ClientSocketHandle handle; 276 TestCompletionCallback callback; 277 int rv = handle.Init( 278 "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog()); 279 EXPECT_EQ(OK, rv); 280 EXPECT_TRUE(handle.is_initialized()); 281 EXPECT_TRUE(handle.socket()); 282 TestLoadTimingInfo(handle); 283} 284 285TEST_F(SSLClientSocketPoolTest, BasicDirectAsync) { 286 StaticSocketDataProvider data; 287 socket_factory_.AddSocketDataProvider(&data); 288 SSLSocketDataProvider ssl(ASYNC, OK); 289 socket_factory_.AddSSLSocketDataProvider(&ssl); 290 291 CreatePool(true /* tcp pool */, false, false); 292 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, 293 false); 294 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()); 302 303 EXPECT_EQ(OK, callback.WaitForResult()); 304 EXPECT_TRUE(handle.is_initialized()); 305 EXPECT_TRUE(handle.socket()); 306 TestLoadTimingInfo(handle); 307} 308 309TEST_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); 314 315 CreatePool(true /* tcp pool */, false, false); 316 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, 317 false); 318 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()); 326 327 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, callback.WaitForResult()); 328 EXPECT_TRUE(handle.is_initialized()); 329 EXPECT_TRUE(handle.socket()); 330 TestLoadTimingInfo(handle); 331} 332 333TEST_F(SSLClientSocketPoolTest, DirectSSLError) { 334 StaticSocketDataProvider data; 335 socket_factory_.AddSocketDataProvider(&data); 336 SSLSocketDataProvider ssl(ASYNC, ERR_SSL_PROTOCOL_ERROR); 337 socket_factory_.AddSSLSocketDataProvider(&ssl); 338 339 CreatePool(true /* tcp pool */, false, false); 340 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, 341 false); 342 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()); 350 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()); 355} 356 357TEST_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); 363 364 CreatePool(true /* tcp pool */, false, false); 365 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, 366 false); 367 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()); 375 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()); 382} 383 384TEST_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); 390 391 CreatePool(true /* tcp pool */, false, false); 392 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, 393 true); 394 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()); 402 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()); 407} 408 409TEST_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); 415 416 CreatePool(true /* tcp pool */, false, false); 417 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, 418 true); 419 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()); 427 428 EXPECT_EQ(OK, callback.WaitForResult()); 429 EXPECT_TRUE(handle.is_initialized()); 430 EXPECT_TRUE(handle.socket()); 431 TestLoadTimingInfo(handle); 432 433 SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket()); 434 EXPECT_TRUE(ssl_socket->WasNpnNegotiated()); 435 std::string proto; 436 std::string server_protos; 437 ssl_socket->GetNextProto(&proto, &server_protos); 438 EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto), 439 kProtoSPDY2); 440} 441 442TEST_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); 448 449 CreatePool(true /* tcp pool */, false, false); 450 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, 451 true); 452 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()); 460 461 EXPECT_EQ(OK, callback.WaitForResult()); 462 EXPECT_TRUE(handle.is_initialized()); 463 EXPECT_TRUE(handle.socket()); 464 TestLoadTimingInfo(handle); 465 466 SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket()); 467 EXPECT_TRUE(ssl_socket->WasNpnNegotiated()); 468 std::string proto; 469 std::string server_protos; 470 ssl_socket->GetNextProto(&proto, &server_protos); 471 EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto), 472 kProtoSPDY2); 473} 474 475TEST_F(SSLClientSocketPoolTest, SOCKSFail) { 476 StaticSocketDataProvider data; 477 data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED)); 478 socket_factory_.AddSocketDataProvider(&data); 479 480 CreatePool(false, true /* http proxy pool */, true /* socks pool */); 481 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5, 482 false); 483 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()); 492} 493 494TEST_F(SSLClientSocketPoolTest, SOCKSFailAsync) { 495 StaticSocketDataProvider data; 496 data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED)); 497 socket_factory_.AddSocketDataProvider(&data); 498 499 CreatePool(false, true /* http proxy pool */, true /* socks pool */); 500 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5, 501 false); 502 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()); 510 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()); 515} 516 517TEST_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); 523 524 CreatePool(false, true /* http proxy pool */, true /* socks pool */); 525 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5, 526 false); 527 528 ClientSocketHandle handle; 529 TestCompletionCallback callback; 530 int rv = handle.Init( 531 "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog()); 532 EXPECT_EQ(OK, rv); 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); 538} 539 540TEST_F(SSLClientSocketPoolTest, SOCKSBasicAsync) { 541 StaticSocketDataProvider data; 542 socket_factory_.AddSocketDataProvider(&data); 543 SSLSocketDataProvider ssl(ASYNC, OK); 544 socket_factory_.AddSSLSocketDataProvider(&ssl); 545 546 CreatePool(false, true /* http proxy pool */, true /* socks pool */); 547 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5, 548 false); 549 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()); 557 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); 564} 565 566TEST_F(SSLClientSocketPoolTest, HttpProxyFail) { 567 StaticSocketDataProvider data; 568 data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED)); 569 socket_factory_.AddSocketDataProvider(&data); 570 571 CreatePool(false, true /* http proxy pool */, true /* socks pool */); 572 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP, 573 false); 574 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()); 583} 584 585TEST_F(SSLClientSocketPoolTest, HttpProxyFailAsync) { 586 StaticSocketDataProvider data; 587 data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED)); 588 socket_factory_.AddSocketDataProvider(&data); 589 590 CreatePool(false, true /* http proxy pool */, true /* socks pool */); 591 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP, 592 false); 593 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()); 601 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()); 606} 607 608TEST_F(SSLClientSocketPoolTest, HttpProxyBasic) { 609 MockWrite writes[] = { 610 MockWrite(SYNCHRONOUS, 611 "CONNECT host:80 HTTP/1.1\r\n" 612 "Host: host\r\n" 613 "Proxy-Connection: keep-alive\r\n" 614 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 615 }; 616 MockRead reads[] = { 617 MockRead(SYNCHRONOUS, "HTTP/1.1 200 Connection Established\r\n\r\n"), 618 }; 619 StaticSocketDataProvider data(reads, arraysize(reads), writes, 620 arraysize(writes)); 621 data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); 622 socket_factory_.AddSocketDataProvider(&data); 623 AddAuthToCache(); 624 SSLSocketDataProvider ssl(SYNCHRONOUS, OK); 625 socket_factory_.AddSSLSocketDataProvider(&ssl); 626 627 CreatePool(false, true /* http proxy pool */, true /* socks pool */); 628 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP, 629 false); 630 631 ClientSocketHandle handle; 632 TestCompletionCallback callback; 633 int rv = handle.Init( 634 "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog()); 635 EXPECT_EQ(OK, rv); 636 EXPECT_TRUE(handle.is_initialized()); 637 EXPECT_TRUE(handle.socket()); 638 TestLoadTimingInfoNoDns(handle); 639} 640 641TEST_F(SSLClientSocketPoolTest, HttpProxyBasicAsync) { 642 MockWrite writes[] = { 643 MockWrite("CONNECT host:80 HTTP/1.1\r\n" 644 "Host: host\r\n" 645 "Proxy-Connection: keep-alive\r\n" 646 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), 647 }; 648 MockRead reads[] = { 649 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"), 650 }; 651 StaticSocketDataProvider data(reads, arraysize(reads), writes, 652 arraysize(writes)); 653 socket_factory_.AddSocketDataProvider(&data); 654 AddAuthToCache(); 655 SSLSocketDataProvider ssl(ASYNC, OK); 656 socket_factory_.AddSSLSocketDataProvider(&ssl); 657 658 CreatePool(false, true /* http proxy pool */, true /* socks pool */); 659 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP, 660 false); 661 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()); 669 670 EXPECT_EQ(OK, callback.WaitForResult()); 671 EXPECT_TRUE(handle.is_initialized()); 672 EXPECT_TRUE(handle.socket()); 673 TestLoadTimingInfoNoDns(handle); 674} 675 676TEST_F(SSLClientSocketPoolTest, NeedProxyAuth) { 677 MockWrite writes[] = { 678 MockWrite("CONNECT host:80 HTTP/1.1\r\n" 679 "Host: host\r\n" 680 "Proxy-Connection: keep-alive\r\n\r\n"), 681 }; 682 MockRead reads[] = { 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"), 687 }; 688 StaticSocketDataProvider data(reads, arraysize(reads), writes, 689 arraysize(writes)); 690 socket_factory_.AddSocketDataProvider(&data); 691 SSLSocketDataProvider ssl(ASYNC, OK); 692 socket_factory_.AddSSLSocketDataProvider(&ssl); 693 694 CreatePool(false, true /* http proxy pool */, true /* socks pool */); 695 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP, 696 false); 697 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()); 705 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()); 716} 717 718TEST_F(SSLClientSocketPoolTest, IPPooling) { 719 const int kTestPort = 80; 720 struct TestHosts { 721 std::string name; 722 std::string iplist; 723 SpdySessionKey key; 724 AddressList addresses; 725 } test_hosts[] = { 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" }, 729 }; 730 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()); 735 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()); 741 742 // Setup a SpdySessionKey 743 test_hosts[i].key = SpdySessionKey( 744 HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct(), 745 kPrivacyModeDisabled); 746 } 747 748 MockRead reads[] = { 749 MockRead(ASYNC, ERR_IO_PENDING), 750 }; 751 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 752 socket_factory_.AddSocketDataProvider(&data); 753 SSLSocketDataProvider ssl(ASYNC, OK); 754 ssl.cert = X509Certificate::CreateFromBytes( 755 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)); 756 ssl.SetNextProto(kProtoSPDY2); 757 socket_factory_.AddSSLSocketDataProvider(&ssl); 758 759 CreatePool(true /* tcp pool */, false, false); 760 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, 761 true); 762 763 scoped_ptr<ClientSocketHandle> handle(new ClientSocketHandle()); 764 TestCompletionCallback callback; 765 int rv = handle->Init( 766 "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog()); 767 EXPECT_EQ(ERR_IO_PENDING, rv); 768 EXPECT_FALSE(handle->is_initialized()); 769 EXPECT_FALSE(handle->socket()); 770 771 EXPECT_EQ(OK, callback.WaitForResult()); 772 EXPECT_TRUE(handle->is_initialized()); 773 EXPECT_TRUE(handle->socket()); 774 775 SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle->socket()); 776 EXPECT_TRUE(ssl_socket->WasNpnNegotiated()); 777 std::string proto; 778 std::string server_protos; 779 ssl_socket->GetNextProto(&proto, &server_protos); 780 EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto), 781 kProtoSPDY2); 782 783 // TODO(rtenneti): MockClientSocket::GetPeerAddress returns 0 as the port 784 // number. Fix it to return port 80 and then use GetPeerAddress to AddAlias. 785 SpdySessionPoolPeer pool_peer(session_->spdy_session_pool()); 786 pool_peer.AddAlias(test_hosts[0].addresses.front(), test_hosts[0].key); 787 788 scoped_refptr<SpdySession> spdy_session; 789 rv = session_->spdy_session_pool()->GetSpdySessionFromSocket( 790 test_hosts[0].key, handle.release(), BoundNetLog(), 0, 791 &spdy_session, true); 792 EXPECT_EQ(0, rv); 793 794 EXPECT_TRUE(session_->spdy_session_pool()->HasSession(test_hosts[0].key)); 795 EXPECT_FALSE(session_->spdy_session_pool()->HasSession(test_hosts[1].key)); 796 EXPECT_TRUE(session_->spdy_session_pool()->HasSession(test_hosts[2].key)); 797 798 session_->spdy_session_pool()->CloseAllSessions(); 799} 800 801void SSLClientSocketPoolTest::TestIPPoolingDisabled( 802 SSLSocketDataProvider* ssl) { 803 const int kTestPort = 80; 804 struct TestHosts { 805 std::string name; 806 std::string iplist; 807 SpdySessionKey key; 808 AddressList addresses; 809 } test_hosts[] = { 810 { "www.webkit.org", "192.0.2.33,192.168.0.1,192.168.0.5" }, 811 { "js.webkit.com", "192.168.0.4,192.168.0.1,192.0.2.33" }, 812 }; 813 814 TestCompletionCallback callback; 815 int rv; 816 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) { 817 host_resolver_.rules()->AddIPLiteralRule( 818 test_hosts[i].name, test_hosts[i].iplist, std::string()); 819 820 // This test requires that the HostResolver cache be populated. Normal 821 // code would have done this already, but we do it manually. 822 HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort)); 823 rv = host_resolver_.Resolve(info, &test_hosts[i].addresses, 824 callback.callback(), NULL, BoundNetLog()); 825 EXPECT_EQ(OK, callback.GetResult(rv)); 826 827 // Setup a SpdySessionKey 828 test_hosts[i].key = SpdySessionKey( 829 HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct(), 830 kPrivacyModeDisabled); 831 } 832 833 MockRead reads[] = { 834 MockRead(ASYNC, ERR_IO_PENDING), 835 }; 836 StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0); 837 socket_factory_.AddSocketDataProvider(&data); 838 socket_factory_.AddSSLSocketDataProvider(ssl); 839 840 CreatePool(true /* tcp pool */, false, false); 841 scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, 842 true); 843 844 scoped_ptr<ClientSocketHandle> handle(new ClientSocketHandle()); 845 rv = handle->Init( 846 "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog()); 847 EXPECT_EQ(ERR_IO_PENDING, rv); 848 EXPECT_FALSE(handle->is_initialized()); 849 EXPECT_FALSE(handle->socket()); 850 851 EXPECT_EQ(OK, callback.WaitForResult()); 852 EXPECT_TRUE(handle->is_initialized()); 853 EXPECT_TRUE(handle->socket()); 854 855 SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle->socket()); 856 EXPECT_TRUE(ssl_socket->WasNpnNegotiated()); 857 std::string proto; 858 std::string server_protos; 859 ssl_socket->GetNextProto(&proto, &server_protos); 860 EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto), 861 kProtoSPDY2); 862 863 // TODO(rtenneti): MockClientSocket::GetPeerAddress returns 0 as the port 864 // number. Fix it to return port 80 and then use GetPeerAddress to AddAlias. 865 SpdySessionPoolPeer pool_peer(session_->spdy_session_pool()); 866 pool_peer.AddAlias(test_hosts[0].addresses.front(), test_hosts[0].key); 867 868 scoped_refptr<SpdySession> spdy_session; 869 rv = session_->spdy_session_pool()->GetSpdySessionFromSocket( 870 test_hosts[0].key, handle.release(), BoundNetLog(), 0, 871 &spdy_session, true); 872 EXPECT_EQ(0, rv); 873 874 EXPECT_TRUE(session_->spdy_session_pool()->HasSession(test_hosts[0].key)); 875 EXPECT_FALSE(session_->spdy_session_pool()->HasSession(test_hosts[1].key)); 876 877 session_->spdy_session_pool()->CloseAllSessions(); 878} 879 880// Verifies that an SSL connection with client authentication disables SPDY IP 881// pooling. 882TEST_F(SSLClientSocketPoolTest, IPPoolingClientCert) { 883 SSLSocketDataProvider ssl(ASYNC, OK); 884 ssl.cert = X509Certificate::CreateFromBytes( 885 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)); 886 ssl.client_cert_sent = true; 887 ssl.SetNextProto(kProtoSPDY2); 888 TestIPPoolingDisabled(&ssl); 889} 890 891// Verifies that an SSL connection with channel ID disables SPDY IP pooling. 892TEST_F(SSLClientSocketPoolTest, IPPoolingChannelID) { 893 SSLSocketDataProvider ssl(ASYNC, OK); 894 ssl.channel_id_sent = true; 895 ssl.SetNextProto(kProtoSPDY2); 896 TestIPPoolingDisabled(&ssl); 897} 898 899// It would be nice to also test the timeouts in SSLClientSocketPool. 900 901} // namespace 902 903} // namespace net 904