Chromium Code Reviews| Index: net/http/http_stream_factory_impl_unittest.cc |
| diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc |
| index 0200b8f984cbbc2c8649fda32015b8ff7ae21bec..9b3c063e82b148aac79cca392e960305f08f874d 100644 |
| --- a/net/http/http_stream_factory_impl_unittest.cc |
| +++ b/net/http/http_stream_factory_impl_unittest.cc |
| @@ -5,6 +5,7 @@ |
| #include "net/http/http_stream_factory_impl.h" |
| #include <string> |
| +#include <vector> |
| #include "base/basictypes.h" |
| #include "net/base/net_log.h" |
| @@ -16,26 +17,72 @@ |
| #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 MockHttpStreamFactoryImpl : public HttpStreamFactoryImpl { |
| +class UseAlternateProtocolsScopedSetter { |
| public: |
| - MockHttpStreamFactoryImpl(HttpNetworkSession* session) |
| - : HttpStreamFactoryImpl(session), |
| + 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) {} |
| @@ -77,6 +124,19 @@ class StreamRequestWaiter : public HttpStreamRequest::Delegate { |
| 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( |
| @@ -113,20 +173,94 @@ class StreamRequestWaiter : public HttpStreamRequest::Delegate { |
| 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(SpdySession* spdy_session) |
| + : MockWebSocketStream(kStreamTypeSpdy), spdy_session_(spdy_session) {} |
| + |
| + virtual ~WebSocketSpdyStream() {} |
| + |
| + SpdySession* spdy_session() { return spdy_session_.get(); } |
| + |
| + private: |
| + scoped_refptr<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( |
| + SpdySession* spdy_session, |
| + bool use_relative_url) OVERRIDE { |
| + return new WebSocketSpdyStream(spdy_session); |
| + } |
| +}; |
| + |
| +class HttpStreamFactoryForDetectOrphanedJobComplete |
| + : public HttpStreamFactoryImpl { |
| + public: |
| + HttpStreamFactoryForDetectOrphanedJobComplete(HttpNetworkSession* session, |
| + bool for_websockets) |
| + : HttpStreamFactoryImpl(session, for_websockets), counter_(0) {} |
| + |
| + size_t counter() const { return counter_; } |
| + |
| + private: |
| + virtual void OnOrphanedJobComplete(const Job* job) OVERRIDE { |
| + HttpStreamFactoryImpl::OnOrphanedJobComplete(job); |
| + ++counter_; |
| + base::MessageLoop::current()->Quit(); |
| + } |
| + |
| + size_t counter_; |
| +}; |
| + |
| struct SessionDependencies { |
| // Custom proxy service dependency. |
| explicit SessionDependencies(ProxyService* proxy_service) |
| @@ -163,6 +297,7 @@ HttpNetworkSession* CreateSession(SessionDependencies* session_deps) { |
| session_deps->http_auth_handler_factory.get(); |
| params.net_log = session_deps->net_log; |
| params.http_server_properties = &session_deps->http_server_properties; |
| + |
| return new HttpNetworkSession(params); |
| } |
| @@ -182,8 +317,8 @@ void PreconnectHelperForURL(int num_streams, |
| const GURL& url, |
| HttpNetworkSession* session) { |
| HttpNetworkSessionPeer peer(session); |
| - MockHttpStreamFactoryImpl* mock_factory = |
| - new MockHttpStreamFactoryImpl(session); |
| + MockHttpStreamFactoryImplForPreconnect* mock_factory = |
| + new MockHttpStreamFactoryImplForPreconnect(session, false); |
| peer.SetHttpStreamFactory(mock_factory); |
| SSLConfig ssl_config; |
| session->ssl_config_service()->GetSSLConfig(&ssl_config); |
| @@ -465,7 +600,7 @@ TEST(HttpStreamFactoryTest, JobNotifiesProxy) { |
| scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); |
| - // Now request a stream. It should succeed using the second proxy in the |
| + // Now request a stream. It should succeed using the second proxy in the |
| // list. |
| HttpRequestInfo request_info; |
| request_info.method = "GET"; |
| @@ -537,7 +672,7 @@ int GetSocketPoolGroupCount(ClientSocketPool* pool) { |
| } |
| return count; |
| } |
| -}; |
| +} // namespace |
| TEST(HttpStreamFactoryTest, PrivacyModeUsesDifferentSocketPoolGroup) { |
| SessionDependencies session_deps(ProxyService::CreateDirect()); |
| @@ -615,6 +750,395 @@ TEST(HttpStreamFactoryTest, GetLoadState) { |
| waiter.WaitForStream(); |
| } |
| +TEST(HttpStreamFactoryTest, RequestHttpStream) { |
| + SessionDependencies session_deps(ProxyService::CreateDirect()); |
| + |
| + StaticSocketDataProvider socket_data; |
| + socket_data.set_connect_data(MockConnect(ASYNC, OK)); |
| + session_deps.socket_factory.AddSocketDataProvider(&socket_data); |
| + |
| + scoped_refptr<HttpNetworkSession> session(CreateSession(&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_TRUE(waiter.used_proxy_info().is_direct()); |
| +} |
| + |
| +TEST(HttpStreamFactoryTest, RequestHttpStreamOverSSL) { |
| + SessionDependencies session_deps(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(CreateSession(&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_TRUE(waiter.used_proxy_info().is_direct()); |
| +} |
| + |
| +TEST(HttpStreamFactoryTest, RequestHttpStreamOverProxy) { |
| + SessionDependencies session_deps(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(CreateSession(&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_FALSE(waiter.used_proxy_info().is_direct()); |
| +} |
| + |
| +TEST(HttpStreamFactoryTest, RequestWebSocketBasicStream) { |
| + SessionDependencies session_deps(ProxyService::CreateDirect()); |
| + |
| + StaticSocketDataProvider socket_data; |
| + socket_data.set_connect_data(MockConnect(ASYNC, OK)); |
| + session_deps.socket_factory.AddSocketDataProvider(&socket_data); |
| + |
| + scoped_refptr<HttpNetworkSession> session(CreateSession(&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(1, GetSocketPoolGroupCount( |
| + session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| + EXPECT_EQ(0, GetSocketPoolGroupCount( |
| + session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| + EXPECT_TRUE(waiter.used_proxy_info().is_direct()); |
| +} |
| + |
| +TEST(HttpStreamFactoryTest, RequestWebSocketBasicStreamOverSSL) { |
| + SessionDependencies session_deps(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(CreateSession(&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(1, GetSocketPoolGroupCount( |
| + session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| + EXPECT_EQ(1, GetSocketPoolGroupCount( |
| + session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| + EXPECT_TRUE(waiter.used_proxy_info().is_direct()); |
| +} |
| + |
| +TEST(HttpStreamFactoryTest, RequestSpdyHttpStream) { |
| + SpdySessionDependencies session_deps(kProtoSPDY3, |
| + 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); |
| + ssl_socket_data.SetNextProto(kProtoSPDY3); |
| + session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); |
| + |
| + HostPortPair host_port_pair("www.google.com", 443); |
| + 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()); |
| + 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_TRUE(waiter.used_proxy_info().is_direct()); |
| +} |
| + |
| +TEST(HttpStreamFactoryTest, RequestWebSocketSpdyStream) { |
| + SpdySessionDependencies session_deps(kProtoSPDY3, |
| + 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(kProtoSPDY3); |
| + 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(1, GetSocketPoolGroupCount( |
| + session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| + EXPECT_EQ(1, GetSocketPoolGroupCount( |
| + session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL))); |
| + EXPECT_TRUE(waiter1.used_proxy_info().is_direct()); |
| +} |
| + |
| +TEST(HttpStreamFactoryTest, OrphanedWebSocketStream) { |
| + UseAlternateProtocolsScopedSetter use_alternate_protocols(true); |
| + SpdySessionDependencies session_deps(kProtoSPDY3, |
| + 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); |
| + |
| + MockRead mock_read2(ASYNC, OK); |
| + StaticSocketDataProvider socket_data2(&mock_read2, 1, NULL, 0); |
| + socket_data2.set_connect_data(MockConnect(ASYNC, ERR_IO_PENDING)); |
| + session_deps.socket_factory->AddSocketDataProvider(&socket_data2); |
| + |
| + SSLSocketDataProvider ssl_socket_data(ASYNC, OK); |
| + ssl_socket_data.SetNextProto(kProtoSPDY3); |
| + session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); |
| + |
| + scoped_refptr<HttpNetworkSession> |
| + session(SpdySessionDependencies::SpdyCreateSession(&session_deps)); |
| + HttpStreamFactoryForDetectOrphanedJobComplete* |
| + http_websocket_stream_factory = |
| + new HttpStreamFactoryForDetectOrphanedJobComplete(session.get(), true); |
| + HttpNetworkSessionPeer peer(session); |
| + peer.SetWebSocketStreamFactory(http_websocket_stream_factory); |
| + |
| + // 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()); |
| + |
| + ASSERT_EQ(0, http_websocket_stream_factory->counter()); |
| + socket_data2.socket()->OnConnectComplete(MockConnect(SYNCHRONOUS, OK)); |
| + while (!http_websocket_stream_factory->counter()) |
| + base::MessageLoop::current()->Run(); |
| + ASSERT_EQ(1, http_websocket_stream_factory->counter()); |
|
mmenke
2013/06/13 17:59:56
Aren't we cancelling orphaned jobs?
yhirano
2013/06/14 04:11:25
Done.
|
| + return; |
| +} |
| + |
| } // namespace |
| } // namespace net |