blob: ff268806bc88e11f72e5cbf3c2073cfafaf165e5 [file] [log] [blame]
Bence Béky7294fc22018-02-08 14:26:171// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/websockets/websocket_basic_stream_adapters.h"
6
7#include <utility>
8
9#include "base/memory/scoped_refptr.h"
Bence Béky29f661602018-02-16 02:45:0210#include "base/memory/weak_ptr.h"
11#include "base/run_loop.h"
Bence Béky7294fc22018-02-08 14:26:1712#include "base/strings/string_piece.h"
13#include "net/base/host_port_pair.h"
14#include "net/base/io_buffer.h"
15#include "net/base/net_errors.h"
Bence Béky29f661602018-02-16 02:45:0216#include "net/base/privacy_mode.h"
17#include "net/base/proxy_server.h"
Bence Béky7294fc22018-02-08 14:26:1718#include "net/base/test_completion_callback.h"
19#include "net/dns/mock_host_resolver.h"
20#include "net/http/http_network_session.h"
Bence Béky29f661602018-02-16 02:45:0221#include "net/log/net_log_with_source.h"
Bence Béky7294fc22018-02-08 14:26:1722#include "net/socket/client_socket_handle.h"
23#include "net/socket/client_socket_pool_manager_impl.h"
Bence Béky29f661602018-02-16 02:45:0224#include "net/socket/socket_tag.h"
Bence Béky7294fc22018-02-08 14:26:1725#include "net/socket/socket_test_util.h"
26#include "net/socket/ssl_client_socket_pool.h"
27#include "net/socket/transport_client_socket_pool.h"
Bence Békyda280c62018-04-12 15:08:3728#include "net/socket/websocket_endpoint_lock_manager.h"
Bence Béky94658bf2018-05-11 19:22:5829#include "net/spdy/spdy_session.h"
30#include "net/spdy/spdy_session_key.h"
31#include "net/spdy/spdy_test_util_common.h"
Bence Béky7294fc22018-02-08 14:26:1732#include "net/ssl/ssl_config.h"
Bence Béky29f661602018-02-16 02:45:0233#include "net/ssl/ssl_info.h"
34#include "net/test/cert_test_util.h"
Bence Béky7294fc22018-02-08 14:26:1735#include "net/test/gtest_util.h"
Bence Béky29f661602018-02-16 02:45:0236#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0137#include "net/test/test_with_scoped_task_environment.h"
Bence Béky7294fc22018-02-08 14:26:1738#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Bence Béky46bfbc12018-02-22 19:28:2039#include "net/websockets/websocket_test_util.h"
Bence Béky29f661602018-02-16 02:45:0240#include "testing/gmock/include/gmock/gmock.h"
Bence Béky7294fc22018-02-08 14:26:1741#include "testing/gtest/include/gtest/gtest.h"
42
Bence Béky29f661602018-02-16 02:45:0243using testing::Test;
44using testing::StrictMock;
45using testing::_;
46
Bence Béky7294fc22018-02-08 14:26:1747namespace net {
48
49namespace test {
50
51const char* const kGroupName = "ssl/www.example.org:443";
52
Bence Béky98447b12018-05-08 03:14:0153class WebSocketClientSocketHandleAdapterTest
54 : public TestWithScopedTaskEnvironment {
Bence Béky7294fc22018-02-08 14:26:1755 protected:
56 WebSocketClientSocketHandleAdapterTest()
57 : host_port_pair_("www.example.org", 443),
58 socket_pool_manager_(std::make_unique<ClientSocketPoolManagerImpl>(
Bence Béky29f661602018-02-16 02:45:0259 net_log_.net_log(),
Bence Béky7294fc22018-02-08 14:26:1760 &socket_factory_,
61 nullptr,
62 nullptr,
63 &host_resolver,
64 nullptr,
65 nullptr,
66 nullptr,
67 nullptr,
68 nullptr,
69 "test_shard",
70 nullptr,
Bence Békyda280c62018-04-12 15:08:3771 &websocket_endpoint_lock_manager_,
Bence Béky7294fc22018-02-08 14:26:1772 HttpNetworkSession::NORMAL_SOCKET_POOL)),
73 transport_params_(base::MakeRefCounted<TransportSocketParams>(
74 host_port_pair_,
75 false,
Matt Menked629fd492018-12-12 05:41:5976 OnHostResolutionCallback())),
Matt Menke01529f012018-12-14 18:13:0177 ssl_params_(
78 base::MakeRefCounted<SSLSocketParams>(transport_params_,
79 nullptr,
80 nullptr,
81 host_port_pair_,
82 SSLConfig(),
83 PRIVACY_MODE_DISABLED)) {}
Bence Béky7294fc22018-02-08 14:26:1784
Bence Béky29f661602018-02-16 02:45:0285 ~WebSocketClientSocketHandleAdapterTest() override = default;
86
Bence Béky7294fc22018-02-08 14:26:1787 bool InitClientSocketHandle(ClientSocketHandle* connection) {
88 TestCompletionCallback callback;
89 int rv = connection->Init(
90 kGroupName, ssl_params_, MEDIUM, SocketTag(),
91 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
Bence Béky29f661602018-02-16 02:45:0292 socket_pool_manager_->GetSSLSocketPool(), net_log_);
Bence Béky7294fc22018-02-08 14:26:1793 rv = callback.GetResult(rv);
94 return rv == OK;
95 }
96
97 const HostPortPair host_port_pair_;
Bence Béky29f661602018-02-16 02:45:0298 NetLogWithSource net_log_;
Bence Béky7294fc22018-02-08 14:26:1799 MockClientSocketFactory socket_factory_;
100 MockHostResolver host_resolver;
101 std::unique_ptr<ClientSocketPoolManagerImpl> socket_pool_manager_;
102 scoped_refptr<TransportSocketParams> transport_params_;
103 scoped_refptr<SSLSocketParams> ssl_params_;
Bence Békyda280c62018-04-12 15:08:37104 WebSocketEndpointLockManager websocket_endpoint_lock_manager_;
Bence Béky7294fc22018-02-08 14:26:17105};
106
107TEST_F(WebSocketClientSocketHandleAdapterTest, Uninitialized) {
108 auto connection = std::make_unique<ClientSocketHandle>();
109 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
110 EXPECT_FALSE(adapter.is_initialized());
111}
112
113TEST_F(WebSocketClientSocketHandleAdapterTest, IsInitialized) {
Ryan Sleevib8d7ea02018-05-07 20:01:01114 StaticSocketDataProvider data;
Bence Béky7294fc22018-02-08 14:26:17115 socket_factory_.AddSocketDataProvider(&data);
116 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
117 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
118
119 auto connection = std::make_unique<ClientSocketHandle>();
120 ClientSocketHandle* const connection_ptr = connection.get();
121
122 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
123 EXPECT_FALSE(adapter.is_initialized());
124
125 EXPECT_TRUE(InitClientSocketHandle(connection_ptr));
126
127 EXPECT_TRUE(adapter.is_initialized());
128}
129
130TEST_F(WebSocketClientSocketHandleAdapterTest, Disconnect) {
Ryan Sleevib8d7ea02018-05-07 20:01:01131 StaticSocketDataProvider data;
Bence Béky7294fc22018-02-08 14:26:17132 socket_factory_.AddSocketDataProvider(&data);
133 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
134 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
135
136 auto connection = std::make_unique<ClientSocketHandle>();
137 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
138
139 StreamSocket* const socket = connection->socket();
140
141 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
142 EXPECT_TRUE(adapter.is_initialized());
143
144 EXPECT_TRUE(socket->IsConnected());
145 adapter.Disconnect();
146 EXPECT_FALSE(socket->IsConnected());
147}
148
149TEST_F(WebSocketClientSocketHandleAdapterTest, Read) {
150 MockRead reads[] = {MockRead(SYNCHRONOUS, "foo"), MockRead("bar")};
Ryan Sleevib8d7ea02018-05-07 20:01:01151 StaticSocketDataProvider data(reads, base::span<MockWrite>());
Bence Béky7294fc22018-02-08 14:26:17152 socket_factory_.AddSocketDataProvider(&data);
153 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
154 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
155
156 auto connection = std::make_unique<ClientSocketHandle>();
157 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
158
159 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
160 EXPECT_TRUE(adapter.is_initialized());
161
162 // Buffer larger than each MockRead.
163 const int kReadBufSize = 1024;
164 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
Bence Békybdbb0e72018-08-07 21:42:59165 int rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky7294fc22018-02-08 14:26:17166 ASSERT_EQ(3, rv);
167 EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
168
169 TestCompletionCallback callback;
170 rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
171 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
172 rv = callback.WaitForResult();
173 ASSERT_EQ(3, rv);
174 EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
175
176 EXPECT_TRUE(data.AllReadDataConsumed());
177 EXPECT_TRUE(data.AllWriteDataConsumed());
178}
179
180TEST_F(WebSocketClientSocketHandleAdapterTest, ReadIntoSmallBuffer) {
181 MockRead reads[] = {MockRead(SYNCHRONOUS, "foo"), MockRead("bar")};
Ryan Sleevib8d7ea02018-05-07 20:01:01182 StaticSocketDataProvider data(reads, base::span<MockWrite>());
Bence Béky7294fc22018-02-08 14:26:17183 socket_factory_.AddSocketDataProvider(&data);
184 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
185 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
186
187 auto connection = std::make_unique<ClientSocketHandle>();
188 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
189
190 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
191 EXPECT_TRUE(adapter.is_initialized());
192
193 // Buffer smaller than each MockRead.
194 const int kReadBufSize = 2;
195 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
Bence Békybdbb0e72018-08-07 21:42:59196 int rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky7294fc22018-02-08 14:26:17197 ASSERT_EQ(2, rv);
198 EXPECT_EQ("fo", base::StringPiece(read_buf->data(), rv));
199
Bence Békybdbb0e72018-08-07 21:42:59200 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky7294fc22018-02-08 14:26:17201 ASSERT_EQ(1, rv);
202 EXPECT_EQ("o", base::StringPiece(read_buf->data(), rv));
203
204 TestCompletionCallback callback1;
205 rv = adapter.Read(read_buf.get(), kReadBufSize, callback1.callback());
206 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
207 rv = callback1.WaitForResult();
208 ASSERT_EQ(2, rv);
209 EXPECT_EQ("ba", base::StringPiece(read_buf->data(), rv));
210
Bence Békybdbb0e72018-08-07 21:42:59211 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky7294fc22018-02-08 14:26:17212 ASSERT_EQ(1, rv);
213 EXPECT_EQ("r", base::StringPiece(read_buf->data(), rv));
214
215 EXPECT_TRUE(data.AllReadDataConsumed());
216 EXPECT_TRUE(data.AllWriteDataConsumed());
217}
218
219TEST_F(WebSocketClientSocketHandleAdapterTest, Write) {
220 MockWrite writes[] = {MockWrite(SYNCHRONOUS, "foo"), MockWrite("bar")};
Ryan Sleevib8d7ea02018-05-07 20:01:01221 StaticSocketDataProvider data(base::span<MockRead>(), writes);
Bence Béky7294fc22018-02-08 14:26:17222 socket_factory_.AddSocketDataProvider(&data);
223 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
224 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
225
226 auto connection = std::make_unique<ClientSocketHandle>();
227 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
228
229 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
230 EXPECT_TRUE(adapter.is_initialized());
231
232 auto write_buf1 = base::MakeRefCounted<StringIOBuffer>("foo");
Bence Békybdbb0e72018-08-07 21:42:59233 int rv =
234 adapter.Write(write_buf1.get(), write_buf1->size(),
235 CompletionOnceCallback(), TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky7294fc22018-02-08 14:26:17236 ASSERT_EQ(3, rv);
237
238 auto write_buf2 = base::MakeRefCounted<StringIOBuffer>("bar");
239 TestCompletionCallback callback;
240 rv = adapter.Write(write_buf2.get(), write_buf2->size(), callback.callback(),
241 TRAFFIC_ANNOTATION_FOR_TESTS);
242 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
243 rv = callback.WaitForResult();
244 ASSERT_EQ(3, rv);
245
246 EXPECT_TRUE(data.AllReadDataConsumed());
247 EXPECT_TRUE(data.AllWriteDataConsumed());
248}
249
250// Test that if both Read() and Write() returns asynchronously,
251// the two callbacks are handled correctly.
252TEST_F(WebSocketClientSocketHandleAdapterTest, AsyncReadAndWrite) {
253 MockRead reads[] = {MockRead("foobar")};
254 MockWrite writes[] = {MockWrite("baz")};
Ryan Sleevib8d7ea02018-05-07 20:01:01255 StaticSocketDataProvider data(reads, writes);
Bence Béky7294fc22018-02-08 14:26:17256 socket_factory_.AddSocketDataProvider(&data);
257 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
258 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
259
260 auto connection = std::make_unique<ClientSocketHandle>();
261 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
262
263 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
264 EXPECT_TRUE(adapter.is_initialized());
265
266 const int kReadBufSize = 1024;
267 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
268 TestCompletionCallback read_callback;
269 int rv = adapter.Read(read_buf.get(), kReadBufSize, read_callback.callback());
270 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
271
272 auto write_buf = base::MakeRefCounted<StringIOBuffer>("baz");
273 TestCompletionCallback write_callback;
274 rv = adapter.Write(write_buf.get(), write_buf->size(),
275 write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
276 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
277
278 rv = read_callback.WaitForResult();
279 ASSERT_EQ(6, rv);
280 EXPECT_EQ("foobar", base::StringPiece(read_buf->data(), rv));
281
282 rv = write_callback.WaitForResult();
283 ASSERT_EQ(3, rv);
284
285 EXPECT_TRUE(data.AllReadDataConsumed());
286 EXPECT_TRUE(data.AllWriteDataConsumed());
287}
288
Bence Béky29f661602018-02-16 02:45:02289class MockDelegate : public WebSocketSpdyStreamAdapter::Delegate {
290 public:
Daniel Cheng4496d0822018-04-26 21:52:15291 ~MockDelegate() override = default;
Bence Béky29f661602018-02-16 02:45:02292 MOCK_METHOD0(OnHeadersSent, void());
Ryan Hamilton0239aac2018-05-19 00:03:13293 MOCK_METHOD1(OnHeadersReceived, void(const spdy::SpdyHeaderBlock&));
Bence Béky29f661602018-02-16 02:45:02294 MOCK_METHOD1(OnClose, void(int));
295};
296
Bence Béky98447b12018-05-08 03:14:01297class WebSocketSpdyStreamAdapterTest : public TestWithScopedTaskEnvironment {
Bence Béky29f661602018-02-16 02:45:02298 protected:
299 WebSocketSpdyStreamAdapterTest()
300 : url_("wss://www.example.org/"),
301 key_(HostPortPair::FromURL(url_),
302 ProxyServer::Direct(),
303 PRIVACY_MODE_DISABLED,
Matt Menke2436b2f2018-12-11 18:07:11304 SpdySessionKey::IsProxySession::kFalse,
Bence Béky29f661602018-02-16 02:45:02305 SocketTag()),
306 session_(SpdySessionDependencies::SpdyCreateSession(&session_deps_)),
307 ssl_(SYNCHRONOUS, OK) {}
308
309 ~WebSocketSpdyStreamAdapterTest() override = default;
310
Ryan Hamilton0239aac2018-05-19 00:03:13311 static spdy::SpdyHeaderBlock RequestHeaders() {
Bence Béky46bfbc12018-02-22 19:28:20312 return WebSocketHttp2Request("/", "www.example.org:443",
313 "http://www.example.org", {});
Bence Béky29f661602018-02-16 02:45:02314 }
315
Ryan Hamilton0239aac2018-05-19 00:03:13316 static spdy::SpdyHeaderBlock ResponseHeaders() {
Bence Béky46bfbc12018-02-22 19:28:20317 return WebSocketHttp2Response({});
Bence Béky29f661602018-02-16 02:45:02318 }
319
320 void AddSocketData(SocketDataProvider* data) {
321 session_deps_.socket_factory->AddSocketDataProvider(data);
322 }
323
324 void AddSSLSocketData() {
325 ssl_.ssl_info.cert =
Bence Béky3a0c48532018-03-02 13:38:51326 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Bence Béky29f661602018-02-16 02:45:02327 ASSERT_TRUE(ssl_.ssl_info.cert);
328 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
329 }
330
331 base::WeakPtr<SpdySession> CreateSpdySession() {
332 return ::net::CreateSpdySession(session_.get(), key_, net_log_);
333 }
334
335 base::WeakPtr<SpdyStream> CreateSpdyStream(
336 base::WeakPtr<SpdySession> session) {
337 return CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session, url_,
338 LOWEST, net_log_);
339 }
340
341 SpdyTestUtil spdy_util_;
342 StrictMock<MockDelegate> mock_delegate_;
343 NetLogWithSource net_log_;
344
345 private:
346 const GURL url_;
Bence Béky46bfbc12018-02-22 19:28:20347 const SpdySessionKey key_;
Bence Béky29f661602018-02-16 02:45:02348 SpdySessionDependencies session_deps_;
349 std::unique_ptr<HttpNetworkSession> session_;
350 SSLSocketDataProvider ssl_;
351};
352
353TEST_F(WebSocketSpdyStreamAdapterTest, Disconnect) {
354 MockRead reads[] = {MockRead(ASYNC, ERR_IO_PENDING, 0),
355 MockRead(ASYNC, 0, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01356 SequencedSocketData data(reads, base::span<MockWrite>());
Bence Béky29f661602018-02-16 02:45:02357 AddSocketData(&data);
358 AddSSLSocketData();
359
360 base::WeakPtr<SpdySession> session = CreateSpdySession();
361 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
362 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
363 EXPECT_TRUE(adapter.is_initialized());
364
365 base::RunLoop().RunUntilIdle();
366
367 EXPECT_TRUE(stream);
368 adapter.Disconnect();
369 EXPECT_FALSE(stream);
370
371 // Read EOF.
372 EXPECT_TRUE(session);
373 data.Resume();
374 base::RunLoop().RunUntilIdle();
375 EXPECT_FALSE(session);
376
377 EXPECT_TRUE(data.AllReadDataConsumed());
378 EXPECT_TRUE(data.AllWriteDataConsumed());
379}
380
381TEST_F(WebSocketSpdyStreamAdapterTest, SendRequestHeadersThenDisconnect) {
382 MockRead reads[] = {MockRead(ASYNC, ERR_IO_PENDING, 0),
383 MockRead(ASYNC, 0, 3)};
Ryan Hamilton0239aac2018-05-19 00:03:13384 spdy::SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02385 1, RequestHeaders(), DEFAULT_PRIORITY, false));
Ryan Hamilton0239aac2018-05-19 00:03:13386 spdy::SpdySerializedFrame rst(
387 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
Bence Béky29f661602018-02-16 02:45:02388 MockWrite writes[] = {CreateMockWrite(headers, 1), CreateMockWrite(rst, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01389 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02390 AddSocketData(&data);
391 AddSSLSocketData();
392
393 base::WeakPtr<SpdySession> session = CreateSpdySession();
394 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
395 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
396 EXPECT_TRUE(adapter.is_initialized());
397
398 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
399 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
400
401 // First read is a pause and it has lower sequence number than first write.
402 // Therefore writing headers does not complete while |data| is paused.
403 base::RunLoop().RunUntilIdle();
404
405 // Reset the stream before writing completes.
406 // OnHeadersSent() will never be called.
407 EXPECT_TRUE(stream);
408 adapter.Disconnect();
409 EXPECT_FALSE(stream);
410
411 // Resume |data|, finish writing headers, and read EOF.
412 EXPECT_TRUE(session);
413 data.Resume();
414 base::RunLoop().RunUntilIdle();
415 EXPECT_FALSE(session);
416
417 EXPECT_TRUE(data.AllReadDataConsumed());
418 EXPECT_TRUE(data.AllWriteDataConsumed());
419}
420
421TEST_F(WebSocketSpdyStreamAdapterTest, OnHeadersSentThenDisconnect) {
422 MockRead reads[] = {MockRead(ASYNC, 0, 2)};
Ryan Hamilton0239aac2018-05-19 00:03:13423 spdy::SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02424 1, RequestHeaders(), DEFAULT_PRIORITY, false));
Ryan Hamilton0239aac2018-05-19 00:03:13425 spdy::SpdySerializedFrame rst(
426 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
Bence Béky29f661602018-02-16 02:45:02427 MockWrite writes[] = {CreateMockWrite(headers, 0), CreateMockWrite(rst, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01428 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02429 AddSocketData(&data);
430 AddSSLSocketData();
431
432 EXPECT_CALL(mock_delegate_, OnHeadersSent());
433
434 base::WeakPtr<SpdySession> session = CreateSpdySession();
435 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
436 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
437 EXPECT_TRUE(adapter.is_initialized());
438
439 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
440 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
441
442 // Finish asynchronous write of headers. This calls OnHeadersSent().
443 base::RunLoop().RunUntilIdle();
444
445 EXPECT_TRUE(stream);
446 adapter.Disconnect();
447 EXPECT_FALSE(stream);
448
449 // Read EOF.
450 EXPECT_TRUE(session);
451 base::RunLoop().RunUntilIdle();
452 EXPECT_FALSE(session);
453
454 EXPECT_TRUE(data.AllReadDataConsumed());
455 EXPECT_TRUE(data.AllWriteDataConsumed());
456}
457
458TEST_F(WebSocketSpdyStreamAdapterTest, OnHeadersReceivedThenDisconnect) {
Ryan Hamilton0239aac2018-05-19 00:03:13459 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02460 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
461 MockRead reads[] = {CreateMockRead(response_headers, 1),
462 MockRead(ASYNC, 0, 3)};
Ryan Hamilton0239aac2018-05-19 00:03:13463 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02464 1, RequestHeaders(), DEFAULT_PRIORITY, false));
Ryan Hamilton0239aac2018-05-19 00:03:13465 spdy::SpdySerializedFrame rst(
466 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
Bence Béky29f661602018-02-16 02:45:02467 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
468 CreateMockWrite(rst, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01469 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02470 AddSocketData(&data);
471 AddSSLSocketData();
472
473 EXPECT_CALL(mock_delegate_, OnHeadersSent());
474 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
475
476 base::WeakPtr<SpdySession> session = CreateSpdySession();
477 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
478 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
479 EXPECT_TRUE(adapter.is_initialized());
480
481 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
482 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
483
484 base::RunLoop().RunUntilIdle();
485
486 EXPECT_TRUE(stream);
487 adapter.Disconnect();
488 EXPECT_FALSE(stream);
489
490 // Read EOF.
491 EXPECT_TRUE(session);
492 base::RunLoop().RunUntilIdle();
493 EXPECT_FALSE(session);
494
495 EXPECT_TRUE(data.AllReadDataConsumed());
496 EXPECT_TRUE(data.AllWriteDataConsumed());
497}
498
499TEST_F(WebSocketSpdyStreamAdapterTest, ServerClosesConnection) {
500 MockRead reads[] = {MockRead(ASYNC, 0, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01501 SequencedSocketData data(reads, base::span<MockWrite>());
Bence Béky29f661602018-02-16 02:45:02502 AddSocketData(&data);
503 AddSSLSocketData();
504
505 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
506
507 base::WeakPtr<SpdySession> session = CreateSpdySession();
508 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
509 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
510 EXPECT_TRUE(adapter.is_initialized());
511
512 EXPECT_TRUE(session);
513 EXPECT_TRUE(stream);
514 base::RunLoop().RunUntilIdle();
515 EXPECT_FALSE(session);
516 EXPECT_FALSE(stream);
517
518 EXPECT_TRUE(data.AllReadDataConsumed());
519 EXPECT_TRUE(data.AllWriteDataConsumed());
520}
521
522TEST_F(WebSocketSpdyStreamAdapterTest,
523 SendRequestHeadersThenServerClosesConnection) {
524 MockRead reads[] = {MockRead(ASYNC, 0, 1)};
Ryan Hamilton0239aac2018-05-19 00:03:13525 spdy::SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02526 1, RequestHeaders(), DEFAULT_PRIORITY, false));
527 MockWrite writes[] = {CreateMockWrite(headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01528 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02529 AddSocketData(&data);
530 AddSSLSocketData();
531
532 EXPECT_CALL(mock_delegate_, OnHeadersSent());
533 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
534
535 base::WeakPtr<SpdySession> session = CreateSpdySession();
536 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
537 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
538 EXPECT_TRUE(adapter.is_initialized());
539
540 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
541 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
542
543 EXPECT_TRUE(session);
544 EXPECT_TRUE(stream);
545 base::RunLoop().RunUntilIdle();
546 EXPECT_FALSE(session);
547 EXPECT_FALSE(stream);
548
549 EXPECT_TRUE(data.AllReadDataConsumed());
550 EXPECT_TRUE(data.AllWriteDataConsumed());
551}
552
553TEST_F(WebSocketSpdyStreamAdapterTest,
554 OnHeadersReceivedThenServerClosesConnection) {
Ryan Hamilton0239aac2018-05-19 00:03:13555 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02556 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
557 MockRead reads[] = {CreateMockRead(response_headers, 1),
558 MockRead(ASYNC, 0, 2)};
Ryan Hamilton0239aac2018-05-19 00:03:13559 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02560 1, RequestHeaders(), DEFAULT_PRIORITY, false));
561 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01562 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02563 AddSocketData(&data);
564 AddSSLSocketData();
565
566 EXPECT_CALL(mock_delegate_, OnHeadersSent());
567 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
568 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
569
570 base::WeakPtr<SpdySession> session = CreateSpdySession();
571 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
572 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
573 EXPECT_TRUE(adapter.is_initialized());
574
575 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
576 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
577
578 EXPECT_TRUE(session);
579 EXPECT_TRUE(stream);
580 base::RunLoop().RunUntilIdle();
581 EXPECT_FALSE(session);
582 EXPECT_FALSE(stream);
583
584 EXPECT_TRUE(data.AllReadDataConsumed());
585 EXPECT_TRUE(data.AllWriteDataConsumed());
586}
587
588TEST_F(WebSocketSpdyStreamAdapterTest, DetachDelegate) {
Ryan Hamilton0239aac2018-05-19 00:03:13589 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02590 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
591 MockRead reads[] = {CreateMockRead(response_headers, 1),
592 MockRead(ASYNC, 0, 2)};
Ryan Hamilton0239aac2018-05-19 00:03:13593 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02594 1, RequestHeaders(), DEFAULT_PRIORITY, false));
595 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01596 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02597 AddSocketData(&data);
598 AddSSLSocketData();
599
600 base::WeakPtr<SpdySession> session = CreateSpdySession();
601 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
602 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
603 EXPECT_TRUE(adapter.is_initialized());
604
605 // No Delegate methods shall be called after this.
606 adapter.DetachDelegate();
607
608 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
609 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
610
611 EXPECT_TRUE(session);
612 EXPECT_TRUE(stream);
613 base::RunLoop().RunUntilIdle();
614 EXPECT_FALSE(session);
615 EXPECT_FALSE(stream);
616
617 EXPECT_TRUE(data.AllReadDataConsumed());
618 EXPECT_TRUE(data.AllWriteDataConsumed());
619}
620
621TEST_F(WebSocketSpdyStreamAdapterTest, Read) {
Ryan Hamilton0239aac2018-05-19 00:03:13622 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02623 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
624 // First read is the same size as the buffer, next is smaller, last is larger.
Ryan Hamilton0239aac2018-05-19 00:03:13625 spdy::SpdySerializedFrame data_frame1(
Bence Békyd74f4382018-02-20 18:26:19626 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
Ryan Hamilton0239aac2018-05-19 00:03:13627 spdy::SpdySerializedFrame data_frame2(
Bence Békyd74f4382018-02-20 18:26:19628 spdy_util_.ConstructSpdyDataFrame(1, "ba", false));
Ryan Hamilton0239aac2018-05-19 00:03:13629 spdy::SpdySerializedFrame data_frame3(
Bence Békyd74f4382018-02-20 18:26:19630 spdy_util_.ConstructSpdyDataFrame(1, "rbaz", true));
Bence Béky29f661602018-02-16 02:45:02631 MockRead reads[] = {CreateMockRead(response_headers, 1),
632 CreateMockRead(data_frame1, 2),
633 CreateMockRead(data_frame2, 3),
634 CreateMockRead(data_frame3, 4), MockRead(ASYNC, 0, 5)};
Ryan Hamilton0239aac2018-05-19 00:03:13635 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02636 1, RequestHeaders(), DEFAULT_PRIORITY, false));
637 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01638 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02639 AddSocketData(&data);
640 AddSSLSocketData();
641
642 EXPECT_CALL(mock_delegate_, OnHeadersSent());
643 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
644
645 base::WeakPtr<SpdySession> session = CreateSpdySession();
646 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
647 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
648 EXPECT_TRUE(adapter.is_initialized());
649
650 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
652
653 const int kReadBufSize = 3;
654 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
655 TestCompletionCallback callback;
656 rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
657 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
658 rv = callback.WaitForResult();
659 ASSERT_EQ(3, rv);
660 EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
661
662 // Read EOF to destroy the connection and the stream.
663 // This calls SpdySession::Delegate::OnClose().
664 EXPECT_TRUE(session);
665 EXPECT_TRUE(stream);
666 base::RunLoop().RunUntilIdle();
667 EXPECT_FALSE(session);
668 EXPECT_FALSE(stream);
669
670 // Two socket reads are concatenated by WebSocketSpdyStreamAdapter.
Bence Békybdbb0e72018-08-07 21:42:59671 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky29f661602018-02-16 02:45:02672 ASSERT_EQ(3, rv);
673 EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
674
Bence Békybdbb0e72018-08-07 21:42:59675 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky29f661602018-02-16 02:45:02676 ASSERT_EQ(3, rv);
677 EXPECT_EQ("baz", base::StringPiece(read_buf->data(), rv));
678
679 // Even though connection and stream are already closed,
680 // WebSocketSpdyStreamAdapter::Delegate::OnClose() is only called after all
681 // buffered data are read.
682 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
683
684 base::RunLoop().RunUntilIdle();
685
686 EXPECT_TRUE(data.AllReadDataConsumed());
687 EXPECT_TRUE(data.AllWriteDataConsumed());
688}
689
690TEST_F(WebSocketSpdyStreamAdapterTest, CallDelegateOnCloseShouldNotCrash) {
Ryan Hamilton0239aac2018-05-19 00:03:13691 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02692 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
Ryan Hamilton0239aac2018-05-19 00:03:13693 spdy::SpdySerializedFrame data_frame1(
Bence Békyd74f4382018-02-20 18:26:19694 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
Ryan Hamilton0239aac2018-05-19 00:03:13695 spdy::SpdySerializedFrame data_frame2(
Bence Békyd74f4382018-02-20 18:26:19696 spdy_util_.ConstructSpdyDataFrame(1, "bar", false));
Ryan Hamilton0239aac2018-05-19 00:03:13697 spdy::SpdySerializedFrame rst(
698 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
Bence Béky29f661602018-02-16 02:45:02699 MockRead reads[] = {CreateMockRead(response_headers, 1),
700 CreateMockRead(data_frame1, 2),
701 CreateMockRead(data_frame2, 3), CreateMockRead(rst, 4),
702 MockRead(ASYNC, 0, 5)};
Ryan Hamilton0239aac2018-05-19 00:03:13703 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02704 1, RequestHeaders(), DEFAULT_PRIORITY, false));
705 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01706 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02707 AddSocketData(&data);
708 AddSSLSocketData();
709
710 EXPECT_CALL(mock_delegate_, OnHeadersSent());
711 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
712
713 base::WeakPtr<SpdySession> session = CreateSpdySession();
714 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
715 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
716 EXPECT_TRUE(adapter.is_initialized());
717
718 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
720
721 // Buffer larger than each MockRead.
722 const int kReadBufSize = 1024;
723 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
724 TestCompletionCallback callback;
725 rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
726 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
727 rv = callback.WaitForResult();
728 ASSERT_EQ(3, rv);
729 EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
730
731 // Read RST_STREAM to destroy the stream.
732 // This calls SpdySession::Delegate::OnClose().
733 EXPECT_TRUE(session);
734 EXPECT_TRUE(stream);
735 base::RunLoop().RunUntilIdle();
736 EXPECT_FALSE(session);
737 EXPECT_FALSE(stream);
738
739 // Read remaining buffered data. This will PostTask CallDelegateOnClose().
Bence Békybdbb0e72018-08-07 21:42:59740 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky29f661602018-02-16 02:45:02741 ASSERT_EQ(3, rv);
742 EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
743
744 adapter.DetachDelegate();
745
746 // Run CallDelegateOnClose(), which should not crash
747 // even if |delegate_| is null.
748 base::RunLoop().RunUntilIdle();
749
750 EXPECT_TRUE(data.AllReadDataConsumed());
751 EXPECT_TRUE(data.AllWriteDataConsumed());
752}
753
754TEST_F(WebSocketSpdyStreamAdapterTest, Write) {
Ryan Hamilton0239aac2018-05-19 00:03:13755 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02756 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
757 MockRead reads[] = {CreateMockRead(response_headers, 1),
758 MockRead(ASYNC, 0, 3)};
Ryan Hamilton0239aac2018-05-19 00:03:13759 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02760 1, RequestHeaders(), DEFAULT_PRIORITY, false));
Ryan Hamilton0239aac2018-05-19 00:03:13761 spdy::SpdySerializedFrame data_frame(
Bence Békyd74f4382018-02-20 18:26:19762 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
Bence Béky29f661602018-02-16 02:45:02763 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
764 CreateMockWrite(data_frame, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01765 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02766 AddSocketData(&data);
767 AddSSLSocketData();
768
769 base::WeakPtr<SpdySession> session = CreateSpdySession();
770 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
771 WebSocketSpdyStreamAdapter adapter(stream, nullptr, net_log_);
772 EXPECT_TRUE(adapter.is_initialized());
773
774 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
775 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
776
777 base::RunLoop().RunUntilIdle();
778
779 auto write_buf = base::MakeRefCounted<StringIOBuffer>("foo");
780 TestCompletionCallback callback;
781 rv = adapter.Write(write_buf.get(), write_buf->size(), callback.callback(),
782 TRAFFIC_ANNOTATION_FOR_TESTS);
783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
784 rv = callback.WaitForResult();
785 ASSERT_EQ(3, rv);
786
787 // Read EOF.
788 base::RunLoop().RunUntilIdle();
789
790 EXPECT_TRUE(data.AllReadDataConsumed());
791 EXPECT_TRUE(data.AllWriteDataConsumed());
792}
793
794// Test that if both Read() and Write() returns asynchronously,
795// the two callbacks are handled correctly.
796TEST_F(WebSocketSpdyStreamAdapterTest, AsyncReadAndWrite) {
Ryan Hamilton0239aac2018-05-19 00:03:13797 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02798 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
Ryan Hamilton0239aac2018-05-19 00:03:13799 spdy::SpdySerializedFrame read_data_frame(
Bence Békyd74f4382018-02-20 18:26:19800 spdy_util_.ConstructSpdyDataFrame(1, "foobar", true));
Bence Béky29f661602018-02-16 02:45:02801 MockRead reads[] = {CreateMockRead(response_headers, 1),
802 CreateMockRead(read_data_frame, 3),
803 MockRead(ASYNC, 0, 4)};
Ryan Hamilton0239aac2018-05-19 00:03:13804 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02805 1, RequestHeaders(), DEFAULT_PRIORITY, false));
Ryan Hamilton0239aac2018-05-19 00:03:13806 spdy::SpdySerializedFrame write_data_frame(
Bence Békyd74f4382018-02-20 18:26:19807 spdy_util_.ConstructSpdyDataFrame(1, "baz", false));
Bence Béky29f661602018-02-16 02:45:02808 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
809 CreateMockWrite(write_data_frame, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01810 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02811 AddSocketData(&data);
812 AddSSLSocketData();
813
814 base::WeakPtr<SpdySession> session = CreateSpdySession();
815 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
816 WebSocketSpdyStreamAdapter adapter(stream, nullptr, net_log_);
817 EXPECT_TRUE(adapter.is_initialized());
818
819 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
821
822 base::RunLoop().RunUntilIdle();
823
824 const int kReadBufSize = 1024;
825 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
826 TestCompletionCallback read_callback;
827 rv = adapter.Read(read_buf.get(), kReadBufSize, read_callback.callback());
828 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
829
830 auto write_buf = base::MakeRefCounted<StringIOBuffer>("baz");
831 TestCompletionCallback write_callback;
832 rv = adapter.Write(write_buf.get(), write_buf->size(),
833 write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
834 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
835
836 rv = read_callback.WaitForResult();
837 ASSERT_EQ(6, rv);
838 EXPECT_EQ("foobar", base::StringPiece(read_buf->data(), rv));
839
840 rv = write_callback.WaitForResult();
841 ASSERT_EQ(3, rv);
842
843 // Read EOF.
844 base::RunLoop().RunUntilIdle();
845
846 EXPECT_TRUE(data.AllReadDataConsumed());
847 EXPECT_TRUE(data.AllWriteDataConsumed());
848}
849
Bence Béky8ddc2492018-06-13 01:02:04850// A helper class that will delete |adapter| when the callback is invoked.
Bence Béky29f661602018-02-16 02:45:02851class KillerCallback : public TestCompletionCallbackBase {
852 public:
853 explicit KillerCallback(std::unique_ptr<WebSocketSpdyStreamAdapter> adapter)
854 : adapter_(std::move(adapter)) {}
855
856 ~KillerCallback() override = default;
857
Bence Béky8ddc2492018-06-13 01:02:04858 CompletionOnceCallback callback() {
859 return base::BindOnce(&KillerCallback::OnComplete, base::Unretained(this));
Bence Béky29f661602018-02-16 02:45:02860 }
861
862 private:
863 void OnComplete(int result) {
864 adapter_.reset();
865 SetResult(result);
866 }
867
868 std::unique_ptr<WebSocketSpdyStreamAdapter> adapter_;
869};
870
871TEST_F(WebSocketSpdyStreamAdapterTest, ReadCallbackDestroysAdapter) {
Ryan Hamilton0239aac2018-05-19 00:03:13872 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02873 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
874 MockRead reads[] = {CreateMockRead(response_headers, 1),
875 MockRead(ASYNC, ERR_IO_PENDING, 2),
876 MockRead(ASYNC, 0, 3)};
Ryan Hamilton0239aac2018-05-19 00:03:13877 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02878 1, RequestHeaders(), DEFAULT_PRIORITY, false));
879 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01880 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02881 AddSocketData(&data);
882 AddSSLSocketData();
883
884 EXPECT_CALL(mock_delegate_, OnHeadersSent());
885 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
886
887 base::WeakPtr<SpdySession> session = CreateSpdySession();
888 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
889 auto adapter = std::make_unique<WebSocketSpdyStreamAdapter>(
890 stream, &mock_delegate_, net_log_);
891 EXPECT_TRUE(adapter->is_initialized());
892
893 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
894 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
895
896 // Send headers.
897 base::RunLoop().RunUntilIdle();
898
899 WebSocketSpdyStreamAdapter* adapter_raw = adapter.get();
900 KillerCallback callback(std::move(adapter));
901
902 const int kReadBufSize = 1024;
903 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
904 rv = adapter_raw->Read(read_buf.get(), kReadBufSize, callback.callback());
905 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
906
907 // Read EOF while read is pending. WebSocketSpdyStreamAdapter::OnClose()
908 // should not crash if read callback destroys |adapter|.
909 data.Resume();
910 rv = callback.WaitForResult();
911 EXPECT_THAT(rv, IsError(ERR_CONNECTION_CLOSED));
912
913 base::RunLoop().RunUntilIdle();
914 EXPECT_FALSE(session);
915 EXPECT_FALSE(stream);
916
917 EXPECT_TRUE(data.AllReadDataConsumed());
918 EXPECT_TRUE(data.AllWriteDataConsumed());
919}
920
921TEST_F(WebSocketSpdyStreamAdapterTest, WriteCallbackDestroysAdapter) {
Ryan Hamilton0239aac2018-05-19 00:03:13922 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02923 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
924 MockRead reads[] = {CreateMockRead(response_headers, 1),
925 MockRead(ASYNC, ERR_IO_PENDING, 2),
926 MockRead(ASYNC, 0, 3)};
Ryan Hamilton0239aac2018-05-19 00:03:13927 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02928 1, RequestHeaders(), DEFAULT_PRIORITY, false));
929 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01930 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02931 AddSocketData(&data);
932 AddSSLSocketData();
933
934 EXPECT_CALL(mock_delegate_, OnHeadersSent());
935 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
936
937 base::WeakPtr<SpdySession> session = CreateSpdySession();
938 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
939 auto adapter = std::make_unique<WebSocketSpdyStreamAdapter>(
940 stream, &mock_delegate_, net_log_);
941 EXPECT_TRUE(adapter->is_initialized());
942
943 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
945
946 // Send headers.
947 base::RunLoop().RunUntilIdle();
948
949 WebSocketSpdyStreamAdapter* adapter_raw = adapter.get();
950 KillerCallback callback(std::move(adapter));
951
952 auto write_buf = base::MakeRefCounted<StringIOBuffer>("foo");
953 rv = adapter_raw->Write(write_buf.get(), write_buf->size(),
954 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
955 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
956
957 // Read EOF while write is pending. WebSocketSpdyStreamAdapter::OnClose()
958 // should not crash if write callback destroys |adapter|.
959 data.Resume();
960 rv = callback.WaitForResult();
961 EXPECT_THAT(rv, IsError(ERR_CONNECTION_CLOSED));
962
963 base::RunLoop().RunUntilIdle();
964 EXPECT_FALSE(session);
965 EXPECT_FALSE(stream);
966
967 EXPECT_TRUE(data.AllReadDataConsumed());
968 EXPECT_TRUE(data.AllWriteDataConsumed());
969}
970
Bence Béky7294fc22018-02-08 14:26:17971} // namespace test
972
973} // namespace net