blob: 77165d4fa6c1454519d5869a4e5bad940bb5f4e3 [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,
76 OnHostResolutionCallback(),
77 TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)),
78 ssl_params_(base::MakeRefCounted<SSLSocketParams>(transport_params_,
79 nullptr,
80 nullptr,
81 host_port_pair_,
82 SSLConfig(),
83 PRIVACY_MODE_DISABLED,
David Benjamine87ad54b2018-02-21 02:16:2584 0)) {}
Bence Béky7294fc22018-02-08 14:26:1785
Bence Béky29f661602018-02-16 02:45:0286 ~WebSocketClientSocketHandleAdapterTest() override = default;
87
Bence Béky7294fc22018-02-08 14:26:1788 bool InitClientSocketHandle(ClientSocketHandle* connection) {
89 TestCompletionCallback callback;
90 int rv = connection->Init(
91 kGroupName, ssl_params_, MEDIUM, SocketTag(),
92 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
Bence Béky29f661602018-02-16 02:45:0293 socket_pool_manager_->GetSSLSocketPool(), net_log_);
Bence Béky7294fc22018-02-08 14:26:1794 rv = callback.GetResult(rv);
95 return rv == OK;
96 }
97
98 const HostPortPair host_port_pair_;
Bence Béky29f661602018-02-16 02:45:0299 NetLogWithSource net_log_;
Bence Béky7294fc22018-02-08 14:26:17100 MockClientSocketFactory socket_factory_;
101 MockHostResolver host_resolver;
102 std::unique_ptr<ClientSocketPoolManagerImpl> socket_pool_manager_;
103 scoped_refptr<TransportSocketParams> transport_params_;
104 scoped_refptr<SSLSocketParams> ssl_params_;
Bence Békyda280c62018-04-12 15:08:37105 WebSocketEndpointLockManager websocket_endpoint_lock_manager_;
Bence Béky7294fc22018-02-08 14:26:17106};
107
108TEST_F(WebSocketClientSocketHandleAdapterTest, Uninitialized) {
109 auto connection = std::make_unique<ClientSocketHandle>();
110 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
111 EXPECT_FALSE(adapter.is_initialized());
112}
113
114TEST_F(WebSocketClientSocketHandleAdapterTest, IsInitialized) {
Ryan Sleevib8d7ea02018-05-07 20:01:01115 StaticSocketDataProvider data;
Bence Béky7294fc22018-02-08 14:26:17116 socket_factory_.AddSocketDataProvider(&data);
117 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
118 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
119
120 auto connection = std::make_unique<ClientSocketHandle>();
121 ClientSocketHandle* const connection_ptr = connection.get();
122
123 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
124 EXPECT_FALSE(adapter.is_initialized());
125
126 EXPECT_TRUE(InitClientSocketHandle(connection_ptr));
127
128 EXPECT_TRUE(adapter.is_initialized());
129}
130
131TEST_F(WebSocketClientSocketHandleAdapterTest, Disconnect) {
Ryan Sleevib8d7ea02018-05-07 20:01:01132 StaticSocketDataProvider data;
Bence Béky7294fc22018-02-08 14:26:17133 socket_factory_.AddSocketDataProvider(&data);
134 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
135 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
136
137 auto connection = std::make_unique<ClientSocketHandle>();
138 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
139
140 StreamSocket* const socket = connection->socket();
141
142 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
143 EXPECT_TRUE(adapter.is_initialized());
144
145 EXPECT_TRUE(socket->IsConnected());
146 adapter.Disconnect();
147 EXPECT_FALSE(socket->IsConnected());
148}
149
150TEST_F(WebSocketClientSocketHandleAdapterTest, Read) {
151 MockRead reads[] = {MockRead(SYNCHRONOUS, "foo"), MockRead("bar")};
Ryan Sleevib8d7ea02018-05-07 20:01:01152 StaticSocketDataProvider data(reads, base::span<MockWrite>());
Bence Béky7294fc22018-02-08 14:26:17153 socket_factory_.AddSocketDataProvider(&data);
154 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
155 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
156
157 auto connection = std::make_unique<ClientSocketHandle>();
158 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
159
160 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
161 EXPECT_TRUE(adapter.is_initialized());
162
163 // Buffer larger than each MockRead.
164 const int kReadBufSize = 1024;
165 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
Bence Békybdbb0e72018-08-07 21:42:59166 int rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky7294fc22018-02-08 14:26:17167 ASSERT_EQ(3, rv);
168 EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
169
170 TestCompletionCallback callback;
171 rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
172 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
173 rv = callback.WaitForResult();
174 ASSERT_EQ(3, rv);
175 EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
176
177 EXPECT_TRUE(data.AllReadDataConsumed());
178 EXPECT_TRUE(data.AllWriteDataConsumed());
179}
180
181TEST_F(WebSocketClientSocketHandleAdapterTest, ReadIntoSmallBuffer) {
182 MockRead reads[] = {MockRead(SYNCHRONOUS, "foo"), MockRead("bar")};
Ryan Sleevib8d7ea02018-05-07 20:01:01183 StaticSocketDataProvider data(reads, base::span<MockWrite>());
Bence Béky7294fc22018-02-08 14:26:17184 socket_factory_.AddSocketDataProvider(&data);
185 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
186 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
187
188 auto connection = std::make_unique<ClientSocketHandle>();
189 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
190
191 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
192 EXPECT_TRUE(adapter.is_initialized());
193
194 // Buffer smaller than each MockRead.
195 const int kReadBufSize = 2;
196 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
Bence Békybdbb0e72018-08-07 21:42:59197 int rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky7294fc22018-02-08 14:26:17198 ASSERT_EQ(2, rv);
199 EXPECT_EQ("fo", base::StringPiece(read_buf->data(), rv));
200
Bence Békybdbb0e72018-08-07 21:42:59201 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky7294fc22018-02-08 14:26:17202 ASSERT_EQ(1, rv);
203 EXPECT_EQ("o", base::StringPiece(read_buf->data(), rv));
204
205 TestCompletionCallback callback1;
206 rv = adapter.Read(read_buf.get(), kReadBufSize, callback1.callback());
207 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
208 rv = callback1.WaitForResult();
209 ASSERT_EQ(2, rv);
210 EXPECT_EQ("ba", base::StringPiece(read_buf->data(), rv));
211
Bence Békybdbb0e72018-08-07 21:42:59212 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky7294fc22018-02-08 14:26:17213 ASSERT_EQ(1, rv);
214 EXPECT_EQ("r", base::StringPiece(read_buf->data(), rv));
215
216 EXPECT_TRUE(data.AllReadDataConsumed());
217 EXPECT_TRUE(data.AllWriteDataConsumed());
218}
219
220TEST_F(WebSocketClientSocketHandleAdapterTest, Write) {
221 MockWrite writes[] = {MockWrite(SYNCHRONOUS, "foo"), MockWrite("bar")};
Ryan Sleevib8d7ea02018-05-07 20:01:01222 StaticSocketDataProvider data(base::span<MockRead>(), writes);
Bence Béky7294fc22018-02-08 14:26:17223 socket_factory_.AddSocketDataProvider(&data);
224 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
225 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
226
227 auto connection = std::make_unique<ClientSocketHandle>();
228 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
229
230 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
231 EXPECT_TRUE(adapter.is_initialized());
232
233 auto write_buf1 = base::MakeRefCounted<StringIOBuffer>("foo");
Bence Békybdbb0e72018-08-07 21:42:59234 int rv =
235 adapter.Write(write_buf1.get(), write_buf1->size(),
236 CompletionOnceCallback(), TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky7294fc22018-02-08 14:26:17237 ASSERT_EQ(3, rv);
238
239 auto write_buf2 = base::MakeRefCounted<StringIOBuffer>("bar");
240 TestCompletionCallback callback;
241 rv = adapter.Write(write_buf2.get(), write_buf2->size(), callback.callback(),
242 TRAFFIC_ANNOTATION_FOR_TESTS);
243 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
244 rv = callback.WaitForResult();
245 ASSERT_EQ(3, rv);
246
247 EXPECT_TRUE(data.AllReadDataConsumed());
248 EXPECT_TRUE(data.AllWriteDataConsumed());
249}
250
251// Test that if both Read() and Write() returns asynchronously,
252// the two callbacks are handled correctly.
253TEST_F(WebSocketClientSocketHandleAdapterTest, AsyncReadAndWrite) {
254 MockRead reads[] = {MockRead("foobar")};
255 MockWrite writes[] = {MockWrite("baz")};
Ryan Sleevib8d7ea02018-05-07 20:01:01256 StaticSocketDataProvider data(reads, writes);
Bence Béky7294fc22018-02-08 14:26:17257 socket_factory_.AddSocketDataProvider(&data);
258 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
259 socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data);
260
261 auto connection = std::make_unique<ClientSocketHandle>();
262 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
263
264 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
265 EXPECT_TRUE(adapter.is_initialized());
266
267 const int kReadBufSize = 1024;
268 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
269 TestCompletionCallback read_callback;
270 int rv = adapter.Read(read_buf.get(), kReadBufSize, read_callback.callback());
271 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
272
273 auto write_buf = base::MakeRefCounted<StringIOBuffer>("baz");
274 TestCompletionCallback write_callback;
275 rv = adapter.Write(write_buf.get(), write_buf->size(),
276 write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
278
279 rv = read_callback.WaitForResult();
280 ASSERT_EQ(6, rv);
281 EXPECT_EQ("foobar", base::StringPiece(read_buf->data(), rv));
282
283 rv = write_callback.WaitForResult();
284 ASSERT_EQ(3, rv);
285
286 EXPECT_TRUE(data.AllReadDataConsumed());
287 EXPECT_TRUE(data.AllWriteDataConsumed());
288}
289
Bence Béky29f661602018-02-16 02:45:02290class MockDelegate : public WebSocketSpdyStreamAdapter::Delegate {
291 public:
Daniel Cheng4496d0822018-04-26 21:52:15292 ~MockDelegate() override = default;
Bence Béky29f661602018-02-16 02:45:02293 MOCK_METHOD0(OnHeadersSent, void());
Ryan Hamilton0239aac2018-05-19 00:03:13294 MOCK_METHOD1(OnHeadersReceived, void(const spdy::SpdyHeaderBlock&));
Bence Béky29f661602018-02-16 02:45:02295 MOCK_METHOD1(OnClose, void(int));
296};
297
Bence Béky98447b12018-05-08 03:14:01298class WebSocketSpdyStreamAdapterTest : public TestWithScopedTaskEnvironment {
Bence Béky29f661602018-02-16 02:45:02299 protected:
300 WebSocketSpdyStreamAdapterTest()
301 : url_("wss://www.example.org/"),
302 key_(HostPortPair::FromURL(url_),
303 ProxyServer::Direct(),
304 PRIVACY_MODE_DISABLED,
Matt Menke2436b2f2018-12-11 18:07:11305 SpdySessionKey::IsProxySession::kFalse,
Bence Béky29f661602018-02-16 02:45:02306 SocketTag()),
307 session_(SpdySessionDependencies::SpdyCreateSession(&session_deps_)),
308 ssl_(SYNCHRONOUS, OK) {}
309
310 ~WebSocketSpdyStreamAdapterTest() override = default;
311
Ryan Hamilton0239aac2018-05-19 00:03:13312 static spdy::SpdyHeaderBlock RequestHeaders() {
Bence Béky46bfbc12018-02-22 19:28:20313 return WebSocketHttp2Request("/", "www.example.org:443",
314 "http://www.example.org", {});
Bence Béky29f661602018-02-16 02:45:02315 }
316
Ryan Hamilton0239aac2018-05-19 00:03:13317 static spdy::SpdyHeaderBlock ResponseHeaders() {
Bence Béky46bfbc12018-02-22 19:28:20318 return WebSocketHttp2Response({});
Bence Béky29f661602018-02-16 02:45:02319 }
320
321 void AddSocketData(SocketDataProvider* data) {
322 session_deps_.socket_factory->AddSocketDataProvider(data);
323 }
324
325 void AddSSLSocketData() {
326 ssl_.ssl_info.cert =
Bence Béky3a0c48532018-03-02 13:38:51327 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Bence Béky29f661602018-02-16 02:45:02328 ASSERT_TRUE(ssl_.ssl_info.cert);
329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
330 }
331
332 base::WeakPtr<SpdySession> CreateSpdySession() {
333 return ::net::CreateSpdySession(session_.get(), key_, net_log_);
334 }
335
336 base::WeakPtr<SpdyStream> CreateSpdyStream(
337 base::WeakPtr<SpdySession> session) {
338 return CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session, url_,
339 LOWEST, net_log_);
340 }
341
342 SpdyTestUtil spdy_util_;
343 StrictMock<MockDelegate> mock_delegate_;
344 NetLogWithSource net_log_;
345
346 private:
347 const GURL url_;
Bence Béky46bfbc12018-02-22 19:28:20348 const SpdySessionKey key_;
Bence Béky29f661602018-02-16 02:45:02349 SpdySessionDependencies session_deps_;
350 std::unique_ptr<HttpNetworkSession> session_;
351 SSLSocketDataProvider ssl_;
352};
353
354TEST_F(WebSocketSpdyStreamAdapterTest, Disconnect) {
355 MockRead reads[] = {MockRead(ASYNC, ERR_IO_PENDING, 0),
356 MockRead(ASYNC, 0, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01357 SequencedSocketData data(reads, base::span<MockWrite>());
Bence Béky29f661602018-02-16 02:45:02358 AddSocketData(&data);
359 AddSSLSocketData();
360
361 base::WeakPtr<SpdySession> session = CreateSpdySession();
362 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
363 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
364 EXPECT_TRUE(adapter.is_initialized());
365
366 base::RunLoop().RunUntilIdle();
367
368 EXPECT_TRUE(stream);
369 adapter.Disconnect();
370 EXPECT_FALSE(stream);
371
372 // Read EOF.
373 EXPECT_TRUE(session);
374 data.Resume();
375 base::RunLoop().RunUntilIdle();
376 EXPECT_FALSE(session);
377
378 EXPECT_TRUE(data.AllReadDataConsumed());
379 EXPECT_TRUE(data.AllWriteDataConsumed());
380}
381
382TEST_F(WebSocketSpdyStreamAdapterTest, SendRequestHeadersThenDisconnect) {
383 MockRead reads[] = {MockRead(ASYNC, ERR_IO_PENDING, 0),
384 MockRead(ASYNC, 0, 3)};
Ryan Hamilton0239aac2018-05-19 00:03:13385 spdy::SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02386 1, RequestHeaders(), DEFAULT_PRIORITY, false));
Ryan Hamilton0239aac2018-05-19 00:03:13387 spdy::SpdySerializedFrame rst(
388 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
Bence Béky29f661602018-02-16 02:45:02389 MockWrite writes[] = {CreateMockWrite(headers, 1), CreateMockWrite(rst, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01390 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02391 AddSocketData(&data);
392 AddSSLSocketData();
393
394 base::WeakPtr<SpdySession> session = CreateSpdySession();
395 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
396 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
397 EXPECT_TRUE(adapter.is_initialized());
398
399 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
400 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
401
402 // First read is a pause and it has lower sequence number than first write.
403 // Therefore writing headers does not complete while |data| is paused.
404 base::RunLoop().RunUntilIdle();
405
406 // Reset the stream before writing completes.
407 // OnHeadersSent() will never be called.
408 EXPECT_TRUE(stream);
409 adapter.Disconnect();
410 EXPECT_FALSE(stream);
411
412 // Resume |data|, finish writing headers, and read EOF.
413 EXPECT_TRUE(session);
414 data.Resume();
415 base::RunLoop().RunUntilIdle();
416 EXPECT_FALSE(session);
417
418 EXPECT_TRUE(data.AllReadDataConsumed());
419 EXPECT_TRUE(data.AllWriteDataConsumed());
420}
421
422TEST_F(WebSocketSpdyStreamAdapterTest, OnHeadersSentThenDisconnect) {
423 MockRead reads[] = {MockRead(ASYNC, 0, 2)};
Ryan Hamilton0239aac2018-05-19 00:03:13424 spdy::SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02425 1, RequestHeaders(), DEFAULT_PRIORITY, false));
Ryan Hamilton0239aac2018-05-19 00:03:13426 spdy::SpdySerializedFrame rst(
427 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
Bence Béky29f661602018-02-16 02:45:02428 MockWrite writes[] = {CreateMockWrite(headers, 0), CreateMockWrite(rst, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:01429 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02430 AddSocketData(&data);
431 AddSSLSocketData();
432
433 EXPECT_CALL(mock_delegate_, OnHeadersSent());
434
435 base::WeakPtr<SpdySession> session = CreateSpdySession();
436 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
437 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
438 EXPECT_TRUE(adapter.is_initialized());
439
440 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
441 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
442
443 // Finish asynchronous write of headers. This calls OnHeadersSent().
444 base::RunLoop().RunUntilIdle();
445
446 EXPECT_TRUE(stream);
447 adapter.Disconnect();
448 EXPECT_FALSE(stream);
449
450 // Read EOF.
451 EXPECT_TRUE(session);
452 base::RunLoop().RunUntilIdle();
453 EXPECT_FALSE(session);
454
455 EXPECT_TRUE(data.AllReadDataConsumed());
456 EXPECT_TRUE(data.AllWriteDataConsumed());
457}
458
459TEST_F(WebSocketSpdyStreamAdapterTest, OnHeadersReceivedThenDisconnect) {
Ryan Hamilton0239aac2018-05-19 00:03:13460 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02461 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
462 MockRead reads[] = {CreateMockRead(response_headers, 1),
463 MockRead(ASYNC, 0, 3)};
Ryan Hamilton0239aac2018-05-19 00:03:13464 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02465 1, RequestHeaders(), DEFAULT_PRIORITY, false));
Ryan Hamilton0239aac2018-05-19 00:03:13466 spdy::SpdySerializedFrame rst(
467 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
Bence Béky29f661602018-02-16 02:45:02468 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
469 CreateMockWrite(rst, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01470 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02471 AddSocketData(&data);
472 AddSSLSocketData();
473
474 EXPECT_CALL(mock_delegate_, OnHeadersSent());
475 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
476
477 base::WeakPtr<SpdySession> session = CreateSpdySession();
478 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
479 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
480 EXPECT_TRUE(adapter.is_initialized());
481
482 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
483 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
484
485 base::RunLoop().RunUntilIdle();
486
487 EXPECT_TRUE(stream);
488 adapter.Disconnect();
489 EXPECT_FALSE(stream);
490
491 // Read EOF.
492 EXPECT_TRUE(session);
493 base::RunLoop().RunUntilIdle();
494 EXPECT_FALSE(session);
495
496 EXPECT_TRUE(data.AllReadDataConsumed());
497 EXPECT_TRUE(data.AllWriteDataConsumed());
498}
499
500TEST_F(WebSocketSpdyStreamAdapterTest, ServerClosesConnection) {
501 MockRead reads[] = {MockRead(ASYNC, 0, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01502 SequencedSocketData data(reads, base::span<MockWrite>());
Bence Béky29f661602018-02-16 02:45:02503 AddSocketData(&data);
504 AddSSLSocketData();
505
506 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
507
508 base::WeakPtr<SpdySession> session = CreateSpdySession();
509 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
510 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
511 EXPECT_TRUE(adapter.is_initialized());
512
513 EXPECT_TRUE(session);
514 EXPECT_TRUE(stream);
515 base::RunLoop().RunUntilIdle();
516 EXPECT_FALSE(session);
517 EXPECT_FALSE(stream);
518
519 EXPECT_TRUE(data.AllReadDataConsumed());
520 EXPECT_TRUE(data.AllWriteDataConsumed());
521}
522
523TEST_F(WebSocketSpdyStreamAdapterTest,
524 SendRequestHeadersThenServerClosesConnection) {
525 MockRead reads[] = {MockRead(ASYNC, 0, 1)};
Ryan Hamilton0239aac2018-05-19 00:03:13526 spdy::SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02527 1, RequestHeaders(), DEFAULT_PRIORITY, false));
528 MockWrite writes[] = {CreateMockWrite(headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01529 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02530 AddSocketData(&data);
531 AddSSLSocketData();
532
533 EXPECT_CALL(mock_delegate_, OnHeadersSent());
534 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
535
536 base::WeakPtr<SpdySession> session = CreateSpdySession();
537 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
538 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
539 EXPECT_TRUE(adapter.is_initialized());
540
541 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
542 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
543
544 EXPECT_TRUE(session);
545 EXPECT_TRUE(stream);
546 base::RunLoop().RunUntilIdle();
547 EXPECT_FALSE(session);
548 EXPECT_FALSE(stream);
549
550 EXPECT_TRUE(data.AllReadDataConsumed());
551 EXPECT_TRUE(data.AllWriteDataConsumed());
552}
553
554TEST_F(WebSocketSpdyStreamAdapterTest,
555 OnHeadersReceivedThenServerClosesConnection) {
Ryan Hamilton0239aac2018-05-19 00:03:13556 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02557 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
558 MockRead reads[] = {CreateMockRead(response_headers, 1),
559 MockRead(ASYNC, 0, 2)};
Ryan Hamilton0239aac2018-05-19 00:03:13560 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02561 1, RequestHeaders(), DEFAULT_PRIORITY, false));
562 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01563 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02564 AddSocketData(&data);
565 AddSSLSocketData();
566
567 EXPECT_CALL(mock_delegate_, OnHeadersSent());
568 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
569 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
570
571 base::WeakPtr<SpdySession> session = CreateSpdySession();
572 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
573 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
574 EXPECT_TRUE(adapter.is_initialized());
575
576 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
577 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
578
579 EXPECT_TRUE(session);
580 EXPECT_TRUE(stream);
581 base::RunLoop().RunUntilIdle();
582 EXPECT_FALSE(session);
583 EXPECT_FALSE(stream);
584
585 EXPECT_TRUE(data.AllReadDataConsumed());
586 EXPECT_TRUE(data.AllWriteDataConsumed());
587}
588
589TEST_F(WebSocketSpdyStreamAdapterTest, DetachDelegate) {
Ryan Hamilton0239aac2018-05-19 00:03:13590 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02591 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
592 MockRead reads[] = {CreateMockRead(response_headers, 1),
593 MockRead(ASYNC, 0, 2)};
Ryan Hamilton0239aac2018-05-19 00:03:13594 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02595 1, RequestHeaders(), DEFAULT_PRIORITY, false));
596 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01597 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02598 AddSocketData(&data);
599 AddSSLSocketData();
600
601 base::WeakPtr<SpdySession> session = CreateSpdySession();
602 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
603 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
604 EXPECT_TRUE(adapter.is_initialized());
605
606 // No Delegate methods shall be called after this.
607 adapter.DetachDelegate();
608
609 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
610 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
611
612 EXPECT_TRUE(session);
613 EXPECT_TRUE(stream);
614 base::RunLoop().RunUntilIdle();
615 EXPECT_FALSE(session);
616 EXPECT_FALSE(stream);
617
618 EXPECT_TRUE(data.AllReadDataConsumed());
619 EXPECT_TRUE(data.AllWriteDataConsumed());
620}
621
622TEST_F(WebSocketSpdyStreamAdapterTest, Read) {
Ryan Hamilton0239aac2018-05-19 00:03:13623 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02624 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
625 // First read is the same size as the buffer, next is smaller, last is larger.
Ryan Hamilton0239aac2018-05-19 00:03:13626 spdy::SpdySerializedFrame data_frame1(
Bence Békyd74f4382018-02-20 18:26:19627 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
Ryan Hamilton0239aac2018-05-19 00:03:13628 spdy::SpdySerializedFrame data_frame2(
Bence Békyd74f4382018-02-20 18:26:19629 spdy_util_.ConstructSpdyDataFrame(1, "ba", false));
Ryan Hamilton0239aac2018-05-19 00:03:13630 spdy::SpdySerializedFrame data_frame3(
Bence Békyd74f4382018-02-20 18:26:19631 spdy_util_.ConstructSpdyDataFrame(1, "rbaz", true));
Bence Béky29f661602018-02-16 02:45:02632 MockRead reads[] = {CreateMockRead(response_headers, 1),
633 CreateMockRead(data_frame1, 2),
634 CreateMockRead(data_frame2, 3),
635 CreateMockRead(data_frame3, 4), MockRead(ASYNC, 0, 5)};
Ryan Hamilton0239aac2018-05-19 00:03:13636 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02637 1, RequestHeaders(), DEFAULT_PRIORITY, false));
638 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01639 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02640 AddSocketData(&data);
641 AddSSLSocketData();
642
643 EXPECT_CALL(mock_delegate_, OnHeadersSent());
644 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
645
646 base::WeakPtr<SpdySession> session = CreateSpdySession();
647 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
648 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
649 EXPECT_TRUE(adapter.is_initialized());
650
651 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
653
654 const int kReadBufSize = 3;
655 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
656 TestCompletionCallback callback;
657 rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
658 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
659 rv = callback.WaitForResult();
660 ASSERT_EQ(3, rv);
661 EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
662
663 // Read EOF to destroy the connection and the stream.
664 // This calls SpdySession::Delegate::OnClose().
665 EXPECT_TRUE(session);
666 EXPECT_TRUE(stream);
667 base::RunLoop().RunUntilIdle();
668 EXPECT_FALSE(session);
669 EXPECT_FALSE(stream);
670
671 // Two socket reads are concatenated by WebSocketSpdyStreamAdapter.
Bence Békybdbb0e72018-08-07 21:42:59672 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky29f661602018-02-16 02:45:02673 ASSERT_EQ(3, rv);
674 EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
675
Bence Békybdbb0e72018-08-07 21:42:59676 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky29f661602018-02-16 02:45:02677 ASSERT_EQ(3, rv);
678 EXPECT_EQ("baz", base::StringPiece(read_buf->data(), rv));
679
680 // Even though connection and stream are already closed,
681 // WebSocketSpdyStreamAdapter::Delegate::OnClose() is only called after all
682 // buffered data are read.
683 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
684
685 base::RunLoop().RunUntilIdle();
686
687 EXPECT_TRUE(data.AllReadDataConsumed());
688 EXPECT_TRUE(data.AllWriteDataConsumed());
689}
690
691TEST_F(WebSocketSpdyStreamAdapterTest, CallDelegateOnCloseShouldNotCrash) {
Ryan Hamilton0239aac2018-05-19 00:03:13692 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02693 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
Ryan Hamilton0239aac2018-05-19 00:03:13694 spdy::SpdySerializedFrame data_frame1(
Bence Békyd74f4382018-02-20 18:26:19695 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
Ryan Hamilton0239aac2018-05-19 00:03:13696 spdy::SpdySerializedFrame data_frame2(
Bence Békyd74f4382018-02-20 18:26:19697 spdy_util_.ConstructSpdyDataFrame(1, "bar", false));
Ryan Hamilton0239aac2018-05-19 00:03:13698 spdy::SpdySerializedFrame rst(
699 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
Bence Béky29f661602018-02-16 02:45:02700 MockRead reads[] = {CreateMockRead(response_headers, 1),
701 CreateMockRead(data_frame1, 2),
702 CreateMockRead(data_frame2, 3), CreateMockRead(rst, 4),
703 MockRead(ASYNC, 0, 5)};
Ryan Hamilton0239aac2018-05-19 00:03:13704 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02705 1, RequestHeaders(), DEFAULT_PRIORITY, false));
706 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01707 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02708 AddSocketData(&data);
709 AddSSLSocketData();
710
711 EXPECT_CALL(mock_delegate_, OnHeadersSent());
712 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
713
714 base::WeakPtr<SpdySession> session = CreateSpdySession();
715 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
716 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_, net_log_);
717 EXPECT_TRUE(adapter.is_initialized());
718
719 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
721
722 // Buffer larger than each MockRead.
723 const int kReadBufSize = 1024;
724 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
725 TestCompletionCallback callback;
726 rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
728 rv = callback.WaitForResult();
729 ASSERT_EQ(3, rv);
730 EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
731
732 // Read RST_STREAM to destroy the stream.
733 // This calls SpdySession::Delegate::OnClose().
734 EXPECT_TRUE(session);
735 EXPECT_TRUE(stream);
736 base::RunLoop().RunUntilIdle();
737 EXPECT_FALSE(session);
738 EXPECT_FALSE(stream);
739
740 // Read remaining buffered data. This will PostTask CallDelegateOnClose().
Bence Békybdbb0e72018-08-07 21:42:59741 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
Bence Béky29f661602018-02-16 02:45:02742 ASSERT_EQ(3, rv);
743 EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
744
745 adapter.DetachDelegate();
746
747 // Run CallDelegateOnClose(), which should not crash
748 // even if |delegate_| is null.
749 base::RunLoop().RunUntilIdle();
750
751 EXPECT_TRUE(data.AllReadDataConsumed());
752 EXPECT_TRUE(data.AllWriteDataConsumed());
753}
754
755TEST_F(WebSocketSpdyStreamAdapterTest, Write) {
Ryan Hamilton0239aac2018-05-19 00:03:13756 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02757 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
758 MockRead reads[] = {CreateMockRead(response_headers, 1),
759 MockRead(ASYNC, 0, 3)};
Ryan Hamilton0239aac2018-05-19 00:03:13760 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02761 1, RequestHeaders(), DEFAULT_PRIORITY, false));
Ryan Hamilton0239aac2018-05-19 00:03:13762 spdy::SpdySerializedFrame data_frame(
Bence Békyd74f4382018-02-20 18:26:19763 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
Bence Béky29f661602018-02-16 02:45:02764 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
765 CreateMockWrite(data_frame, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01766 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02767 AddSocketData(&data);
768 AddSSLSocketData();
769
770 base::WeakPtr<SpdySession> session = CreateSpdySession();
771 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
772 WebSocketSpdyStreamAdapter adapter(stream, nullptr, net_log_);
773 EXPECT_TRUE(adapter.is_initialized());
774
775 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
776 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
777
778 base::RunLoop().RunUntilIdle();
779
780 auto write_buf = base::MakeRefCounted<StringIOBuffer>("foo");
781 TestCompletionCallback callback;
782 rv = adapter.Write(write_buf.get(), write_buf->size(), callback.callback(),
783 TRAFFIC_ANNOTATION_FOR_TESTS);
784 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
785 rv = callback.WaitForResult();
786 ASSERT_EQ(3, rv);
787
788 // Read EOF.
789 base::RunLoop().RunUntilIdle();
790
791 EXPECT_TRUE(data.AllReadDataConsumed());
792 EXPECT_TRUE(data.AllWriteDataConsumed());
793}
794
795// Test that if both Read() and Write() returns asynchronously,
796// the two callbacks are handled correctly.
797TEST_F(WebSocketSpdyStreamAdapterTest, AsyncReadAndWrite) {
Ryan Hamilton0239aac2018-05-19 00:03:13798 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02799 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
Ryan Hamilton0239aac2018-05-19 00:03:13800 spdy::SpdySerializedFrame read_data_frame(
Bence Békyd74f4382018-02-20 18:26:19801 spdy_util_.ConstructSpdyDataFrame(1, "foobar", true));
Bence Béky29f661602018-02-16 02:45:02802 MockRead reads[] = {CreateMockRead(response_headers, 1),
803 CreateMockRead(read_data_frame, 3),
804 MockRead(ASYNC, 0, 4)};
Ryan Hamilton0239aac2018-05-19 00:03:13805 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02806 1, RequestHeaders(), DEFAULT_PRIORITY, false));
Ryan Hamilton0239aac2018-05-19 00:03:13807 spdy::SpdySerializedFrame write_data_frame(
Bence Békyd74f4382018-02-20 18:26:19808 spdy_util_.ConstructSpdyDataFrame(1, "baz", false));
Bence Béky29f661602018-02-16 02:45:02809 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
810 CreateMockWrite(write_data_frame, 2)};
Ryan Sleevib8d7ea02018-05-07 20:01:01811 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02812 AddSocketData(&data);
813 AddSSLSocketData();
814
815 base::WeakPtr<SpdySession> session = CreateSpdySession();
816 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
817 WebSocketSpdyStreamAdapter adapter(stream, nullptr, net_log_);
818 EXPECT_TRUE(adapter.is_initialized());
819
820 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
821 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
822
823 base::RunLoop().RunUntilIdle();
824
825 const int kReadBufSize = 1024;
826 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
827 TestCompletionCallback read_callback;
828 rv = adapter.Read(read_buf.get(), kReadBufSize, read_callback.callback());
829 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
830
831 auto write_buf = base::MakeRefCounted<StringIOBuffer>("baz");
832 TestCompletionCallback write_callback;
833 rv = adapter.Write(write_buf.get(), write_buf->size(),
834 write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
835 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
836
837 rv = read_callback.WaitForResult();
838 ASSERT_EQ(6, rv);
839 EXPECT_EQ("foobar", base::StringPiece(read_buf->data(), rv));
840
841 rv = write_callback.WaitForResult();
842 ASSERT_EQ(3, rv);
843
844 // Read EOF.
845 base::RunLoop().RunUntilIdle();
846
847 EXPECT_TRUE(data.AllReadDataConsumed());
848 EXPECT_TRUE(data.AllWriteDataConsumed());
849}
850
Bence Béky8ddc2492018-06-13 01:02:04851// A helper class that will delete |adapter| when the callback is invoked.
Bence Béky29f661602018-02-16 02:45:02852class KillerCallback : public TestCompletionCallbackBase {
853 public:
854 explicit KillerCallback(std::unique_ptr<WebSocketSpdyStreamAdapter> adapter)
855 : adapter_(std::move(adapter)) {}
856
857 ~KillerCallback() override = default;
858
Bence Béky8ddc2492018-06-13 01:02:04859 CompletionOnceCallback callback() {
860 return base::BindOnce(&KillerCallback::OnComplete, base::Unretained(this));
Bence Béky29f661602018-02-16 02:45:02861 }
862
863 private:
864 void OnComplete(int result) {
865 adapter_.reset();
866 SetResult(result);
867 }
868
869 std::unique_ptr<WebSocketSpdyStreamAdapter> adapter_;
870};
871
872TEST_F(WebSocketSpdyStreamAdapterTest, ReadCallbackDestroysAdapter) {
Ryan Hamilton0239aac2018-05-19 00:03:13873 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02874 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
875 MockRead reads[] = {CreateMockRead(response_headers, 1),
876 MockRead(ASYNC, ERR_IO_PENDING, 2),
877 MockRead(ASYNC, 0, 3)};
Ryan Hamilton0239aac2018-05-19 00:03:13878 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02879 1, RequestHeaders(), DEFAULT_PRIORITY, false));
880 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01881 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02882 AddSocketData(&data);
883 AddSSLSocketData();
884
885 EXPECT_CALL(mock_delegate_, OnHeadersSent());
886 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
887
888 base::WeakPtr<SpdySession> session = CreateSpdySession();
889 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
890 auto adapter = std::make_unique<WebSocketSpdyStreamAdapter>(
891 stream, &mock_delegate_, net_log_);
892 EXPECT_TRUE(adapter->is_initialized());
893
894 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
896
897 // Send headers.
898 base::RunLoop().RunUntilIdle();
899
900 WebSocketSpdyStreamAdapter* adapter_raw = adapter.get();
901 KillerCallback callback(std::move(adapter));
902
903 const int kReadBufSize = 1024;
904 auto read_buf = base::MakeRefCounted<IOBuffer>(kReadBufSize);
905 rv = adapter_raw->Read(read_buf.get(), kReadBufSize, callback.callback());
906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
907
908 // Read EOF while read is pending. WebSocketSpdyStreamAdapter::OnClose()
909 // should not crash if read callback destroys |adapter|.
910 data.Resume();
911 rv = callback.WaitForResult();
912 EXPECT_THAT(rv, IsError(ERR_CONNECTION_CLOSED));
913
914 base::RunLoop().RunUntilIdle();
915 EXPECT_FALSE(session);
916 EXPECT_FALSE(stream);
917
918 EXPECT_TRUE(data.AllReadDataConsumed());
919 EXPECT_TRUE(data.AllWriteDataConsumed());
920}
921
922TEST_F(WebSocketSpdyStreamAdapterTest, WriteCallbackDestroysAdapter) {
Ryan Hamilton0239aac2018-05-19 00:03:13923 spdy::SpdySerializedFrame response_headers(
Bence Béky29f661602018-02-16 02:45:02924 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
925 MockRead reads[] = {CreateMockRead(response_headers, 1),
926 MockRead(ASYNC, ERR_IO_PENDING, 2),
927 MockRead(ASYNC, 0, 3)};
Ryan Hamilton0239aac2018-05-19 00:03:13928 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
Bence Béky29f661602018-02-16 02:45:02929 1, RequestHeaders(), DEFAULT_PRIORITY, false));
930 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
Ryan Sleevib8d7ea02018-05-07 20:01:01931 SequencedSocketData data(reads, writes);
Bence Béky29f661602018-02-16 02:45:02932 AddSocketData(&data);
933 AddSSLSocketData();
934
935 EXPECT_CALL(mock_delegate_, OnHeadersSent());
936 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
937
938 base::WeakPtr<SpdySession> session = CreateSpdySession();
939 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
940 auto adapter = std::make_unique<WebSocketSpdyStreamAdapter>(
941 stream, &mock_delegate_, net_log_);
942 EXPECT_TRUE(adapter->is_initialized());
943
944 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
945 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
946
947 // Send headers.
948 base::RunLoop().RunUntilIdle();
949
950 WebSocketSpdyStreamAdapter* adapter_raw = adapter.get();
951 KillerCallback callback(std::move(adapter));
952
953 auto write_buf = base::MakeRefCounted<StringIOBuffer>("foo");
954 rv = adapter_raw->Write(write_buf.get(), write_buf->size(),
955 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
956 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
957
958 // Read EOF while write is pending. WebSocketSpdyStreamAdapter::OnClose()
959 // should not crash if write callback destroys |adapter|.
960 data.Resume();
961 rv = callback.WaitForResult();
962 EXPECT_THAT(rv, IsError(ERR_CONNECTION_CLOSED));
963
964 base::RunLoop().RunUntilIdle();
965 EXPECT_FALSE(session);
966 EXPECT_FALSE(stream);
967
968 EXPECT_TRUE(data.AllReadDataConsumed());
969 EXPECT_TRUE(data.AllWriteDataConsumed());
970}
971
Bence Béky7294fc22018-02-08 14:26:17972} // namespace test
973
974} // namespace net