diff options
author | toyoshim@chromium.org <toyoshim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-11 12:06:39 +0000 |
---|---|---|
committer | toyoshim@chromium.org <toyoshim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-11 12:06:39 +0000 |
commit | de35eaae2ef556ce48a7719e890a2cb6b4982cc7 (patch) | |
tree | dd9c2db7357b34f8e1ec1b1648e9fb90c701124c | |
parent | 8c1bd0e23219648ddca761d592fb25493725b3f5 (diff) | |
download | chromium_src-de35eaae2ef556ce48a7719e890a2cb6b4982cc7.zip chromium_src-de35eaae2ef556ce48a7719e890a2cb6b4982cc7.tar.gz chromium_src-de35eaae2ef556ce48a7719e890a2cb6b4982cc7.tar.bz2 |
Revert 91997 - Add WebSocket over SPDY experimental implementation.
- Realize WebSocketJob's internal protocol switch to SPDY using SpdyWebSocketStream
- Add simple test to verify connection over SPDY
BUG=42320
TEST=net_unittests --gtest_filter=WebSocketJobTest\*
Review URL: http://codereview.chromium.org/7185032
TBR=toyoshim@chromium.org
Review URL: http://codereview.chromium.org/7333006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@92003 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/socket_stream/socket_stream.cc | 6 | ||||
-rw-r--r-- | net/socket_stream/socket_stream_unittest.cc | 70 | ||||
-rw-r--r-- | net/websockets/websocket_job.cc | 182 | ||||
-rw-r--r-- | net/websockets/websocket_job.h | 17 | ||||
-rw-r--r-- | net/websockets/websocket_job_unittest.cc | 222 |
5 files changed, 87 insertions, 410 deletions
diff --git a/net/socket_stream/socket_stream.cc b/net/socket_stream/socket_stream.cc index d89c074..4c5b13a 100644 --- a/net/socket_stream/socket_stream.cc +++ b/net/socket_stream/socket_stream.cc @@ -290,14 +290,14 @@ void SocketStream::Finish(int result) { result = ERR_CONNECTION_CLOSED; DCHECK_EQ(next_state_, STATE_NONE); DVLOG(1) << "Finish result=" << ErrorToString(result); + if (delegate_) + delegate_->OnError(this, result); metrics_->OnClose(); Delegate* delegate = delegate_; delegate_ = NULL; if (delegate) { - delegate->OnError(this, result); - if (result != ERR_PROTOCOL_SWITCHED) - delegate->OnClose(this); + delegate->OnClose(this); } Release(); } diff --git a/net/socket_stream/socket_stream_unittest.cc b/net/socket_stream/socket_stream_unittest.cc index 090ecff..a1ea8ac 100644 --- a/net/socket_stream/socket_stream_unittest.cc +++ b/net/socket_stream/socket_stream_unittest.cc @@ -24,7 +24,7 @@ struct SocketStreamEvent { enum EventType { EVENT_START_OPEN_CONNECTION, EVENT_CONNECTED, EVENT_SENT_DATA, - EVENT_RECEIVED_DATA, EVENT_CLOSE, EVENT_AUTH_REQUIRED, EVENT_ERROR, + EVENT_RECEIVED_DATA, EVENT_CLOSE, EVENT_AUTH_REQUIRED, }; SocketStreamEvent(EventType type, @@ -32,17 +32,15 @@ struct SocketStreamEvent { int num, const std::string& str, net::AuthChallengeInfo* auth_challenge_info, - net::CompletionCallback* callback, - int error) + net::CompletionCallback* callback) : event_type(type), socket(socket_stream), number(num), data(str), - auth_info(auth_challenge_info), error_code(error) {} + auth_info(auth_challenge_info) {} EventType event_type; net::SocketStream* socket; int number; std::string data; scoped_refptr<net::AuthChallengeInfo> auth_info; - int error_code; }; class SocketStreamEventRecorder : public net::SocketStream::Delegate { @@ -74,16 +72,13 @@ class SocketStreamEventRecorder : public net::SocketStream::Delegate { const base::Callback<void(SocketStreamEvent*)>& callback) { on_auth_required_ = callback; } - void SetOnError(const base::Callback<void(SocketStreamEvent*)>& callback) { - on_error_ = callback; - } virtual int OnStartOpenConnection(net::SocketStream* socket, net::CompletionCallback* callback) { connection_callback_ = callback; events_.push_back( SocketStreamEvent(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, - socket, 0, std::string(), NULL, callback, net::OK)); + socket, 0, std::string(), NULL, callback)); if (!on_start_open_connection_.is_null()) return on_start_open_connection_.Run(&events_.back()); return net::OK; @@ -93,30 +88,30 @@ class SocketStreamEventRecorder : public net::SocketStream::Delegate { events_.push_back( SocketStreamEvent(SocketStreamEvent::EVENT_CONNECTED, socket, num_pending_send_allowed, std::string(), - NULL, NULL, net::OK)); + NULL, NULL)); if (!on_connected_.is_null()) on_connected_.Run(&events_.back()); } virtual void OnSentData(net::SocketStream* socket, int amount_sent) { events_.push_back( - SocketStreamEvent(SocketStreamEvent::EVENT_SENT_DATA, socket, - amount_sent, std::string(), NULL, NULL, net::OK)); + SocketStreamEvent(SocketStreamEvent::EVENT_SENT_DATA, + socket, amount_sent, std::string(), NULL, NULL)); if (!on_sent_data_.is_null()) on_sent_data_.Run(&events_.back()); } virtual void OnReceivedData(net::SocketStream* socket, const char* data, int len) { events_.push_back( - SocketStreamEvent(SocketStreamEvent::EVENT_RECEIVED_DATA, socket, len, - std::string(data, len), NULL, NULL, net::OK)); + SocketStreamEvent(SocketStreamEvent::EVENT_RECEIVED_DATA, + socket, len, std::string(data, len), NULL, NULL)); if (!on_received_data_.is_null()) on_received_data_.Run(&events_.back()); } virtual void OnClose(net::SocketStream* socket) { events_.push_back( - SocketStreamEvent(SocketStreamEvent::EVENT_CLOSE, socket, 0, - std::string(), NULL, NULL, net::OK)); + SocketStreamEvent(SocketStreamEvent::EVENT_CLOSE, + socket, 0, std::string(), NULL, NULL)); if (!on_close_.is_null()) on_close_.Run(&events_.back()); if (callback_) @@ -125,20 +120,11 @@ class SocketStreamEventRecorder : public net::SocketStream::Delegate { virtual void OnAuthRequired(net::SocketStream* socket, net::AuthChallengeInfo* auth_info) { events_.push_back( - SocketStreamEvent(SocketStreamEvent::EVENT_AUTH_REQUIRED, socket, 0, - std::string(), auth_info, NULL, net::OK)); + SocketStreamEvent(SocketStreamEvent::EVENT_AUTH_REQUIRED, + socket, 0, std::string(), auth_info, NULL)); if (!on_auth_required_.is_null()) on_auth_required_.Run(&events_.back()); } - virtual void OnError(const net::SocketStream* socket, int error) { - events_.push_back( - SocketStreamEvent(SocketStreamEvent::EVENT_ERROR, NULL, 0, - std::string(), NULL, NULL, error)); - if (!on_error_.is_null()) - on_error_.Run(&events_.back()); - if (callback_) - callback_->Run(error); - } void DoClose(SocketStreamEvent* event) { event->socket->Close(); @@ -169,7 +155,6 @@ class SocketStreamEventRecorder : public net::SocketStream::Delegate { base::Callback<void(SocketStreamEvent*)> on_received_data_; base::Callback<void(SocketStreamEvent*)> on_close_; base::Callback<void(SocketStreamEvent*)> on_auth_required_; - base::Callback<void(SocketStreamEvent*)> on_error_; net::CompletionCallback* callback_; net::CompletionCallback* connection_callback_; @@ -319,7 +304,7 @@ TEST_F(SocketStreamTest, CloseFlushPendingWrite) { callback.WaitForResult(); const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); - ASSERT_EQ(8U, events.size()); + ASSERT_EQ(7U, events.size()); EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, events[0].event_type); @@ -328,9 +313,7 @@ TEST_F(SocketStreamTest, CloseFlushPendingWrite) { EXPECT_EQ(SocketStreamEvent::EVENT_RECEIVED_DATA, events[3].event_type); EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[4].event_type); EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[5].event_type); - EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[6].event_type); - EXPECT_EQ(net::ERR_CONNECTION_CLOSED, events[6].error_code); - EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[7].event_type); + EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[6].event_type); } TEST_F(SocketStreamTest, BasicAuthProxy) { @@ -392,15 +375,13 @@ TEST_F(SocketStreamTest, BasicAuthProxy) { callback.WaitForResult(); const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); - ASSERT_EQ(5U, events.size()); + ASSERT_EQ(4U, events.size()); EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, events[0].event_type); EXPECT_EQ(SocketStreamEvent::EVENT_AUTH_REQUIRED, events[1].event_type); EXPECT_EQ(SocketStreamEvent::EVENT_CONNECTED, events[2].event_type); - EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[3].event_type); - EXPECT_EQ(net::ERR_ABORTED, events[3].error_code); - EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[4].event_type); + EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[3].event_type); // TODO(eroman): Add back NetLogTest here... } @@ -459,7 +440,7 @@ TEST_F(SocketStreamTest, IOPending) { EXPECT_EQ(net::OK, callback.WaitForResult()); const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); - ASSERT_EQ(8U, events.size()); + ASSERT_EQ(7U, events.size()); EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, events[0].event_type); @@ -468,9 +449,7 @@ TEST_F(SocketStreamTest, IOPending) { EXPECT_EQ(SocketStreamEvent::EVENT_RECEIVED_DATA, events[3].event_type); EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[4].event_type); EXPECT_EQ(SocketStreamEvent::EVENT_SENT_DATA, events[5].event_type); - EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[6].event_type); - EXPECT_EQ(net::ERR_CONNECTION_CLOSED, events[6].error_code); - EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[7].event_type); + EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[6].event_type); } TEST_F(SocketStreamTest, SwitchToSpdy) { @@ -491,15 +470,14 @@ TEST_F(SocketStreamTest, SwitchToSpdy) { socket_stream->Connect(); - EXPECT_EQ(net::ERR_PROTOCOL_SWITCHED, callback.WaitForResult()); + EXPECT_EQ(net::OK, callback.WaitForResult()); const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); ASSERT_EQ(2U, events.size()); EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, events[0].event_type); - EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[1].event_type); - EXPECT_EQ(net::ERR_PROTOCOL_SWITCHED, events[1].error_code); + EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[1].event_type); } TEST_F(SocketStreamTest, SwitchAfterPending) { @@ -524,15 +502,15 @@ TEST_F(SocketStreamTest, SwitchAfterPending) { socket_stream->next_state_); delegate->CompleteConnection(net::ERR_PROTOCOL_SWITCHED); - EXPECT_EQ(net::ERR_PROTOCOL_SWITCHED, callback.WaitForResult()); + int result = callback.WaitForResult(); const std::vector<SocketStreamEvent>& events = delegate->GetSeenEvents(); ASSERT_EQ(2U, events.size()); EXPECT_EQ(SocketStreamEvent::EVENT_START_OPEN_CONNECTION, events[0].event_type); - EXPECT_EQ(SocketStreamEvent::EVENT_ERROR, events[1].event_type); - EXPECT_EQ(net::ERR_PROTOCOL_SWITCHED, events[1].error_code); + EXPECT_EQ(SocketStreamEvent::EVENT_CLOSE, events[1].event_type); + EXPECT_EQ(net::OK, result); } } // namespace net diff --git a/net/websockets/websocket_job.cc b/net/websockets/websocket_job.cc index b627a07..77fc058 100644 --- a/net/websockets/websocket_job.cc +++ b/net/websockets/websocket_job.cc @@ -24,8 +24,6 @@ #include "net/websockets/websocket_net_log_params.h" #include "net/websockets/websocket_throttle.h" -static const int kMaxPendingSendAllowed = 32768; // 32 kilobytes. - namespace { // lower-case header names. @@ -180,14 +178,14 @@ int WebSocketJob::OnStartOpenConnection( state_ = CONNECTING; addresses_ = socket->address_list(); WebSocketThrottle::GetInstance()->PutInQueue(this); - if (waiting_) { - // PutInQueue() may set |waiting_| true for throttling. In this case, - // Wakeup() will be called later. - callback_ = callback; - AddRef(); // Balanced when callback_ becomes NULL. - return ERR_IO_PENDING; + if (!waiting_) { + int result = TrySpdyStream(); + if (result != ERR_IO_PENDING) + return result; } - return TrySpdyStream(); + callback_ = callback; + AddRef(); // Balanced when callback_ becomes NULL. + return ERR_IO_PENDING; // Wakeup will be called later. } void WebSocketJob::OnConnected( @@ -278,73 +276,8 @@ void WebSocketJob::OnAuthRequired( } void WebSocketJob::OnError(const SocketStream* socket, int error) { - if (delegate_ && error != ERR_PROTOCOL_SWITCHED) - delegate_->OnError(socket, error); -} - -void WebSocketJob::OnCreatedSpdyStream(int result) { - DCHECK(spdy_websocket_stream_.get()); - DCHECK(socket_.get()); - DCHECK_NE(ERR_IO_PENDING, result); - - if (state_ == CLOSED) { - result = ERR_ABORTED; - } else if (result == OK) { - state_ = CONNECTING; - result = ERR_PROTOCOL_SWITCHED; - } else { - spdy_websocket_stream_.reset(); - } - - CompleteIO(result); -} - -void WebSocketJob::OnSentSpdyHeaders(int result) { - DCHECK_NE(INITIALIZED, state_); - if (state_ != CONNECTING) - return; if (delegate_) - delegate_->OnSentData(socket_, handshake_request_->original_length()); - handshake_request_.reset(); -} - -int WebSocketJob::OnReceivedSpdyResponseHeader( - const spdy::SpdyHeaderBlock& headers, int status) { - DCHECK_NE(INITIALIZED, state_); - if (state_ != CONNECTING) - return status; - if (status != OK) - return status; - // TODO(toyoshim): Fallback to non-spdy connection? - handshake_response_->ParseResponseHeaderBlock(headers, challenge_); - - SaveCookiesAndNotifyHeaderComplete(); - return OK; -} - -void WebSocketJob::OnSentSpdyData(int amount_sent) { - DCHECK_NE(INITIALIZED, state_); - DCHECK_NE(CONNECTING, state_); - if (state_ == CLOSED) - return; - if (!spdy_websocket_stream_.get()) - return; - OnSentData(socket_, amount_sent); -} - -void WebSocketJob::OnReceivedSpdyData(const char* data, int length) { - DCHECK_NE(INITIALIZED, state_); - DCHECK_NE(CONNECTING, state_); - if (state_ == CLOSED) - return; - if (!spdy_websocket_stream_.get()) - return; - OnReceivedData(socket_, data, length); -} - -void WebSocketJob::OnCloseSpdyStream() { - spdy_websocket_stream_.reset(); - OnClose(socket_); + delegate_->OnError(socket, error); } bool WebSocketJob::SendHandshakeRequest(const char* data, int len) { @@ -384,22 +317,14 @@ void WebSocketJob::AddCookieHeaderAndSend() { } } - if (spdy_websocket_stream_.get()) { - linked_ptr<spdy::SpdyHeaderBlock> headers(new spdy::SpdyHeaderBlock); - handshake_request_->GetRequestHeaderBlock( - socket_->url(), headers.get(), &challenge_); - spdy_websocket_stream_->SendRequest(headers); - } else { - const std::string& handshake_request = - handshake_request_->GetRawRequest(); - handshake_request_sent_ = 0; - socket_->net_log()->AddEvent( - NetLog::TYPE_WEB_SOCKET_SEND_REQUEST_HEADERS, - make_scoped_refptr( - new NetLogWebSocketHandshakeParameter(handshake_request))); - socket_->SendData(handshake_request.data(), - handshake_request.size()); - } + const std::string& handshake_request = handshake_request_->GetRawRequest(); + handshake_request_sent_ = 0; + socket_->net_log()->AddEvent( + NetLog::TYPE_WEB_SOCKET_SEND_REQUEST_HEADERS, + make_scoped_refptr( + new NetLogWebSocketHandshakeParameter(handshake_request))); + socket_->SendData(handshake_request.data(), + handshake_request.size()); } } @@ -527,48 +452,27 @@ int WebSocketJob::TrySpdyStream() { if (!socket_.get()) return ERR_FAILED; - if (!websocket_over_spdy_enabled_) - return OK; - - // Check if we have a SPDY session available. - HttpTransactionFactory* factory = - socket_->context()->http_transaction_factory(); - if (!factory) - return OK; - scoped_refptr<HttpNetworkSession> session = factory->GetSession(); - if (!session.get()) - return OK; - SpdySessionPool* spdy_pool = session->spdy_session_pool(); - const HostPortProxyPair pair(HostPortPair::FromURL(socket_->url()), - socket_->proxy_server()); - if (!spdy_pool->HasSession(pair)) - return OK; - - // Forbid wss downgrade to SPDY without SSL. - // TODO(toyoshim): Does it realize the same policy with HTTP? - scoped_refptr<SpdySession> spdy_session = - spdy_pool->Get(pair, *socket_->net_log()); - SSLInfo ssl_info; - bool was_npn_negotiated; - bool use_ssl = spdy_session->GetSSLInfo(&ssl_info, &was_npn_negotiated); - if (socket_->is_secure() && !use_ssl) - return OK; - - // Create SpdyWebSocketStream. - spdy_websocket_stream_.reset(new SpdyWebSocketStream(spdy_session, this)); - - int result = spdy_websocket_stream_->InitializeStream( - socket_->url(), MEDIUM, *socket_->net_log()); - if (result == OK) { - OnConnected(socket_, kMaxPendingSendAllowed); - return ERR_PROTOCOL_SWITCHED; - } - if (result != ERR_IO_PENDING) { - spdy_websocket_stream_.reset(); - return OK; + if (websocket_over_spdy_enabled_) { + // Check if we have a SPDY session available. + // If so, use it to create the websocket stream. + HttpTransactionFactory* factory = + socket_->context()->http_transaction_factory(); + if (factory) { + scoped_refptr<HttpNetworkSession> session = factory->GetSession(); + if (session.get()) { + SpdySessionPool* spdy_pool = session->spdy_session_pool(); + const HostPortProxyPair pair(HostPortPair::FromURL(socket_->url()), + socket_->proxy_server()); + if (spdy_pool->HasSession(pair)) { + // TODO(toyoshim): Switch to SpdyWebSocketStream here by returning + // ERR_PROTOCOL_SWITCHED. + } + } + } } - - return ERR_IO_PENDING; + // No SPDY session was available. + // Fallback to connecting a new socket. + return OK; } void WebSocketJob::SetWaiting() { @@ -591,14 +495,6 @@ void WebSocketJob::Wakeup() { void WebSocketJob::RetryPendingIO() { int result = TrySpdyStream(); - - // In the case of ERR_IO_PENDING, CompleteIO() will be called from - // OnCreatedSpdyStream(). - if (result != ERR_IO_PENDING) - CompleteIO(result); -} - -void WebSocketJob::CompleteIO(int result) { // |callback_| may be NULL if OnClose() or DetachDelegate() was called. if (callback_) { net::CompletionCallback* callback = callback_; @@ -609,14 +505,12 @@ void WebSocketJob::CompleteIO(int result) { } bool WebSocketJob::SendDataInternal(const char* data, int length) { - if (spdy_websocket_stream_.get()) - return ERR_IO_PENDING == spdy_websocket_stream_->SendData(data, length); + // TODO(toyoshim): Call protocol specific SendData(). return socket_->SendData(data, length); } void WebSocketJob::CloseInternal() { - if (spdy_websocket_stream_.get()) - spdy_websocket_stream_->Close(); + // TODO(toyoshim): Call protocol specific Close(). socket_->Close(); } diff --git a/net/websockets/websocket_job.h b/net/websockets/websocket_job.h index f0e67c6..369ef56 100644 --- a/net/websockets/websocket_job.h +++ b/net/websockets/websocket_job.h @@ -13,7 +13,6 @@ #include "net/base/address_list.h" #include "net/base/completion_callback.h" #include "net/socket_stream/socket_stream_job.h" -#include "net/spdy/spdy_websocket_stream.h" class GURL; @@ -32,8 +31,7 @@ class WebSocketHandshakeResponseHandler; // TODO(ukai): refactor websocket.cc to use this. class NET_API WebSocketJob : public SocketStreamJob, - public SocketStream::Delegate, - public SpdyWebSocketStream::Delegate { + public SocketStream::Delegate { public: // This is state of WebSocket, not SocketStream. enum State { @@ -72,15 +70,6 @@ class NET_API WebSocketJob SocketStream* socket, AuthChallengeInfo* auth_info); virtual void OnError(const SocketStream* socket, int error); - // SpdyWebSocketStream::Delegate methods. - virtual void OnCreatedSpdyStream(int status); - virtual void OnSentSpdyHeaders(int status); - virtual int OnReceivedSpdyResponseHeader( - const spdy::SpdyHeaderBlock& headers, int status); - virtual void OnSentSpdyData(int amount_sent); - virtual void OnReceivedSpdyData(const char* data, int length); - virtual void OnCloseSpdyStream(); - private: friend class WebSocketThrottle; friend class WebSocketJobTest; @@ -103,7 +92,6 @@ class NET_API WebSocketJob bool IsWaiting() const; void Wakeup(); void RetryPendingIO(); - void CompleteIO(int result); bool SendDataInternal(const char* data, int length); void CloseInternal(); @@ -130,9 +118,6 @@ class NET_API WebSocketJob scoped_refptr<DrainableIOBuffer> current_buffer_; scoped_ptr<WebSocketFrameHandler> receive_frame_handler_; - scoped_ptr<SpdyWebSocketStream> spdy_websocket_stream_; - std::string challenge_; - DISALLOW_COPY_AND_ASSIGN(WebSocketJob); }; diff --git a/net/websockets/websocket_job_unittest.cc b/net/websockets/websocket_job_unittest.cc index ca17c33..e863faf 100644 --- a/net/websockets/websocket_job_unittest.cc +++ b/net/websockets/websocket_job_unittest.cc @@ -19,13 +19,9 @@ #include "net/base/sys_addrinfo.h" #include "net/base/test_completion_callback.h" #include "net/base/transport_security_state.h" -#include "net/http/http_transaction_factory.h" #include "net/proxy/proxy_service.h" #include "net/socket/socket_test_util.h" #include "net/socket_stream/socket_stream.h" -#include "net/spdy/spdy_session.h" -#include "net/spdy/spdy_test_util.h" -#include "net/spdy/spdy_websocket_test_util.h" #include "net/url_request/url_request_context.h" #include "net/websockets/websocket_throttle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -202,65 +198,6 @@ class MockURLRequestContext : public net::URLRequestContext { scoped_refptr<net::TransportSecurityState> transport_security_state_; }; -class MockHttpTransactionFactory : public net::HttpTransactionFactory { - public: - MockHttpTransactionFactory(scoped_refptr<net::OrderedSocketData>& data) { - data_ = data; - data_->AddRef(); - net::MockConnect connect_data(false, net::OK); - data_->set_connect_data(connect_data); - session_deps_.reset(new net::SpdySessionDependencies); - session_deps_->socket_factory->AddSocketDataProvider(data_.get()); - http_session_ = - net::SpdySessionDependencies::SpdyCreateSession(session_deps_.get()); - host_port_pair_.set_host("example.com"); - host_port_pair_.set_port(80); - host_port_proxy_pair_.first = host_port_pair_; - host_port_proxy_pair_.second = net::ProxyServer::Direct(); - net::SpdySessionPool* spdy_session_pool = - http_session_->spdy_session_pool(); - DCHECK(spdy_session_pool); - EXPECT_FALSE(spdy_session_pool->HasSession(host_port_proxy_pair_)); - session_ = - spdy_session_pool->Get(host_port_proxy_pair_, net::BoundNetLog()); - EXPECT_TRUE(spdy_session_pool->HasSession(host_port_proxy_pair_)); - - transport_params_ = new net::TransportSocketParams(host_port_pair_, - net::MEDIUM, - GURL(), - false, - false); - net::ClientSocketHandle* connection = new net::ClientSocketHandle; - EXPECT_EQ(net::OK, connection->Init(host_port_pair_.ToString(), - transport_params_, - net::MEDIUM, - NULL, - http_session_->transport_socket_pool(), - net::BoundNetLog())); - EXPECT_EQ(net::OK, - session_->InitializeWithSocket(connection, false, net::OK)); - } - virtual int CreateTransaction(scoped_ptr<net::HttpTransaction>* trans) { - NOTREACHED(); - return net::ERR_UNEXPECTED; - } - virtual net::HttpCache* GetCache() { - NOTREACHED(); - return NULL; - } - virtual net::HttpNetworkSession* GetSession() { - return http_session_.get(); - } - private: - scoped_refptr<net::OrderedSocketData> data_; - scoped_ptr<net::SpdySessionDependencies> session_deps_; - scoped_refptr<net::HttpNetworkSession> http_session_; - scoped_refptr<net::TransportSocketParams> transport_params_; - scoped_refptr<net::SpdySession> session_; - net::HostPortPair host_port_pair_; - net::HostPortProxyPair host_port_proxy_pair_; -}; - } namespace net { @@ -268,7 +205,6 @@ namespace net { class WebSocketJobTest : public PlatformTest { public: virtual void SetUp() { - spdy::SpdyFramer::set_enable_compression_default(false); stream_type_ = STREAM_INVALID; cookie_store_ = new MockCookieStore; context_ = new MockURLRequestContext(cookie_store_.get()); @@ -303,33 +239,37 @@ class WebSocketJobTest : public PlatformTest { void InitWebSocketJob(const GURL& url, MockSocketStreamDelegate* delegate, StreamType stream_type) { - DCHECK_NE(STREAM_INVALID, stream_type); stream_type_ = stream_type; websocket_ = new WebSocketJob(delegate); - if (stream_type == STREAM_MOCK_SOCKET) - socket_ = new MockSocketStream(url, websocket_.get()); - - if (stream_type == STREAM_SOCKET || stream_type == STREAM_SPDY_WEBSOCKET) { - if (stream_type == STREAM_SPDY_WEBSOCKET) { - http_factory_.reset(new MockHttpTransactionFactory(data_)); - context_->set_http_transaction_factory(http_factory_.get()); - } - + if (stream_type == STREAM_SOCKET || + stream_type == STREAM_SPDY_WEBSOCKET) { ssl_config_service_ = new MockSSLConfigService(); context_->set_ssl_config_service(ssl_config_service_); proxy_service_.reset(net::ProxyService::CreateDirect()); context_->set_proxy_service(proxy_service_.get()); host_resolver_.reset(new net::MockHostResolver); context_->set_host_resolver(host_resolver_.get()); - - socket_ = new SocketStream(url, websocket_.get()); - socket_factory_.reset(new MockClientSocketFactory); - DCHECK(data_.get()); - socket_factory_->AddSocketDataProvider(data_.get()); - socket_->SetClientSocketFactory(socket_factory_.get()); } + switch (stream_type) { + case STREAM_INVALID: + NOTREACHED(); + break; + case STREAM_MOCK_SOCKET: + socket_ = new MockSocketStream(url, websocket_.get()); + break; + case STREAM_SOCKET: + socket_ = new SocketStream(url, websocket_.get()); + socket_factory_.reset(new MockClientSocketFactory); + DCHECK(data_.get()); + socket_factory_->AddSocketDataProvider(data_.get()); + socket_->SetClientSocketFactory(socket_factory_.get()); + break; + case STREAM_SPDY_WEBSOCKET: + // TODO(toyoshim): Support SpdyWebSocketStream. + break; + } websocket_->InitSocketStream(socket_.get()); websocket_->set_context(context_.get()); struct addrinfo addr; @@ -384,7 +324,6 @@ class WebSocketJobTest : public PlatformTest { void TestHSTSUpgrade(); void TestInvalidSendData(); void TestConnectByWebSocket(); - void TestConnectBySpdy(bool use_spdy); StreamType stream_type_; scoped_refptr<MockCookieStore> cookie_store_; @@ -397,7 +336,6 @@ class WebSocketJobTest : public PlatformTest { scoped_refptr<MockSSLConfigService> ssl_config_service_; scoped_ptr<net::ProxyService> proxy_service_; scoped_ptr<net::MockHostResolver> host_resolver_; - scoped_ptr<MockHttpTransactionFactory> http_factory_; static const char kHandshakeRequestWithoutCookie[]; static const char kHandshakeRequestWithCookie[]; @@ -406,8 +344,6 @@ class WebSocketJobTest : public PlatformTest { static const char kHandshakeResponseWithCookie[]; static const char kDataHello[]; static const char kDataWorld[]; - static const char* const kHandshakeRequestForSpdy[]; - static const char* const kHandshakeResponseForSpdy[]; static const size_t kHandshakeRequestWithoutCookieLength; static const size_t kHandshakeRequestWithCookieLength; static const size_t kHandshakeRequestWithFilteredCookieLength; @@ -480,22 +416,6 @@ const char WebSocketJobTest::kDataHello[] = "Hello, "; const char WebSocketJobTest::kDataWorld[] = "World!\n"; -// TODO(toyoshim): I should clarify which WebSocket headers for handshake must -// be exported to SPDY SYN_STREAM and SYN_REPLY. -// Because it depends on HyBi versions, just define it as follow for now. -const char* const WebSocketJobTest::kHandshakeRequestForSpdy[] = { - "host", "example.com", - "origin", "http://example.com", - "sec-websocket-protocol", "sample", - "url", "ws://example.com/demo" -}; - -const char* const WebSocketJobTest::kHandshakeResponseForSpdy[] = { - "sec-websocket-origin", "http://example.com", - "sec-websocket-location", "ws://example.com/demo", - "sec-websocket-protocol", "sample", -}; - const size_t WebSocketJobTest::kHandshakeRequestWithoutCookieLength = arraysize(kHandshakeRequestWithoutCookie) - 1; const size_t WebSocketJobTest::kHandshakeRequestWithCookieLength = @@ -704,6 +624,7 @@ void WebSocketJobTest::TestInvalidSendData() { // OrderedSocketData provide socket level verifiation by checking out-going // packets in comparison with the MockWrite array and emulating in-coming // packets with MockRead array. +// TODO(toyoshim): Add tests which verify protocol switch and ERR_IO_PENDING. void WebSocketJobTest::TestConnectByWebSocket() { // This is a test for verifying cooperation between WebSocketJob and @@ -750,94 +671,6 @@ void WebSocketJobTest::TestConnectByWebSocket() { EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState()); } -void WebSocketJobTest::TestConnectBySpdy(bool use_spdy) { - // This is a test for verifying cooperation between WebSocketJob and - // SocketStream in the situation we have SPDY session to the server. - MockWrite writes_websocket[] = { - MockWrite(true, - kHandshakeRequestWithoutCookie, - kHandshakeRequestWithoutCookieLength, - 1), - MockWrite(true, - kDataHello, - kDataHelloLength, - 3) - }; - MockRead reads_websocket[] = { - MockRead(true, - kHandshakeResponseWithoutCookie, - kHandshakeResponseWithoutCookieLength, - 2), - MockRead(true, - kDataWorld, - kDataWorldLength, - 4), - MockRead(false, 0, 5) // EOF - }; - - const spdy::SpdyStreamId kStreamId = 1; - scoped_ptr<spdy::SpdyFrame> request_frame( - ConstructSpdyWebSocketHandshakeRequestFrame( - kHandshakeRequestForSpdy, - arraysize(kHandshakeRequestForSpdy) / 2, - kStreamId, - MEDIUM)); - scoped_ptr<spdy::SpdyFrame> response_frame( - ConstructSpdyWebSocketHandshakeResponseFrame( - kHandshakeResponseForSpdy, - arraysize(kHandshakeResponseForSpdy) / 2, - kStreamId, - MEDIUM)); - scoped_ptr<spdy::SpdyFrame> data_hello_frame( - ConstructSpdyWebSocketDataFrame( - kDataHello, - kDataHelloLength, - kStreamId, - false)); - scoped_ptr<spdy::SpdyFrame> data_world_frame( - ConstructSpdyWebSocketDataFrame( - kDataWorld, - kDataWorldLength, - kStreamId, - false)); - MockWrite writes_spdy[] = { - CreateMockWrite(*request_frame.get(), 1), - CreateMockWrite(*data_hello_frame.get(), 3), - }; - MockRead reads_spdy[] = { - CreateMockRead(*response_frame.get(), 2), - CreateMockRead(*data_world_frame.get(), 4), - MockRead(false, 0, 5) // EOF - }; - - if (use_spdy) - data_ = new OrderedSocketData( - reads_spdy, arraysize(reads_spdy), - writes_spdy, arraysize(writes_spdy)); - else - data_ = new OrderedSocketData( - reads_websocket, arraysize(reads_websocket), - writes_websocket, arraysize(writes_websocket)); - - GURL url("ws://example.com/demo"); - MockSocketStreamDelegate delegate; - WebSocketJobTest* test = this; - delegate.SetOnConnected( - NewCallback(test, &WebSocketJobTest::DoSendRequest)); - delegate.SetOnReceivedData( - NewCallback(test, &WebSocketJobTest::DoSendData)); - delegate.SetOnClose( - NewCallback(test, &WebSocketJobTest::DoSync)); - InitWebSocketJob(url, &delegate, STREAM_SPDY_WEBSOCKET); - - websocket_->Connect(); - EXPECT_EQ(OK, WaitForResult()); - - EXPECT_TRUE(data_->at_read_eof()); - EXPECT_TRUE(data_->at_write_eof()); - EXPECT_EQ(WebSocketJob::CLOSED, GetWebSocketJobState()); -} - // Execute tests in both spdy-disabled mode and spdy-enabled mode. TEST_F(WebSocketJobTest, SimpleHandshake) { WebSocketJob::set_websocket_over_spdy_enabled(false); @@ -909,17 +742,4 @@ TEST_F(WebSocketJobTest, ConnectByWebSocketSpdyEnabled) { TestConnectByWebSocket(); } -TEST_F(WebSocketJobTest, ConnectBySpdy) { - WebSocketJob::set_websocket_over_spdy_enabled(false); - TestConnectBySpdy(false); -} - -TEST_F(WebSocketJobTest, ConnectBySpdySpdyEnabled) { - WebSocketJob::set_websocket_over_spdy_enabled(true); - TestConnectBySpdy(true); -} - -// TODO(toyoshim): Add tests to verify throttling, SPDY stream limitation. -// TODO(toyoshim,yutak): Add tests to verify closing handshake. - } // namespace net |