diff options
author | ricea@chromium.org <ricea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-14 02:14:44 +0000 |
---|---|---|
committer | ricea@chromium.org <ricea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-14 02:14:44 +0000 |
commit | 831e4a3102c7ad705d69386e52981c66a4ba0ccd (patch) | |
tree | f5f0e687cbe554caa6f7da3341fe1ff09a055660 | |
parent | 993bd9bd5c7e6f7505b6f6cfe852f9d3e6f67e76 (diff) | |
download | chromium_src-831e4a3102c7ad705d69386e52981c66a4ba0ccd.zip chromium_src-831e4a3102c7ad705d69386e52981c66a4ba0ccd.tar.gz chromium_src-831e4a3102c7ad705d69386e52981c66a4ba0ccd.tar.bz2 |
Add a SetWebSocketHandshakeStreamFactory() method to the HttpTransaction base class so that
URLRequestHttpJob can pass through the WebSocketHandshakeStreamBase::Factory object.
Implement OnWebSocketHandshakeStreamReady().
BUG=315027
TEST=net_unittests
Review URL: https://codereview.chromium.org/23856018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235016 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/http/http_cache_transaction.cc | 6 | ||||
-rw-r--r-- | net/http/http_cache_transaction.h | 2 | ||||
-rw-r--r-- | net/http/http_cache_unittest.cc | 45 | ||||
-rw-r--r-- | net/http/http_network_session_peer.cc | 14 | ||||
-rw-r--r-- | net/http/http_network_session_peer.h | 9 | ||||
-rw-r--r-- | net/http/http_network_transaction.cc | 48 | ||||
-rw-r--r-- | net/http/http_network_transaction.h | 11 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 117 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl_unittest.cc | 37 | ||||
-rw-r--r-- | net/http/http_transaction.h | 7 | ||||
-rw-r--r-- | net/http/http_transaction_unittest.cc | 6 | ||||
-rw-r--r-- | net/http/http_transaction_unittest.h | 8 |
12 files changed, 254 insertions, 56 deletions
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index ba42d16..7035ffa 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc @@ -533,6 +533,12 @@ void HttpCache::Transaction::SetPriority(RequestPriority priority) { network_trans_->SetPriority(priority_); } +void HttpCache::Transaction::SetWebSocketHandshakeStreamCreateHelper( + WebSocketHandshakeStreamBase::CreateHelper* create_helper) { + if (network_trans_) + network_trans_->SetWebSocketHandshakeStreamCreateHelper(create_helper); +} + //----------------------------------------------------------------------------- void HttpCache::Transaction::DoCallback(int rv) { diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h index b1f32bd..b0a1a88 100644 --- a/net/http/http_cache_transaction.h +++ b/net/http/http_cache_transaction.h @@ -130,6 +130,8 @@ class HttpCache::Transaction : public HttpTransaction { virtual bool GetLoadTimingInfo( LoadTimingInfo* load_timing_info) const OVERRIDE; virtual void SetPriority(RequestPriority priority) OVERRIDE; + virtual void SetWebSocketHandshakeStreamCreateHelper( + net::WebSocketHandshakeStreamBase::CreateHelper* create_helper) OVERRIDE; private: static const size_t kNumValidationHeaders = 2; diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc index 67f8d98..2906680 100644 --- a/net/http/http_cache_unittest.cc +++ b/net/http/http_cache_unittest.cc @@ -32,6 +32,7 @@ #include "net/http/http_util.h" #include "net/http/mock_http_cache.h" #include "net/ssl/ssl_cert_request_info.h" +#include "net/websockets/websocket_handshake_stream_base.h" #include "testing/gtest/include/gtest/gtest.h" using base::Time; @@ -574,6 +575,21 @@ struct Context { scoped_ptr<net::HttpTransaction> trans; }; +class FakeWebSocketHandshakeStreamCreateHelper + : public net::WebSocketHandshakeStreamBase::CreateHelper { + public: + virtual ~FakeWebSocketHandshakeStreamCreateHelper() {} + virtual net::WebSocketHandshakeStreamBase* CreateBasicStream( + net::ClientSocketHandle* connect, bool using_proxy) OVERRIDE { + return NULL; + } + virtual net::WebSocketHandshakeStreamBase* CreateSpdyStream( + const base::WeakPtr<net::SpdySession>& session, + bool use_relative_url) OVERRIDE { + return NULL; + } +}; + } // namespace @@ -6298,6 +6314,35 @@ TEST(HttpCache, SetPriority) { EXPECT_EQ(net::OK, callback.WaitForResult()); } +// Make sure that calling SetWebSocketHandshakeStreamCreateHelper on a cache +// transaction passes on its argument to the underlying network transaction. +TEST(HttpCache, SetWebSocketHandshakeStreamCreateHelper) { + MockHttpCache cache; + + FakeWebSocketHandshakeStreamCreateHelper create_helper; + scoped_ptr<net::HttpTransaction> trans; + EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction( + net::IDLE, &trans, NULL)); + ASSERT_TRUE(trans.get()); + + EXPECT_FALSE(cache.network_layer()->last_transaction()); + + net::HttpRequestInfo info; + info.url = GURL(kSimpleGET_Transaction.url); + net::TestCompletionCallback callback; + EXPECT_EQ(net::ERR_IO_PENDING, + trans->Start(&info, callback.callback(), net::BoundNetLog())); + + ASSERT_TRUE(cache.network_layer()->last_transaction()); + EXPECT_FALSE(cache.network_layer()->last_transaction()-> + websocket_handshake_stream_create_helper()); + trans->SetWebSocketHandshakeStreamCreateHelper(&create_helper); + EXPECT_EQ(&create_helper, + cache.network_layer()->last_transaction()-> + websocket_handshake_stream_create_helper()); + EXPECT_EQ(net::OK, callback.WaitForResult()); +} + // Make sure that a cache transaction passes on its priority to // newly-created network transactions. TEST(HttpCache, SetPriorityNewTransaction) { diff --git a/net/http/http_network_session_peer.cc b/net/http/http_network_session_peer.cc index 2a4ad33..b762a5f 100644 --- a/net/http/http_network_session_peer.cc +++ b/net/http/http_network_session_peer.cc @@ -21,8 +21,8 @@ HttpNetworkSessionPeer::HttpNetworkSessionPeer( HttpNetworkSessionPeer::~HttpNetworkSessionPeer() {} void HttpNetworkSessionPeer::SetClientSocketPoolManager( - ClientSocketPoolManager* socket_pool_manager) { - session_->normal_socket_pool_manager_.reset(socket_pool_manager); + scoped_ptr<ClientSocketPoolManager> socket_pool_manager) { + session_->normal_socket_pool_manager_.swap(socket_pool_manager); } void HttpNetworkSessionPeer::SetProxyService(ProxyService* proxy_service) { @@ -30,13 +30,13 @@ void HttpNetworkSessionPeer::SetProxyService(ProxyService* proxy_service) { } void HttpNetworkSessionPeer::SetHttpStreamFactory( - HttpStreamFactory* http_stream_factory) { - session_->http_stream_factory_.reset(http_stream_factory); + scoped_ptr<HttpStreamFactory> http_stream_factory) { + session_->http_stream_factory_.swap(http_stream_factory); } -void HttpNetworkSessionPeer::SetWebSocketStreamFactory( - HttpStreamFactory* http_stream_factory) { - session_->websocket_handshake_stream_factory_.reset(http_stream_factory); +void HttpNetworkSessionPeer::SetWebSocketHandshakeStreamFactory( + scoped_ptr<HttpStreamFactory> http_stream_factory) { + session_->websocket_handshake_stream_factory_.swap(http_stream_factory); } } // namespace net diff --git a/net/http/http_network_session_peer.h b/net/http/http_network_session_peer.h index ebe1af1..4df7b75 100644 --- a/net/http/http_network_session_peer.h +++ b/net/http/http_network_session_peer.h @@ -6,6 +6,7 @@ #define NET_HTTP_HTTP_NETWORK_SESSION_PEER_H_ #include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" #include "net/base/net_export.h" namespace net { @@ -22,13 +23,13 @@ class NET_EXPORT_PRIVATE HttpNetworkSessionPeer { ~HttpNetworkSessionPeer(); void SetClientSocketPoolManager( - ClientSocketPoolManager* socket_pool_manager); + scoped_ptr<ClientSocketPoolManager> socket_pool_manager); void SetProxyService(ProxyService* proxy_service); - void SetHttpStreamFactory(HttpStreamFactory* http_stream_factory); - void SetWebSocketStreamFactory( - HttpStreamFactory* websocket_handshake_stream_factory); + void SetHttpStreamFactory(scoped_ptr<HttpStreamFactory> http_stream_factory); + void SetWebSocketHandshakeStreamFactory( + scoped_ptr<HttpStreamFactory> websocket_handshake_stream_factory); private: const scoped_refptr<HttpNetworkSession> session_; diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index ff94e30..d20ee4c6 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -129,7 +129,8 @@ HttpNetworkTransaction::HttpNetworkTransaction(RequestPriority priority, request_headers_(), read_buf_len_(0), next_state_(STATE_NONE), - establishing_tunnel_(false) { + establishing_tunnel_(false), + websocket_handshake_stream_base_create_helper_(NULL) { session->ssl_config_service()->GetSSLConfig(&server_ssl_config_); if (session->http_stream_factory()->has_next_protos()) { server_ssl_config_.next_protos = @@ -429,6 +430,11 @@ void HttpNetworkTransaction::SetPriority(RequestPriority priority) { stream_->SetPriority(priority); } +void HttpNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper( + WebSocketHandshakeStreamBase::CreateHelper* create_helper) { + websocket_handshake_stream_base_create_helper_ = create_helper; +} + void HttpNetworkTransaction::OnStreamReady(const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, HttpStreamBase* stream) { @@ -451,7 +457,7 @@ void HttpNetworkTransaction::OnWebSocketHandshakeStreamReady( const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, WebSocketHandshakeStreamBase* stream) { - NOTREACHED() << "This function should never be called."; + OnStreamReady(used_ssl_config, used_proxy_info, stream); } void HttpNetworkTransaction::OnStreamFailed(int result, @@ -657,14 +663,27 @@ int HttpNetworkTransaction::DoLoop(int result) { int HttpNetworkTransaction::DoCreateStream() { next_state_ = STATE_CREATE_STREAM_COMPLETE; - stream_request_.reset( - session_->http_stream_factory()->RequestStream( - *request_, - priority_, - server_ssl_config_, - proxy_ssl_config_, - this, - net_log_)); + if (ForWebSocketHandshake()) { + stream_request_.reset( + session_->websocket_handshake_stream_factory() + ->RequestWebSocketHandshakeStream( + *request_, + priority_, + server_ssl_config_, + proxy_ssl_config_, + this, + websocket_handshake_stream_base_create_helper_, + net_log_)); + } else { + stream_request_.reset( + session_->http_stream_factory()->RequestStream( + *request_, + priority_, + server_ssl_config_, + proxy_ssl_config_, + this, + net_log_)); + } DCHECK(stream_request_.get()); return ERR_IO_PENDING; } @@ -1000,7 +1019,9 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { // need to skip over it. // We treat any other 1xx in this same way (although in practice getting // a 1xx that isn't a 100 is rare). - if (response_.headers->response_code() / 100 == 1) { + // Unless this is a WebSocket request, in which case we pass it on up. + if (response_.headers->response_code() / 100 == 1 && + !ForWebSocketHandshake()) { response_.headers = new HttpResponseHeaders(std::string()); next_state_ = STATE_READ_HEADERS; return OK; @@ -1487,6 +1508,11 @@ GURL HttpNetworkTransaction::AuthURL(HttpAuth::Target target) const { } } +bool HttpNetworkTransaction::ForWebSocketHandshake() const { + return (websocket_handshake_stream_base_create_helper_ && + (request_->url.SchemeIs("ws") || request_->url.SchemeIs("wss"))); +} + #define STATE_CASE(s) \ case s: \ description = base::StringPrintf("%s (0x%08X)", #s, s); \ diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index b0950a2..3610a75 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h @@ -21,6 +21,7 @@ #include "net/http/http_transaction.h" #include "net/proxy/proxy_service.h" #include "net/ssl/ssl_config_service.h" +#include "net/websockets/websocket_handshake_stream_base.h" namespace net { @@ -68,6 +69,8 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction virtual bool GetLoadTimingInfo( LoadTimingInfo* load_timing_info) const OVERRIDE; virtual void SetPriority(RequestPriority priority) OVERRIDE; + virtual void SetWebSocketHandshakeStreamCreateHelper( + WebSocketHandshakeStreamBase::CreateHelper* create_helper) OVERRIDE; // HttpStreamRequest::Delegate methods: virtual void OnStreamReady(const SSLConfig& used_ssl_config, @@ -242,6 +245,9 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction // Get the {scheme, host, path, port} for the authentication target GURL AuthURL(HttpAuth::Target target) const; + // Returns true if this transaction is for a WebSocket handshake + bool ForWebSocketHandshake() const; + // Debug helper. static std::string DescribeState(State state); @@ -306,6 +312,11 @@ class NET_EXPORT_PRIVATE HttpNetworkTransaction // read from the socket until the tunnel is done. bool establishing_tunnel_; + // The helper object to use to create WebSocketHandshakeStreamBase + // objects. Only relevant when establishing a WebSocket connection. + WebSocketHandshakeStreamBase::CreateHelper* + websocket_handshake_stream_base_create_helper_; + DISALLOW_COPY_AND_ASSIGN(HttpNetworkTransaction); }; diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index f84c3f6..f23d0fb 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -64,6 +64,7 @@ #include "net/ssl/ssl_config_service_defaults.h" #include "net/ssl/ssl_info.h" #include "net/test/cert_test_util.h" +#include "net/websockets/websocket_handshake_stream_base.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" #include "url/gurl.h" @@ -7171,11 +7172,12 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) { new CaptureGroupNameTransportSocketPool(NULL, NULL); CaptureGroupNameSSLSocketPool* ssl_conn_pool = new CaptureGroupNameSSLSocketPool(NULL, NULL); - MockClientSocketPoolManager* mock_pool_manager = - new MockClientSocketPoolManager; + scoped_ptr<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); + peer.SetClientSocketPoolManager( + mock_pool_manager.PassAs<ClientSocketPoolManager>()); EXPECT_EQ(ERR_IO_PENDING, GroupNameTransactionHelper(tests[i].url, session)); @@ -7237,11 +7239,12 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) { CaptureGroupNameSSLSocketPool* ssl_conn_pool = new CaptureGroupNameSSLSocketPool(NULL, NULL); - MockClientSocketPoolManager* mock_pool_manager = - new MockClientSocketPoolManager; + scoped_ptr<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); + peer.SetClientSocketPoolManager( + mock_pool_manager.PassAs<ClientSocketPoolManager>()); EXPECT_EQ(ERR_IO_PENDING, GroupNameTransactionHelper(tests[i].url, session)); @@ -7307,11 +7310,12 @@ TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) { CaptureGroupNameSSLSocketPool* ssl_conn_pool = new CaptureGroupNameSSLSocketPool(NULL, NULL); - MockClientSocketPoolManager* mock_pool_manager = - new MockClientSocketPoolManager; + scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( + new MockClientSocketPoolManager); mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool); mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); - peer.SetClientSocketPoolManager(mock_pool_manager); + peer.SetClientSocketPoolManager( + mock_pool_manager.PassAs<ClientSocketPoolManager>()); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); @@ -9363,10 +9367,11 @@ TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) { session_deps_.host_resolver.get(), session_deps_.socket_factory.get(), session_deps_.net_log); - MockClientSocketPoolManager* mock_pool_manager = - new MockClientSocketPoolManager; + scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( + new MockClientSocketPoolManager); mock_pool_manager->SetTransportSocketPool(transport_pool); - session_peer.SetClientSocketPoolManager(mock_pool_manager); + session_peer.SetClientSocketPoolManager( + mock_pool_manager.PassAs<ClientSocketPoolManager>()); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); @@ -11851,12 +11856,25 @@ class FakeStreamRequest : public HttpStreamRequest, FakeStreamRequest(RequestPriority priority, HttpStreamRequest::Delegate* delegate) : priority_(priority), - delegate_(delegate) {} + delegate_(delegate), + websocket_stream_create_helper_(NULL) {} + + FakeStreamRequest(RequestPriority priority, + HttpStreamRequest::Delegate* delegate, + WebSocketHandshakeStreamBase::CreateHelper* create_helper) + : priority_(priority), + delegate_(delegate), + websocket_stream_create_helper_(create_helper) {} virtual ~FakeStreamRequest() {} RequestPriority priority() const { return priority_; } + const WebSocketHandshakeStreamBase::CreateHelper* + websocket_stream_create_helper() const { + return websocket_stream_create_helper_; + } + // Create a new FakeStream and pass it to the request's // delegate. Returns a weak pointer to the FakeStream. base::WeakPtr<FakeStream> FinishStreamRequest() { @@ -11898,6 +11916,7 @@ class FakeStreamRequest : public HttpStreamRequest, private: RequestPriority priority_; HttpStreamRequest::Delegate* const delegate_; + WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_; DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest); }; @@ -11934,8 +11953,10 @@ class FakeStreamFactory : public HttpStreamFactory { HttpStreamRequest::Delegate* delegate, WebSocketHandshakeStreamBase::CreateHelper* create_helper, const BoundNetLog& net_log) OVERRIDE { - ADD_FAILURE(); - return NULL; + FakeStreamRequest* fake_request = + new FakeStreamRequest(priority, delegate, create_helper); + last_stream_request_ = fake_request->AsWeakPtr(); + return fake_request; } virtual void PreconnectStreams(int num_streams, @@ -11962,6 +11983,33 @@ class FakeStreamFactory : public HttpStreamFactory { DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory); }; +// TODO(yhirano): Split this class out into a net/websockets file, if it is +// worth doing. +class FakeWebSocketStreamCreateHelper : + public WebSocketHandshakeStreamBase::CreateHelper { + public: + virtual WebSocketHandshakeStreamBase* CreateBasicStream( + ClientSocketHandle* connection, + bool using_proxy) OVERRIDE { + NOTREACHED(); + return NULL; + } + + virtual WebSocketHandshakeStreamBase* CreateSpdyStream( + const base::WeakPtr<SpdySession>& session, + bool use_relative_url) OVERRIDE { + NOTREACHED(); + return NULL; + }; + + virtual ~FakeWebSocketStreamCreateHelper() {} + + virtual scoped_ptr<WebSocketStream> Upgrade() { + NOTREACHED(); + return scoped_ptr<WebSocketStream>(); + } +}; + } // namespace // Make sure that HttpNetworkTransaction passes on its priority to its @@ -11970,7 +12018,7 @@ TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) { scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); HttpNetworkSessionPeer peer(session); FakeStreamFactory* fake_factory = new FakeStreamFactory(); - peer.SetHttpStreamFactory(fake_factory); + peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory)); HttpNetworkTransaction trans(LOW, session); @@ -11993,7 +12041,7 @@ TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) { scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); HttpNetworkSessionPeer peer(session); FakeStreamFactory* fake_factory = new FakeStreamFactory(); - peer.SetHttpStreamFactory(fake_factory); + peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory)); HttpNetworkTransaction trans(LOW, session); @@ -12018,7 +12066,7 @@ TEST_P(HttpNetworkTransactionTest, SetStreamPriority) { scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); HttpNetworkSessionPeer peer(session); FakeStreamFactory* fake_factory = new FakeStreamFactory(); - peer.SetHttpStreamFactory(fake_factory); + peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory)); HttpNetworkTransaction trans(LOW, session); @@ -12038,6 +12086,39 @@ TEST_P(HttpNetworkTransactionTest, SetStreamPriority) { EXPECT_EQ(LOWEST, fake_stream->priority()); } +TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) { + // The same logic needs to be tested for both ws: and wss: schemes, but this + // test is already parameterised on NextProto, so it uses a loop to verify + // that the different schemes work. + std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"}; + for (size_t i = 0; i < arraysize(test_cases); ++i) { + scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + HttpNetworkSessionPeer peer(session); + FakeStreamFactory* fake_factory = new FakeStreamFactory(); + FakeWebSocketStreamCreateHelper websocket_stream_create_helper; + peer.SetWebSocketHandshakeStreamFactory( + scoped_ptr<HttpStreamFactory>(fake_factory)); + + HttpNetworkTransaction trans(LOW, session); + trans.SetWebSocketHandshakeStreamCreateHelper( + &websocket_stream_create_helper); + + HttpRequestInfo request; + TestCompletionCallback callback; + request.method = "GET"; + request.url = GURL(test_cases[i]); + + EXPECT_EQ(ERR_IO_PENDING, + trans.Start(&request, callback.callback(), BoundNetLog())); + + base::WeakPtr<FakeStreamRequest> fake_request = + fake_factory->last_stream_request(); + ASSERT_TRUE(fake_request != NULL); + EXPECT_EQ(&websocket_stream_create_helper, + fake_request->websocket_stream_create_helper()); + } +} + // Tests that when a used socket is returned to the SSL socket pool, it's closed // if the transport socket pool is stalled on the global socket limit. TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) { diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc index c9463a7..b87b4b8 100644 --- a/net/http/http_stream_factory_impl_unittest.cc +++ b/net/http/http_stream_factory_impl_unittest.cc @@ -308,7 +308,7 @@ void PreconnectHelperForURL(int num_streams, HttpNetworkSessionPeer peer(session); MockHttpStreamFactoryImplForPreconnect* mock_factory = new MockHttpStreamFactoryImplForPreconnect(session, false); - peer.SetHttpStreamFactory(mock_factory); + peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(mock_factory)); SSLConfig ssl_config; session->ssl_config_service()->GetSSLConfig(&ssl_config); @@ -458,11 +458,12 @@ TEST_P(HttpStreamFactoryTest, PreconnectDirect) { new CapturePreconnectsSSLSocketPool( session_deps.host_resolver.get(), session_deps.cert_verifier.get()); - MockClientSocketPoolManager* mock_pool_manager = - new MockClientSocketPoolManager; + scoped_ptr<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); + peer.SetClientSocketPoolManager( + mock_pool_manager.PassAs<ClientSocketPoolManager>()); PreconnectHelper(kTests[i], session.get()); if (kTests[i].ssl) EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); @@ -487,11 +488,12 @@ TEST_P(HttpStreamFactoryTest, PreconnectHttpProxy) { new CapturePreconnectsSSLSocketPool( session_deps.host_resolver.get(), session_deps.cert_verifier.get()); - MockClientSocketPoolManager* mock_pool_manager = - new MockClientSocketPoolManager; + scoped_ptr<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); + peer.SetClientSocketPoolManager( + mock_pool_manager.PassAs<ClientSocketPoolManager>()); PreconnectHelper(kTests[i], session.get()); if (kTests[i].ssl) EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); @@ -516,11 +518,12 @@ TEST_P(HttpStreamFactoryTest, PreconnectSocksProxy) { new CapturePreconnectsSSLSocketPool( session_deps.host_resolver.get(), session_deps.cert_verifier.get()); - MockClientSocketPoolManager* mock_pool_manager = - new MockClientSocketPoolManager; + scoped_ptr<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); + peer.SetClientSocketPoolManager( + mock_pool_manager.PassAs<ClientSocketPoolManager>()); PreconnectHelper(kTests[i], session.get()); if (kTests[i].ssl) EXPECT_EQ(kTests[i].num_streams, ssl_conn_pool->last_num_streams()); @@ -551,11 +554,12 @@ TEST_P(HttpStreamFactoryTest, PreconnectDirectWithExistingSpdySession) { new CapturePreconnectsSSLSocketPool( session_deps.host_resolver.get(), session_deps.cert_verifier.get()); - MockClientSocketPoolManager* mock_pool_manager = - new MockClientSocketPoolManager; + scoped_ptr<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); + peer.SetClientSocketPoolManager( + mock_pool_manager.PassAs<ClientSocketPoolManager>()); 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. @@ -582,10 +586,11 @@ TEST_P(HttpStreamFactoryTest, PreconnectUnsafePort) { new CapturePreconnectsTransportSocketPool( session_deps.host_resolver.get(), session_deps.cert_verifier.get()); - MockClientSocketPoolManager* mock_pool_manager = - new MockClientSocketPoolManager; + scoped_ptr<MockClientSocketPoolManager> mock_pool_manager( + new MockClientSocketPoolManager); mock_pool_manager->SetTransportSocketPool(transport_conn_pool); - peer.SetClientSocketPoolManager(mock_pool_manager); + peer.SetClientSocketPoolManager( + mock_pool_manager.PassAs<ClientSocketPoolManager>()); PreconnectHelperForURL(1, GURL("http://www.google.com:7"), session.get()); diff --git a/net/http/http_transaction.h b/net/http/http_transaction.h index d440500..849d03a 100644 --- a/net/http/http_transaction.h +++ b/net/http/http_transaction.h @@ -10,6 +10,7 @@ #include "net/base/net_export.h" #include "net/base/request_priority.h" #include "net/base/upload_progress.h" +#include "net/websockets/websocket_handshake_stream_base.h" namespace net { @@ -134,6 +135,12 @@ class NET_EXPORT_PRIVATE HttpTransaction { // Called when the priority of the parent job changes. virtual void SetPriority(RequestPriority priority) = 0; + + // Set the WebSocketHandshakeStreamBase::CreateHelper to be used for the + // request. Only relevant to WebSocket transactions. Must be called before + // Start(). Ownership of |create_helper| remains with the caller. + virtual void SetWebSocketHandshakeStreamCreateHelper( + WebSocketHandshakeStreamBase::CreateHelper* create_helper) = 0; }; } // namespace net diff --git a/net/http/http_transaction_unittest.cc b/net/http/http_transaction_unittest.cc index 9aa81cf..e161eca 100644 --- a/net/http/http_transaction_unittest.cc +++ b/net/http/http_transaction_unittest.cc @@ -228,6 +228,7 @@ MockNetworkTransaction::MockNetworkTransaction( : weak_factory_(this), data_cursor_(0), priority_(priority), + websocket_handshake_stream_create_helper_(NULL), transaction_factory_(factory->AsWeakPtr()), socket_log_id_(net::NetLog::Source::kInvalidId) { } @@ -375,6 +376,11 @@ void MockNetworkTransaction::SetPriority(net::RequestPriority priority) { priority_ = priority; } +void MockNetworkTransaction::SetWebSocketHandshakeStreamCreateHelper( + net::WebSocketHandshakeStreamBase::CreateHelper* create_helper) { + websocket_handshake_stream_create_helper_ = create_helper; +} + void MockNetworkTransaction::CallbackLater( const net::CompletionCallback& callback, int result) { base::MessageLoop::current()->PostTask( diff --git a/net/http/http_transaction_unittest.h b/net/http/http_transaction_unittest.h index 407fc9f..3d6bb02 100644 --- a/net/http/http_transaction_unittest.h +++ b/net/http/http_transaction_unittest.h @@ -162,6 +162,7 @@ class MockNetworkLayer; class MockNetworkTransaction : public net::HttpTransaction, public base::SupportsWeakPtr<MockNetworkTransaction> { + typedef net::WebSocketHandshakeStreamBase::CreateHelper CreateHelper; public: MockNetworkTransaction(net::RequestPriority priority, MockNetworkLayer* factory); @@ -205,6 +206,12 @@ class MockNetworkTransaction virtual void SetPriority(net::RequestPriority priority) OVERRIDE; + virtual void SetWebSocketHandshakeStreamCreateHelper( + CreateHelper* create_helper) OVERRIDE; + + CreateHelper* websocket_handshake_stream_create_helper() { + return websocket_handshake_stream_create_helper_; + } net::RequestPriority priority() const { return priority_; } private: @@ -217,6 +224,7 @@ class MockNetworkTransaction int data_cursor_; int test_mode_; net::RequestPriority priority_; + CreateHelper* websocket_handshake_stream_create_helper_; base::WeakPtr<MockNetworkLayer> transaction_factory_; // NetLog ID of the fake / non-existent underlying socket used by the |