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