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_stream_factory_impl.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "base/basictypes.h" 11 #include "base/compiler_specific.h" 12 #include "net/base/net_log.h" 13 #include "net/base/test_completion_callback.h" 14 #include "net/cert/mock_cert_verifier.h" 15 #include "net/dns/mock_host_resolver.h" 16 #include "net/http/http_auth_handler_factory.h" 17 #include "net/http/http_network_session.h" 18 #include "net/http/http_network_session_peer.h" 19 #include "net/http/http_network_transaction.h" 20 #include "net/http/http_request_info.h" 21 #include "net/http/http_server_properties.h" 22 #include "net/http/http_server_properties_impl.h" 23 #include "net/http/http_stream.h" 24 #include "net/http/transport_security_state.h" 25 #include "net/proxy/proxy_info.h" 26 #include "net/proxy/proxy_service.h" 27 #include "net/socket/client_socket_handle.h" 28 #include "net/socket/mock_client_socket_pool_manager.h" 29 #include "net/socket/next_proto.h" 30 #include "net/socket/socket_test_util.h" 31 #include "net/spdy/spdy_session.h" 32 #include "net/spdy/spdy_session_pool.h" 33 #include "net/spdy/spdy_test_util_common.h" 34 #include "net/ssl/ssl_config_service.h" 35 #include "net/ssl/ssl_config_service_defaults.h" 36 // This file can be included from net/http even though 37 // it is in net/websockets because it doesn't 38 // introduce any link dependency to net/websockets. 39 #include "net/websockets/websocket_handshake_stream_base.h" 40 #include "testing/gtest/include/gtest/gtest.h" 41 42 namespace net { 43 44 namespace { 45 46 class UseAlternateProtocolsScopedSetter { 47 public: 48 explicit UseAlternateProtocolsScopedSetter(bool use_alternate_protocols) 49 : use_alternate_protocols_(HttpStreamFactory::use_alternate_protocols()) { 50 HttpStreamFactory::set_use_alternate_protocols(use_alternate_protocols); 51 } 52 ~UseAlternateProtocolsScopedSetter() { 53 HttpStreamFactory::set_use_alternate_protocols(use_alternate_protocols_); 54 } 55 56 private: 57 bool use_alternate_protocols_; 58 }; 59 60 class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase { 61 public: 62 enum StreamType { 63 kStreamTypeBasic, 64 kStreamTypeSpdy, 65 }; 66 67 explicit MockWebSocketHandshakeStream(StreamType type) : type_(type) {} 68 69 virtual ~MockWebSocketHandshakeStream() {} 70 71 StreamType type() const { 72 return type_; 73 } 74 75 // HttpStreamBase methods 76 virtual int InitializeStream(const HttpRequestInfo* request_info, 77 RequestPriority priority, 78 const BoundNetLog& net_log, 79 const CompletionCallback& callback) OVERRIDE { 80 return ERR_IO_PENDING; 81 } 82 virtual int SendRequest(const HttpRequestHeaders& request_headers, 83 HttpResponseInfo* response, 84 const CompletionCallback& callback) OVERRIDE { 85 return ERR_IO_PENDING; 86 } 87 virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE { 88 return ERR_IO_PENDING; 89 } 90 virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE { 91 return NULL; 92 } 93 virtual int ReadResponseBody(IOBuffer* buf, 94 int buf_len, 95 const CompletionCallback& callback) OVERRIDE { 96 return ERR_IO_PENDING; 97 } 98 virtual void Close(bool not_reusable) OVERRIDE {} 99 virtual bool IsResponseBodyComplete() const OVERRIDE { return false; } 100 virtual bool CanFindEndOfResponse() const OVERRIDE { return false; } 101 virtual bool IsConnectionReused() const OVERRIDE { return false; } 102 virtual void SetConnectionReused() OVERRIDE {} 103 virtual bool IsConnectionReusable() const OVERRIDE { return false; } 104 virtual int64 GetTotalReceivedBytes() const OVERRIDE { return 0; } 105 virtual bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const 106 OVERRIDE { 107 return false; 108 } 109 virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {} 110 virtual void GetSSLCertRequestInfo( 111 SSLCertRequestInfo* cert_request_info) OVERRIDE {} 112 virtual bool IsSpdyHttpStream() const OVERRIDE { return false; } 113 virtual void Drain(HttpNetworkSession* session) OVERRIDE {} 114 virtual void SetPriority(RequestPriority priority) OVERRIDE {} 115 116 virtual scoped_ptr<WebSocketStream> Upgrade() OVERRIDE { 117 return scoped_ptr<WebSocketStream>(); 118 } 119 120 private: 121 const StreamType type_; 122 }; 123 124 // HttpStreamFactoryImpl subclass that can wait until a preconnect is complete. 125 class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl { 126 public: 127 MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session, 128 bool for_websockets) 129 : HttpStreamFactoryImpl(session, for_websockets), 130 preconnect_done_(false), 131 waiting_for_preconnect_(false) {} 132 133 134 void WaitForPreconnects() { 135 while (!preconnect_done_) { 136 waiting_for_preconnect_ = true; 137 base::MessageLoop::current()->Run(); 138 waiting_for_preconnect_ = false; 139 } 140 } 141 142 private: 143 // HttpStreamFactoryImpl methods. 144 virtual void OnPreconnectsCompleteInternal() OVERRIDE { 145 preconnect_done_ = true; 146 if (waiting_for_preconnect_) 147 base::MessageLoop::current()->Quit(); 148 } 149 150 bool preconnect_done_; 151 bool waiting_for_preconnect_; 152 }; 153 154 class StreamRequestWaiter : public HttpStreamRequest::Delegate { 155 public: 156 StreamRequestWaiter() 157 : waiting_for_stream_(false), 158 stream_done_(false) {} 159 160 // HttpStreamRequest::Delegate 161 162 virtual void OnStreamReady( 163 const SSLConfig& used_ssl_config, 164 const ProxyInfo& used_proxy_info, 165 HttpStreamBase* stream) OVERRIDE { 166 stream_done_ = true; 167 if (waiting_for_stream_) 168 base::MessageLoop::current()->Quit(); 169 stream_.reset(stream); 170 used_ssl_config_ = used_ssl_config; 171 used_proxy_info_ = used_proxy_info; 172 } 173 174 virtual void OnWebSocketHandshakeStreamReady( 175 const SSLConfig& used_ssl_config, 176 const ProxyInfo& used_proxy_info, 177 WebSocketHandshakeStreamBase* stream) OVERRIDE { 178 stream_done_ = true; 179 if (waiting_for_stream_) 180 base::MessageLoop::current()->Quit(); 181 websocket_stream_.reset(stream); 182 used_ssl_config_ = used_ssl_config; 183 used_proxy_info_ = used_proxy_info; 184 } 185 186 virtual void OnStreamFailed( 187 int status, 188 const SSLConfig& used_ssl_config) OVERRIDE {} 189 190 virtual void OnCertificateError( 191 int status, 192 const SSLConfig& used_ssl_config, 193 const SSLInfo& ssl_info) OVERRIDE {} 194 195 virtual void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response, 196 const SSLConfig& used_ssl_config, 197 const ProxyInfo& used_proxy_info, 198 HttpAuthController* auth_controller) OVERRIDE {} 199 200 virtual void OnNeedsClientAuth(const SSLConfig& used_ssl_config, 201 SSLCertRequestInfo* cert_info) OVERRIDE {} 202 203 virtual void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info, 204 const SSLConfig& used_ssl_config, 205 const ProxyInfo& used_proxy_info, 206 HttpStreamBase* stream) OVERRIDE {} 207 208 void WaitForStream() { 209 while (!stream_done_) { 210 waiting_for_stream_ = true; 211 base::MessageLoop::current()->Run(); 212 waiting_for_stream_ = false; 213 } 214 } 215 216 const SSLConfig& used_ssl_config() const { 217 return used_ssl_config_; 218 } 219 220 const ProxyInfo& used_proxy_info() const { 221 return used_proxy_info_; 222 } 223 224 HttpStreamBase* stream() { 225 return stream_.get(); 226 } 227 228 MockWebSocketHandshakeStream* websocket_stream() { 229 return static_cast<MockWebSocketHandshakeStream*>(websocket_stream_.get()); 230 } 231 232 bool stream_done() const { return stream_done_; } 233 234 private: 235 bool waiting_for_stream_; 236 bool stream_done_; 237 scoped_ptr<HttpStreamBase> stream_; 238 scoped_ptr<WebSocketHandshakeStreamBase> websocket_stream_; 239 SSLConfig used_ssl_config_; 240 ProxyInfo used_proxy_info_; 241 242 DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter); 243 }; 244 245 class WebSocketSpdyHandshakeStream : public MockWebSocketHandshakeStream { 246 public: 247 explicit WebSocketSpdyHandshakeStream( 248 const base::WeakPtr<SpdySession>& spdy_session) 249 : MockWebSocketHandshakeStream(kStreamTypeSpdy), 250 spdy_session_(spdy_session) {} 251 252 virtual ~WebSocketSpdyHandshakeStream() {} 253 254 SpdySession* spdy_session() { return spdy_session_.get(); } 255 256 private: 257 base::WeakPtr<SpdySession> spdy_session_; 258 }; 259 260 class WebSocketBasicHandshakeStream : public MockWebSocketHandshakeStream { 261 public: 262 explicit WebSocketBasicHandshakeStream( 263 scoped_ptr<ClientSocketHandle> connection) 264 : MockWebSocketHandshakeStream(kStreamTypeBasic), 265 connection_(connection.Pass()) {} 266 267 virtual ~WebSocketBasicHandshakeStream() { 268 connection_->socket()->Disconnect(); 269 } 270 271 ClientSocketHandle* connection() { return connection_.get(); } 272 273 private: 274 scoped_ptr<ClientSocketHandle> connection_; 275 }; 276 277 class WebSocketStreamCreateHelper 278 : public WebSocketHandshakeStreamBase::CreateHelper { 279 public: 280 virtual ~WebSocketStreamCreateHelper() {} 281 282 virtual WebSocketHandshakeStreamBase* CreateBasicStream( 283 scoped_ptr<ClientSocketHandle> connection, 284 bool using_proxy) OVERRIDE { 285 return new WebSocketBasicHandshakeStream(connection.Pass()); 286 } 287 288 virtual WebSocketHandshakeStreamBase* CreateSpdyStream( 289 const base::WeakPtr<SpdySession>& spdy_session, 290 bool use_relative_url) OVERRIDE { 291 return new WebSocketSpdyHandshakeStream(spdy_session); 292 } 293 }; 294 295 struct TestCase { 296 int num_streams; 297 bool ssl; 298 }; 299 300 TestCase kTests[] = { 301 { 1, false }, 302 { 2, false }, 303 { 1, true}, 304 { 2, true}, 305 }; 306 307 void PreconnectHelperForURL(int num_streams, 308 const GURL& url, 309 HttpNetworkSession* session) { 310 HttpNetworkSessionPeer peer(session); 311 MockHttpStreamFactoryImplForPreconnect* mock_factory = 312 new MockHttpStreamFactoryImplForPreconnect(session, false); 313 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(mock_factory)); 314 SSLConfig ssl_config; 315 session->ssl_config_service()->GetSSLConfig(&ssl_config); 316 317 HttpRequestInfo request; 318 request.method = "GET"; 319 request.url = url; 320 request.load_flags = 0; 321 322 session->http_stream_factory()->PreconnectStreams( 323 num_streams, request, DEFAULT_PRIORITY, ssl_config, ssl_config); 324 mock_factory->WaitForPreconnects(); 325 }; 326 327 void PreconnectHelper(const TestCase& test, 328 HttpNetworkSession* session) { 329 GURL url = test.ssl ? GURL("https://www.google.com") : 330 GURL("http://www.google.com"); 331 PreconnectHelperForURL(test.num_streams, url, session); 332 }; 333 334 template<typename ParentPool> 335 class CapturePreconnectsSocketPool : public ParentPool { 336 public: 337 CapturePreconnectsSocketPool(HostResolver* host_resolver, 338 CertVerifier* cert_verifier); 339 340 int last_num_streams() const { 341 return last_num_streams_; 342 } 343 344 virtual int RequestSocket(const std::string& group_name, 345 const void* socket_params, 346 RequestPriority priority, 347 ClientSocketHandle* handle, 348 const CompletionCallback& callback, 349 const BoundNetLog& net_log) OVERRIDE { 350 ADD_FAILURE(); 351 return ERR_UNEXPECTED; 352 } 353 354 virtual void RequestSockets(const std::string& group_name, 355 const void* socket_params, 356 int num_sockets, 357 const BoundNetLog& net_log) OVERRIDE { 358 last_num_streams_ = num_sockets; 359 } 360 361 virtual void CancelRequest(const std::string& group_name, 362 ClientSocketHandle* handle) OVERRIDE { 363 ADD_FAILURE(); 364 } 365 virtual void ReleaseSocket(const std::string& group_name, 366 scoped_ptr<StreamSocket> socket, 367 int id) OVERRIDE { 368 ADD_FAILURE(); 369 } 370 virtual void CloseIdleSockets() OVERRIDE { 371 ADD_FAILURE(); 372 } 373 virtual int IdleSocketCount() const OVERRIDE { 374 ADD_FAILURE(); 375 return 0; 376 } 377 virtual int IdleSocketCountInGroup( 378 const std::string& group_name) const OVERRIDE { 379 ADD_FAILURE(); 380 return 0; 381 } 382 virtual LoadState GetLoadState( 383 const std::string& group_name, 384 const ClientSocketHandle* handle) const OVERRIDE { 385 ADD_FAILURE(); 386 return LOAD_STATE_IDLE; 387 } 388 virtual base::TimeDelta ConnectionTimeout() const OVERRIDE { 389 return base::TimeDelta(); 390 } 391 392 private: 393 int last_num_streams_; 394 }; 395 396 typedef CapturePreconnectsSocketPool<TransportClientSocketPool> 397 CapturePreconnectsTransportSocketPool; 398 typedef CapturePreconnectsSocketPool<HttpProxyClientSocketPool> 399 CapturePreconnectsHttpProxySocketPool; 400 typedef CapturePreconnectsSocketPool<SOCKSClientSocketPool> 401 CapturePreconnectsSOCKSSocketPool; 402 typedef CapturePreconnectsSocketPool<SSLClientSocketPool> 403 CapturePreconnectsSSLSocketPool; 404 405 template<typename ParentPool> 406 CapturePreconnectsSocketPool<ParentPool>::CapturePreconnectsSocketPool( 407 HostResolver* host_resolver, CertVerifier* /* cert_verifier */) 408 : ParentPool(0, 0, NULL, host_resolver, NULL, NULL), 409 last_num_streams_(-1) {} 410 411 template<> 412 CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool( 413 HostResolver* host_resolver, CertVerifier* /* cert_verifier */) 414 : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL), 415 last_num_streams_(-1) {} 416 417 template <> 418 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool( 419 HostResolver* host_resolver, 420 CertVerifier* cert_verifier) 421 : SSLClientSocketPool(0, 422 0, 423 NULL, 424 host_resolver, 425 cert_verifier, 426 NULL, 427 NULL, 428 NULL, 429 std::string(), 430 NULL, 431 NULL, 432 NULL, 433 NULL, 434 NULL, 435 NULL), 436 last_num_streams_(-1) {} 437 438 class HttpStreamFactoryTest : public ::testing::Test, 439 public ::testing::WithParamInterface<NextProto> { 440 }; 441 442 INSTANTIATE_TEST_CASE_P( 443 NextProto, 444 HttpStreamFactoryTest, 445 testing::Values(kProtoDeprecatedSPDY2, 446 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, 447 kProtoHTTP2Draft04)); 448 449 TEST_P(HttpStreamFactoryTest, PreconnectDirect) { 450 for (size_t i = 0; i < arraysize(kTests); ++i) { 451 SpdySessionDependencies session_deps( 452 GetParam(), ProxyService::CreateDirect()); 453 scoped_refptr<HttpNetworkSession> session( 454 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 455 HttpNetworkSessionPeer peer(session); 456 CapturePreconnectsTransportSocketPool* transport_conn_pool = 457 new CapturePreconnectsTransportSocketPool( 458 session_deps.host_resolver.get(), 459 session_deps.cert_verifier.get()); 460 CapturePreconnectsSSLSocketPool* ssl_conn_pool = 461 new CapturePreconnectsSSLSocketPool( 462 session_deps.host_resolver.get(), 463 session_deps.cert_verifier.get()); 464 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 465 new MockClientSocketPoolManager); 466 mock_pool_manager->SetTransportSocketPool(transport_conn_pool); 467 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool); 468 peer.SetClientSocketPoolManager( 469 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 470 PreconnectHelper(kTests[i], session.get()); 471 if (kTests[i].ssl) 472 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); 473 else 474 EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams()); 475 } 476 } 477 478 TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) { 479 for (size_t i = 0; i < arraysize(kTests); ++i) { 480 SpdySessionDependencies session_deps( 481 GetParam(), ProxyService::CreateFixed("http_proxy")); 482 scoped_refptr<HttpNetworkSession> session( 483 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 484 HttpNetworkSessionPeer peer(session); 485 HostPortPair proxy_host("http_proxy", 80); 486 CapturePreconnectsHttpProxySocketPool* http_proxy_pool = 487 new CapturePreconnectsHttpProxySocketPool( 488 session_deps.host_resolver.get(), 489 session_deps.cert_verifier.get()); 490 CapturePreconnectsSSLSocketPool* ssl_conn_pool = 491 new CapturePreconnectsSSLSocketPool( 492 session_deps.host_resolver.get(), 493 session_deps.cert_verifier.get()); 494 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 495 new MockClientSocketPoolManager); 496 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool); 497 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); 498 peer.SetClientSocketPoolManager( 499 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 500 PreconnectHelper(kTests[i], session.get()); 501 if (kTests[i].ssl) 502 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); 503 else 504 EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams()); 505 } 506 } 507 508 TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) { 509 for (size_t i = 0; i < arraysize(kTests); ++i) { 510 SpdySessionDependencies session_deps( 511 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080")); 512 scoped_refptr<HttpNetworkSession> session( 513 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 514 HttpNetworkSessionPeer peer(session); 515 HostPortPair proxy_host("socks_proxy", 1080); 516 CapturePreconnectsSOCKSSocketPool* socks_proxy_pool = 517 new CapturePreconnectsSOCKSSocketPool( 518 session_deps.host_resolver.get(), 519 session_deps.cert_verifier.get()); 520 CapturePreconnectsSSLSocketPool* ssl_conn_pool = 521 new CapturePreconnectsSSLSocketPool( 522 session_deps.host_resolver.get(), 523 session_deps.cert_verifier.get()); 524 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 525 new MockClientSocketPoolManager); 526 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_proxy_pool); 527 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); 528 peer.SetClientSocketPoolManager( 529 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 530 PreconnectHelper(kTests[i], session.get()); 531 if (kTests[i].ssl) 532 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); 533 else 534 EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams()); 535 } 536 } 537 538 TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) { 539 for (size_t i = 0; i < arraysize(kTests); ++i) { 540 SpdySessionDependencies session_deps( 541 GetParam(), ProxyService::CreateDirect()); 542 scoped_refptr<HttpNetworkSession> session( 543 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 544 HttpNetworkSessionPeer peer(session); 545 546 // Put a SpdySession in the pool. 547 HostPortPair host_port_pair("www.google.com", 443); 548 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), 549 kPrivacyModeDisabled); 550 ignore_result(CreateFakeSpdySession(session->spdy_session_pool(), key)); 551 552 CapturePreconnectsTransportSocketPool* transport_conn_pool = 553 new CapturePreconnectsTransportSocketPool( 554 session_deps.host_resolver.get(), 555 session_deps.cert_verifier.get()); 556 CapturePreconnectsSSLSocketPool* ssl_conn_pool = 557 new CapturePreconnectsSSLSocketPool( 558 session_deps.host_resolver.get(), 559 session_deps.cert_verifier.get()); 560 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 561 new MockClientSocketPoolManager); 562 mock_pool_manager->SetTransportSocketPool(transport_conn_pool); 563 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool); 564 peer.SetClientSocketPoolManager( 565 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 566 PreconnectHelper(kTests[i], session.get()); 567 // We shouldn't be preconnecting if we have an existing session, which is 568 // the case for https://www.google.com. 569 if (kTests[i].ssl) 570 EXPECT_EQ(-1, ssl_conn_pool->last_num_streams()); 571 else 572 EXPECT_EQ(kTests[i].num_streams, 573 transport_conn_pool->last_num_streams()); 574 } 575 } 576 577 // Verify that preconnects to unsafe ports are cancelled before they reach 578 // the SocketPool. 579 TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) { 580 ASSERT_FALSE(IsPortAllowedByDefault(7)); 581 ASSERT_FALSE(IsPortAllowedByOverride(7)); 582 583 SpdySessionDependencies session_deps( 584 GetParam(), ProxyService::CreateDirect()); 585 scoped_refptr<HttpNetworkSession> session( 586 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 587 HttpNetworkSessionPeer peer(session); 588 CapturePreconnectsTransportSocketPool* transport_conn_pool = 589 new CapturePreconnectsTransportSocketPool( 590 session_deps.host_resolver.get(), 591 session_deps.cert_verifier.get()); 592 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 593 new MockClientSocketPoolManager); 594 mock_pool_manager->SetTransportSocketPool(transport_conn_pool); 595 peer.SetClientSocketPoolManager( 596 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 597 598 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get()); 599 600 EXPECT_EQ(-1, transport_conn_pool->last_num_streams()); 601 } 602 603 TEST_P(HttpStreamFactoryTest, JobNotifiesProxy) { 604 const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT"; 605 SpdySessionDependencies session_deps( 606 GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString)); 607 608 // First connection attempt fails 609 StaticSocketDataProvider socket_data1; 610 socket_data1.set_connect_data(MockConnect(ASYNC, ERR_ADDRESS_UNREACHABLE)); 611 session_deps.socket_factory->AddSocketDataProvider(&socket_data1); 612 613 // Second connection attempt succeeds 614 StaticSocketDataProvider socket_data2; 615 socket_data2.set_connect_data(MockConnect(ASYNC, OK)); 616 session_deps.socket_factory->AddSocketDataProvider(&socket_data2); 617 618 scoped_refptr<HttpNetworkSession> session( 619 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 620 621 // Now request a stream. It should succeed using the second proxy in the 622 // list. 623 HttpRequestInfo request_info; 624 request_info.method = "GET"; 625 request_info.url = GURL("http://www.google.com"); 626 627 SSLConfig ssl_config; 628 StreamRequestWaiter waiter; 629 scoped_ptr<HttpStreamRequest> request( 630 session->http_stream_factory()->RequestStream( 631 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, 632 &waiter, BoundNetLog())); 633 waiter.WaitForStream(); 634 635 // The proxy that failed should now be known to the proxy_service as bad. 636 const ProxyRetryInfoMap& retry_info = 637 session->proxy_service()->proxy_retry_info(); 638 EXPECT_EQ(1u, retry_info.size()); 639 ProxyRetryInfoMap::const_iterator iter = retry_info.find("bad:99"); 640 EXPECT_TRUE(iter != retry_info.end()); 641 } 642 643 TEST_P(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) { 644 SpdySessionDependencies session_deps( 645 GetParam(), ProxyService::CreateDirect()); 646 647 StaticSocketDataProvider socket_data; 648 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 649 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 650 651 SSLSocketDataProvider ssl(ASYNC, OK); 652 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl); 653 654 scoped_refptr<HttpNetworkSession> session( 655 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 656 657 // Set an existing SpdySession in the pool. 658 HostPortPair host_port_pair("www.google.com", 443); 659 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), 660 kPrivacyModeEnabled); 661 662 HttpRequestInfo request_info; 663 request_info.method = "GET"; 664 request_info.url = GURL("https://www.google.com"); 665 request_info.load_flags = 0; 666 request_info.privacy_mode = kPrivacyModeDisabled; 667 668 SSLConfig ssl_config; 669 StreamRequestWaiter waiter; 670 scoped_ptr<HttpStreamRequest> request( 671 session->http_stream_factory()->RequestStream( 672 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, 673 &waiter, BoundNetLog())); 674 waiter.WaitForStream(); 675 676 // The stream shouldn't come from spdy as we are using different privacy mode 677 EXPECT_FALSE(request->using_spdy()); 678 679 SSLConfig used_ssl_config = waiter.used_ssl_config(); 680 EXPECT_EQ(used_ssl_config.channel_id_enabled, ssl_config.channel_id_enabled); 681 } 682 683 namespace { 684 // Return count of distinct groups in given socket pool. 685 int GetSocketPoolGroupCount(ClientSocketPool* pool) { 686 int count = 0; 687 scoped_ptr<base::DictionaryValue> dict(pool->GetInfoAsValue("", "", false)); 688 EXPECT_TRUE(dict != NULL); 689 base::DictionaryValue* groups = NULL; 690 if (dict->GetDictionary("groups", &groups) && (groups != NULL)) { 691 count = static_cast<int>(groups->size()); 692 } 693 return count; 694 } 695 } // namespace 696 697 TEST_P(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) { 698 SpdySessionDependencies session_deps( 699 GetParam(), ProxyService::CreateDirect()); 700 701 StaticSocketDataProvider socket_data; 702 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 703 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 704 705 SSLSocketDataProvider ssl(ASYNC, OK); 706 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl); 707 708 scoped_refptr<HttpNetworkSession> session( 709 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 710 SSLClientSocketPool* ssl_pool = session->GetSSLSocketPool( 711 HttpNetworkSession::NORMAL_SOCKET_POOL); 712 713 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0); 714 715 HttpRequestInfo request_info; 716 request_info.method = "GET"; 717 request_info.url = GURL("https://www.google.com"); 718 request_info.load_flags = 0; 719 request_info.privacy_mode = kPrivacyModeDisabled; 720 721 SSLConfig ssl_config; 722 StreamRequestWaiter waiter; 723 724 scoped_ptr<HttpStreamRequest> request1( 725 session->http_stream_factory()->RequestStream( 726 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, 727 &waiter, BoundNetLog())); 728 waiter.WaitForStream(); 729 730 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1); 731 732 scoped_ptr<HttpStreamRequest> request2( 733 session->http_stream_factory()->RequestStream( 734 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, 735 &waiter, BoundNetLog())); 736 waiter.WaitForStream(); 737 738 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1); 739 740 request_info.privacy_mode = kPrivacyModeEnabled; 741 scoped_ptr<HttpStreamRequest> request3( 742 session->http_stream_factory()->RequestStream( 743 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, 744 &waiter, BoundNetLog())); 745 waiter.WaitForStream(); 746 747 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2); 748 } 749 750 TEST_P(HttpStreamFactoryTest, GetLoadState) { 751 SpdySessionDependencies session_deps( 752 GetParam(), ProxyService::CreateDirect()); 753 754 StaticSocketDataProvider socket_data; 755 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 756 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 757 758 scoped_refptr<HttpNetworkSession> session( 759 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 760 761 HttpRequestInfo request_info; 762 request_info.method = "GET"; 763 request_info.url = GURL("http://www.google.com"); 764 765 SSLConfig ssl_config; 766 StreamRequestWaiter waiter; 767 scoped_ptr<HttpStreamRequest> request( 768 session->http_stream_factory()->RequestStream( 769 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, 770 &waiter, BoundNetLog())); 771 772 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState()); 773 774 waiter.WaitForStream(); 775 } 776 777 TEST_P(HttpStreamFactoryTest, RequestHttpStream) { 778 SpdySessionDependencies session_deps( 779 GetParam(), ProxyService::CreateDirect()); 780 781 StaticSocketDataProvider socket_data; 782 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 783 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 784 785 scoped_refptr<HttpNetworkSession> session( 786 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 787 788 // Now request a stream. It should succeed using the second proxy in the 789 // list. 790 HttpRequestInfo request_info; 791 request_info.method = "GET"; 792 request_info.url = GURL("http://www.google.com"); 793 request_info.load_flags = 0; 794 795 SSLConfig ssl_config; 796 StreamRequestWaiter waiter; 797 scoped_ptr<HttpStreamRequest> request( 798 session->http_stream_factory()->RequestStream( 799 request_info, 800 DEFAULT_PRIORITY, 801 ssl_config, 802 ssl_config, 803 &waiter, 804 BoundNetLog())); 805 waiter.WaitForStream(); 806 EXPECT_TRUE(waiter.stream_done()); 807 ASSERT_TRUE(NULL != waiter.stream()); 808 EXPECT_TRUE(NULL == waiter.websocket_stream()); 809 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream()); 810 811 EXPECT_EQ(1, GetSocketPoolGroupCount( 812 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 813 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( 814 HttpNetworkSession::NORMAL_SOCKET_POOL))); 815 EXPECT_EQ(0, GetSocketPoolGroupCount( 816 session->GetTransportSocketPool( 817 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 818 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( 819 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 820 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 821 } 822 823 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverSSL) { 824 SpdySessionDependencies session_deps( 825 GetParam(), ProxyService::CreateDirect()); 826 827 MockRead mock_read(ASYNC, OK); 828 StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0); 829 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 830 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 831 832 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); 833 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); 834 835 scoped_refptr<HttpNetworkSession> session( 836 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 837 838 // Now request a stream. 839 HttpRequestInfo request_info; 840 request_info.method = "GET"; 841 request_info.url = GURL("https://www.google.com"); 842 request_info.load_flags = 0; 843 844 SSLConfig ssl_config; 845 StreamRequestWaiter waiter; 846 scoped_ptr<HttpStreamRequest> request( 847 session->http_stream_factory()->RequestStream( 848 request_info, 849 DEFAULT_PRIORITY, 850 ssl_config, 851 ssl_config, 852 &waiter, 853 BoundNetLog())); 854 waiter.WaitForStream(); 855 EXPECT_TRUE(waiter.stream_done()); 856 ASSERT_TRUE(NULL != waiter.stream()); 857 EXPECT_TRUE(NULL == waiter.websocket_stream()); 858 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream()); 859 EXPECT_EQ(1, GetSocketPoolGroupCount( 860 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 861 EXPECT_EQ(1, GetSocketPoolGroupCount( 862 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 863 EXPECT_EQ(0, GetSocketPoolGroupCount( 864 session->GetTransportSocketPool( 865 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 866 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( 867 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 868 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 869 } 870 871 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) { 872 SpdySessionDependencies session_deps( 873 GetParam(), ProxyService::CreateFixed("myproxy:8888")); 874 875 StaticSocketDataProvider socket_data; 876 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 877 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 878 879 scoped_refptr<HttpNetworkSession> session( 880 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 881 882 // Now request a stream. It should succeed using the second proxy in the 883 // list. 884 HttpRequestInfo request_info; 885 request_info.method = "GET"; 886 request_info.url = GURL("http://www.google.com"); 887 request_info.load_flags = 0; 888 889 SSLConfig ssl_config; 890 StreamRequestWaiter waiter; 891 scoped_ptr<HttpStreamRequest> request( 892 session->http_stream_factory()->RequestStream( 893 request_info, 894 DEFAULT_PRIORITY, 895 ssl_config, 896 ssl_config, 897 &waiter, 898 BoundNetLog())); 899 waiter.WaitForStream(); 900 EXPECT_TRUE(waiter.stream_done()); 901 ASSERT_TRUE(NULL != waiter.stream()); 902 EXPECT_TRUE(NULL == waiter.websocket_stream()); 903 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream()); 904 EXPECT_EQ(0, GetSocketPoolGroupCount( 905 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 906 EXPECT_EQ(0, GetSocketPoolGroupCount( 907 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 908 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy( 909 HttpNetworkSession::NORMAL_SOCKET_POOL, 910 HostPortPair("myproxy", 8888)))); 911 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( 912 HttpNetworkSession::NORMAL_SOCKET_POOL, 913 HostPortPair("myproxy", 8888)))); 914 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy( 915 HttpNetworkSession::WEBSOCKET_SOCKET_POOL, 916 HostPortPair("myproxy", 8888)))); 917 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( 918 HttpNetworkSession::WEBSOCKET_SOCKET_POOL, 919 HostPortPair("myproxy", 8888)))); 920 EXPECT_FALSE(waiter.used_proxy_info().is_direct()); 921 } 922 923 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) { 924 SpdySessionDependencies session_deps( 925 GetParam(), ProxyService::CreateDirect()); 926 927 StaticSocketDataProvider socket_data; 928 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 929 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 930 931 scoped_refptr<HttpNetworkSession> session( 932 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 933 934 // Now request a stream. 935 HttpRequestInfo request_info; 936 request_info.method = "GET"; 937 request_info.url = GURL("ws://www.google.com"); 938 request_info.load_flags = 0; 939 940 SSLConfig ssl_config; 941 StreamRequestWaiter waiter; 942 WebSocketStreamCreateHelper create_helper; 943 scoped_ptr<HttpStreamRequest> request( 944 session->http_stream_factory_for_websocket() 945 ->RequestWebSocketHandshakeStream(request_info, 946 DEFAULT_PRIORITY, 947 ssl_config, 948 ssl_config, 949 &waiter, 950 &create_helper, 951 BoundNetLog())); 952 waiter.WaitForStream(); 953 EXPECT_TRUE(waiter.stream_done()); 954 EXPECT_TRUE(NULL == waiter.stream()); 955 ASSERT_TRUE(NULL != waiter.websocket_stream()); 956 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic, 957 waiter.websocket_stream()->type()); 958 EXPECT_EQ(0, GetSocketPoolGroupCount( 959 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 960 EXPECT_EQ(0, GetSocketPoolGroupCount( 961 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 962 EXPECT_EQ(1, GetSocketPoolGroupCount( 963 session->GetTransportSocketPool( 964 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 965 EXPECT_EQ(0, GetSocketPoolGroupCount( 966 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 967 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 968 } 969 970 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverSSL) { 971 SpdySessionDependencies session_deps( 972 GetParam(), ProxyService::CreateDirect()); 973 974 MockRead mock_read(ASYNC, OK); 975 StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0); 976 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 977 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 978 979 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); 980 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); 981 982 scoped_refptr<HttpNetworkSession> session( 983 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 984 985 // Now request a stream. 986 HttpRequestInfo request_info; 987 request_info.method = "GET"; 988 request_info.url = GURL("wss://www.google.com"); 989 request_info.load_flags = 0; 990 991 SSLConfig ssl_config; 992 StreamRequestWaiter waiter; 993 WebSocketStreamCreateHelper create_helper; 994 scoped_ptr<HttpStreamRequest> request( 995 session->http_stream_factory_for_websocket() 996 ->RequestWebSocketHandshakeStream(request_info, 997 DEFAULT_PRIORITY, 998 ssl_config, 999 ssl_config, 1000 &waiter, 1001 &create_helper, 1002 BoundNetLog())); 1003 waiter.WaitForStream(); 1004 EXPECT_TRUE(waiter.stream_done()); 1005 EXPECT_TRUE(NULL == waiter.stream()); 1006 ASSERT_TRUE(NULL != waiter.websocket_stream()); 1007 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic, 1008 waiter.websocket_stream()->type()); 1009 EXPECT_EQ(0, GetSocketPoolGroupCount( 1010 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1011 EXPECT_EQ(0, GetSocketPoolGroupCount( 1012 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1013 EXPECT_EQ(1, GetSocketPoolGroupCount( 1014 session->GetTransportSocketPool( 1015 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1016 EXPECT_EQ(1, GetSocketPoolGroupCount( 1017 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1018 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 1019 } 1020 1021 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) { 1022 SpdySessionDependencies session_deps( 1023 GetParam(), ProxyService::CreateFixed("myproxy:8888")); 1024 1025 MockRead read(SYNCHRONOUS, "HTTP/1.0 200 Connection established\r\n\r\n"); 1026 StaticSocketDataProvider socket_data(&read, 1, 0, 0); 1027 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 1028 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 1029 1030 scoped_refptr<HttpNetworkSession> session( 1031 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 1032 1033 // Now request a stream. 1034 HttpRequestInfo request_info; 1035 request_info.method = "GET"; 1036 request_info.url = GURL("ws://www.google.com"); 1037 request_info.load_flags = 0; 1038 1039 SSLConfig ssl_config; 1040 StreamRequestWaiter waiter; 1041 WebSocketStreamCreateHelper create_helper; 1042 scoped_ptr<HttpStreamRequest> request( 1043 session->http_stream_factory_for_websocket() 1044 ->RequestWebSocketHandshakeStream(request_info, 1045 DEFAULT_PRIORITY, 1046 ssl_config, 1047 ssl_config, 1048 &waiter, 1049 &create_helper, 1050 BoundNetLog())); 1051 waiter.WaitForStream(); 1052 EXPECT_TRUE(waiter.stream_done()); 1053 EXPECT_TRUE(NULL == waiter.stream()); 1054 ASSERT_TRUE(NULL != waiter.websocket_stream()); 1055 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic, 1056 waiter.websocket_stream()->type()); 1057 EXPECT_EQ(0, GetSocketPoolGroupCount( 1058 session->GetTransportSocketPool( 1059 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1060 EXPECT_EQ(0, GetSocketPoolGroupCount( 1061 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1062 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy( 1063 HttpNetworkSession::NORMAL_SOCKET_POOL, 1064 HostPortPair("myproxy", 8888)))); 1065 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( 1066 HttpNetworkSession::NORMAL_SOCKET_POOL, 1067 HostPortPair("myproxy", 8888)))); 1068 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy( 1069 HttpNetworkSession::WEBSOCKET_SOCKET_POOL, 1070 HostPortPair("myproxy", 8888)))); 1071 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( 1072 HttpNetworkSession::WEBSOCKET_SOCKET_POOL, 1073 HostPortPair("myproxy", 8888)))); 1074 EXPECT_FALSE(waiter.used_proxy_info().is_direct()); 1075 } 1076 1077 TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) { 1078 SpdySessionDependencies session_deps(GetParam(), 1079 ProxyService::CreateDirect()); 1080 1081 MockRead mock_read(ASYNC, OK); 1082 DeterministicSocketData socket_data(&mock_read, 1, NULL, 0); 1083 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 1084 session_deps.deterministic_socket_factory->AddSocketDataProvider( 1085 &socket_data); 1086 1087 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); 1088 ssl_socket_data.SetNextProto(GetParam()); 1089 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider( 1090 &ssl_socket_data); 1091 1092 HostPortPair host_port_pair("www.google.com", 443); 1093 scoped_refptr<HttpNetworkSession> 1094 session(SpdySessionDependencies::SpdyCreateSessionDeterministic( 1095 &session_deps)); 1096 1097 // Now request a stream. 1098 HttpRequestInfo request_info; 1099 request_info.method = "GET"; 1100 request_info.url = GURL("https://www.google.com"); 1101 request_info.load_flags = 0; 1102 1103 SSLConfig ssl_config; 1104 StreamRequestWaiter waiter; 1105 scoped_ptr<HttpStreamRequest> request( 1106 session->http_stream_factory()->RequestStream( 1107 request_info, 1108 DEFAULT_PRIORITY, 1109 ssl_config, 1110 ssl_config, 1111 &waiter, 1112 BoundNetLog())); 1113 waiter.WaitForStream(); 1114 EXPECT_TRUE(waiter.stream_done()); 1115 EXPECT_TRUE(NULL == waiter.websocket_stream()); 1116 ASSERT_TRUE(NULL != waiter.stream()); 1117 EXPECT_TRUE(waiter.stream()->IsSpdyHttpStream()); 1118 EXPECT_EQ(1, GetSocketPoolGroupCount( 1119 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1120 EXPECT_EQ(1, GetSocketPoolGroupCount( 1121 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1122 EXPECT_EQ(0, GetSocketPoolGroupCount( 1123 session->GetTransportSocketPool( 1124 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1125 EXPECT_EQ(0, GetSocketPoolGroupCount( 1126 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1127 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 1128 } 1129 1130 TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStream) { 1131 SpdySessionDependencies session_deps(GetParam(), 1132 ProxyService::CreateDirect()); 1133 1134 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING); 1135 StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0); 1136 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 1137 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 1138 1139 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); 1140 ssl_socket_data.SetNextProto(GetParam()); 1141 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); 1142 1143 HostPortPair host_port_pair("www.google.com", 80); 1144 scoped_refptr<HttpNetworkSession> 1145 session(SpdySessionDependencies::SpdyCreateSession(&session_deps)); 1146 1147 // Now request a stream. 1148 HttpRequestInfo request_info; 1149 request_info.method = "GET"; 1150 request_info.url = GURL("wss://www.google.com"); 1151 request_info.load_flags = 0; 1152 1153 SSLConfig ssl_config; 1154 StreamRequestWaiter waiter1; 1155 WebSocketStreamCreateHelper create_helper; 1156 scoped_ptr<HttpStreamRequest> request1( 1157 session->http_stream_factory_for_websocket() 1158 ->RequestWebSocketHandshakeStream(request_info, 1159 DEFAULT_PRIORITY, 1160 ssl_config, 1161 ssl_config, 1162 &waiter1, 1163 &create_helper, 1164 BoundNetLog())); 1165 waiter1.WaitForStream(); 1166 EXPECT_TRUE(waiter1.stream_done()); 1167 ASSERT_TRUE(NULL != waiter1.websocket_stream()); 1168 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy, 1169 waiter1.websocket_stream()->type()); 1170 EXPECT_TRUE(NULL == waiter1.stream()); 1171 1172 StreamRequestWaiter waiter2; 1173 scoped_ptr<HttpStreamRequest> request2( 1174 session->http_stream_factory_for_websocket() 1175 ->RequestWebSocketHandshakeStream(request_info, 1176 DEFAULT_PRIORITY, 1177 ssl_config, 1178 ssl_config, 1179 &waiter2, 1180 &create_helper, 1181 BoundNetLog())); 1182 waiter2.WaitForStream(); 1183 EXPECT_TRUE(waiter2.stream_done()); 1184 ASSERT_TRUE(NULL != waiter2.websocket_stream()); 1185 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy, 1186 waiter2.websocket_stream()->type()); 1187 EXPECT_TRUE(NULL == waiter2.stream()); 1188 EXPECT_NE(waiter2.websocket_stream(), waiter1.websocket_stream()); 1189 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream*>( 1190 waiter2.websocket_stream())->spdy_session(), 1191 static_cast<WebSocketSpdyHandshakeStream*>( 1192 waiter1.websocket_stream())->spdy_session()); 1193 1194 EXPECT_EQ(0, GetSocketPoolGroupCount( 1195 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1196 EXPECT_EQ(0, GetSocketPoolGroupCount( 1197 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1198 EXPECT_EQ(1, GetSocketPoolGroupCount( 1199 session->GetTransportSocketPool( 1200 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1201 EXPECT_EQ(1, GetSocketPoolGroupCount( 1202 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1203 EXPECT_TRUE(waiter1.used_proxy_info().is_direct()); 1204 } 1205 1206 TEST_P(HttpStreamFactoryTest, OrphanedWebSocketStream) { 1207 UseAlternateProtocolsScopedSetter use_alternate_protocols(true); 1208 SpdySessionDependencies session_deps(GetParam(), 1209 ProxyService::CreateDirect()); 1210 1211 MockRead mock_read(ASYNC, OK); 1212 DeterministicSocketData socket_data(&mock_read, 1, NULL, 0); 1213 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 1214 session_deps.deterministic_socket_factory->AddSocketDataProvider( 1215 &socket_data); 1216 1217 MockRead mock_read2(ASYNC, OK); 1218 DeterministicSocketData socket_data2(&mock_read2, 1, NULL, 0); 1219 socket_data2.set_connect_data(MockConnect(ASYNC, ERR_IO_PENDING)); 1220 session_deps.deterministic_socket_factory->AddSocketDataProvider( 1221 &socket_data2); 1222 1223 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); 1224 ssl_socket_data.SetNextProto(GetParam()); 1225 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider( 1226 &ssl_socket_data); 1227 1228 scoped_refptr<HttpNetworkSession> 1229 session(SpdySessionDependencies::SpdyCreateSessionDeterministic( 1230 &session_deps)); 1231 1232 // Now request a stream. 1233 HttpRequestInfo request_info; 1234 request_info.method = "GET"; 1235 request_info.url = GURL("ws://www.google.com:8888"); 1236 request_info.load_flags = 0; 1237 1238 session->http_server_properties()->SetAlternateProtocol( 1239 HostPortPair("www.google.com", 8888), 1240 9999, 1241 NPN_SPDY_3); 1242 1243 SSLConfig ssl_config; 1244 StreamRequestWaiter waiter; 1245 WebSocketStreamCreateHelper create_helper; 1246 scoped_ptr<HttpStreamRequest> request( 1247 session->http_stream_factory_for_websocket() 1248 ->RequestWebSocketHandshakeStream(request_info, 1249 DEFAULT_PRIORITY, 1250 ssl_config, 1251 ssl_config, 1252 &waiter, 1253 &create_helper, 1254 BoundNetLog())); 1255 waiter.WaitForStream(); 1256 EXPECT_TRUE(waiter.stream_done()); 1257 EXPECT_TRUE(NULL == waiter.stream()); 1258 ASSERT_TRUE(NULL != waiter.websocket_stream()); 1259 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy, 1260 waiter.websocket_stream()->type()); 1261 1262 // Make sure that there was an alternative connection 1263 // which consumes extra connections. 1264 EXPECT_EQ(0, GetSocketPoolGroupCount( 1265 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1266 EXPECT_EQ(0, GetSocketPoolGroupCount( 1267 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1268 EXPECT_EQ(2, GetSocketPoolGroupCount( 1269 session->GetTransportSocketPool( 1270 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1271 EXPECT_EQ(1, GetSocketPoolGroupCount( 1272 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1273 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 1274 1275 // Make sure there is no orphaned job. it is already canceled. 1276 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>( 1277 session->http_stream_factory_for_websocket())->num_orphaned_jobs()); 1278 } 1279 1280 } // namespace 1281 1282 } // namespace net 1283