diff options
Diffstat (limited to 'chromium/net/http/http_stream_factory_impl_unittest.cc')
-rw-r--r-- | chromium/net/http/http_stream_factory_impl_unittest.cc | 1226 |
1 files changed, 1226 insertions, 0 deletions
diff --git a/chromium/net/http/http_stream_factory_impl_unittest.cc b/chromium/net/http/http_stream_factory_impl_unittest.cc new file mode 100644 index 00000000000..f378c93ea18 --- /dev/null +++ b/chromium/net/http/http_stream_factory_impl_unittest.cc @@ -0,0 +1,1226 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/http/http_stream_factory_impl.h" + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "net/base/net_log.h" +#include "net/base/test_completion_callback.h" +#include "net/cert/mock_cert_verifier.h" +#include "net/dns/mock_host_resolver.h" +#include "net/http/http_auth_handler_factory.h" +#include "net/http/http_network_session.h" +#include "net/http/http_network_session_peer.h" +#include "net/http/http_network_transaction.h" +#include "net/http/http_request_info.h" +#include "net/http/http_server_properties.h" +#include "net/http/http_server_properties_impl.h" +#include "net/http/http_stream.h" +#include "net/http/transport_security_state.h" +#include "net/proxy/proxy_info.h" +#include "net/proxy/proxy_service.h" +#include "net/socket/client_socket_handle.h" +#include "net/socket/mock_client_socket_pool_manager.h" +#include "net/socket/next_proto.h" +#include "net/socket/socket_test_util.h" +#include "net/spdy/spdy_session.h" +#include "net/spdy/spdy_session_pool.h" +#include "net/spdy/spdy_test_util_common.h" +#include "net/ssl/ssl_config_service.h" +#include "net/ssl/ssl_config_service_defaults.h" +// This file can be included from net/http even though +// it is in net/websockets because it doesn't +// introduce any link dependency to net/websockets. +#include "net/websockets/websocket_stream_base.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { + +namespace { + +class UseAlternateProtocolsScopedSetter { + public: + explicit UseAlternateProtocolsScopedSetter(bool use_alternate_protocols) + : use_alternate_protocols_(HttpStreamFactory::use_alternate_protocols()) { + HttpStreamFactory::set_use_alternate_protocols(use_alternate_protocols); + } + ~UseAlternateProtocolsScopedSetter() { + HttpStreamFactory::set_use_alternate_protocols(use_alternate_protocols_); + } + + private: + bool use_alternate_protocols_; +}; + +class MockWebSocketStream : public WebSocketStreamBase { + public: + enum StreamType { + kStreamTypeBasic, + kStreamTypeSpdy, + }; + + explicit MockWebSocketStream(StreamType type) : type_(type) {} + + virtual ~MockWebSocketStream() {} + + virtual WebSocketStream* AsWebSocketStream() OVERRIDE { return NULL; } + + StreamType type() const { + return type_; + } + + private: + const StreamType type_; +}; + +// HttpStreamFactoryImpl subclass that can wait until a preconnect is complete. +class MockHttpStreamFactoryImplForPreconnect : public HttpStreamFactoryImpl { + public: + MockHttpStreamFactoryImplForPreconnect(HttpNetworkSession* session, + bool for_websockets) + : HttpStreamFactoryImpl(session, for_websockets), + preconnect_done_(false), + waiting_for_preconnect_(false) {} + + + void WaitForPreconnects() { + while (!preconnect_done_) { + waiting_for_preconnect_ = true; + base::MessageLoop::current()->Run(); + waiting_for_preconnect_ = false; + } + } + + private: + // HttpStreamFactoryImpl methods. + virtual void OnPreconnectsCompleteInternal() OVERRIDE { + preconnect_done_ = true; + if (waiting_for_preconnect_) + base::MessageLoop::current()->Quit(); + } + + bool preconnect_done_; + bool waiting_for_preconnect_; +}; + +class StreamRequestWaiter : public HttpStreamRequest::Delegate { + public: + StreamRequestWaiter() + : waiting_for_stream_(false), + stream_done_(false) {} + + // HttpStreamRequest::Delegate + + virtual void OnStreamReady( + const SSLConfig& used_ssl_config, + const ProxyInfo& used_proxy_info, + HttpStreamBase* stream) OVERRIDE { + stream_done_ = true; + if (waiting_for_stream_) + base::MessageLoop::current()->Quit(); + stream_.reset(stream); + used_ssl_config_ = used_ssl_config; + used_proxy_info_ = used_proxy_info; + } + + virtual void OnWebSocketStreamReady( + const SSLConfig& used_ssl_config, + const ProxyInfo& used_proxy_info, + WebSocketStreamBase* stream) OVERRIDE { + stream_done_ = true; + if (waiting_for_stream_) + base::MessageLoop::current()->Quit(); + websocket_stream_.reset(stream); + used_ssl_config_ = used_ssl_config; + used_proxy_info_ = used_proxy_info; + } + + virtual void OnStreamFailed( + int status, + const SSLConfig& used_ssl_config) OVERRIDE {} + + virtual void OnCertificateError( + int status, + const SSLConfig& used_ssl_config, + const SSLInfo& ssl_info) OVERRIDE {} + + virtual void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response, + const SSLConfig& used_ssl_config, + const ProxyInfo& used_proxy_info, + HttpAuthController* auth_controller) OVERRIDE {} + + virtual void OnNeedsClientAuth(const SSLConfig& used_ssl_config, + SSLCertRequestInfo* cert_info) OVERRIDE {} + + virtual void OnHttpsProxyTunnelResponse(const HttpResponseInfo& response_info, + const SSLConfig& used_ssl_config, + const ProxyInfo& used_proxy_info, + HttpStreamBase* stream) OVERRIDE {} + + void WaitForStream() { + while (!stream_done_) { + waiting_for_stream_ = true; + base::MessageLoop::current()->Run(); + waiting_for_stream_ = false; + } + } + + const SSLConfig& used_ssl_config() const { + return used_ssl_config_; + } + + const ProxyInfo& used_proxy_info() const { + return used_proxy_info_; + } + + HttpStreamBase* stream() { + return stream_.get(); + } + + MockWebSocketStream* websocket_stream() { + return static_cast<MockWebSocketStream*>(websocket_stream_.get()); + } + + bool stream_done() const { return stream_done_; } + + private: + bool waiting_for_stream_; + bool stream_done_; + scoped_ptr<HttpStreamBase> stream_; + scoped_ptr<WebSocketStreamBase> websocket_stream_; + SSLConfig used_ssl_config_; + ProxyInfo used_proxy_info_; + + DISALLOW_COPY_AND_ASSIGN(StreamRequestWaiter); +}; + +class WebSocketSpdyStream : public MockWebSocketStream { + public: + explicit WebSocketSpdyStream(const base::WeakPtr<SpdySession>& spdy_session) + : MockWebSocketStream(kStreamTypeSpdy), spdy_session_(spdy_session) {} + + virtual ~WebSocketSpdyStream() {} + + SpdySession* spdy_session() { return spdy_session_.get(); } + + private: + base::WeakPtr<SpdySession> spdy_session_; +}; + +class WebSocketBasicStream : public MockWebSocketStream { + public: + explicit WebSocketBasicStream(ClientSocketHandle* connection) + : MockWebSocketStream(kStreamTypeBasic), connection_(connection) {} + + virtual ~WebSocketBasicStream() { + connection_->socket()->Disconnect(); + } + + ClientSocketHandle* connection() { return connection_.get(); } + + private: + scoped_ptr<ClientSocketHandle> connection_; +}; + +class WebSocketStreamFactory : public WebSocketStreamBase::Factory { + public: + virtual ~WebSocketStreamFactory() {} + + virtual WebSocketStreamBase* CreateBasicStream(ClientSocketHandle* connection, + bool using_proxy) OVERRIDE { + return new WebSocketBasicStream(connection); + } + + virtual WebSocketStreamBase* CreateSpdyStream( + const base::WeakPtr<SpdySession>& spdy_session, + bool use_relative_url) OVERRIDE { + return new WebSocketSpdyStream(spdy_session); + } +}; + +struct TestCase { + int num_streams; + bool ssl; +}; + +TestCase kTests[] = { + { 1, false }, + { 2, false }, + { 1, true}, + { 2, true}, +}; + +void PreconnectHelperForURL(int num_streams, + const GURL& url, + HttpNetworkSession* session) { + HttpNetworkSessionPeer peer(session); + MockHttpStreamFactoryImplForPreconnect* mock_factory = + new MockHttpStreamFactoryImplForPreconnect(session, false); + peer.SetHttpStreamFactory(mock_factory); + SSLConfig ssl_config; + session->ssl_config_service()->GetSSLConfig(&ssl_config); + + HttpRequestInfo request; + request.method = "GET"; + request.url = url; + request.load_flags = 0; + + session->http_stream_factory()->PreconnectStreams( + num_streams, request, DEFAULT_PRIORITY, ssl_config, ssl_config); + mock_factory->WaitForPreconnects(); +}; + +void PreconnectHelper(const TestCase& test, + HttpNetworkSession* session) { + GURL url = test.ssl ? GURL("https://www.google.com") : + GURL("http://www.google.com"); + PreconnectHelperForURL(test.num_streams, url, session); +}; + +template<typename ParentPool> +class CapturePreconnectsSocketPool : public ParentPool { + public: + CapturePreconnectsSocketPool(HostResolver* host_resolver, + CertVerifier* cert_verifier); + + int last_num_streams() const { + return last_num_streams_; + } + + virtual int RequestSocket(const std::string& group_name, + const void* socket_params, + RequestPriority priority, + ClientSocketHandle* handle, + const CompletionCallback& callback, + const BoundNetLog& net_log) OVERRIDE { + ADD_FAILURE(); + return ERR_UNEXPECTED; + } + + virtual void RequestSockets(const std::string& group_name, + const void* socket_params, + int num_sockets, + const BoundNetLog& net_log) OVERRIDE { + last_num_streams_ = num_sockets; + } + + virtual void CancelRequest(const std::string& group_name, + ClientSocketHandle* handle) OVERRIDE { + ADD_FAILURE(); + } + virtual void ReleaseSocket(const std::string& group_name, + scoped_ptr<StreamSocket> socket, + int id) OVERRIDE { + ADD_FAILURE(); + } + virtual void CloseIdleSockets() OVERRIDE { + ADD_FAILURE(); + } + virtual int IdleSocketCount() const OVERRIDE { + ADD_FAILURE(); + return 0; + } + virtual int IdleSocketCountInGroup( + const std::string& group_name) const OVERRIDE { + ADD_FAILURE(); + return 0; + } + virtual LoadState GetLoadState( + const std::string& group_name, + const ClientSocketHandle* handle) const OVERRIDE { + ADD_FAILURE(); + return LOAD_STATE_IDLE; + } + virtual base::TimeDelta ConnectionTimeout() const OVERRIDE { + return base::TimeDelta(); + } + + private: + int last_num_streams_; +}; + +typedef CapturePreconnectsSocketPool<TransportClientSocketPool> +CapturePreconnectsTransportSocketPool; +typedef CapturePreconnectsSocketPool<HttpProxyClientSocketPool> +CapturePreconnectsHttpProxySocketPool; +typedef CapturePreconnectsSocketPool<SOCKSClientSocketPool> +CapturePreconnectsSOCKSSocketPool; +typedef CapturePreconnectsSocketPool<SSLClientSocketPool> +CapturePreconnectsSSLSocketPool; + +template<typename ParentPool> +CapturePreconnectsSocketPool<ParentPool>::CapturePreconnectsSocketPool( + HostResolver* host_resolver, CertVerifier* /* cert_verifier */) + : ParentPool(0, 0, NULL, host_resolver, NULL, NULL), + last_num_streams_(-1) {} + +template<> +CapturePreconnectsHttpProxySocketPool::CapturePreconnectsSocketPool( + HostResolver* host_resolver, CertVerifier* /* cert_verifier */) + : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL), + last_num_streams_(-1) {} + +template <> +CapturePreconnectsSSLSocketPool::CapturePreconnectsSocketPool( + HostResolver* host_resolver, + CertVerifier* cert_verifier) + : SSLClientSocketPool(0, + 0, + NULL, + host_resolver, + cert_verifier, + NULL, + NULL, + std::string(), + NULL, + NULL, + NULL, + NULL, + NULL, + NULL), + last_num_streams_(-1) {} + +class HttpStreamFactoryTest : public ::testing::Test, + public ::testing::WithParamInterface<NextProto> { +}; + +INSTANTIATE_TEST_CASE_P( + NextProto, + HttpStreamFactoryTest, + testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, + kProtoHTTP2Draft04)); + +TEST_P(HttpStreamFactoryTest, PreconnectDirect) { + for (size_t i = 0; i < arraysize(kTests); ++i) { + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateDirect()); + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + HttpNetworkSessionPeer peer(session); + CapturePreconnectsTransportSocketPool* transport_conn_pool = + new CapturePreconnectsTransportSocketPool( + session_deps.host_resolver.get(), + session_deps.cert_verifier.get()); + CapturePreconnectsSSLSocketPool* ssl_conn_pool = + new CapturePreconnectsSSLSocketPool( + session_deps.host_resolver.get(), + session_deps.cert_verifier.get()); + MockClientSocketPoolManager* mock_pool_manager = + new MockClientSocketPoolManager; + mock_pool_manager->SetTransportSocketPool(transport_conn_pool); + mock_pool_manager->SetSSLSocketPool(ssl_conn_pool); + peer.SetClientSocketPoolManager(mock_pool_manager); + PreconnectHelper(kTests[i], session.get()); + if (kTests[i].ssl) + EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); + else + EXPECT_EQ(kTests[i].num_streams, transport_conn_pool->last_num_streams()); + } +} + +TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) { + for (size_t i = 0; i < arraysize(kTests); ++i) { + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateFixed("http_proxy")); + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + HttpNetworkSessionPeer peer(session); + HostPortPair proxy_host("http_proxy", 80); + CapturePreconnectsHttpProxySocketPool* http_proxy_pool = + new CapturePreconnectsHttpProxySocketPool( + session_deps.host_resolver.get(), + session_deps.cert_verifier.get()); + CapturePreconnectsSSLSocketPool* ssl_conn_pool = + new CapturePreconnectsSSLSocketPool( + session_deps.host_resolver.get(), + session_deps.cert_verifier.get()); + MockClientSocketPoolManager* mock_pool_manager = + new MockClientSocketPoolManager; + mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool); + mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); + peer.SetClientSocketPoolManager(mock_pool_manager); + PreconnectHelper(kTests[i], session.get()); + if (kTests[i].ssl) + EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); + else + EXPECT_EQ(kTests[i].num_streams, http_proxy_pool->last_num_streams()); + } +} + +TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) { + for (size_t i = 0; i < arraysize(kTests); ++i) { + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateFixed("socks4://socks_proxy:1080")); + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + HttpNetworkSessionPeer peer(session); + HostPortPair proxy_host("socks_proxy", 1080); + CapturePreconnectsSOCKSSocketPool* socks_proxy_pool = + new CapturePreconnectsSOCKSSocketPool( + session_deps.host_resolver.get(), + session_deps.cert_verifier.get()); + CapturePreconnectsSSLSocketPool* ssl_conn_pool = + new CapturePreconnectsSSLSocketPool( + session_deps.host_resolver.get(), + session_deps.cert_verifier.get()); + MockClientSocketPoolManager* mock_pool_manager = + new MockClientSocketPoolManager; + mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_proxy_pool); + mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); + peer.SetClientSocketPoolManager(mock_pool_manager); + PreconnectHelper(kTests[i], session.get()); + if (kTests[i].ssl) + EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); + else + EXPECT_EQ(kTests[i].num_streams, socks_proxy_pool->last_num_streams()); + } +} + +TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) { + for (size_t i = 0; i < arraysize(kTests); ++i) { + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateDirect()); + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + HttpNetworkSessionPeer peer(session); + + // Put a SpdySession in the pool. + HostPortPair host_port_pair("www.google.com", 443); + SpdySessionKey key(host_port_pair, ProxyServer::Direct(), + kPrivacyModeDisabled); + ignore_result(CreateFakeSpdySession(session->spdy_session_pool(), key)); + + CapturePreconnectsTransportSocketPool* transport_conn_pool = + new CapturePreconnectsTransportSocketPool( + session_deps.host_resolver.get(), + session_deps.cert_verifier.get()); + CapturePreconnectsSSLSocketPool* ssl_conn_pool = + new CapturePreconnectsSSLSocketPool( + session_deps.host_resolver.get(), + session_deps.cert_verifier.get()); + MockClientSocketPoolManager* mock_pool_manager = + new MockClientSocketPoolManager; + mock_pool_manager->SetTransportSocketPool(transport_conn_pool); + mock_pool_manager->SetSSLSocketPool(ssl_conn_pool); + peer.SetClientSocketPoolManager(mock_pool_manager); + PreconnectHelper(kTests[i], session.get()); + // We shouldn't be preconnecting if we have an existing session, which is + // the case for https://www.google.com. + if (kTests[i].ssl) + EXPECT_EQ(-1, ssl_conn_pool->last_num_streams()); + else + EXPECT_EQ(kTests[i].num_streams, + transport_conn_pool->last_num_streams()); + } +} + +// Verify that preconnects to unsafe ports are cancelled before they reach +// the SocketPool. +TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) { + ASSERT_FALSE(IsPortAllowedByDefault(7)); + ASSERT_FALSE(IsPortAllowedByOverride(7)); + + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateDirect()); + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + HttpNetworkSessionPeer peer(session); + CapturePreconnectsTransportSocketPool* transport_conn_pool = + new CapturePreconnectsTransportSocketPool( + session_deps.host_resolver.get(), + session_deps.cert_verifier.get()); + MockClientSocketPoolManager* mock_pool_manager = + new MockClientSocketPoolManager; + mock_pool_manager->SetTransportSocketPool(transport_conn_pool); + peer.SetClientSocketPoolManager(mock_pool_manager); + + PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get()); + + EXPECT_EQ(-1, transport_conn_pool->last_num_streams()); +} + +TEST_P(HttpStreamFactoryTest, JobNotifiesProxy) { + const char* kProxyString = "PROXY bad:99; PROXY maybe:80; DIRECT"; + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateFixedFromPacResult(kProxyString)); + + // First connection attempt fails + StaticSocketDataProvider socket_data1; + socket_data1.set_connect_data(MockConnect(ASYNC, ERR_ADDRESS_UNREACHABLE)); + session_deps.socket_factory->AddSocketDataProvider(&socket_data1); + + // Second connection attempt succeeds + StaticSocketDataProvider socket_data2; + socket_data2.set_connect_data(MockConnect(ASYNC, OK)); + session_deps.socket_factory->AddSocketDataProvider(&socket_data2); + + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + + // Now request a stream. It should succeed using the second proxy in the + // list. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("http://www.google.com"); + + SSLConfig ssl_config; + StreamRequestWaiter waiter; + scoped_ptr<HttpStreamRequest> request( + session->http_stream_factory()->RequestStream( + request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, + &waiter, BoundNetLog())); + waiter.WaitForStream(); + + // The proxy that failed should now be known to the proxy_service as bad. + const ProxyRetryInfoMap& retry_info = + session->proxy_service()->proxy_retry_info(); + EXPECT_EQ(1u, retry_info.size()); + ProxyRetryInfoMap::const_iterator iter = retry_info.find("bad:99"); + EXPECT_TRUE(iter != retry_info.end()); +} + +TEST_P(HttpStreamFactoryTest, PrivacyModeDisablesChannelId) { + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateDirect()); + + StaticSocketDataProvider socket_data; + socket_data.set_connect_data(MockConnect(ASYNC, OK)); + session_deps.socket_factory->AddSocketDataProvider(&socket_data); + + SSLSocketDataProvider ssl(ASYNC, OK); + session_deps.socket_factory->AddSSLSocketDataProvider(&ssl); + + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + + // Set an existing SpdySession in the pool. + HostPortPair host_port_pair("www.google.com", 443); + SpdySessionKey key(host_port_pair, ProxyServer::Direct(), + kPrivacyModeEnabled); + + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("https://www.google.com"); + request_info.load_flags = 0; + request_info.privacy_mode = kPrivacyModeDisabled; + + SSLConfig ssl_config; + StreamRequestWaiter waiter; + scoped_ptr<HttpStreamRequest> request( + session->http_stream_factory()->RequestStream( + request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, + &waiter, BoundNetLog())); + waiter.WaitForStream(); + + // The stream shouldn't come from spdy as we are using different privacy mode + EXPECT_FALSE(request->using_spdy()); + + SSLConfig used_ssl_config = waiter.used_ssl_config(); + EXPECT_EQ(used_ssl_config.channel_id_enabled, ssl_config.channel_id_enabled); +} + +namespace { +// Return count of distinct groups in given socket pool. +int GetSocketPoolGroupCount(ClientSocketPool* pool) { + int count = 0; + scoped_ptr<base::DictionaryValue> dict(pool->GetInfoAsValue("", "", false)); + EXPECT_TRUE(dict != NULL); + base::DictionaryValue* groups = NULL; + if (dict->GetDictionary("groups", &groups) && (groups != NULL)) { + count = static_cast<int>(groups->size()); + } + return count; +} +} // namespace + +TEST_P(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) { + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateDirect()); + + StaticSocketDataProvider socket_data; + socket_data.set_connect_data(MockConnect(ASYNC, OK)); + session_deps.socket_factory->AddSocketDataProvider(&socket_data); + + SSLSocketDataProvider ssl(ASYNC, OK); + session_deps.socket_factory->AddSSLSocketDataProvider(&ssl); + + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + SSLClientSocketPool* ssl_pool = session->GetSSLSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL); + + EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 0); + + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("https://www.google.com"); + request_info.load_flags = 0; + request_info.privacy_mode = kPrivacyModeDisabled; + + SSLConfig ssl_config; + StreamRequestWaiter waiter; + + scoped_ptr<HttpStreamRequest> request1( + session->http_stream_factory()->RequestStream( + request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, + &waiter, BoundNetLog())); + waiter.WaitForStream(); + + EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1); + + scoped_ptr<HttpStreamRequest> request2( + session->http_stream_factory()->RequestStream( + request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, + &waiter, BoundNetLog())); + waiter.WaitForStream(); + + EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 1); + + request_info.privacy_mode = kPrivacyModeEnabled; + scoped_ptr<HttpStreamRequest> request3( + session->http_stream_factory()->RequestStream( + request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, + &waiter, BoundNetLog())); + waiter.WaitForStream(); + + EXPECT_EQ(GetSocketPoolGroupCount(ssl_pool), 2); +} + +TEST_P(HttpStreamFactoryTest, GetLoadState) { + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateDirect()); + + StaticSocketDataProvider socket_data; + socket_data.set_connect_data(MockConnect(ASYNC, OK)); + session_deps.socket_factory->AddSocketDataProvider(&socket_data); + + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("http://www.google.com"); + + SSLConfig ssl_config; + StreamRequestWaiter waiter; + scoped_ptr<HttpStreamRequest> request( + session->http_stream_factory()->RequestStream( + request_info, DEFAULT_PRIORITY, ssl_config, ssl_config, + &waiter, BoundNetLog())); + + EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, request->GetLoadState()); + + waiter.WaitForStream(); +} + +TEST_P(HttpStreamFactoryTest, RequestHttpStream) { + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateDirect()); + + StaticSocketDataProvider socket_data; + socket_data.set_connect_data(MockConnect(ASYNC, OK)); + session_deps.socket_factory->AddSocketDataProvider(&socket_data); + + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + + // Now request a stream. It should succeed using the second proxy in the + // list. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("http://www.google.com"); + request_info.load_flags = 0; + + SSLConfig ssl_config; + StreamRequestWaiter waiter; + scoped_ptr<HttpStreamRequest> request( + session->http_stream_factory()->RequestStream( + request_info, + DEFAULT_PRIORITY, + ssl_config, + ssl_config, + &waiter, + BoundNetLog())); + waiter.WaitForStream(); + EXPECT_TRUE(waiter.stream_done()); + ASSERT_TRUE(NULL != waiter.stream()); + EXPECT_TRUE(NULL == waiter.websocket_stream()); + EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream()); + + EXPECT_EQ(1, GetSocketPoolGroupCount( + session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( + HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetTransportSocketPool( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_TRUE(waiter.used_proxy_info().is_direct()); +} + +TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverSSL) { + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateDirect()); + + MockRead mock_read(ASYNC, OK); + StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0); + socket_data.set_connect_data(MockConnect(ASYNC, OK)); + session_deps.socket_factory->AddSocketDataProvider(&socket_data); + + SSLSocketDataProvider ssl_socket_data(ASYNC, OK); + session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); + + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + + // Now request a stream. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("https://www.google.com"); + request_info.load_flags = 0; + + SSLConfig ssl_config; + StreamRequestWaiter waiter; + scoped_ptr<HttpStreamRequest> request( + session->http_stream_factory()->RequestStream( + request_info, + DEFAULT_PRIORITY, + ssl_config, + ssl_config, + &waiter, + BoundNetLog())); + waiter.WaitForStream(); + EXPECT_TRUE(waiter.stream_done()); + ASSERT_TRUE(NULL != waiter.stream()); + EXPECT_TRUE(NULL == waiter.websocket_stream()); + EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream()); + EXPECT_EQ(1, GetSocketPoolGroupCount( + session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(1, GetSocketPoolGroupCount( + session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetTransportSocketPool( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSSLSocketPool( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_TRUE(waiter.used_proxy_info().is_direct()); +} + +TEST_P(HttpStreamFactoryTest, RequestHttpStreamOverProxy) { + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateFixed("myproxy:8888")); + + StaticSocketDataProvider socket_data; + socket_data.set_connect_data(MockConnect(ASYNC, OK)); + session_deps.socket_factory->AddSocketDataProvider(&socket_data); + + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + + // Now request a stream. It should succeed using the second proxy in the + // list. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("http://www.google.com"); + request_info.load_flags = 0; + + SSLConfig ssl_config; + StreamRequestWaiter waiter; + scoped_ptr<HttpStreamRequest> request( + session->http_stream_factory()->RequestStream( + request_info, + DEFAULT_PRIORITY, + ssl_config, + ssl_config, + &waiter, + BoundNetLog())); + waiter.WaitForStream(); + EXPECT_TRUE(waiter.stream_done()); + ASSERT_TRUE(NULL != waiter.stream()); + EXPECT_TRUE(NULL == waiter.websocket_stream()); + EXPECT_FALSE(waiter.stream()->IsSpdyHttpStream()); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy( + HttpNetworkSession::NORMAL_SOCKET_POOL, + HostPortPair("myproxy", 8888)))); + EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( + HttpNetworkSession::NORMAL_SOCKET_POOL, + HostPortPair("myproxy", 8888)))); + EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL, + HostPortPair("myproxy", 8888)))); + EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL, + HostPortPair("myproxy", 8888)))); + EXPECT_FALSE(waiter.used_proxy_info().is_direct()); +} + +TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicStream) { + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateDirect()); + + StaticSocketDataProvider socket_data; + socket_data.set_connect_data(MockConnect(ASYNC, OK)); + session_deps.socket_factory->AddSocketDataProvider(&socket_data); + + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + + // Now request a stream. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("ws://www.google.com"); + request_info.load_flags = 0; + + SSLConfig ssl_config; + StreamRequestWaiter waiter; + WebSocketStreamFactory factory; + scoped_ptr<HttpStreamRequest> request( + session->websocket_stream_factory()->RequestWebSocketStream( + request_info, + DEFAULT_PRIORITY, + ssl_config, + ssl_config, + &waiter, + &factory, + BoundNetLog())); + waiter.WaitForStream(); + EXPECT_TRUE(waiter.stream_done()); + EXPECT_TRUE(NULL == waiter.stream()); + ASSERT_TRUE(NULL != waiter.websocket_stream()); + EXPECT_EQ(MockWebSocketStream::kStreamTypeBasic, + waiter.websocket_stream()->type()); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(1, GetSocketPoolGroupCount( + session->GetTransportSocketPool( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_TRUE(waiter.used_proxy_info().is_direct()); +} + +TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicStreamOverSSL) { + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateDirect()); + + MockRead mock_read(ASYNC, OK); + StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0); + socket_data.set_connect_data(MockConnect(ASYNC, OK)); + session_deps.socket_factory->AddSocketDataProvider(&socket_data); + + SSLSocketDataProvider ssl_socket_data(ASYNC, OK); + session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); + + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + + // Now request a stream. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("wss://www.google.com"); + request_info.load_flags = 0; + + SSLConfig ssl_config; + StreamRequestWaiter waiter; + WebSocketStreamFactory factory; + scoped_ptr<HttpStreamRequest> request( + session->websocket_stream_factory()->RequestWebSocketStream( + request_info, + DEFAULT_PRIORITY, + ssl_config, + ssl_config, + &waiter, + &factory, + BoundNetLog())); + waiter.WaitForStream(); + EXPECT_TRUE(waiter.stream_done()); + EXPECT_TRUE(NULL == waiter.stream()); + ASSERT_TRUE(NULL != waiter.websocket_stream()); + EXPECT_EQ(MockWebSocketStream::kStreamTypeBasic, + waiter.websocket_stream()->type()); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(1, GetSocketPoolGroupCount( + session->GetTransportSocketPool( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ(1, GetSocketPoolGroupCount( + session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_TRUE(waiter.used_proxy_info().is_direct()); +} + +TEST_P(HttpStreamFactoryTest, RequestWebSocketBasicStreamOverProxy) { + SpdySessionDependencies session_deps( + GetParam(), ProxyService::CreateFixed("myproxy:8888")); + + MockRead read(SYNCHRONOUS, "HTTP/1.0 200 Connection established\r\n\r\n"); + StaticSocketDataProvider socket_data(&read, 1, 0, 0); + socket_data.set_connect_data(MockConnect(ASYNC, OK)); + session_deps.socket_factory->AddSocketDataProvider(&socket_data); + + scoped_refptr<HttpNetworkSession> session( + SpdySessionDependencies::SpdyCreateSession(&session_deps)); + + // Now request a stream. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("ws://www.google.com"); + request_info.load_flags = 0; + + SSLConfig ssl_config; + StreamRequestWaiter waiter; + WebSocketStreamFactory factory; + scoped_ptr<HttpStreamRequest> request( + session->websocket_stream_factory()->RequestWebSocketStream( + request_info, + DEFAULT_PRIORITY, + ssl_config, + ssl_config, + &waiter, + &factory, + BoundNetLog())); + waiter.WaitForStream(); + EXPECT_TRUE(waiter.stream_done()); + EXPECT_TRUE(NULL == waiter.stream()); + ASSERT_TRUE(NULL != waiter.websocket_stream()); + EXPECT_EQ(MockWebSocketStream::kStreamTypeBasic, + waiter.websocket_stream()->type()); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetTransportSocketPool( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy( + HttpNetworkSession::NORMAL_SOCKET_POOL, + HostPortPair("myproxy", 8888)))); + EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( + HttpNetworkSession::NORMAL_SOCKET_POOL, + HostPortPair("myproxy", 8888)))); + EXPECT_EQ(1, GetSocketPoolGroupCount(session->GetSocketPoolForHTTPProxy( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL, + HostPortPair("myproxy", 8888)))); + EXPECT_EQ(0, GetSocketPoolGroupCount(session->GetSocketPoolForSSLWithProxy( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL, + HostPortPair("myproxy", 8888)))); + EXPECT_FALSE(waiter.used_proxy_info().is_direct()); +} + +TEST_P(HttpStreamFactoryTest, RequestSpdyHttpStream) { + SpdySessionDependencies session_deps(GetParam(), + ProxyService::CreateDirect()); + + MockRead mock_read(ASYNC, OK); + DeterministicSocketData socket_data(&mock_read, 1, NULL, 0); + socket_data.set_connect_data(MockConnect(ASYNC, OK)); + session_deps.deterministic_socket_factory->AddSocketDataProvider( + &socket_data); + + SSLSocketDataProvider ssl_socket_data(ASYNC, OK); + ssl_socket_data.SetNextProto(GetParam()); + session_deps.deterministic_socket_factory->AddSSLSocketDataProvider( + &ssl_socket_data); + + HostPortPair host_port_pair("www.google.com", 443); + scoped_refptr<HttpNetworkSession> + session(SpdySessionDependencies::SpdyCreateSessionDeterministic( + &session_deps)); + + // Now request a stream. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("https://www.google.com"); + request_info.load_flags = 0; + + SSLConfig ssl_config; + StreamRequestWaiter waiter; + scoped_ptr<HttpStreamRequest> request( + session->http_stream_factory()->RequestStream( + request_info, + DEFAULT_PRIORITY, + ssl_config, + ssl_config, + &waiter, + BoundNetLog())); + waiter.WaitForStream(); + EXPECT_TRUE(waiter.stream_done()); + EXPECT_TRUE(NULL == waiter.websocket_stream()); + ASSERT_TRUE(NULL != waiter.stream()); + EXPECT_TRUE(waiter.stream()->IsSpdyHttpStream()); + EXPECT_EQ(1, GetSocketPoolGroupCount( + session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(1, GetSocketPoolGroupCount( + session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetTransportSocketPool( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_TRUE(waiter.used_proxy_info().is_direct()); +} + +TEST_P(HttpStreamFactoryTest, RequestWebSocketSpdyStream) { + SpdySessionDependencies session_deps(GetParam(), + ProxyService::CreateDirect()); + + MockRead mock_read(SYNCHRONOUS, ERR_IO_PENDING); + StaticSocketDataProvider socket_data(&mock_read, 1, NULL, 0); + socket_data.set_connect_data(MockConnect(ASYNC, OK)); + session_deps.socket_factory->AddSocketDataProvider(&socket_data); + + SSLSocketDataProvider ssl_socket_data(ASYNC, OK); + ssl_socket_data.SetNextProto(GetParam()); + session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); + + HostPortPair host_port_pair("www.google.com", 80); + scoped_refptr<HttpNetworkSession> + session(SpdySessionDependencies::SpdyCreateSession(&session_deps)); + + // Now request a stream. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("wss://www.google.com"); + request_info.load_flags = 0; + + SSLConfig ssl_config; + StreamRequestWaiter waiter1; + WebSocketStreamFactory factory; + scoped_ptr<HttpStreamRequest> request1( + session->websocket_stream_factory()->RequestWebSocketStream( + request_info, + DEFAULT_PRIORITY, + ssl_config, + ssl_config, + &waiter1, + &factory, + BoundNetLog())); + waiter1.WaitForStream(); + EXPECT_TRUE(waiter1.stream_done()); + ASSERT_TRUE(NULL != waiter1.websocket_stream()); + EXPECT_EQ(MockWebSocketStream::kStreamTypeSpdy, + waiter1.websocket_stream()->type()); + EXPECT_TRUE(NULL == waiter1.stream()); + + StreamRequestWaiter waiter2; + scoped_ptr<HttpStreamRequest> request2( + session->websocket_stream_factory()->RequestWebSocketStream( + request_info, + DEFAULT_PRIORITY, + ssl_config, + ssl_config, + &waiter2, + &factory, + BoundNetLog())); + waiter2.WaitForStream(); + EXPECT_TRUE(waiter2.stream_done()); + ASSERT_TRUE(NULL != waiter2.websocket_stream()); + EXPECT_EQ(MockWebSocketStream::kStreamTypeSpdy, + waiter2.websocket_stream()->type()); + EXPECT_TRUE(NULL == waiter2.stream()); + EXPECT_NE(waiter2.websocket_stream(), waiter1.websocket_stream()); + EXPECT_EQ(static_cast<WebSocketSpdyStream*>(waiter2.websocket_stream())-> + spdy_session(), + static_cast<WebSocketSpdyStream*>(waiter1.websocket_stream())-> + spdy_session()); + + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(1, GetSocketPoolGroupCount( + session->GetTransportSocketPool( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ(1, GetSocketPoolGroupCount( + session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_TRUE(waiter1.used_proxy_info().is_direct()); +} + +TEST_P(HttpStreamFactoryTest, OrphanedWebSocketStream) { + UseAlternateProtocolsScopedSetter use_alternate_protocols(true); + SpdySessionDependencies session_deps(GetParam(), + ProxyService::CreateDirect()); + + MockRead mock_read(ASYNC, OK); + DeterministicSocketData socket_data(&mock_read, 1, NULL, 0); + socket_data.set_connect_data(MockConnect(ASYNC, OK)); + session_deps.deterministic_socket_factory->AddSocketDataProvider( + &socket_data); + + MockRead mock_read2(ASYNC, OK); + DeterministicSocketData socket_data2(&mock_read2, 1, NULL, 0); + socket_data2.set_connect_data(MockConnect(ASYNC, ERR_IO_PENDING)); + session_deps.deterministic_socket_factory->AddSocketDataProvider( + &socket_data2); + + SSLSocketDataProvider ssl_socket_data(ASYNC, OK); + ssl_socket_data.SetNextProto(GetParam()); + session_deps.deterministic_socket_factory->AddSSLSocketDataProvider( + &ssl_socket_data); + + scoped_refptr<HttpNetworkSession> + session(SpdySessionDependencies::SpdyCreateSessionDeterministic( + &session_deps)); + + // Now request a stream. + HttpRequestInfo request_info; + request_info.method = "GET"; + request_info.url = GURL("ws://www.google.com:8888"); + request_info.load_flags = 0; + + session->http_server_properties()->SetAlternateProtocol( + HostPortPair("www.google.com", 8888), + 9999, + NPN_SPDY_3); + + SSLConfig ssl_config; + StreamRequestWaiter waiter; + WebSocketStreamFactory factory; + scoped_ptr<HttpStreamRequest> request( + session->websocket_stream_factory()->RequestWebSocketStream( + request_info, + DEFAULT_PRIORITY, + ssl_config, + ssl_config, + &waiter, + &factory, + BoundNetLog())); + waiter.WaitForStream(); + EXPECT_TRUE(waiter.stream_done()); + EXPECT_TRUE(NULL == waiter.stream()); + ASSERT_TRUE(NULL != waiter.websocket_stream()); + EXPECT_EQ(MockWebSocketStream::kStreamTypeSpdy, + waiter.websocket_stream()->type()); + + // Make sure that there was an alternative connection + // which consumes extra connections. + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(0, GetSocketPoolGroupCount( + session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); + EXPECT_EQ(2, GetSocketPoolGroupCount( + session->GetTransportSocketPool( + HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_EQ(1, GetSocketPoolGroupCount( + session->GetSSLSocketPool(HttpNetworkSession::WEBSOCKET_SOCKET_POOL))); + EXPECT_TRUE(waiter.used_proxy_info().is_direct()); + + // Make sure there is no orphaned job. it is already canceled. + ASSERT_EQ(0u, static_cast<HttpStreamFactoryImpl*>( + session->websocket_stream_factory())->num_orphaned_jobs()); +} + +} // namespace + +} // namespace net |