blob: b54e25f0aa976765992bea83234f90652df7c906 [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éky29f661602018-02-16 02:45:0229#include "net/spdy/chromium/spdy_session.h"
30#include "net/spdy/chromium/spdy_session_key.h"
31#include "net/spdy/chromium/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éky7294fc22018-02-08 14:26:1737#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Bence Béky46bfbc12018-02-22 19:28:2038#include "net/websockets/websocket_test_util.h"
Bence Béky29f661602018-02-16 02:45:0239#include "testing/gmock/include/gmock/gmock.h"
Bence Béky7294fc22018-02-08 14:26:1740#include "testing/gtest/include/gtest/gtest.h"
41
Bence Béky29f661602018-02-16 02:45:0242using testing::Test;
43using testing::StrictMock;
44using testing::_;
45
Bence Béky7294fc22018-02-08 14:26:1746namespace net {
47
48namespace test {
49
50const char* const kGroupName = "ssl/www.example.org:443";
51
Bence Béky29f661602018-02-16 02:45:0252class WebSocketClientSocketHandleAdapterTest : public Test {
Bence Béky7294fc22018-02-08 14:26:1753 protected:
54 WebSocketClientSocketHandleAdapterTest()
55 : host_port_pair_("www.example.org", 443),
56 socket_pool_manager_(std::make_unique<ClientSocketPoolManagerImpl>(
Bence Béky29f661602018-02-16 02:45:0257 net_log_.net_log(),
Bence Béky7294fc22018-02-08 14:26:1758 &socket_factory_,
59 nullptr,
60 nullptr,
61 &host_resolver,
62 nullptr,
63 nullptr,
64 nullptr,
65 nullptr,
66 nullptr,
67 "test_shard",
68 nullptr,
Bence Békyda280c62018-04-12 15:08:3769 &websocket_endpoint_lock_manager_,
Bence Béky7294fc22018-02-08 14:26:1770 HttpNetworkSession::NORMAL_SOCKET_POOL)),
71 transport_params_(base::MakeRefCounted<TransportSocketParams>(
72 host_port_pair_,
73 false,
74 OnHostResolutionCallback(),
75 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)),
76 ssl_params_(base::MakeRefCounted<SSLSocketParams>(transport_params_,
77 nullptr,
78 nullptr,
79 host_port_pair_,
80 SSLConfig(),
81 PRIVACY_MODE_DISABLED,
David Benjamine87ad54b2018-02-21 02:16:2582 0)) {}
Bence Béky7294fc22018-02-08 14:26:1783
Bence Béky29f661602018-02-16 02:45:0284 ~WebSocketClientSocketHandleAdapterTest() override = default;
85
Bence Béky7294fc22018-02-08 14:26:1786 bool InitClientSocketHandle(ClientSocketHandle* connection) {
87 TestCompletionCallback callback;
88 int rv = connection->Init(
89 kGroupName, ssl_params_, MEDIUM, SocketTag(),
90 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
Bence Béky29f661602018-02-16 02:45:0291 socket_pool_manager_->GetSSLSocketPool(), net_log_);
Bence Béky7294fc22018-02-08 14:26:1792 rv = callback.GetResult(rv);
93 return rv == OK;
94 }
95
96 const HostPortPair host_port_pair_;
Bence Béky29f661602018-02-16 02:45:0297 NetLogWithSource net_log_;
Bence Béky7294fc22018-02-08 14:26:1798 MockClientSocketFactory socket_factory_;
99 MockHostResolver host_resolver;
100 std::unique_ptr<ClientSocketPoolManagerImpl> socket_pool_manager_;
101 scoped_refptr<TransportSocketParams> transport_params_;
102 scoped_refptr<SSLSocketParams> ssl_params_;
Bence Békyda280c62018-04-12 15:08:37103 WebSocketEndpointLockManager websocket_endpoint_lock_manager_;
Bence Béky7294fc22018-02-08 14:26:17104};
105
106TEST_F(WebSocketClientSocketHandleAdapterTest, Uninitialized) {
107 auto connection = std::make_unique<ClientSocketHandle>();
108 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
109 EXPECT_FALSE(adapter.is_initialized());
110}
111
112TEST_F(WebSocketClientSocketHandleAdapterTest, IsInitialized) {
Ryan Sleevib8d7ea02018-05-07 20:01:01113 StaticSocketDataProvider data;
Bence Béky7294fc22018-02-08 14:26:17114 socket_factory_.AddSocketDataProvider(&data);
115 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
116 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
117
118 auto connection = std::make_unique<ClientSocketHandle>();
119 ClientSocketHandle* const connection_ptr = connection.get();
120
121 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
122 EXPECT_FALSE(adapter.is_initialized());
123
124 EXPECT_TRUE(InitClientSocketHandle(connection_ptr));
125
126 EXPECT_TRUE(adapter.is_initialized());
127}
128
129TEST_F(WebSocketClientSocketHandleAdapterTest, Disconnect) {
Ryan Sleevib8d7ea02018-05-07 20:01:01130 StaticSocketDataProvider data;
Bence Béky7294fc22018-02-08 14:26:17131 socket_factory_.AddSocketDataProvider(&data);
132 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
133 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
134
135 auto connection = std::make_unique<ClientSocketHandle>();
136 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
137
138 StreamSocket* const socket = connection->socket();
139
140 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
141 EXPECT_TRUE(adapter.is_initialized());
142
143 EXPECT_TRUE(socket->IsConnected());
144 adapter.Disconnect();
145 EXPECT_FALSE(socket->IsConnected());
146}
147
148TEST_F(WebSocketClientSocketHandleAdapterTest, Read) {
149 MockRead reads[] = {MockRead(SYNCHRONOUS, "foo"), MockRead("bar")};
Ryan Sleevib8d7ea02018-05-07 20:01:01150 StaticSocketDataProvider data(reads, base::span<MockWrite>());
Bence Béky7294fc22018-02-08 14:26:17151 socket_factory_.AddSocketDataProvider(&data);
152 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
153 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
154
155 auto connection = std::make_unique<ClientSocketHandle>();
156 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
157
158 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
159 EXPECT_TRUE(adapter.is_initialized());
160
161 // Buffer larger than each MockRead.
162 const int kReadBufSize = 1024;
163 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
164 int rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionCallback());
165 ASSERT_EQ(3, rv);
166 EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
167
168 TestCompletionCallback callback;
169 rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
170 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
171 rv = callback.WaitForResult();
172 ASSERT_EQ(3, rv);
173 EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
174
175 EXPECT_TRUE(data.AllReadDataConsumed());
176 EXPECT_TRUE(data.AllWriteDataConsumed());
177}
178
179TEST_F(WebSocketClientSocketHandleAdapterTest, ReadIntoSmallBuffer) {
180 MockRead reads[] = {MockRead(SYNCHRONOUS, "foo"), MockRead("bar")};
Ryan Sleevib8d7ea02018-05-07 20:01:01181 StaticSocketDataProvider data(reads, base::span<MockWrite>());
Bence Béky7294fc22018-02-08 14:26:17182 socket_factory_.AddSocketDataProvider(&data);
183 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
184 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
185
186 auto connection = std::make_unique<ClientSocketHandle>();
187 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
188
189 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
190 EXPECT_TRUE(adapter.is_initialized());
191
192 // Buffer smaller than each MockRead.
193 const int kReadBufSize = 2;
194 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
195 int rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionCallback());
196 ASSERT_EQ(2, rv);
197 EXPECT_EQ("fo", base::StringPiece(read_buf->data(), rv));
198
199 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionCallback());
200 ASSERT_EQ(1, rv);
201 EXPECT_EQ("o", base::StringPiece(read_buf->data(), rv));
202
203 TestCompletionCallback callback1;
204 rv = adapter.Read(read_buf.get(), kReadBufSize, callback1.callback());
205 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
206 rv = callback1.WaitForResult();
207 ASSERT_EQ(2, rv);
208 EXPECT_EQ("ba", base::StringPiece(read_buf->data(), rv));
209
210 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionCallback());
211 ASSERT_EQ(1, rv);
212 EXPECT_EQ("r", base::StringPiece(read_buf->data(), rv));
213
214 EXPECT_TRUE(data.AllReadDataConsumed());
215 EXPECT_TRUE(data.AllWriteDataConsumed());
216}
217
218TEST_F(WebSocketClientSocketHandleAdapterTest, Write) {
219 MockWrite writes[] = {MockWrite(SYNCHRONOUS, "foo"), MockWrite("bar")};
Ryan Sleevib8d7ea02018-05-07 20:01:01220 StaticSocketDataProvider data(base::span<MockRead>(), writes);
Bence Béky7294fc22018-02-08 14:26:17221 socket_factory_.AddSocketDataProvider(&data);
222 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
223 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
224
225 auto connection = std::make_unique<ClientSocketHandle>();
226 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
227
228 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
229 EXPECT_TRUE(adapter.is_initialized());
230
231 auto write_buf1 = base::MakeRefCounted<StringIOBuffer>("foo");
232 int rv = adapter.Write(write_buf1.get(), write_buf1->size(),
233 CompletionCallback(), TRAFFIC_ANNOTATION_FOR_TESTS);
234 ASSERT_EQ(3, rv);
235
236 auto write_buf2 = base::MakeRefCounted<StringIOBuffer>("bar");
237 TestCompletionCallback callback;
238 rv = adapter.Write(write_buf2.get(), write_buf2->size(), callback.callback(),
239 TRAFFIC_ANNOTATION_FOR_TESTS);
240 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
241 rv = callback.WaitForResult();
242 ASSERT_EQ(3, rv);
243
244 EXPECT_TRUE(data.AllReadDataConsumed());
245 EXPECT_TRUE(data.AllWriteDataConsumed());
246}
247
248// Test that if both Read() and Write() returns asynchronously,
249// the two callbacks are handled correctly.
250TEST_F(WebSocketClientSocketHandleAdapterTest, AsyncReadAndWrite) {
251 MockRead reads[] = {MockRead("foobar")};
252 MockWrite writes[] = {MockWrite("baz")};
Ryan Sleevib8d7ea02018-05-07 20:01:01253 StaticSocketDataProvider data(reads, writes);
Bence Béky7294fc22018-02-08 14:26:17254 socket_factory_.AddSocketDataProvider(&data);
255 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
256 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
257
258 auto connection = std::make_unique<ClientSocketHandle>();
259 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
260
261 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
262 EXPECT_TRUE(adapter.is_initialized());
263
264 const int kReadBufSize = 1024;
265 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
266 TestCompletionCallback read_callback;
267 int rv = adapter.Read(read_buf.get(), kReadBufSize, read_callback.callback());
268 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
269
270 auto write_buf = base::MakeRefCounted<StringIOBuffer>("baz");
271 TestCompletionCallback write_callback;
272 rv = adapter.Write(write_buf.get(), write_buf->size(),
273 write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
274 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
275
276 rv = read_callback.WaitForResult();
277 ASSERT_EQ(6, rv);
278 EXPECT_EQ("foobar", base::StringPiece(read_buf->data(), rv));
279
280 rv = write_callback.WaitForResult();
281 ASSERT_EQ(3, rv);
282
283 EXPECT_TRUE(data.AllReadDataConsumed());
284 EXPECT_TRUE(data.AllWriteDataConsumed());
285}
286
Bence Béky29f661602018-02-16 02:45:02287class MockDelegate : public WebSocketSpdyStreamAdapter::Delegate {
288 public:
Daniel Cheng4496d0822018-04-26 21:52:15289 ~MockDelegate() override = default;
Bence Béky29f661602018-02-16 02:45:02290 MOCK_METHOD0(OnHeadersSent, void());
291 MOCK_METHOD1(OnHeadersReceived, void(const SpdyHeaderBlock&));
292 MOCK_METHOD1(OnClose, void(int));
293};
294
295class WebSocketSpdyStreamAdapterTest : public Test {
296 protected:
297 WebSocketSpdyStreamAdapterTest()
298 : url_("wss://www.example.org/"),
299 key_(HostPortPair::FromURL(url_),
300 ProxyServer::Direct(),
301 PRIVACY_MODE_DISABLED,
302 SocketTag()),
303 session_(SpdySessionDependencies::SpdyCreateSession(&session_deps_)),
304 ssl_(SYNCHRONOUS, OK) {}
305
306 ~WebSocketSpdyStreamAdapterTest() override = default;
307
308 static SpdyHeaderBlock RequestHeaders() {
Bence Béky46bfbc12018-02-22 19:28:20309 return WebSocketHttp2Request("/", "www.example.org:443",
310 "http://www.example.org", {});
Bence Béky29f661602018-02-16 02:45:02311 }
312
313 static SpdyHeaderBlock ResponseHeaders() {
Bence Béky46bfbc12018-02-22 19:28:20314 return WebSocketHttp2Response({});
Bence Béky29f661602018-02-16 02:45:02315 }
316
317 void AddSocketData(SocketDataProvider* data) {
318 session_deps_.socket_factory->AddSocketDataProvider(data);
319 }
320
321 void AddSSLSocketData() {
322 ssl_.ssl_info.cert =
Bence Béky3a0c48532018-03-02 13:38:51323 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Bence Béky29f661602018-02-16 02:45:02324 ASSERT_TRUE(ssl_.ssl_info.cert);
325 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
326 }
327
328 base::WeakPtr<SpdySession> CreateSpdySession() {
329 return ::net::CreateSpdySession(session_.get(), key_, net_log_);
330 }
331
332 base::WeakPtr<SpdyStream> CreateSpdyStream(
333 base::WeakPtr<SpdySession> session) {
334 return CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session, url_,
335 LOWEST, net_log_);
336 }
337
338 SpdyTestUtil spdy_util_;
339 StrictMock<MockDelegate> mock_delegate_;
340 NetLogWithSource net_log_;
341
342 private:
343 const GURL url_;
Bence Béky46bfbc12018-02-22 19:28:20344 const SpdySessionKey key_;
Bence Béky29f661602018-02-16 02:45:02345 SpdySessionDependencies session_deps_;
346 std::unique_ptr<HttpNetworkSession> session_;
347 SSLSocketDataProvider ssl_;
348};
349
350TEST_F(WebSocketSpdyStreamAdapterTest, Disconnect) {
351 MockRead reads[] = {MockRead(ASYNC, ERR_IO_PENDING, 0),
352 MockRead(ASYNC, 0, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01353 SequencedSocketData data(reads, base::span<MockWrite>());
Bence Béky29f661602018-02-16 02:45:02354 AddSocketData(&data);
355 AddSSLSocketData();
356
357 base::WeakPtr<SpdySession> session = CreateSpdySession();
358 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
359 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
360 EXPECT_TRUE(adapter.is_initialized());
361
362 base::RunLoop().RunUntilIdle();
363
364 EXPECT_TRUE(stream);
365 adapter.Disconnect();
366 EXPECT_FALSE(stream);
367
368 // Read EOF.
369 EXPECT_TRUE(session);
370 data.Resume();
371 base::RunLoop().RunUntilIdle();
372 EXPECT_FALSE(session);
373
374 EXPECT_TRUE(data.AllReadDataConsumed());
375 EXPECT_TRUE(data.AllWriteDataConsumed());
376}
377
378TEST_F(WebSocketSpdyStreamAdapterTest, SendRequestHeadersThenDisconnect) {
379 MockRead reads[] = {MockRead(ASYNC, ERR_IO_PENDING, 0),
380 MockRead(ASYNC, 0, 3)};
381 SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
382 1, RequestHeaders(), DEFAULT_PRIORITY, false));
383 SpdySerializedFrame rst(
384 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
385 MockWrite writes[] = {CreateMockWrite(headers, 1), CreateMockWrite(rst, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01386 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02387 AddSocketData(&data);
388 AddSSLSocketData();
389
390 base::WeakPtr<SpdySession> session = CreateSpdySession();
391 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
392 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
393 EXPECT_TRUE(adapter.is_initialized());
394
395 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
396 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
397
398 // First read is a pause and it has lower sequence number than first write.
399 // Therefore writing headers does not complete while |data| is paused.
400 base::RunLoop().RunUntilIdle();
401
402 // Reset the stream before writing completes.
403 // OnHeadersSent() will never be called.
404 EXPECT_TRUE(stream);
405 adapter.Disconnect();
406 EXPECT_FALSE(stream);
407
408 // Resume |data|, finish writing headers, and read EOF.
409 EXPECT_TRUE(session);
410 data.Resume();
411 base::RunLoop().RunUntilIdle();
412 EXPECT_FALSE(session);
413
414 EXPECT_TRUE(data.AllReadDataConsumed());
415 EXPECT_TRUE(data.AllWriteDataConsumed());
416}
417
418TEST_F(WebSocketSpdyStreamAdapterTest, OnHeadersSentThenDisconnect) {
419 MockRead reads[] = {MockRead(ASYNC, 0, 2)};
420 SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
421 1, RequestHeaders(), DEFAULT_PRIORITY, false));
422 SpdySerializedFrame rst(
423 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
424 MockWrite writes[] = {CreateMockWrite(headers, 0), CreateMockWrite(rst, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01425 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02426 AddSocketData(&data);
427 AddSSLSocketData();
428
429 EXPECT_CALL(mock_delegate_, OnHeadersSent());
430
431 base::WeakPtr<SpdySession> session = CreateSpdySession();
432 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
433 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
434 EXPECT_TRUE(adapter.is_initialized());
435
436 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
437 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
438
439 // Finish asynchronous write of headers. This calls OnHeadersSent().
440 base::RunLoop().RunUntilIdle();
441
442 EXPECT_TRUE(stream);
443 adapter.Disconnect();
444 EXPECT_FALSE(stream);
445
446 // Read EOF.
447 EXPECT_TRUE(session);
448 base::RunLoop().RunUntilIdle();
449 EXPECT_FALSE(session);
450
451 EXPECT_TRUE(data.AllReadDataConsumed());
452 EXPECT_TRUE(data.AllWriteDataConsumed());
453}
454
455TEST_F(WebSocketSpdyStreamAdapterTest, OnHeadersReceivedThenDisconnect) {
456 SpdySerializedFrame response_headers(
457 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
458 MockRead reads[] = {CreateMockRead(response_headers, 1),
459 MockRead(ASYNC, 0, 3)};
460 SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
461 1, RequestHeaders(), DEFAULT_PRIORITY, false));
462 SpdySerializedFrame rst(
463 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
464 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
465 CreateMockWrite(rst, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01466 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02467 AddSocketData(&data);
468 AddSSLSocketData();
469
470 EXPECT_CALL(mock_delegate_, OnHeadersSent());
471 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
472
473 base::WeakPtr<SpdySession> session = CreateSpdySession();
474 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
475 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
476 EXPECT_TRUE(adapter.is_initialized());
477
478 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
479 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
480
481 base::RunLoop().RunUntilIdle();
482
483 EXPECT_TRUE(stream);
484 adapter.Disconnect();
485 EXPECT_FALSE(stream);
486
487 // Read EOF.
488 EXPECT_TRUE(session);
489 base::RunLoop().RunUntilIdle();
490 EXPECT_FALSE(session);
491
492 EXPECT_TRUE(data.AllReadDataConsumed());
493 EXPECT_TRUE(data.AllWriteDataConsumed());
494}
495
496TEST_F(WebSocketSpdyStreamAdapterTest, ServerClosesConnection) {
497 MockRead reads[] = {MockRead(ASYNC, 0, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01498 SequencedSocketData data(reads, base::span<MockWrite>());
Bence Béky29f661602018-02-16 02:45:02499 AddSocketData(&data);
500 AddSSLSocketData();
501
502 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
503
504 base::WeakPtr<SpdySession> session = CreateSpdySession();
505 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
506 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
507 EXPECT_TRUE(adapter.is_initialized());
508
509 EXPECT_TRUE(session);
510 EXPECT_TRUE(stream);
511 base::RunLoop().RunUntilIdle();
512 EXPECT_FALSE(session);
513 EXPECT_FALSE(stream);
514
515 EXPECT_TRUE(data.AllReadDataConsumed());
516 EXPECT_TRUE(data.AllWriteDataConsumed());
517}
518
519TEST_F(WebSocketSpdyStreamAdapterTest,
520 SendRequestHeadersThenServerClosesConnection) {
521 MockRead reads[] = {MockRead(ASYNC, 0, 1)};
522 SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
523 1, RequestHeaders(), DEFAULT_PRIORITY, false));
524 MockWrite writes[] = {CreateMockWrite(headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01525 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02526 AddSocketData(&data);
527 AddSSLSocketData();
528
529 EXPECT_CALL(mock_delegate_, OnHeadersSent());
530 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
531
532 base::WeakPtr<SpdySession> session = CreateSpdySession();
533 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
534 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
535 EXPECT_TRUE(adapter.is_initialized());
536
537 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
538 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
539
540 EXPECT_TRUE(session);
541 EXPECT_TRUE(stream);
542 base::RunLoop().RunUntilIdle();
543 EXPECT_FALSE(session);
544 EXPECT_FALSE(stream);
545
546 EXPECT_TRUE(data.AllReadDataConsumed());
547 EXPECT_TRUE(data.AllWriteDataConsumed());
548}
549
550TEST_F(WebSocketSpdyStreamAdapterTest,
551 OnHeadersReceivedThenServerClosesConnection) {
552 SpdySerializedFrame response_headers(
553 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
554 MockRead reads[] = {CreateMockRead(response_headers, 1),
555 MockRead(ASYNC, 0, 2)};
556 SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
557 1, RequestHeaders(), DEFAULT_PRIORITY, false));
558 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01559 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02560 AddSocketData(&data);
561 AddSSLSocketData();
562
563 EXPECT_CALL(mock_delegate_, OnHeadersSent());
564 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
565 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
566
567 base::WeakPtr<SpdySession> session = CreateSpdySession();
568 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
569 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
570 EXPECT_TRUE(adapter.is_initialized());
571
572 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
573 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
574
575 EXPECT_TRUE(session);
576 EXPECT_TRUE(stream);
577 base::RunLoop().RunUntilIdle();
578 EXPECT_FALSE(session);
579 EXPECT_FALSE(stream);
580
581 EXPECT_TRUE(data.AllReadDataConsumed());
582 EXPECT_TRUE(data.AllWriteDataConsumed());
583}
584
585TEST_F(WebSocketSpdyStreamAdapterTest, DetachDelegate) {
586 SpdySerializedFrame response_headers(
587 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
588 MockRead reads[] = {CreateMockRead(response_headers, 1),
589 MockRead(ASYNC, 0, 2)};
590 SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
591 1, RequestHeaders(), DEFAULT_PRIORITY, false));
592 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01593 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02594 AddSocketData(&data);
595 AddSSLSocketData();
596
597 base::WeakPtr<SpdySession> session = CreateSpdySession();
598 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
599 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
600 EXPECT_TRUE(adapter.is_initialized());
601
602 // No Delegate methods shall be called after this.
603 adapter.DetachDelegate();
604
605 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
606 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
607
608 EXPECT_TRUE(session);
609 EXPECT_TRUE(stream);
610 base::RunLoop().RunUntilIdle();
611 EXPECT_FALSE(session);
612 EXPECT_FALSE(stream);
613
614 EXPECT_TRUE(data.AllReadDataConsumed());
615 EXPECT_TRUE(data.AllWriteDataConsumed());
616}
617
618TEST_F(WebSocketSpdyStreamAdapterTest, Read) {
619 SpdySerializedFrame response_headers(
620 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
621 // First read is the same size as the buffer, next is smaller, last is larger.
622 SpdySerializedFrame data_frame1(
Bence Békyd74f4382018-02-20 18:26:19623 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
Bence Béky29f661602018-02-16 02:45:02624 SpdySerializedFrame data_frame2(
Bence Békyd74f4382018-02-20 18:26:19625 spdy_util_.ConstructSpdyDataFrame(1, "ba", false));
Bence Béky29f661602018-02-16 02:45:02626 SpdySerializedFrame data_frame3(
Bence Békyd74f4382018-02-20 18:26:19627 spdy_util_.ConstructSpdyDataFrame(1, "rbaz", true));
Bence Béky29f661602018-02-16 02:45:02628 MockRead reads[] = {CreateMockRead(response_headers, 1),
629 CreateMockRead(data_frame1, 2),
630 CreateMockRead(data_frame2, 3),
631 CreateMockRead(data_frame3, 4), MockRead(ASYNC, 0, 5)};
632 SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
633 1, RequestHeaders(), DEFAULT_PRIORITY, false));
634 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01635 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02636 AddSocketData(&data);
637 AddSSLSocketData();
638
639 EXPECT_CALL(mock_delegate_, OnHeadersSent());
640 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
641
642 base::WeakPtr<SpdySession> session = CreateSpdySession();
643 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
644 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
645 EXPECT_TRUE(adapter.is_initialized());
646
647 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
648 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
649
650 const int kReadBufSize = 3;
651 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
652 TestCompletionCallback callback;
653 rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
654 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
655 rv = callback.WaitForResult();
656 ASSERT_EQ(3, rv);
657 EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
658
659 // Read EOF to destroy the connection and the stream.
660 // This calls SpdySession::Delegate::OnClose().
661 EXPECT_TRUE(session);
662 EXPECT_TRUE(stream);
663 base::RunLoop().RunUntilIdle();
664 EXPECT_FALSE(session);
665 EXPECT_FALSE(stream);
666
667 // Two socket reads are concatenated by WebSocketSpdyStreamAdapter.
668 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionCallback());
669 ASSERT_EQ(3, rv);
670 EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
671
672 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionCallback());
673 ASSERT_EQ(3, rv);
674 EXPECT_EQ("baz", base::StringPiece(read_buf->data(), rv));
675
676 // Even though connection and stream are already closed,
677 // WebSocketSpdyStreamAdapter::Delegate::OnClose() is only called after all
678 // buffered data are read.
679 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
680
681 base::RunLoop().RunUntilIdle();
682
683 EXPECT_TRUE(data.AllReadDataConsumed());
684 EXPECT_TRUE(data.AllWriteDataConsumed());
685}
686
687TEST_F(WebSocketSpdyStreamAdapterTest, CallDelegateOnCloseShouldNotCrash) {
688 SpdySerializedFrame response_headers(
689 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
690 SpdySerializedFrame data_frame1(
Bence Békyd74f4382018-02-20 18:26:19691 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
Bence Béky29f661602018-02-16 02:45:02692 SpdySerializedFrame data_frame2(
Bence Békyd74f4382018-02-20 18:26:19693 spdy_util_.ConstructSpdyDataFrame(1, "bar", false));
Bence Béky29f661602018-02-16 02:45:02694 SpdySerializedFrame rst(
695 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
696 MockRead reads[] = {CreateMockRead(response_headers, 1),
697 CreateMockRead(data_frame1, 2),
698 CreateMockRead(data_frame2, 3), CreateMockRead(rst, 4),
699 MockRead(ASYNC, 0, 5)};
700 SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
701 1, RequestHeaders(), DEFAULT_PRIORITY, false));
702 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01703 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02704 AddSocketData(&data);
705 AddSSLSocketData();
706
707 EXPECT_CALL(mock_delegate_, OnHeadersSent());
708 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
709
710 base::WeakPtr<SpdySession> session = CreateSpdySession();
711 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
712 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
713 EXPECT_TRUE(adapter.is_initialized());
714
715 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
717
718 // Buffer larger than each MockRead.
719 const int kReadBufSize = 1024;
720 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
721 TestCompletionCallback callback;
722 rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
723 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
724 rv = callback.WaitForResult();
725 ASSERT_EQ(3, rv);
726 EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
727
728 // Read RST_STREAM to destroy the stream.
729 // This calls SpdySession::Delegate::OnClose().
730 EXPECT_TRUE(session);
731 EXPECT_TRUE(stream);
732 base::RunLoop().RunUntilIdle();
733 EXPECT_FALSE(session);
734 EXPECT_FALSE(stream);
735
736 // Read remaining buffered data. This will PostTask CallDelegateOnClose().
737 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionCallback());
738 ASSERT_EQ(3, rv);
739 EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
740
741 adapter.DetachDelegate();
742
743 // Run CallDelegateOnClose(), which should not crash
744 // even if |delegate_| is null.
745 base::RunLoop().RunUntilIdle();
746
747 EXPECT_TRUE(data.AllReadDataConsumed());
748 EXPECT_TRUE(data.AllWriteDataConsumed());
749}
750
751TEST_F(WebSocketSpdyStreamAdapterTest, Write) {
752 SpdySerializedFrame response_headers(
753 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
754 MockRead reads[] = {CreateMockRead(response_headers, 1),
755 MockRead(ASYNC, 0, 3)};
756 SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
757 1, RequestHeaders(), DEFAULT_PRIORITY, false));
758 SpdySerializedFrame data_frame(
Bence Békyd74f4382018-02-20 18:26:19759 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
Bence Béky29f661602018-02-16 02:45:02760 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
761 CreateMockWrite(data_frame, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01762 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02763 AddSocketData(&data);
764 AddSSLSocketData();
765
766 base::WeakPtr<SpdySession> session = CreateSpdySession();
767 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
768 WebSocketSpdyStreamAdapter adapter(stream, nullptr, net_log_);
769 EXPECT_TRUE(adapter.is_initialized());
770
771 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
772 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
773
774 base::RunLoop().RunUntilIdle();
775
776 auto write_buf = base::MakeRefCounted<StringIOBuffer>("foo");
777 TestCompletionCallback callback;
778 rv = adapter.Write(write_buf.get(), write_buf->size(), callback.callback(),
779 TRAFFIC_ANNOTATION_FOR_TESTS);
780 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
781 rv = callback.WaitForResult();
782 ASSERT_EQ(3, rv);
783
784 // Read EOF.
785 base::RunLoop().RunUntilIdle();
786
787 EXPECT_TRUE(data.AllReadDataConsumed());
788 EXPECT_TRUE(data.AllWriteDataConsumed());
789}
790
791// Test that if both Read() and Write() returns asynchronously,
792// the two callbacks are handled correctly.
793TEST_F(WebSocketSpdyStreamAdapterTest, AsyncReadAndWrite) {
794 SpdySerializedFrame response_headers(
795 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
796 SpdySerializedFrame read_data_frame(
Bence Békyd74f4382018-02-20 18:26:19797 spdy_util_.ConstructSpdyDataFrame(1, "foobar", true));
Bence Béky29f661602018-02-16 02:45:02798 MockRead reads[] = {CreateMockRead(response_headers, 1),
799 CreateMockRead(read_data_frame, 3),
800 MockRead(ASYNC, 0, 4)};
801 SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
802 1, RequestHeaders(), DEFAULT_PRIORITY, false));
803 SpdySerializedFrame write_data_frame(
Bence Békyd74f4382018-02-20 18:26:19804 spdy_util_.ConstructSpdyDataFrame(1, "baz", false));
Bence Béky29f661602018-02-16 02:45:02805 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
806 CreateMockWrite(write_data_frame, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01807 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02808 AddSocketData(&data);
809 AddSSLSocketData();
810
811 base::WeakPtr<SpdySession> session = CreateSpdySession();
812 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
813 WebSocketSpdyStreamAdapter adapter(stream, nullptr, net_log_);
814 EXPECT_TRUE(adapter.is_initialized());
815
816 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
818
819 base::RunLoop().RunUntilIdle();
820
821 const int kReadBufSize = 1024;
822 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
823 TestCompletionCallback read_callback;
824 rv = adapter.Read(read_buf.get(), kReadBufSize, read_callback.callback());
825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
826
827 auto write_buf = base::MakeRefCounted<StringIOBuffer>("baz");
828 TestCompletionCallback write_callback;
829 rv = adapter.Write(write_buf.get(), write_buf->size(),
830 write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
831 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
832
833 rv = read_callback.WaitForResult();
834 ASSERT_EQ(6, rv);
835 EXPECT_EQ("foobar", base::StringPiece(read_buf->data(), rv));
836
837 rv = write_callback.WaitForResult();
838 ASSERT_EQ(3, rv);
839
840 // Read EOF.
841 base::RunLoop().RunUntilIdle();
842
843 EXPECT_TRUE(data.AllReadDataConsumed());
844 EXPECT_TRUE(data.AllWriteDataConsumed());
845}
846
847// KillerCallback will delete the adapter as part of the callback.
848class KillerCallback : public TestCompletionCallbackBase {
849 public:
850 explicit KillerCallback(std::unique_ptr<WebSocketSpdyStreamAdapter> adapter)
851 : adapter_(std::move(adapter)) {}
852
853 ~KillerCallback() override = default;
854
855 CompletionCallback callback() {
856 return base::Bind(&KillerCallback::OnComplete, base::Unretained(this));
857 }
858
859 private:
860 void OnComplete(int result) {
861 adapter_.reset();
862 SetResult(result);
863 }
864
865 std::unique_ptr<WebSocketSpdyStreamAdapter> adapter_;
866};
867
868TEST_F(WebSocketSpdyStreamAdapterTest, ReadCallbackDestroysAdapter) {
869 SpdySerializedFrame response_headers(
870 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
871 MockRead reads[] = {CreateMockRead(response_headers, 1),
872 MockRead(ASYNC, ERR_IO_PENDING, 2),
873 MockRead(ASYNC, 0, 3)};
874 SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
875 1, RequestHeaders(), DEFAULT_PRIORITY, false));
876 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01877 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02878 AddSocketData(&data);
879 AddSSLSocketData();
880
881 EXPECT_CALL(mock_delegate_, OnHeadersSent());
882 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
883
884 base::WeakPtr<SpdySession> session = CreateSpdySession();
885 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
886 auto adapter = std::make_unique<WebSocketSpdyStreamAdapter>(
887 stream, &mock_delegate_, net_log_);
888 EXPECT_TRUE(adapter->is_initialized());
889
890 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
892
893 // Send headers.
894 base::RunLoop().RunUntilIdle();
895
896 WebSocketSpdyStreamAdapter* adapter_raw = adapter.get();
897 KillerCallback callback(std::move(adapter));
898
899 const int kReadBufSize = 1024;
900 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
901 rv = adapter_raw->Read(read_buf.get(), kReadBufSize, callback.callback());
902 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
903
904 // Read EOF while read is pending. WebSocketSpdyStreamAdapter::OnClose()
905 // should not crash if read callback destroys |adapter|.
906 data.Resume();
907 rv = callback.WaitForResult();
908 EXPECT_THAT(rv, IsError(ERR_CONNECTION_CLOSED));
909
910 base::RunLoop().RunUntilIdle();
911 EXPECT_FALSE(session);
912 EXPECT_FALSE(stream);
913
914 EXPECT_TRUE(data.AllReadDataConsumed());
915 EXPECT_TRUE(data.AllWriteDataConsumed());
916}
917
918TEST_F(WebSocketSpdyStreamAdapterTest, WriteCallbackDestroysAdapter) {
919 SpdySerializedFrame response_headers(
920 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
921 MockRead reads[] = {CreateMockRead(response_headers, 1),
922 MockRead(ASYNC, ERR_IO_PENDING, 2),
923 MockRead(ASYNC, 0, 3)};
924 SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
925 1, RequestHeaders(), DEFAULT_PRIORITY, false));
926 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01927 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02928 AddSocketData(&data);
929 AddSSLSocketData();
930
931 EXPECT_CALL(mock_delegate_, OnHeadersSent());
932 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
933
934 base::WeakPtr<SpdySession> session = CreateSpdySession();
935 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
936 auto adapter = std::make_unique<WebSocketSpdyStreamAdapter>(
937 stream, &mock_delegate_, net_log_);
938 EXPECT_TRUE(adapter->is_initialized());
939
940 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
941 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
942
943 // Send headers.
944 base::RunLoop().RunUntilIdle();
945
946 WebSocketSpdyStreamAdapter* adapter_raw = adapter.get();
947 KillerCallback callback(std::move(adapter));
948
949 auto write_buf = base::MakeRefCounted<StringIOBuffer>("foo");
950 rv = adapter_raw->Write(write_buf.get(), write_buf->size(),
951 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
952 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
953
954 // Read EOF while write is pending. WebSocketSpdyStreamAdapter::OnClose()
955 // should not crash if write callback destroys |adapter|.
956 data.Resume();
957 rv = callback.WaitForResult();
958 EXPECT_THAT(rv, IsError(ERR_CONNECTION_CLOSED));
959
960 base::RunLoop().RunUntilIdle();
961 EXPECT_FALSE(session);
962 EXPECT_FALSE(stream);
963
964 EXPECT_TRUE(data.AllReadDataConsumed());
965 EXPECT_TRUE(data.AllWriteDataConsumed());
966}
967
Bence Béky7294fc22018-02-08 14:26:17968} // namespace test
969
970} // namespace net