summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorricea@chromium.org <ricea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-14 02:14:44 +0000
committerricea@chromium.org <ricea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-14 02:14:44 +0000
commit831e4a3102c7ad705d69386e52981c66a4ba0ccd (patch)
treef5f0e687cbe554caa6f7da3341fe1ff09a055660
parent993bd9bd5c7e6f7505b6f6cfe852f9d3e6f67e76 (diff)
downloadchromium_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.cc6
-rw-r--r--net/http/http_cache_transaction.h2
-rw-r--r--net/http/http_cache_unittest.cc45
-rw-r--r--net/http/http_network_session_peer.cc14
-rw-r--r--net/http/http_network_session_peer.h9
-rw-r--r--net/http/http_network_transaction.cc48
-rw-r--r--net/http/http_network_transaction.h11
-rw-r--r--net/http/http_network_transaction_unittest.cc117
-rw-r--r--net/http/http_stream_factory_impl_unittest.cc37
-rw-r--r--net/http/http_transaction.h7
-rw-r--r--net/http/http_transaction_unittest.cc6
-rw-r--r--net/http/http_transaction_unittest.h8
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