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(0, 0, NULL, host_resolver, NULL, NULL, NULL), 398 last_num_streams_(-1) {} 399 400 template <> 401 CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool( 402 HostResolver* host_resolver, 403 CertVerifier* cert_verifier) 404 : SSLClientSocketPool(0, 405 0, 406 NULL, // ssl_histograms 407 host_resolver, 408 cert_verifier, 409 NULL, // server_bound_cert_store 410 NULL, // transport_security_state 411 NULL, // cert_transparency_verifier 412 std::string(), // ssl_session_cache_shard 413 NULL, // deterministic_socket_factory 414 NULL, // transport_socket_pool 415 NULL, 416 NULL, 417 NULL, // ssl_config_service 418 NULL), // net_log 419 last_num_streams_(-1) {} 420 421 class HttpStreamFactoryTest : public ::testing::Test, 422 public ::testing::WithParamInterface<NextProto> { 423 }; 424 425 INSTANTIATE_TEST_CASE_P( 426 NextProto, 427 HttpStreamFactoryTest, 428 testing::Values(kProtoDeprecatedSPDY2, 429 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4)); 430 431 TEST_P(HttpStreamFactoryTest, PreconnectDirect) { 432 for (size_t i = 0; i < arraysize(kTests); ++i) { 433 SpdySessionDependencies session_deps( 434 GetParam(), ProxyService::CreateDirect()); 435 scoped_refptr<HttpNetworkSession> session( 436 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 437 HttpNetworkSessionPeer peer(session); 438 CapturePreconnectsTransportSocketPool* transport_conn_pool = 439 new CapturePreconnectsTransportSocketPool( 440 session_deps.host_resolver.get(), 441 session_deps.cert_verifier.get()); 442 CapturePreconnectsSSLSocketPool* ssl_conn_pool = 443 new CapturePreconnectsSSLSocketPool( 444 session_deps.host_resolver.get(), 445 session_deps.cert_verifier.get()); 446 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 447 new MockClientSocketPoolManager); 448 mock_pool_manager->SetTransportSocketPool(transport_conn_pool); 449 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool); 450 peer.SetClientSocketPoolManager( 451 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 452 PreconnectHelper(kTests[i], session.get()); 453 if (kTests[i].ssl) 454 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); 455 else 456 EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams()); 457 } 458 } 459 460 TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) { 461 for (size_t i = 0; i < arraysize(kTests); ++i) { 462 SpdySessionDependencies session_deps( 463 GetParam(), ProxyService::CreateFixed("http_proxy")); 464 scoped_refptr<HttpNetworkSession> session( 465 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 466 HttpNetworkSessionPeer peer(session); 467 HostPortPair proxy_host("http_proxy", 80); 468 CapturePreconnectsHttpProxySocketPool* http_proxy_pool = 469 new CapturePreconnectsHttpProxySocketPool( 470 session_deps.host_resolver.get(), 471 session_deps.cert_verifier.get()); 472 CapturePreconnectsSSLSocketPool* ssl_conn_pool = 473 new CapturePreconnectsSSLSocketPool( 474 session_deps.host_resolver.get(), 475 session_deps.cert_verifier.get()); 476 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 477 new MockClientSocketPoolManager); 478 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool); 479 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); 480 peer.SetClientSocketPoolManager( 481 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 482 PreconnectHelper(kTests[i], session.get()); 483 if (kTests[i].ssl) 484 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); 485 else 486 EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams()); 487 } 488 } 489 490 TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) { 491 for (size_t i = 0; i < arraysize(kTests); ++i) { 492 SpdySessionDependencies session_deps( 493 GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080")); 494 scoped_refptr<HttpNetworkSession> session( 495 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 496 HttpNetworkSessionPeer peer(session); 497 HostPortPair proxy_host("socks_proxy", 1080); 498 CapturePreconnectsSOCKSSocketPool* socks_proxy_pool = 499 new CapturePreconnectsSOCKSSocketPool( 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 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 507 new MockClientSocketPoolManager); 508 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_proxy_pool); 509 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); 510 peer.SetClientSocketPoolManager( 511 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 512 PreconnectHelper(kTests[i], session.get()); 513 if (kTests[i].ssl) 514 EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); 515 else 516 EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams()); 517 } 518 } 519 520 TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) { 521 for (size_t i = 0; i < arraysize(kTests); ++i) { 522 SpdySessionDependencies session_deps( 523 GetParam(), ProxyService::CreateDirect()); 524 scoped_refptr<HttpNetworkSession> session( 525 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 526 HttpNetworkSessionPeer peer(session); 527 528 // Put a SpdySession in the pool. 529 HostPortPair host_port_pair("www.google.com", 443); 530 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), 531 PRIVACY_MODE_DISABLED); 532 ignore_result(CreateFakeSpdySession(session->spdy_session_pool(), key)); 533 534 CapturePreconnectsTransportSocketPool* transport_conn_pool = 535 new CapturePreconnectsTransportSocketPool( 536 session_deps.host_resolver.get(), 537 session_deps.cert_verifier.get()); 538 CapturePreconnectsSSLSocketPool* ssl_conn_pool = 539 new CapturePreconnectsSSLSocketPool( 540 session_deps.host_resolver.get(), 541 session_deps.cert_verifier.get()); 542 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 543 new MockClientSocketPoolManager); 544 mock_pool_manager->SetTransportSocketPool(transport_conn_pool); 545 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool); 546 peer.SetClientSocketPoolManager( 547 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 548 PreconnectHelper(kTests[i], session.get()); 549 // We shouldn't be preconnecting if we have an existing session, which is 550 // the case for https://www.google.com. 551 if (kTests[i].ssl) 552 EXPECT_EQ(-1, ssl_conn_pool->last_num_streams()); 553 else 554 EXPECT_EQ(kTests[i].num_streams, 555 transport_conn_pool->last_num_streams()); 556 } 557 } 558 559 // Verify that preconnects to unsafe ports are cancelled before they reach 560 // the SocketPool. 561 TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) { 562 ASSERT_FALSE(IsPortAllowedByDefault(7)); 563 ASSERT_FALSE(IsPortAllowedByOverride(7)); 564 565 SpdySessionDependencies session_deps( 566 GetParam(), ProxyService::CreateDirect()); 567 scoped_refptr<HttpNetworkSession> session( 568 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 569 HttpNetworkSessionPeer peer(session); 570 CapturePreconnectsTransportSocketPool* transport_conn_pool = 571 new CapturePreconnectsTransportSocketPool( 572 session_deps.host_resolver.get(), 573 session_deps.cert_verifier.get()); 574 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( 575 new MockClientSocketPoolManager); 576 mock_pool_manager->SetTransportSocketPool(transport_conn_pool); 577 peer.SetClientSocketPoolManager( 578 mock_pool_manager.PassAs<ClientSocketPoolManager>()); 579 580 PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get()); 581 582 EXPECT_EQ(-1, transport_conn_pool->last_num_streams()); 583 } 584 585 TEST_P(HttpStreamFactoryTest, JobNotifiesProxy) { 586 const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT"; 587 SpdySessionDependencies session_deps( 588 GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString)); 589 590 // First connection attempt fails 591 StaticSocketDataProvider socket_data1; 592 socket_data1.set_connect_data(MockConnect(ASYNC, ERR_ADDRESS_UNREACHABLE)); 593 session_deps.socket_factory->AddSocketDataProvider(&socket_data1); 594 595 // Second connection attempt succeeds 596 StaticSocketDataProvider socket_data2; 597 socket_data2.set_connect_data(MockConnect(ASYNC, OK)); 598 session_deps.socket_factory->AddSocketDataProvider(&socket_data2); 599 600 scoped_refptr<HttpNetworkSession> session( 601 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 602 603 // Now request a stream. It should succeed using the second proxy in the 604 // list. 605 HttpRequestInfo request_info; 606 request_info.method = "GET"; 607 request_info.url = GURL("http://www.google.com"); 608 609 SSLConfig ssl_config; 610 StreamRequestWaiter waiter; 611 scoped_ptr<HttpStreamRequest> request( 612 session->http_stream_factory()->RequestStream( 613 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, 614 &waiter, BoundNetLog())); 615 waiter.WaitForStream(); 616 617 // The proxy that failed should now be known to the proxy_service as bad. 618 const ProxyRetryInfoMap& retry_info = 619 session->proxy_service()->proxy_retry_info(); 620 EXPECT_EQ(1u, retry_info.size()); 621 ProxyRetryInfoMap::const_iterator iter = retry_info.find("bad:99"); 622 EXPECT_TRUE(iter != retry_info.end()); 623 } 624 625 TEST_P(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) { 626 SpdySessionDependencies session_deps( 627 GetParam(), ProxyService::CreateDirect()); 628 629 StaticSocketDataProvider socket_data; 630 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 631 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 632 633 SSLSocketDataProvider ssl(ASYNC, OK); 634 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl); 635 636 scoped_refptr<HttpNetworkSession> session( 637 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 638 639 // Set an existing SpdySession in the pool. 640 HostPortPair host_port_pair("www.google.com", 443); 641 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), 642 PRIVACY_MODE_ENABLED); 643 644 HttpRequestInfo request_info; 645 request_info.method = "GET"; 646 request_info.url = GURL("https://www.google.com"); 647 request_info.load_flags = 0; 648 request_info.privacy_mode = PRIVACY_MODE_DISABLED; 649 650 SSLConfig ssl_config; 651 StreamRequestWaiter waiter; 652 scoped_ptr<HttpStreamRequest> request( 653 session->http_stream_factory()->RequestStream( 654 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, 655 &waiter, BoundNetLog())); 656 waiter.WaitForStream(); 657 658 // The stream shouldn't come from spdy as we are using different privacy mode 659 EXPECT_FALSE(request->using_spdy()); 660 661 SSLConfig used_ssl_config = waiter.used_ssl_config(); 662 EXPECT_EQ(used_ssl_config.channel_id_enabled, ssl_config.channel_id_enabled); 663 } 664 665 namespace { 666 // Return count of distinct groups in given socket pool. 667 int GetSocketPoolGroupCount(ClientSocketPool* pool) { 668 int count = 0; 669 scoped_ptr<base::DictionaryValue> dict(pool->GetInfoAsValue("", "", false)); 670 EXPECT_TRUE(dict != NULL); 671 base::DictionaryValue* groups = NULL; 672 if (dict->GetDictionary("groups", &groups) && (groups != NULL)) { 673 count = static_cast<int>(groups->size()); 674 } 675 return count; 676 } 677 } // namespace 678 679 TEST_P(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) { 680 SpdySessionDependencies session_deps( 681 GetParam(), ProxyService::CreateDirect()); 682 683 StaticSocketDataProvider socket_data; 684 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 685 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 686 687 SSLSocketDataProvider ssl(ASYNC, OK); 688 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl); 689 690 scoped_refptr<HttpNetworkSession> session( 691 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 692 SSLClientSocketPool* ssl_pool = session->GetSSLSocketPool( 693 HttpNetworkSession::NORMAL_SOCKET_POOL); 694 695 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0); 696 697 HttpRequestInfo request_info; 698 request_info.method = "GET"; 699 request_info.url = GURL("https://www.google.com"); 700 request_info.load_flags = 0; 701 request_info.privacy_mode = PRIVACY_MODE_DISABLED; 702 703 SSLConfig ssl_config; 704 StreamRequestWaiter waiter; 705 706 scoped_ptr<HttpStreamRequest> request1( 707 session->http_stream_factory()->RequestStream( 708 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, 709 &waiter, BoundNetLog())); 710 waiter.WaitForStream(); 711 712 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1); 713 714 scoped_ptr<HttpStreamRequest> request2( 715 session->http_stream_factory()->RequestStream( 716 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, 717 &waiter, BoundNetLog())); 718 waiter.WaitForStream(); 719 720 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1); 721 722 request_info.privacy_mode = PRIVACY_MODE_ENABLED; 723 scoped_ptr<HttpStreamRequest> request3( 724 session->http_stream_factory()->RequestStream( 725 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, 726 &waiter, BoundNetLog())); 727 waiter.WaitForStream(); 728 729 EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2); 730 } 731 732 TEST_P(HttpStreamFactoryTest, GetLoadState) { 733 SpdySessionDependencies session_deps( 734 GetParam(), ProxyService::CreateDirect()); 735 736 StaticSocketDataProvider socket_data; 737 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 738 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 739 740 scoped_refptr<HttpNetworkSession> session( 741 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 742 743 HttpRequestInfo request_info; 744 request_info.method = "GET"; 745 request_info.url = GURL("http://www.google.com"); 746 747 SSLConfig ssl_config; 748 StreamRequestWaiter waiter; 749 scoped_ptr<HttpStreamRequest> request( 750 session->http_stream_factory()->RequestStream( 751 request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, 752 &waiter, BoundNetLog())); 753 754 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState()); 755 756 waiter.WaitForStream(); 757 } 758 759 TEST_P(HttpStreamFactoryTest, RequestHttpStream) { 760 SpdySessionDependencies session_deps( 761 GetParam(), ProxyService::CreateDirect()); 762 763 StaticSocketDataProvider socket_data; 764 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 765 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 766 767 scoped_refptr<HttpNetworkSession> session( 768 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 769 770 // Now request a stream. It should succeed using the second proxy in the 771 // list. 772 HttpRequestInfo request_info; 773 request_info.method = "GET"; 774 request_info.url = GURL("http://www.google.com"); 775 request_info.load_flags = 0; 776 777 SSLConfig ssl_config; 778 StreamRequestWaiter waiter; 779 scoped_ptr<HttpStreamRequest> request( 780 session->http_stream_factory()->RequestStream( 781 request_info, 782 DEFAULT_PRIORITY, 783 ssl_config, 784 ssl_config, 785 &waiter, 786 BoundNetLog())); 787 waiter.WaitForStream(); 788 EXPECT_TRUE(waiter.stream_done()); 789 ASSERT_TRUE(NULL != waiter.stream()); 790 EXPECT_TRUE(NULL == waiter.websocket_stream()); 791 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream()); 792 793 EXPECT_EQ(1, GetSocketPoolGroupCount( 794 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 795 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( 796 HttpNetworkSession::NORMAL_SOCKET_POOL))); 797 EXPECT_EQ(0, GetSocketPoolGroupCount( 798 session->GetTransportSocketPool( 799 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 800 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( 801 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 802 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 803 } 804 805 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverSSL) { 806 SpdySessionDependencies session_deps( 807 GetParam(), ProxyService::CreateDirect()); 808 809 MockRead mock_read(ASYNC, OK); 810 StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0); 811 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 812 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 813 814 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); 815 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); 816 817 scoped_refptr<HttpNetworkSession> session( 818 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 819 820 // Now request a stream. 821 HttpRequestInfo request_info; 822 request_info.method = "GET"; 823 request_info.url = GURL("https://www.google.com"); 824 request_info.load_flags = 0; 825 826 SSLConfig ssl_config; 827 StreamRequestWaiter waiter; 828 scoped_ptr<HttpStreamRequest> request( 829 session->http_stream_factory()->RequestStream( 830 request_info, 831 DEFAULT_PRIORITY, 832 ssl_config, 833 ssl_config, 834 &waiter, 835 BoundNetLog())); 836 waiter.WaitForStream(); 837 EXPECT_TRUE(waiter.stream_done()); 838 ASSERT_TRUE(NULL != waiter.stream()); 839 EXPECT_TRUE(NULL == waiter.websocket_stream()); 840 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream()); 841 EXPECT_EQ(1, GetSocketPoolGroupCount( 842 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 843 EXPECT_EQ(1, GetSocketPoolGroupCount( 844 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 845 EXPECT_EQ(0, GetSocketPoolGroupCount( 846 session->GetTransportSocketPool( 847 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 848 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( 849 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 850 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 851 } 852 853 TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) { 854 SpdySessionDependencies session_deps( 855 GetParam(), ProxyService::CreateFixed("myproxy:8888")); 856 857 StaticSocketDataProvider socket_data; 858 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 859 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 860 861 scoped_refptr<HttpNetworkSession> session( 862 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 863 864 // Now request a stream. It should succeed using the second proxy in the 865 // list. 866 HttpRequestInfo request_info; 867 request_info.method = "GET"; 868 request_info.url = GURL("http://www.google.com"); 869 request_info.load_flags = 0; 870 871 SSLConfig ssl_config; 872 StreamRequestWaiter waiter; 873 scoped_ptr<HttpStreamRequest> request( 874 session->http_stream_factory()->RequestStream( 875 request_info, 876 DEFAULT_PRIORITY, 877 ssl_config, 878 ssl_config, 879 &waiter, 880 BoundNetLog())); 881 waiter.WaitForStream(); 882 EXPECT_TRUE(waiter.stream_done()); 883 ASSERT_TRUE(NULL != waiter.stream()); 884 EXPECT_TRUE(NULL == waiter.websocket_stream()); 885 EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream()); 886 EXPECT_EQ(0, GetSocketPoolGroupCount( 887 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 888 EXPECT_EQ(0, GetSocketPoolGroupCount( 889 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 890 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy( 891 HttpNetworkSession::NORMAL_SOCKET_POOL, 892 HostPortPair("myproxy", 8888)))); 893 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( 894 HttpNetworkSession::NORMAL_SOCKET_POOL, 895 HostPortPair("myproxy", 8888)))); 896 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy( 897 HttpNetworkSession::WEBSOCKET_SOCKET_POOL, 898 HostPortPair("myproxy", 8888)))); 899 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( 900 HttpNetworkSession::WEBSOCKET_SOCKET_POOL, 901 HostPortPair("myproxy", 8888)))); 902 EXPECT_FALSE(waiter.used_proxy_info().is_direct()); 903 } 904 905 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStream) { 906 SpdySessionDependencies session_deps( 907 GetParam(), ProxyService::CreateDirect()); 908 909 StaticSocketDataProvider socket_data; 910 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 911 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 912 913 scoped_refptr<HttpNetworkSession> session( 914 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 915 916 // Now request a stream. 917 HttpRequestInfo request_info; 918 request_info.method = "GET"; 919 request_info.url = GURL("ws://www.google.com"); 920 request_info.load_flags = 0; 921 922 SSLConfig ssl_config; 923 StreamRequestWaiter waiter; 924 WebSocketStreamCreateHelper create_helper; 925 scoped_ptr<HttpStreamRequest> request( 926 session->http_stream_factory_for_websocket() 927 ->RequestWebSocketHandshakeStream(request_info, 928 DEFAULT_PRIORITY, 929 ssl_config, 930 ssl_config, 931 &waiter, 932 &create_helper, 933 BoundNetLog())); 934 waiter.WaitForStream(); 935 EXPECT_TRUE(waiter.stream_done()); 936 EXPECT_TRUE(NULL == waiter.stream()); 937 ASSERT_TRUE(NULL != waiter.websocket_stream()); 938 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic, 939 waiter.websocket_stream()->type()); 940 EXPECT_EQ(0, GetSocketPoolGroupCount( 941 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 942 EXPECT_EQ(0, GetSocketPoolGroupCount( 943 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 944 EXPECT_EQ(1, GetSocketPoolGroupCount( 945 session->GetTransportSocketPool( 946 HttpNetworkSession::WEBSOCKET_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->GetTransportSocketPool( 997 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 998 EXPECT_EQ(1, GetSocketPoolGroupCount( 999 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1000 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 1001 } 1002 1003 TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicHandshakeStreamOverProxy) { 1004 SpdySessionDependencies session_deps( 1005 GetParam(), ProxyService::CreateFixed("myproxy:8888")); 1006 1007 MockRead read(SYNCHRONOUS, "HTTP/1.0 200 Connection established\r\n\r\n"); 1008 StaticSocketDataProvider socket_data(&read, 1, 0, 0); 1009 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 1010 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 1011 1012 scoped_refptr<HttpNetworkSession> session( 1013 SpdySessionDependencies::SpdyCreateSession(&session_deps)); 1014 1015 // Now request a stream. 1016 HttpRequestInfo request_info; 1017 request_info.method = "GET"; 1018 request_info.url = GURL("ws://www.google.com"); 1019 request_info.load_flags = 0; 1020 1021 SSLConfig ssl_config; 1022 StreamRequestWaiter waiter; 1023 WebSocketStreamCreateHelper create_helper; 1024 scoped_ptr<HttpStreamRequest> request( 1025 session->http_stream_factory_for_websocket() 1026 ->RequestWebSocketHandshakeStream(request_info, 1027 DEFAULT_PRIORITY, 1028 ssl_config, 1029 ssl_config, 1030 &waiter, 1031 &create_helper, 1032 BoundNetLog())); 1033 waiter.WaitForStream(); 1034 EXPECT_TRUE(waiter.stream_done()); 1035 EXPECT_TRUE(NULL == waiter.stream()); 1036 ASSERT_TRUE(NULL != waiter.websocket_stream()); 1037 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic, 1038 waiter.websocket_stream()->type()); 1039 EXPECT_EQ(0, GetSocketPoolGroupCount( 1040 session->GetTransportSocketPool( 1041 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1042 EXPECT_EQ(0, GetSocketPoolGroupCount( 1043 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1044 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy( 1045 HttpNetworkSession::NORMAL_SOCKET_POOL, 1046 HostPortPair("myproxy", 8888)))); 1047 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( 1048 HttpNetworkSession::NORMAL_SOCKET_POOL, 1049 HostPortPair("myproxy", 8888)))); 1050 EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy( 1051 HttpNetworkSession::WEBSOCKET_SOCKET_POOL, 1052 HostPortPair("myproxy", 8888)))); 1053 EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( 1054 HttpNetworkSession::WEBSOCKET_SOCKET_POOL, 1055 HostPortPair("myproxy", 8888)))); 1056 EXPECT_FALSE(waiter.used_proxy_info().is_direct()); 1057 } 1058 1059 TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) { 1060 SpdySessionDependencies session_deps(GetParam(), 1061 ProxyService::CreateDirect()); 1062 1063 MockRead mock_read(ASYNC, OK); 1064 DeterministicSocketData socket_data(&mock_read, 1, NULL, 0); 1065 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 1066 session_deps.deterministic_socket_factory->AddSocketDataProvider( 1067 &socket_data); 1068 1069 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); 1070 ssl_socket_data.SetNextProto(GetParam()); 1071 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider( 1072 &ssl_socket_data); 1073 1074 HostPortPair host_port_pair("www.google.com", 443); 1075 scoped_refptr<HttpNetworkSession> 1076 session(SpdySessionDependencies::SpdyCreateSessionDeterministic( 1077 &session_deps)); 1078 1079 // Now request a stream. 1080 HttpRequestInfo request_info; 1081 request_info.method = "GET"; 1082 request_info.url = GURL("https://www.google.com"); 1083 request_info.load_flags = 0; 1084 1085 SSLConfig ssl_config; 1086 StreamRequestWaiter waiter; 1087 scoped_ptr<HttpStreamRequest> request( 1088 session->http_stream_factory()->RequestStream( 1089 request_info, 1090 DEFAULT_PRIORITY, 1091 ssl_config, 1092 ssl_config, 1093 &waiter, 1094 BoundNetLog())); 1095 waiter.WaitForStream(); 1096 EXPECT_TRUE(waiter.stream_done()); 1097 EXPECT_TRUE(NULL == waiter.websocket_stream()); 1098 ASSERT_TRUE(NULL != waiter.stream()); 1099 EXPECT_TRUE(waiter.stream()->IsSpdyHttpStream()); 1100 EXPECT_EQ(1, GetSocketPoolGroupCount( 1101 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1102 EXPECT_EQ(1, GetSocketPoolGroupCount( 1103 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1104 EXPECT_EQ(0, GetSocketPoolGroupCount( 1105 session->GetTransportSocketPool( 1106 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1107 EXPECT_EQ(0, GetSocketPoolGroupCount( 1108 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1109 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 1110 } 1111 1112 // TODO(ricea): This test can be removed once the new WebSocket stack supports 1113 // SPDY. Currently, even if we connect to a SPDY-supporting server, we need to 1114 // use plain SSL. 1115 TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyHandshakeStreamButGetSSL) { 1116 SpdySessionDependencies session_deps(GetParam(), 1117 ProxyService::CreateDirect()); 1118 1119 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING); 1120 StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0); 1121 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 1122 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 1123 1124 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); 1125 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); 1126 1127 HostPortPair host_port_pair("www.google.com", 80); 1128 scoped_refptr<HttpNetworkSession> 1129 session(SpdySessionDependencies::SpdyCreateSession(&session_deps)); 1130 1131 // Now request a stream. 1132 HttpRequestInfo request_info; 1133 request_info.method = "GET"; 1134 request_info.url = GURL("wss://www.google.com"); 1135 request_info.load_flags = 0; 1136 1137 SSLConfig ssl_config; 1138 StreamRequestWaiter waiter1; 1139 WebSocketStreamCreateHelper create_helper; 1140 scoped_ptr<HttpStreamRequest> request1( 1141 session->http_stream_factory_for_websocket() 1142 ->RequestWebSocketHandshakeStream(request_info, 1143 DEFAULT_PRIORITY, 1144 ssl_config, 1145 ssl_config, 1146 &waiter1, 1147 &create_helper, 1148 BoundNetLog())); 1149 waiter1.WaitForStream(); 1150 EXPECT_TRUE(waiter1.stream_done()); 1151 ASSERT_TRUE(NULL != waiter1.websocket_stream()); 1152 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeBasic, 1153 waiter1.websocket_stream()->type()); 1154 EXPECT_TRUE(NULL == waiter1.stream()); 1155 1156 EXPECT_EQ(0, GetSocketPoolGroupCount( 1157 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1158 EXPECT_EQ(0, GetSocketPoolGroupCount( 1159 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1160 EXPECT_EQ(1, GetSocketPoolGroupCount( 1161 session->GetTransportSocketPool( 1162 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1163 EXPECT_EQ(1, GetSocketPoolGroupCount( 1164 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1165 EXPECT_TRUE(waiter1.used_proxy_info().is_direct()); 1166 } 1167 1168 // TODO(ricea): Re-enable once WebSocket-over-SPDY is implemented. 1169 TEST_P(HttpStreamFactoryTest, DISABLED_RequestWebSocketSpdyHandshakeStream) { 1170 SpdySessionDependencies session_deps(GetParam(), 1171 ProxyService::CreateDirect()); 1172 1173 MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING); 1174 StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0); 1175 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 1176 session_deps.socket_factory->AddSocketDataProvider(&socket_data); 1177 1178 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); 1179 ssl_socket_data.SetNextProto(GetParam()); 1180 session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); 1181 1182 HostPortPair host_port_pair("www.google.com", 80); 1183 scoped_refptr<HttpNetworkSession> 1184 session(SpdySessionDependencies::SpdyCreateSession(&session_deps)); 1185 1186 // Now request a stream. 1187 HttpRequestInfo request_info; 1188 request_info.method = "GET"; 1189 request_info.url = GURL("wss://www.google.com"); 1190 request_info.load_flags = 0; 1191 1192 SSLConfig ssl_config; 1193 StreamRequestWaiter waiter1; 1194 WebSocketStreamCreateHelper create_helper; 1195 scoped_ptr<HttpStreamRequest> request1( 1196 session->http_stream_factory_for_websocket() 1197 ->RequestWebSocketHandshakeStream(request_info, 1198 DEFAULT_PRIORITY, 1199 ssl_config, 1200 ssl_config, 1201 &waiter1, 1202 &create_helper, 1203 BoundNetLog())); 1204 waiter1.WaitForStream(); 1205 EXPECT_TRUE(waiter1.stream_done()); 1206 ASSERT_TRUE(NULL != waiter1.websocket_stream()); 1207 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy, 1208 waiter1.websocket_stream()->type()); 1209 EXPECT_TRUE(NULL == waiter1.stream()); 1210 1211 StreamRequestWaiter waiter2; 1212 scoped_ptr<HttpStreamRequest> request2( 1213 session->http_stream_factory_for_websocket() 1214 ->RequestWebSocketHandshakeStream(request_info, 1215 DEFAULT_PRIORITY, 1216 ssl_config, 1217 ssl_config, 1218 &waiter2, 1219 &create_helper, 1220 BoundNetLog())); 1221 waiter2.WaitForStream(); 1222 EXPECT_TRUE(waiter2.stream_done()); 1223 ASSERT_TRUE(NULL != waiter2.websocket_stream()); 1224 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy, 1225 waiter2.websocket_stream()->type()); 1226 EXPECT_TRUE(NULL == waiter2.stream()); 1227 EXPECT_NE(waiter2.websocket_stream(), waiter1.websocket_stream()); 1228 EXPECT_EQ(static_cast<WebSocketSpdyHandshakeStream*>( 1229 waiter2.websocket_stream())->spdy_session(), 1230 static_cast<WebSocketSpdyHandshakeStream*>( 1231 waiter1.websocket_stream())->spdy_session()); 1232 1233 EXPECT_EQ(0, GetSocketPoolGroupCount( 1234 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1235 EXPECT_EQ(0, GetSocketPoolGroupCount( 1236 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1237 EXPECT_EQ(1, GetSocketPoolGroupCount( 1238 session->GetTransportSocketPool( 1239 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1240 EXPECT_EQ(1, GetSocketPoolGroupCount( 1241 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1242 EXPECT_TRUE(waiter1.used_proxy_info().is_direct()); 1243 } 1244 1245 // TODO(ricea): Re-enable once WebSocket over SPDY is implemented. 1246 TEST_P(HttpStreamFactoryTest, DISABLED_OrphanedWebSocketStream) { 1247 SpdySessionDependencies session_deps(GetParam(), 1248 ProxyService::CreateDirect()); 1249 session_deps.use_alternate_protocols = true; 1250 1251 MockRead mock_read(ASYNC, OK); 1252 DeterministicSocketData socket_data(&mock_read, 1, NULL, 0); 1253 socket_data.set_connect_data(MockConnect(ASYNC, OK)); 1254 session_deps.deterministic_socket_factory->AddSocketDataProvider( 1255 &socket_data); 1256 1257 MockRead mock_read2(ASYNC, OK); 1258 DeterministicSocketData socket_data2(&mock_read2, 1, NULL, 0); 1259 socket_data2.set_connect_data(MockConnect(ASYNC, ERR_IO_PENDING)); 1260 session_deps.deterministic_socket_factory->AddSocketDataProvider( 1261 &socket_data2); 1262 1263 SSLSocketDataProvider ssl_socket_data(ASYNC, OK); 1264 ssl_socket_data.SetNextProto(GetParam()); 1265 session_deps.deterministic_socket_factory->AddSSLSocketDataProvider( 1266 &ssl_socket_data); 1267 1268 scoped_refptr<HttpNetworkSession> 1269 session(SpdySessionDependencies::SpdyCreateSessionDeterministic( 1270 &session_deps)); 1271 1272 // Now request a stream. 1273 HttpRequestInfo request_info; 1274 request_info.method = "GET"; 1275 request_info.url = GURL("ws://www.google.com:8888"); 1276 request_info.load_flags = 0; 1277 1278 session->http_server_properties()->SetAlternateProtocol( 1279 HostPortPair("www.google.com", 8888), 1280 9999, 1281 NPN_SPDY_3); 1282 1283 SSLConfig ssl_config; 1284 StreamRequestWaiter waiter; 1285 WebSocketStreamCreateHelper create_helper; 1286 scoped_ptr<HttpStreamRequest> request( 1287 session->http_stream_factory_for_websocket() 1288 ->RequestWebSocketHandshakeStream(request_info, 1289 DEFAULT_PRIORITY, 1290 ssl_config, 1291 ssl_config, 1292 &waiter, 1293 &create_helper, 1294 BoundNetLog())); 1295 waiter.WaitForStream(); 1296 EXPECT_TRUE(waiter.stream_done()); 1297 EXPECT_TRUE(NULL == waiter.stream()); 1298 ASSERT_TRUE(NULL != waiter.websocket_stream()); 1299 EXPECT_EQ(MockWebSocketHandshakeStream::kStreamTypeSpdy, 1300 waiter.websocket_stream()->type()); 1301 1302 // Make sure that there was an alternative connection 1303 // which consumes extra connections. 1304 EXPECT_EQ(0, GetSocketPoolGroupCount( 1305 session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1306 EXPECT_EQ(0, GetSocketPoolGroupCount( 1307 session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); 1308 EXPECT_EQ(2, GetSocketPoolGroupCount( 1309 session->GetTransportSocketPool( 1310 HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1311 EXPECT_EQ(1, GetSocketPoolGroupCount( 1312 session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); 1313 EXPECT_TRUE(waiter.used_proxy_info().is_direct()); 1314 1315 // Make sure there is no orphaned job. it is already canceled. 1316 ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>( 1317 session->http_stream_factory_for_websocket())->num_orphaned_jobs()); 1318 } 1319 1320 } // namespace 1321 1322 } // namespace net 1323