diff options
author | ricea@chromium.org <ricea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-28 09:35:41 +0000 |
---|---|---|
committer | ricea@chromium.org <ricea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-28 09:35:41 +0000 |
commit | f4533ba8c4dbce9f5bc35a0da3fe08c5f4ed0501 (patch) | |
tree | 33903cd7e19e38204faa3c7f56fe1050bd6fe57f /net/url_request/url_request_http_job_unittest.cc | |
parent | 91cd4febe4c959d8256341e25a59a4d9dca9ca69 (diff) | |
download | chromium_src-f4533ba8c4dbce9f5bc35a0da3fe08c5f4ed0501.zip chromium_src-f4533ba8c4dbce9f5bc35a0da3fe08c5f4ed0501.tar.gz chromium_src-f4533ba8c4dbce9f5bc35a0da3fe08c5f4ed0501.tar.bz2 |
Add WebSocket handshake support to UrlRequestHttpJob, by supporting ws: and wss: protocols and passing the WebSocketStreamFactory through to HttpNetworkTransaction.
BUG=315027
TEST=net_unittests --gtest_filter=URLRequestHttpJob*
Review URL: https://codereview.chromium.org/23500007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@237751 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/url_request/url_request_http_job_unittest.cc')
-rw-r--r-- | net/url_request/url_request_http_job_unittest.cc | 169 |
1 files changed, 168 insertions, 1 deletions
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc index 50d3391..3a20b30 100644 --- a/net/url_request/url_request_http_job_unittest.cc +++ b/net/url_request/url_request_http_job_unittest.cc @@ -8,12 +8,16 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" +#include "base/run_loop.h" #include "net/base/auth.h" #include "net/base/request_priority.h" #include "net/http/http_transaction_factory.h" #include "net/http/http_transaction_unittest.h" +#include "net/socket/socket_test_util.h" #include "net/url_request/url_request_status.h" #include "net/url_request/url_request_test_util.h" +#include "net/websockets/websocket_handshake_stream_base.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -21,12 +25,14 @@ namespace net { namespace { +using ::testing::Return; + // Inherit from URLRequestHttpJob to expose the priority and some // other hidden functions. class TestURLRequestHttpJob : public URLRequestHttpJob { public: explicit TestURLRequestHttpJob(URLRequest* request) - : URLRequestHttpJob(request, NULL, + : URLRequestHttpJob(request, request->context()->network_delegate(), request->context()->http_user_agent_settings()) {} using URLRequestHttpJob::SetPriority; @@ -119,6 +125,167 @@ TEST_F(URLRequestHttpJobTest, SetSubsequentTransactionPriority) { EXPECT_EQ(LOW, network_layer_.last_transaction()->priority()); } +// This base class just serves to set up some things before the TestURLRequest +// constructor is called. +class URLRequestHttpJobWebSocketTestBase : public ::testing::Test { + protected: + URLRequestHttpJobWebSocketTestBase() : socket_data_(NULL, 0, NULL, 0), + context_(true) { + // A Network Delegate is required for the WebSocketHandshakeStreamBase + // object to be passed on to the HttpNetworkTransaction. + context_.set_network_delegate(&network_delegate_); + + // Attempting to create real ClientSocketHandles is not going to work out so + // well. Set up a fake socket factory. + socket_factory_.AddSocketDataProvider(&socket_data_); + context_.set_client_socket_factory(&socket_factory_); + context_.Init(); + } + + StaticSocketDataProvider socket_data_; + TestNetworkDelegate network_delegate_; + MockClientSocketFactory socket_factory_; + TestURLRequestContext context_; +}; + +class URLRequestHttpJobWebSocketTest + : public URLRequestHttpJobWebSocketTestBase { + protected: + URLRequestHttpJobWebSocketTest() + : req_(GURL("ws://www.example.com"), + DEFAULT_PRIORITY, + &delegate_, + &context_) { + // The TestNetworkDelegate expects a call to NotifyBeforeURLRequest before + // anything else happens. + GURL url("ws://localhost/"); + TestCompletionCallback dummy; + network_delegate_.NotifyBeforeURLRequest(&req_, dummy.callback(), &url); + } + + TestDelegate delegate_; + TestURLRequest req_; +}; + +class MockCreateHelper : public WebSocketHandshakeStreamBase::CreateHelper { + public: + // GoogleMock does not appear to play nicely with move-only types like + // scoped_ptr, so this forwarding method acts as a workaround. + virtual WebSocketHandshakeStreamBase* CreateBasicStream( + scoped_ptr<ClientSocketHandle> connection, + bool using_proxy) OVERRIDE { + // Discard the arguments since we don't need them anyway. + return CreateBasicStreamMock(); + } + + MOCK_METHOD0(CreateBasicStreamMock, + WebSocketHandshakeStreamBase*()); + + MOCK_METHOD2(CreateSpdyStream, + WebSocketHandshakeStreamBase*(const base::WeakPtr<SpdySession>&, + bool)); +}; + +class FakeWebSocketHandshakeStream : public WebSocketHandshakeStreamBase { + public: + FakeWebSocketHandshakeStream() : initialize_stream_was_called_(false) {} + + bool initialize_stream_was_called() const { + return initialize_stream_was_called_; + } + + // Fake implementation of HttpStreamBase methods. + virtual int InitializeStream(const HttpRequestInfo* request_info, + RequestPriority priority, + const BoundNetLog& net_log, + const CompletionCallback& callback) OVERRIDE { + initialize_stream_was_called_ = true; + return ERR_IO_PENDING; + } + + virtual int SendRequest(const HttpRequestHeaders& request_headers, + HttpResponseInfo* response, + const CompletionCallback& callback) OVERRIDE { + return ERR_IO_PENDING; + } + + virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE { + return ERR_IO_PENDING; + } + + virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE { + return NULL; + } + + virtual int ReadResponseBody(IOBuffer* buf, + int buf_len, + const CompletionCallback& callback) OVERRIDE { + return ERR_IO_PENDING; + } + + virtual void Close(bool not_reusable) OVERRIDE {} + + virtual bool IsResponseBodyComplete() const OVERRIDE { return false; } + + virtual bool CanFindEndOfResponse() const OVERRIDE { return false; } + + virtual bool IsConnectionReused() const OVERRIDE { return false; } + virtual void SetConnectionReused() OVERRIDE {} + + virtual bool IsConnectionReusable() const OVERRIDE { return false; } + + virtual bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const + OVERRIDE { + return false; + } + + virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {} + + virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) + OVERRIDE {} + + virtual bool IsSpdyHttpStream() const OVERRIDE { return false; } + + virtual void Drain(HttpNetworkSession* session) OVERRIDE {} + + virtual void SetPriority(RequestPriority priority) OVERRIDE {} + + // Fake implementation of WebSocketHandshakeStreamBase method(s) + virtual scoped_ptr<WebSocketStream> Upgrade() OVERRIDE { + return scoped_ptr<WebSocketStream>(); + } + + private: + bool initialize_stream_was_called_; +}; + +TEST_F(URLRequestHttpJobWebSocketTest, RejectedWithoutCreateHelper) { + scoped_refptr<TestURLRequestHttpJob> job(new TestURLRequestHttpJob(&req_)); + job->Start(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(URLRequestStatus::FAILED, req_.status().status()); + EXPECT_EQ(ERR_DISALLOWED_URL_SCHEME, req_.status().error()); +} + +TEST_F(URLRequestHttpJobWebSocketTest, CreateHelperPassedThrough) { + scoped_refptr<TestURLRequestHttpJob> job(new TestURLRequestHttpJob(&req_)); + scoped_ptr<MockCreateHelper> create_helper( + new ::testing::StrictMock<MockCreateHelper>()); + FakeWebSocketHandshakeStream* fake_handshake_stream( + new FakeWebSocketHandshakeStream); + // Ownership of fake_handshake_stream is transferred when CreateBasicStream() + // is called. + EXPECT_CALL(*create_helper, CreateBasicStreamMock()) + .WillOnce(Return(fake_handshake_stream)); + req_.SetUserData(WebSocketHandshakeStreamBase::CreateHelper::DataKey(), + create_helper.release()); + req_.SetLoadFlags(LOAD_DISABLE_CACHE); + job->Start(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(URLRequestStatus::IO_PENDING, req_.status().status()); + EXPECT_TRUE(fake_handshake_stream->initialize_stream_was_called()); +} + } // namespace } // namespace net |