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