blob: 31f7892b47feddd25f6ecbdbee7377e276023933 [file] [log] [blame]
Andrew Top0d1858f2019-05-15 22:01:47 -07001// 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"
10#include "base/memory/weak_ptr.h"
11#include "base/run_loop.h"
12#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"
16#include "net/base/privacy_mode.h"
17#include "net/base/proxy_server.h"
18#include "net/base/test_completion_callback.h"
19#include "net/dns/mock_host_resolver.h"
20#include "net/http/http_network_session.h"
21#include "net/log/net_log_with_source.h"
22#include "net/socket/client_socket_handle.h"
23#include "net/socket/client_socket_pool_manager_impl.h"
24#include "net/socket/socket_tag.h"
25#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"
28#include "net/socket/websocket_endpoint_lock_manager.h"
29#include "net/spdy/spdy_session.h"
30#include "net/spdy/spdy_session_key.h"
31#include "net/spdy/spdy_test_util_common.h"
32#include "net/ssl/ssl_config.h"
33#include "net/ssl/ssl_info.h"
34#include "net/test/cert_test_util.h"
35#include "net/test/gtest_util.h"
36#include "net/test/test_data_directory.h"
37#include "net/test/test_with_scoped_task_environment.h"
38#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
39#include "net/websockets/websocket_test_util.h"
40#include "testing/gmock/include/gmock/gmock.h"
41#include "testing/gtest/include/gtest/gtest.h"
42
43using testing::Test;
44using testing::StrictMock;
45using testing::_;
46
47namespace net {
48
49namespace test {
50
51const char* const kGroupName = "ssl/www.example.org:443";
52
53class WebSocketClientSocketHandleAdapterTest
54 : public TestWithScopedTaskEnvironment {
55 protected:
56 WebSocketClientSocketHandleAdapterTest()
57 : host_port_pair_("www.example.org", 443),
58 socket_pool_manager_(std::make_unique<ClientSocketPoolManagerImpl>(
59 net_log_.net_log(),
60 &socket_factory_,
61 nullptr,
62 nullptr,
63 &host_resolver,
64 nullptr,
65 nullptr,
66 nullptr,
67 nullptr,
68 nullptr,
69 "test_shard",
70 nullptr,
71 &websocket_endpoint_lock_manager_,
72 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,
84 0)) {}
85
86 ~WebSocketClientSocketHandleAdapterTest() override = default;
87
88 bool InitClientSocketHandle(ClientSocketHandle* connection) {
89 TestCompletionCallback callback;
90 int rv = connection->Init(
91 kGroupName, ssl_params_, MEDIUM, SocketTag(),
92 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
93 socket_pool_manager_->GetSSLSocketPool(), net_log_);
94 rv = callback.GetResult(rv);
95 return rv == OK;
96 }
97
98 const HostPortPair host_port_pair_;
99 NetLogWithSource net_log_;
100 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_;
105 WebSocketEndpointLockManager websocket_endpoint_lock_manager_;
106};
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) {
115 StaticSocketDataProvider data;
116 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) {
132 StaticSocketDataProvider data;
133 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")};
152 StaticSocketDataProvider data(reads, base::span<MockWrite>());
153 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);
166 int rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
167 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")};
183 StaticSocketDataProvider data(reads, base::span<MockWrite>());
184 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);
197 int rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
198 ASSERT_EQ(2, rv);
199 EXPECT_EQ("fo", base::StringPiece(read_buf->data(), rv));
200
201 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
202 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
212 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
213 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")};
222 StaticSocketDataProvider data(base::span<MockRead>(), writes);
223 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");
234 int rv =
235 adapter.Write(write_buf1.get(), write_buf1->size(),
236 CompletionOnceCallback(), TRAFFIC_ANNOTATION_FOR_TESTS);
237 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")};
256 StaticSocketDataProvider data(reads, writes);
257 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
290class MockDelegate : public WebSocketSpdyStreamAdapter::Delegate {
291 public:
292 ~MockDelegate() override = default;
293 MOCK_METHOD0(OnHeadersSent, void());
294 MOCK_METHOD1(OnHeadersReceived, void(const spdy::SpdyHeaderBlock&));
295 MOCK_METHOD1(OnClose, void(int));
296};
297
298class WebSocketSpdyStreamAdapterTest : public TestWithScopedTaskEnvironment {
299 protected:
300 WebSocketSpdyStreamAdapterTest()
301 : url_("wss://www.example.org/"),
302 key_(HostPortPair::FromURL(url_),
303 ProxyServer::Direct(),
304 PRIVACY_MODE_DISABLED,
305 SocketTag()),
306 session_(SpdySessionDependencies::SpdyCreateSession(&session_deps_)),
307 ssl_(SYNCHRONOUS, OK) {}
308
309 ~WebSocketSpdyStreamAdapterTest() override = default;
310
311 static spdy::SpdyHeaderBlock RequestHeaders() {
312 return WebSocketHttp2Request("/", "www.example.org:443",
313 "http://www.example.org", {});
314 }
315
316 static spdy::SpdyHeaderBlock ResponseHeaders() {
317 return WebSocketHttp2Response({});
318 }
319
320 void AddSocketData(SocketDataProvider* data) {
321 session_deps_.socket_factory->AddSocketDataProvider(data);
322 }
323
324 void AddSSLSocketData() {
325 ssl_.ssl_info.cert =
326 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
327 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_;
347 const SpdySessionKey key_;
348 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)};
356 SequencedSocketData data(reads, base::span<MockWrite>());
357 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)};
384 spdy::SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
385 1, RequestHeaders(), DEFAULT_PRIORITY, false));
386 spdy::SpdySerializedFrame rst(
387 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
388 MockWrite writes[] = {CreateMockWrite(headers, 1), CreateMockWrite(rst, 2)};
389 SequencedSocketData data(reads, writes);
390 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)};
423 spdy::SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
424 1, RequestHeaders(), DEFAULT_PRIORITY, false));
425 spdy::SpdySerializedFrame rst(
426 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
427 MockWrite writes[] = {CreateMockWrite(headers, 0), CreateMockWrite(rst, 1)};
428 SequencedSocketData data(reads, writes);
429 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) {
459 spdy::SpdySerializedFrame response_headers(
460 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
461 MockRead reads[] = {CreateMockRead(response_headers, 1),
462 MockRead(ASYNC, 0, 3)};
463 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
464 1, RequestHeaders(), DEFAULT_PRIORITY, false));
465 spdy::SpdySerializedFrame rst(
466 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
467 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
468 CreateMockWrite(rst, 2)};
469 SequencedSocketData data(reads, writes);
470 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)};
501 SequencedSocketData data(reads, base::span<MockWrite>());
502 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)};
525 spdy::SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
526 1, RequestHeaders(), DEFAULT_PRIORITY, false));
527 MockWrite writes[] = {CreateMockWrite(headers, 0)};
528 SequencedSocketData data(reads, writes);
529 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) {
555 spdy::SpdySerializedFrame response_headers(
556 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
557 MockRead reads[] = {CreateMockRead(response_headers, 1),
558 MockRead(ASYNC, 0, 2)};
559 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
560 1, RequestHeaders(), DEFAULT_PRIORITY, false));
561 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
562 SequencedSocketData data(reads, writes);
563 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) {
589 spdy::SpdySerializedFrame response_headers(
590 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
591 MockRead reads[] = {CreateMockRead(response_headers, 1),
592 MockRead(ASYNC, 0, 2)};
593 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
594 1, RequestHeaders(), DEFAULT_PRIORITY, false));
595 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
596 SequencedSocketData data(reads, writes);
597 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) {
622 spdy::SpdySerializedFrame response_headers(
623 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
624 // First read is the same size as the buffer, next is smaller, last is larger.
625 spdy::SpdySerializedFrame data_frame1(
626 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
627 spdy::SpdySerializedFrame data_frame2(
628 spdy_util_.ConstructSpdyDataFrame(1, "ba", false));
629 spdy::SpdySerializedFrame data_frame3(
630 spdy_util_.ConstructSpdyDataFrame(1, "rbaz", true));
631 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)};
635 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
636 1, RequestHeaders(), DEFAULT_PRIORITY, false));
637 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
638 SequencedSocketData data(reads, writes);
639 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.
671 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
672 ASSERT_EQ(3, rv);
673 EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
674
675 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
676 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) {
691 spdy::SpdySerializedFrame response_headers(
692 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
693 spdy::SpdySerializedFrame data_frame1(
694 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
695 spdy::SpdySerializedFrame data_frame2(
696 spdy_util_.ConstructSpdyDataFrame(1, "bar", false));
697 spdy::SpdySerializedFrame rst(
698 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
699 MockRead reads[] = {CreateMockRead(response_headers, 1),
700 CreateMockRead(data_frame1, 2),
701 CreateMockRead(data_frame2, 3), CreateMockRead(rst, 4),
702 MockRead(ASYNC, 0, 5)};
703 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
704 1, RequestHeaders(), DEFAULT_PRIORITY, false));
705 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
706 SequencedSocketData data(reads, writes);
707 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().
740 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
741 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) {
755 spdy::SpdySerializedFrame response_headers(
756 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
757 MockRead reads[] = {CreateMockRead(response_headers, 1),
758 MockRead(ASYNC, 0, 3)};
759 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
760 1, RequestHeaders(), DEFAULT_PRIORITY, false));
761 spdy::SpdySerializedFrame data_frame(
762 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
763 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
764 CreateMockWrite(data_frame, 2)};
765 SequencedSocketData data(reads, writes);
766 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) {
797 spdy::SpdySerializedFrame response_headers(
798 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
799 spdy::SpdySerializedFrame read_data_frame(
800 spdy_util_.ConstructSpdyDataFrame(1, "foobar", true));
801 MockRead reads[] = {CreateMockRead(response_headers, 1),
802 CreateMockRead(read_data_frame, 3),
803 MockRead(ASYNC, 0, 4)};
804 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
805 1, RequestHeaders(), DEFAULT_PRIORITY, false));
806 spdy::SpdySerializedFrame write_data_frame(
807 spdy_util_.ConstructSpdyDataFrame(1, "baz", false));
808 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
809 CreateMockWrite(write_data_frame, 2)};
810 SequencedSocketData data(reads, writes);
811 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
850// A helper class that will delete |adapter| when the callback is invoked.
851class KillerCallback : public TestCompletionCallbackBase {
852 public:
853 explicit KillerCallback(std::unique_ptr<WebSocketSpdyStreamAdapter> adapter)
854 : adapter_(std::move(adapter)) {}
855
856 ~KillerCallback() override = default;
857
858 CompletionOnceCallback callback() {
859 return base::BindOnce(&KillerCallback::OnComplete, base::Unretained(this));
860 }
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) {
872 spdy::SpdySerializedFrame response_headers(
873 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)};
877 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
878 1, RequestHeaders(), DEFAULT_PRIORITY, false));
879 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
880 SequencedSocketData data(reads, writes);
881 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) {
922 spdy::SpdySerializedFrame response_headers(
923 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)};
927 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
928 1, RequestHeaders(), DEFAULT_PRIORITY, false));
929 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
930 SequencedSocketData data(reads, writes);
931 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
971} // namespace test
972
973} // namespace net