1 // Copyright 2018 The Chromium Authors
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 <stdint.h>
8
9 #include <string>
10 #include <utility>
11 #include <vector>
12
13 #include "base/check.h"
14 #include "base/containers/span.h"
15 #include "base/functional/bind.h"
16 #include "base/functional/callback.h"
17 #include "base/memory/raw_ptr.h"
18 #include "base/memory/scoped_refptr.h"
19 #include "base/memory/weak_ptr.h"
20 #include "base/run_loop.h"
21 #include "base/strings/strcat.h"
22 #include "base/strings/string_piece.h"
23 #include "base/task/single_thread_task_runner.h"
24 #include "base/time/default_tick_clock.h"
25 #include "base/time/time.h"
26 #include "net/base/host_port_pair.h"
27 #include "net/base/io_buffer.h"
28 #include "net/base/ip_address.h"
29 #include "net/base/ip_endpoint.h"
30 #include "net/base/net_errors.h"
31 #include "net/base/network_anonymization_key.h"
32 #include "net/base/network_handle.h"
33 #include "net/base/privacy_mode.h"
34 #include "net/base/proxy_chain.h"
35 #include "net/base/request_priority.h"
36 #include "net/base/test_completion_callback.h"
37 #include "net/cert/cert_verify_result.h"
38 #include "net/dns/public/host_resolver_results.h"
39 #include "net/dns/public/secure_dns_policy.h"
40 #include "net/http/http_network_session.h"
41 #include "net/http/transport_security_state.h"
42 #include "net/log/net_log.h"
43 #include "net/log/net_log_with_source.h"
44 #include "net/quic/address_utils.h"
45 #include "net/quic/crypto/proof_verifier_chromium.h"
46 #include "net/quic/mock_crypto_client_stream_factory.h"
47 #include "net/quic/mock_quic_data.h"
48 #include "net/quic/quic_chromium_alarm_factory.h"
49 #include "net/quic/quic_chromium_client_session.h"
50 #include "net/quic/quic_chromium_client_session_peer.h"
51 #include "net/quic/quic_chromium_connection_helper.h"
52 #include "net/quic/quic_chromium_packet_reader.h"
53 #include "net/quic/quic_chromium_packet_writer.h"
54 #include "net/quic/quic_context.h"
55 #include "net/quic/quic_http_utils.h"
56 #include "net/quic/quic_server_info.h"
57 #include "net/quic/quic_session_key.h"
58 #include "net/quic/quic_test_packet_maker.h"
59 #include "net/quic/test_quic_crypto_client_config_handle.h"
60 #include "net/quic/test_task_runner.h"
61 #include "net/socket/client_socket_handle.h"
62 #include "net/socket/client_socket_pool.h"
63 #include "net/socket/next_proto.h"
64 #include "net/socket/socket_tag.h"
65 #include "net/socket/socket_test_util.h"
66 #include "net/socket/stream_socket.h"
67 #include "net/spdy/spdy_session_key.h"
68 #include "net/spdy/spdy_test_util_common.h"
69 #include "net/ssl/ssl_config.h"
70 #include "net/ssl/ssl_config_service_defaults.h"
71 #include "net/ssl/ssl_info.h"
72 #include "net/test/cert_test_util.h"
73 #include "net/test/gtest_util.h"
74 #include "net/test/test_data_directory.h"
75 #include "net/test/test_with_task_environment.h"
76 #include "net/third_party/quiche/src/quiche/common/http/http_header_block.h"
77 #include "net/third_party/quiche/src/quiche/common/platform/api/quiche_flags.h"
78 #include "net/third_party/quiche/src/quiche/common/quiche_buffer_allocator.h"
79 #include "net/third_party/quiche/src/quiche/common/simple_buffer_allocator.h"
80 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_client_config.h"
81 #include "net/third_party/quiche/src/quiche/quic/core/http/http_encoder.h"
82 #include "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_decoder.h"
83 #include "net/third_party/quiche/src/quiche/quic/core/quic_connection.h"
84 #include "net/third_party/quiche/src/quiche/quic/core/quic_connection_id.h"
85 #include "net/third_party/quiche/src/quiche/quic/core/quic_error_codes.h"
86 #include "net/third_party/quiche/src/quiche/quic/core/quic_packets.h"
87 #include "net/third_party/quiche/src/quiche/quic/core/quic_time.h"
88 #include "net/third_party/quiche/src/quiche/quic/core/quic_types.h"
89 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
90 #include "net/third_party/quiche/src/quiche/quic/core/quic_versions.h"
91 #include "net/third_party/quiche/src/quiche/quic/platform/api/quic_socket_address.h"
92 #include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
93 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_clock.h"
94 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_connection_id_generator.h"
95 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
96 #include "net/third_party/quiche/src/quiche/quic/test_tools/qpack/qpack_test_utils.h"
97 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
98 #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
99 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
100 #include "net/websockets/websocket_test_util.h"
101 #include "testing/gmock/include/gmock/gmock.h"
102 #include "testing/gtest/include/gtest/gtest.h"
103 #include "url/gurl.h"
104 #include "url/scheme_host_port.h"
105 #include "url/url_constants.h"
106
107 namespace net {
108 class QuicChromiumClientStream;
109 class SpdySession;
110 class WebSocketEndpointLockManager;
111 class X509Certificate;
112 } // namespace net
113
114 using testing::_;
115 using testing::AnyNumber;
116 using testing::Invoke;
117 using testing::Return;
118 using testing::StrictMock;
119 using testing::Test;
120
121 namespace net::test {
122
123 class WebSocketClientSocketHandleAdapterTest : public TestWithTaskEnvironment {
124 protected:
WebSocketClientSocketHandleAdapterTest()125 WebSocketClientSocketHandleAdapterTest()
126 : network_session_(
127 SpdySessionDependencies::SpdyCreateSession(&session_deps_)),
128 websocket_endpoint_lock_manager_(
129 network_session_->websocket_endpoint_lock_manager()) {}
130
131 ~WebSocketClientSocketHandleAdapterTest() override = default;
132
InitClientSocketHandle(ClientSocketHandle * connection)133 bool InitClientSocketHandle(ClientSocketHandle* connection) {
134 auto ssl_config_for_origin = std::make_unique<SSLConfig>();
135 ssl_config_for_origin->alpn_protos = {kProtoHTTP11};
136 scoped_refptr<ClientSocketPool::SocketParams> socks_params =
137 base::MakeRefCounted<ClientSocketPool::SocketParams>(
138 std::move(ssl_config_for_origin),
139 /*base_ssl_config_for_proxies=*/nullptr);
140 TestCompletionCallback callback;
141 int rv = connection->Init(
142 ClientSocketPool::GroupId(
143 url::SchemeHostPort(url::kHttpsScheme, "www.example.org", 443),
144 PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
145 SecureDnsPolicy::kAllow),
146 socks_params, /*proxy_annotation_tag=*/TRAFFIC_ANNOTATION_FOR_TESTS,
147 MEDIUM, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
148 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
149 network_session_->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
150 ProxyChain::Direct()),
151 NetLogWithSource());
152 rv = callback.GetResult(rv);
153 return rv == OK;
154 }
155
156 SpdySessionDependencies session_deps_;
157 std::unique_ptr<HttpNetworkSession> network_session_;
158 raw_ptr<WebSocketEndpointLockManager> websocket_endpoint_lock_manager_;
159 };
160
TEST_F(WebSocketClientSocketHandleAdapterTest,Uninitialized)161 TEST_F(WebSocketClientSocketHandleAdapterTest, Uninitialized) {
162 auto connection = std::make_unique<ClientSocketHandle>();
163 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
164 EXPECT_FALSE(adapter.is_initialized());
165 }
166
TEST_F(WebSocketClientSocketHandleAdapterTest,IsInitialized)167 TEST_F(WebSocketClientSocketHandleAdapterTest, IsInitialized) {
168 StaticSocketDataProvider data;
169 session_deps_.socket_factory->AddSocketDataProvider(&data);
170 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
171 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
172
173 auto connection = std::make_unique<ClientSocketHandle>();
174 ClientSocketHandle* const connection_ptr = connection.get();
175
176 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
177 EXPECT_FALSE(adapter.is_initialized());
178
179 EXPECT_TRUE(InitClientSocketHandle(connection_ptr));
180
181 EXPECT_TRUE(adapter.is_initialized());
182 }
183
TEST_F(WebSocketClientSocketHandleAdapterTest,Disconnect)184 TEST_F(WebSocketClientSocketHandleAdapterTest, Disconnect) {
185 StaticSocketDataProvider data;
186 session_deps_.socket_factory->AddSocketDataProvider(&data);
187 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
188 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
189
190 auto connection = std::make_unique<ClientSocketHandle>();
191 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
192
193 StreamSocket* const socket = connection->socket();
194
195 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
196 EXPECT_TRUE(adapter.is_initialized());
197
198 EXPECT_TRUE(socket->IsConnected());
199 adapter.Disconnect();
200 EXPECT_FALSE(socket->IsConnected());
201 }
202
TEST_F(WebSocketClientSocketHandleAdapterTest,Read)203 TEST_F(WebSocketClientSocketHandleAdapterTest, Read) {
204 MockRead reads[] = {MockRead(SYNCHRONOUS, "foo"), MockRead("bar")};
205 StaticSocketDataProvider data(reads, base::span<MockWrite>());
206 session_deps_.socket_factory->AddSocketDataProvider(&data);
207 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
208 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
209
210 auto connection = std::make_unique<ClientSocketHandle>();
211 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
212
213 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
214 EXPECT_TRUE(adapter.is_initialized());
215
216 // Buffer larger than each MockRead.
217 const int kReadBufSize = 1024;
218 auto read_buf = base::MakeRefCounted<IOBufferWithSize>(kReadBufSize);
219 int rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
220 ASSERT_EQ(3, rv);
221 EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
222
223 TestCompletionCallback callback;
224 rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
225 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
226 rv = callback.WaitForResult();
227 ASSERT_EQ(3, rv);
228 EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
229
230 EXPECT_TRUE(data.AllReadDataConsumed());
231 EXPECT_TRUE(data.AllWriteDataConsumed());
232 }
233
TEST_F(WebSocketClientSocketHandleAdapterTest,ReadIntoSmallBuffer)234 TEST_F(WebSocketClientSocketHandleAdapterTest, ReadIntoSmallBuffer) {
235 MockRead reads[] = {MockRead(SYNCHRONOUS, "foo"), MockRead("bar")};
236 StaticSocketDataProvider data(reads, base::span<MockWrite>());
237 session_deps_.socket_factory->AddSocketDataProvider(&data);
238 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
239 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
240
241 auto connection = std::make_unique<ClientSocketHandle>();
242 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
243
244 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
245 EXPECT_TRUE(adapter.is_initialized());
246
247 // Buffer smaller than each MockRead.
248 const int kReadBufSize = 2;
249 auto read_buf = base::MakeRefCounted<IOBufferWithSize>(kReadBufSize);
250 int rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
251 ASSERT_EQ(2, rv);
252 EXPECT_EQ("fo", base::StringPiece(read_buf->data(), rv));
253
254 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
255 ASSERT_EQ(1, rv);
256 EXPECT_EQ("o", base::StringPiece(read_buf->data(), rv));
257
258 TestCompletionCallback callback1;
259 rv = adapter.Read(read_buf.get(), kReadBufSize, callback1.callback());
260 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
261 rv = callback1.WaitForResult();
262 ASSERT_EQ(2, rv);
263 EXPECT_EQ("ba", base::StringPiece(read_buf->data(), rv));
264
265 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
266 ASSERT_EQ(1, rv);
267 EXPECT_EQ("r", base::StringPiece(read_buf->data(), rv));
268
269 EXPECT_TRUE(data.AllReadDataConsumed());
270 EXPECT_TRUE(data.AllWriteDataConsumed());
271 }
272
TEST_F(WebSocketClientSocketHandleAdapterTest,Write)273 TEST_F(WebSocketClientSocketHandleAdapterTest, Write) {
274 MockWrite writes[] = {MockWrite(SYNCHRONOUS, "foo"), MockWrite("bar")};
275 StaticSocketDataProvider data(base::span<MockRead>(), writes);
276 session_deps_.socket_factory->AddSocketDataProvider(&data);
277 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
278 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
279
280 auto connection = std::make_unique<ClientSocketHandle>();
281 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
282
283 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
284 EXPECT_TRUE(adapter.is_initialized());
285
286 auto write_buf1 = base::MakeRefCounted<StringIOBuffer>("foo");
287 int rv =
288 adapter.Write(write_buf1.get(), write_buf1->size(),
289 CompletionOnceCallback(), TRAFFIC_ANNOTATION_FOR_TESTS);
290 ASSERT_EQ(3, rv);
291
292 auto write_buf2 = base::MakeRefCounted<StringIOBuffer>("bar");
293 TestCompletionCallback callback;
294 rv = adapter.Write(write_buf2.get(), write_buf2->size(), callback.callback(),
295 TRAFFIC_ANNOTATION_FOR_TESTS);
296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
297 rv = callback.WaitForResult();
298 ASSERT_EQ(3, rv);
299
300 EXPECT_TRUE(data.AllReadDataConsumed());
301 EXPECT_TRUE(data.AllWriteDataConsumed());
302 }
303
304 // Test that if both Read() and Write() returns asynchronously,
305 // the two callbacks are handled correctly.
TEST_F(WebSocketClientSocketHandleAdapterTest,AsyncReadAndWrite)306 TEST_F(WebSocketClientSocketHandleAdapterTest, AsyncReadAndWrite) {
307 MockRead reads[] = {MockRead("foobar")};
308 MockWrite writes[] = {MockWrite("baz")};
309 StaticSocketDataProvider data(reads, writes);
310 session_deps_.socket_factory->AddSocketDataProvider(&data);
311 SSLSocketDataProvider ssl_socket_data(ASYNC, OK);
312 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data);
313
314 auto connection = std::make_unique<ClientSocketHandle>();
315 EXPECT_TRUE(InitClientSocketHandle(connection.get()));
316
317 WebSocketClientSocketHandleAdapter adapter(std::move(connection));
318 EXPECT_TRUE(adapter.is_initialized());
319
320 const int kReadBufSize = 1024;
321 auto read_buf = base::MakeRefCounted<IOBufferWithSize>(kReadBufSize);
322 TestCompletionCallback read_callback;
323 int rv = adapter.Read(read_buf.get(), kReadBufSize, read_callback.callback());
324 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
325
326 auto write_buf = base::MakeRefCounted<StringIOBuffer>("baz");
327 TestCompletionCallback write_callback;
328 rv = adapter.Write(write_buf.get(), write_buf->size(),
329 write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
330 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
331
332 rv = read_callback.WaitForResult();
333 ASSERT_EQ(6, rv);
334 EXPECT_EQ("foobar", base::StringPiece(read_buf->data(), rv));
335
336 rv = write_callback.WaitForResult();
337 ASSERT_EQ(3, rv);
338
339 EXPECT_TRUE(data.AllReadDataConsumed());
340 EXPECT_TRUE(data.AllWriteDataConsumed());
341 }
342
343 class MockDelegate : public WebSocketSpdyStreamAdapter::Delegate {
344 public:
345 ~MockDelegate() override = default;
346 MOCK_METHOD(void, OnHeadersSent, (), (override));
347 MOCK_METHOD(void,
348 OnHeadersReceived,
349 (const spdy::Http2HeaderBlock&),
350 (override));
351 MOCK_METHOD(void, OnClose, (int), (override));
352 };
353
354 class WebSocketSpdyStreamAdapterTest : public TestWithTaskEnvironment {
355 protected:
WebSocketSpdyStreamAdapterTest()356 WebSocketSpdyStreamAdapterTest()
357 : url_("wss://www.example.org/"),
358 key_(HostPortPair::FromURL(url_),
359 ProxyChain::Direct(),
360 PRIVACY_MODE_DISABLED,
361 SpdySessionKey::IsProxySession::kFalse,
362 SocketTag(),
363 NetworkAnonymizationKey(),
364 SecureDnsPolicy::kAllow),
365 session_(SpdySessionDependencies::SpdyCreateSession(&session_deps_)),
366 ssl_(SYNCHRONOUS, OK) {}
367
368 ~WebSocketSpdyStreamAdapterTest() override = default;
369
RequestHeaders()370 static spdy::Http2HeaderBlock RequestHeaders() {
371 return WebSocketHttp2Request("/", "www.example.org:443",
372 "http://www.example.org", {});
373 }
374
ResponseHeaders()375 static spdy::Http2HeaderBlock ResponseHeaders() {
376 return WebSocketHttp2Response({});
377 }
378
AddSocketData(SocketDataProvider * data)379 void AddSocketData(SocketDataProvider* data) {
380 session_deps_.socket_factory->AddSocketDataProvider(data);
381 }
382
AddSSLSocketData()383 void AddSSLSocketData() {
384 ssl_.ssl_info.cert =
385 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
386 ASSERT_TRUE(ssl_.ssl_info.cert);
387 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
388 }
389
CreateSpdySession()390 base::WeakPtr<SpdySession> CreateSpdySession() {
391 return ::net::CreateSpdySession(session_.get(), key_, NetLogWithSource());
392 }
393
CreateSpdyStream(base::WeakPtr<SpdySession> session)394 base::WeakPtr<SpdyStream> CreateSpdyStream(
395 base::WeakPtr<SpdySession> session) {
396 return CreateStreamSynchronously(SPDY_BIDIRECTIONAL_STREAM, session, url_,
397 LOWEST, NetLogWithSource());
398 }
399
400 SpdyTestUtil spdy_util_;
401 StrictMock<MockDelegate> mock_delegate_;
402
403 private:
404 const GURL url_;
405 const SpdySessionKey key_;
406 SpdySessionDependencies session_deps_;
407 std::unique_ptr<HttpNetworkSession> session_;
408 SSLSocketDataProvider ssl_;
409 };
410
TEST_F(WebSocketSpdyStreamAdapterTest,Disconnect)411 TEST_F(WebSocketSpdyStreamAdapterTest, Disconnect) {
412 MockRead reads[] = {MockRead(ASYNC, ERR_IO_PENDING, 0),
413 MockRead(ASYNC, 0, 1)};
414 SequencedSocketData data(reads, base::span<MockWrite>());
415 AddSocketData(&data);
416 AddSSLSocketData();
417
418 base::WeakPtr<SpdySession> session = CreateSpdySession();
419 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
420 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_,
421 NetLogWithSource());
422 EXPECT_TRUE(adapter.is_initialized());
423
424 base::RunLoop().RunUntilIdle();
425
426 EXPECT_TRUE(stream);
427 adapter.Disconnect();
428 EXPECT_FALSE(stream);
429
430 // Read EOF.
431 EXPECT_TRUE(session);
432 data.Resume();
433 base::RunLoop().RunUntilIdle();
434 EXPECT_FALSE(session);
435
436 EXPECT_TRUE(data.AllReadDataConsumed());
437 EXPECT_TRUE(data.AllWriteDataConsumed());
438 }
439
TEST_F(WebSocketSpdyStreamAdapterTest,SendRequestHeadersThenDisconnect)440 TEST_F(WebSocketSpdyStreamAdapterTest, SendRequestHeadersThenDisconnect) {
441 MockRead reads[] = {MockRead(ASYNC, ERR_IO_PENDING, 0),
442 MockRead(ASYNC, 0, 3)};
443 spdy::SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
444 1, RequestHeaders(), DEFAULT_PRIORITY, false));
445 spdy::SpdySerializedFrame rst(
446 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
447 MockWrite writes[] = {CreateMockWrite(headers, 1), CreateMockWrite(rst, 2)};
448 SequencedSocketData data(reads, writes);
449 AddSocketData(&data);
450 AddSSLSocketData();
451
452 base::WeakPtr<SpdySession> session = CreateSpdySession();
453 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
454 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_,
455 NetLogWithSource());
456 EXPECT_TRUE(adapter.is_initialized());
457
458 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
459 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
460
461 // First read is a pause and it has lower sequence number than first write.
462 // Therefore writing headers does not complete while |data| is paused.
463 base::RunLoop().RunUntilIdle();
464
465 // Reset the stream before writing completes.
466 // OnHeadersSent() will never be called.
467 EXPECT_TRUE(stream);
468 adapter.Disconnect();
469 EXPECT_FALSE(stream);
470
471 // Resume |data|, finish writing headers, and read EOF.
472 EXPECT_TRUE(session);
473 data.Resume();
474 base::RunLoop().RunUntilIdle();
475 EXPECT_FALSE(session);
476
477 EXPECT_TRUE(data.AllReadDataConsumed());
478 EXPECT_TRUE(data.AllWriteDataConsumed());
479 }
480
TEST_F(WebSocketSpdyStreamAdapterTest,OnHeadersSentThenDisconnect)481 TEST_F(WebSocketSpdyStreamAdapterTest, OnHeadersSentThenDisconnect) {
482 MockRead reads[] = {MockRead(ASYNC, 0, 2)};
483 spdy::SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
484 1, RequestHeaders(), DEFAULT_PRIORITY, false));
485 spdy::SpdySerializedFrame rst(
486 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
487 MockWrite writes[] = {CreateMockWrite(headers, 0), CreateMockWrite(rst, 1)};
488 SequencedSocketData data(reads, writes);
489 AddSocketData(&data);
490 AddSSLSocketData();
491
492 EXPECT_CALL(mock_delegate_, OnHeadersSent());
493
494 base::WeakPtr<SpdySession> session = CreateSpdySession();
495 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
496 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_,
497 NetLogWithSource());
498 EXPECT_TRUE(adapter.is_initialized());
499
500 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
501 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
502
503 // Finish asynchronous write of headers. This calls OnHeadersSent().
504 base::RunLoop().RunUntilIdle();
505
506 EXPECT_TRUE(stream);
507 adapter.Disconnect();
508 EXPECT_FALSE(stream);
509
510 // Read EOF.
511 EXPECT_TRUE(session);
512 base::RunLoop().RunUntilIdle();
513 EXPECT_FALSE(session);
514
515 EXPECT_TRUE(data.AllReadDataConsumed());
516 EXPECT_TRUE(data.AllWriteDataConsumed());
517 }
518
TEST_F(WebSocketSpdyStreamAdapterTest,OnHeadersReceivedThenDisconnect)519 TEST_F(WebSocketSpdyStreamAdapterTest, OnHeadersReceivedThenDisconnect) {
520 spdy::SpdySerializedFrame response_headers(
521 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
522 MockRead reads[] = {CreateMockRead(response_headers, 1),
523 MockRead(ASYNC, 0, 3)};
524 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
525 1, RequestHeaders(), DEFAULT_PRIORITY, false));
526 spdy::SpdySerializedFrame rst(
527 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
528 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
529 CreateMockWrite(rst, 2)};
530 SequencedSocketData data(reads, writes);
531 AddSocketData(&data);
532 AddSSLSocketData();
533
534 EXPECT_CALL(mock_delegate_, OnHeadersSent());
535 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
536
537 base::WeakPtr<SpdySession> session = CreateSpdySession();
538 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
539 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_,
540 NetLogWithSource());
541 EXPECT_TRUE(adapter.is_initialized());
542
543 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
545
546 base::RunLoop().RunUntilIdle();
547
548 EXPECT_TRUE(stream);
549 adapter.Disconnect();
550 EXPECT_FALSE(stream);
551
552 // Read EOF.
553 EXPECT_TRUE(session);
554 base::RunLoop().RunUntilIdle();
555 EXPECT_FALSE(session);
556
557 EXPECT_TRUE(data.AllReadDataConsumed());
558 EXPECT_TRUE(data.AllWriteDataConsumed());
559 }
560
TEST_F(WebSocketSpdyStreamAdapterTest,ServerClosesConnection)561 TEST_F(WebSocketSpdyStreamAdapterTest, ServerClosesConnection) {
562 MockRead reads[] = {MockRead(ASYNC, 0, 0)};
563 SequencedSocketData data(reads, base::span<MockWrite>());
564 AddSocketData(&data);
565 AddSSLSocketData();
566
567 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
568
569 base::WeakPtr<SpdySession> session = CreateSpdySession();
570 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
571 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_,
572 NetLogWithSource());
573 EXPECT_TRUE(adapter.is_initialized());
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
TEST_F(WebSocketSpdyStreamAdapterTest,SendRequestHeadersThenServerClosesConnection)585 TEST_F(WebSocketSpdyStreamAdapterTest,
586 SendRequestHeadersThenServerClosesConnection) {
587 MockRead reads[] = {MockRead(ASYNC, 0, 1)};
588 spdy::SpdySerializedFrame headers(spdy_util_.ConstructSpdyHeaders(
589 1, RequestHeaders(), DEFAULT_PRIORITY, false));
590 MockWrite writes[] = {CreateMockWrite(headers, 0)};
591 SequencedSocketData data(reads, writes);
592 AddSocketData(&data);
593 AddSSLSocketData();
594
595 EXPECT_CALL(mock_delegate_, OnHeadersSent());
596 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
597
598 base::WeakPtr<SpdySession> session = CreateSpdySession();
599 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
600 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_,
601 NetLogWithSource());
602 EXPECT_TRUE(adapter.is_initialized());
603
604 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
606
607 EXPECT_TRUE(session);
608 EXPECT_TRUE(stream);
609 base::RunLoop().RunUntilIdle();
610 EXPECT_FALSE(session);
611 EXPECT_FALSE(stream);
612
613 EXPECT_TRUE(data.AllReadDataConsumed());
614 EXPECT_TRUE(data.AllWriteDataConsumed());
615 }
616
TEST_F(WebSocketSpdyStreamAdapterTest,OnHeadersReceivedThenServerClosesConnection)617 TEST_F(WebSocketSpdyStreamAdapterTest,
618 OnHeadersReceivedThenServerClosesConnection) {
619 spdy::SpdySerializedFrame response_headers(
620 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
621 MockRead reads[] = {CreateMockRead(response_headers, 1),
622 MockRead(ASYNC, 0, 2)};
623 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
624 1, RequestHeaders(), DEFAULT_PRIORITY, false));
625 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
626 SequencedSocketData data(reads, writes);
627 AddSocketData(&data);
628 AddSSLSocketData();
629
630 EXPECT_CALL(mock_delegate_, OnHeadersSent());
631 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
632 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
633
634 base::WeakPtr<SpdySession> session = CreateSpdySession();
635 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
636 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_,
637 NetLogWithSource());
638 EXPECT_TRUE(adapter.is_initialized());
639
640 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
642
643 EXPECT_TRUE(session);
644 EXPECT_TRUE(stream);
645 base::RunLoop().RunUntilIdle();
646 EXPECT_FALSE(session);
647 EXPECT_FALSE(stream);
648
649 EXPECT_TRUE(data.AllReadDataConsumed());
650 EXPECT_TRUE(data.AllWriteDataConsumed());
651 }
652
653 // Previously we failed to detect a half-close by the server that indicated the
654 // stream should be closed. This test ensures a half-close is correctly
655 // detected. See https://crbug.com/1151393.
TEST_F(WebSocketSpdyStreamAdapterTest,OnHeadersReceivedThenStreamEnd)656 TEST_F(WebSocketSpdyStreamAdapterTest, OnHeadersReceivedThenStreamEnd) {
657 spdy::SpdySerializedFrame response_headers(
658 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
659 spdy::SpdySerializedFrame stream_end(
660 spdy_util_.ConstructSpdyDataFrame(1, "", true));
661 MockRead reads[] = {CreateMockRead(response_headers, 1),
662 CreateMockRead(stream_end, 2),
663 MockRead(ASYNC, ERR_IO_PENDING, 3), // pause here
664 MockRead(ASYNC, 0, 4)};
665 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
666 1, RequestHeaders(), DEFAULT_PRIORITY, /* fin = */ false));
667 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
668 SequencedSocketData data(reads, writes);
669 AddSocketData(&data);
670 AddSSLSocketData();
671
672 EXPECT_CALL(mock_delegate_, OnHeadersSent());
673 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
674 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
675
676 base::WeakPtr<SpdySession> session = CreateSpdySession();
677 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
678 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_,
679 NetLogWithSource());
680 EXPECT_TRUE(adapter.is_initialized());
681
682 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
683 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
684
685 constexpr int kReadBufSize = 1024;
686 auto read_buf = base::MakeRefCounted<IOBufferWithSize>(kReadBufSize);
687 TestCompletionCallback read_callback;
688 rv = adapter.Read(read_buf.get(), kReadBufSize, read_callback.callback());
689 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
690
691 EXPECT_TRUE(session);
692 EXPECT_TRUE(stream);
693 rv = read_callback.WaitForResult();
694 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv);
695 EXPECT_TRUE(session);
696 EXPECT_FALSE(stream);
697
698 // Close the session.
699 data.Resume();
700
701 base::RunLoop().RunUntilIdle();
702
703 EXPECT_TRUE(data.AllReadDataConsumed());
704 EXPECT_TRUE(data.AllWriteDataConsumed());
705 }
706
TEST_F(WebSocketSpdyStreamAdapterTest,DetachDelegate)707 TEST_F(WebSocketSpdyStreamAdapterTest, DetachDelegate) {
708 spdy::SpdySerializedFrame response_headers(
709 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
710 MockRead reads[] = {CreateMockRead(response_headers, 1),
711 MockRead(ASYNC, 0, 2)};
712 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
713 1, RequestHeaders(), DEFAULT_PRIORITY, false));
714 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
715 SequencedSocketData data(reads, writes);
716 AddSocketData(&data);
717 AddSSLSocketData();
718
719 base::WeakPtr<SpdySession> session = CreateSpdySession();
720 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
721 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_,
722 NetLogWithSource());
723 EXPECT_TRUE(adapter.is_initialized());
724
725 // No Delegate methods shall be called after this.
726 adapter.DetachDelegate();
727
728 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
729 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
730
731 EXPECT_TRUE(session);
732 EXPECT_TRUE(stream);
733 base::RunLoop().RunUntilIdle();
734 EXPECT_FALSE(session);
735 EXPECT_FALSE(stream);
736
737 EXPECT_TRUE(data.AllReadDataConsumed());
738 EXPECT_TRUE(data.AllWriteDataConsumed());
739 }
740
TEST_F(WebSocketSpdyStreamAdapterTest,Read)741 TEST_F(WebSocketSpdyStreamAdapterTest, Read) {
742 spdy::SpdySerializedFrame response_headers(
743 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
744 // First read is the same size as the buffer, next is smaller, last is larger.
745 spdy::SpdySerializedFrame data_frame1(
746 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
747 spdy::SpdySerializedFrame data_frame2(
748 spdy_util_.ConstructSpdyDataFrame(1, "ba", false));
749 spdy::SpdySerializedFrame data_frame3(
750 spdy_util_.ConstructSpdyDataFrame(1, "rbaz", true));
751 MockRead reads[] = {CreateMockRead(response_headers, 1),
752 CreateMockRead(data_frame1, 2),
753 CreateMockRead(data_frame2, 3),
754 CreateMockRead(data_frame3, 4), MockRead(ASYNC, 0, 5)};
755 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
756 1, RequestHeaders(), DEFAULT_PRIORITY, false));
757 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
758 SequencedSocketData data(reads, writes);
759 AddSocketData(&data);
760 AddSSLSocketData();
761
762 EXPECT_CALL(mock_delegate_, OnHeadersSent());
763 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
764
765 base::WeakPtr<SpdySession> session = CreateSpdySession();
766 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
767 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_,
768 NetLogWithSource());
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 const int kReadBufSize = 3;
775 auto read_buf = base::MakeRefCounted<IOBufferWithSize>(kReadBufSize);
776 TestCompletionCallback callback;
777 rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
778 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
779 rv = callback.WaitForResult();
780 ASSERT_EQ(3, rv);
781 EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
782
783 // Read EOF to destroy the connection and the stream.
784 // This calls SpdySession::Delegate::OnClose().
785 EXPECT_TRUE(session);
786 EXPECT_TRUE(stream);
787 base::RunLoop().RunUntilIdle();
788 EXPECT_FALSE(session);
789 EXPECT_FALSE(stream);
790
791 // Two socket reads are concatenated by WebSocketSpdyStreamAdapter.
792 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
793 ASSERT_EQ(3, rv);
794 EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
795
796 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
797 ASSERT_EQ(3, rv);
798 EXPECT_EQ("baz", base::StringPiece(read_buf->data(), rv));
799
800 // Even though connection and stream are already closed,
801 // WebSocketSpdyStreamAdapter::Delegate::OnClose() is only called after all
802 // buffered data are read.
803 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
804
805 base::RunLoop().RunUntilIdle();
806
807 EXPECT_TRUE(data.AllReadDataConsumed());
808 EXPECT_TRUE(data.AllWriteDataConsumed());
809 }
810
TEST_F(WebSocketSpdyStreamAdapterTest,CallDelegateOnCloseShouldNotCrash)811 TEST_F(WebSocketSpdyStreamAdapterTest, CallDelegateOnCloseShouldNotCrash) {
812 spdy::SpdySerializedFrame response_headers(
813 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
814 spdy::SpdySerializedFrame data_frame1(
815 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
816 spdy::SpdySerializedFrame data_frame2(
817 spdy_util_.ConstructSpdyDataFrame(1, "bar", false));
818 spdy::SpdySerializedFrame rst(
819 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
820 MockRead reads[] = {CreateMockRead(response_headers, 1),
821 CreateMockRead(data_frame1, 2),
822 CreateMockRead(data_frame2, 3), CreateMockRead(rst, 4),
823 MockRead(ASYNC, 0, 5)};
824 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
825 1, RequestHeaders(), DEFAULT_PRIORITY, false));
826 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
827 SequencedSocketData data(reads, writes);
828 AddSocketData(&data);
829 AddSSLSocketData();
830
831 EXPECT_CALL(mock_delegate_, OnHeadersSent());
832 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
833
834 base::WeakPtr<SpdySession> session = CreateSpdySession();
835 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
836 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_,
837 NetLogWithSource());
838 EXPECT_TRUE(adapter.is_initialized());
839
840 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
842
843 // Buffer larger than each MockRead.
844 const int kReadBufSize = 1024;
845 auto read_buf = base::MakeRefCounted<IOBufferWithSize>(kReadBufSize);
846 TestCompletionCallback callback;
847 rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
848 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
849 rv = callback.WaitForResult();
850 ASSERT_EQ(3, rv);
851 EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
852
853 // Read RST_STREAM to destroy the stream.
854 // This calls SpdySession::Delegate::OnClose().
855 EXPECT_TRUE(session);
856 EXPECT_TRUE(stream);
857 base::RunLoop().RunUntilIdle();
858 EXPECT_FALSE(session);
859 EXPECT_FALSE(stream);
860
861 // Read remaining buffered data. This will PostTask CallDelegateOnClose().
862 rv = adapter.Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
863 ASSERT_EQ(3, rv);
864 EXPECT_EQ("bar", base::StringPiece(read_buf->data(), rv));
865
866 adapter.DetachDelegate();
867
868 // Run CallDelegateOnClose(), which should not crash
869 // even if |delegate_| is null.
870 base::RunLoop().RunUntilIdle();
871
872 EXPECT_TRUE(data.AllReadDataConsumed());
873 EXPECT_TRUE(data.AllWriteDataConsumed());
874 }
875
TEST_F(WebSocketSpdyStreamAdapterTest,Write)876 TEST_F(WebSocketSpdyStreamAdapterTest, Write) {
877 spdy::SpdySerializedFrame response_headers(
878 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
879 MockRead reads[] = {CreateMockRead(response_headers, 1),
880 MockRead(ASYNC, 0, 3)};
881 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
882 1, RequestHeaders(), DEFAULT_PRIORITY, false));
883 spdy::SpdySerializedFrame data_frame(
884 spdy_util_.ConstructSpdyDataFrame(1, "foo", false));
885 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
886 CreateMockWrite(data_frame, 2)};
887 SequencedSocketData data(reads, writes);
888 AddSocketData(&data);
889 AddSSLSocketData();
890
891 base::WeakPtr<SpdySession> session = CreateSpdySession();
892 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
893 WebSocketSpdyStreamAdapter adapter(stream, nullptr, NetLogWithSource());
894 EXPECT_TRUE(adapter.is_initialized());
895
896 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
898
899 base::RunLoop().RunUntilIdle();
900
901 auto write_buf = base::MakeRefCounted<StringIOBuffer>("foo");
902 TestCompletionCallback callback;
903 rv = adapter.Write(write_buf.get(), write_buf->size(), callback.callback(),
904 TRAFFIC_ANNOTATION_FOR_TESTS);
905 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
906 rv = callback.WaitForResult();
907 ASSERT_EQ(3, rv);
908
909 // Read EOF.
910 base::RunLoop().RunUntilIdle();
911
912 EXPECT_TRUE(data.AllReadDataConsumed());
913 EXPECT_TRUE(data.AllWriteDataConsumed());
914 }
915
916 // Test that if both Read() and Write() returns asynchronously,
917 // the two callbacks are handled correctly.
TEST_F(WebSocketSpdyStreamAdapterTest,AsyncReadAndWrite)918 TEST_F(WebSocketSpdyStreamAdapterTest, AsyncReadAndWrite) {
919 spdy::SpdySerializedFrame response_headers(
920 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
921 spdy::SpdySerializedFrame read_data_frame(
922 spdy_util_.ConstructSpdyDataFrame(1, "foobar", true));
923 MockRead reads[] = {CreateMockRead(response_headers, 1),
924 CreateMockRead(read_data_frame, 3),
925 MockRead(ASYNC, 0, 4)};
926 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
927 1, RequestHeaders(), DEFAULT_PRIORITY, false));
928 spdy::SpdySerializedFrame write_data_frame(
929 spdy_util_.ConstructSpdyDataFrame(1, "baz", false));
930 MockWrite writes[] = {CreateMockWrite(request_headers, 0),
931 CreateMockWrite(write_data_frame, 2)};
932 SequencedSocketData data(reads, writes);
933 AddSocketData(&data);
934 AddSSLSocketData();
935
936 base::WeakPtr<SpdySession> session = CreateSpdySession();
937 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
938 WebSocketSpdyStreamAdapter adapter(stream, nullptr, NetLogWithSource());
939 EXPECT_TRUE(adapter.is_initialized());
940
941 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
942 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
943
944 base::RunLoop().RunUntilIdle();
945
946 const int kReadBufSize = 1024;
947 auto read_buf = base::MakeRefCounted<IOBufferWithSize>(kReadBufSize);
948 TestCompletionCallback read_callback;
949 rv = adapter.Read(read_buf.get(), kReadBufSize, read_callback.callback());
950 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
951
952 auto write_buf = base::MakeRefCounted<StringIOBuffer>("baz");
953 TestCompletionCallback write_callback;
954 rv = adapter.Write(write_buf.get(), write_buf->size(),
955 write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
956 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
957
958 rv = read_callback.WaitForResult();
959 ASSERT_EQ(6, rv);
960 EXPECT_EQ("foobar", base::StringPiece(read_buf->data(), rv));
961
962 rv = write_callback.WaitForResult();
963 ASSERT_EQ(3, rv);
964
965 // Read EOF.
966 base::RunLoop().RunUntilIdle();
967
968 EXPECT_TRUE(data.AllReadDataConsumed());
969 EXPECT_TRUE(data.AllWriteDataConsumed());
970 }
971
972 // A helper class that will delete |adapter| when the callback is invoked.
973 class KillerCallback : public TestCompletionCallbackBase {
974 public:
KillerCallback(std::unique_ptr<WebSocketSpdyStreamAdapter> adapter)975 explicit KillerCallback(std::unique_ptr<WebSocketSpdyStreamAdapter> adapter)
976 : adapter_(std::move(adapter)) {}
977
978 ~KillerCallback() override = default;
979
callback()980 CompletionOnceCallback callback() {
981 return base::BindOnce(&KillerCallback::OnComplete, base::Unretained(this));
982 }
983
984 private:
OnComplete(int result)985 void OnComplete(int result) {
986 adapter_.reset();
987 SetResult(result);
988 }
989
990 std::unique_ptr<WebSocketSpdyStreamAdapter> adapter_;
991 };
992
TEST_F(WebSocketSpdyStreamAdapterTest,ReadCallbackDestroysAdapter)993 TEST_F(WebSocketSpdyStreamAdapterTest, ReadCallbackDestroysAdapter) {
994 spdy::SpdySerializedFrame response_headers(
995 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
996 MockRead reads[] = {CreateMockRead(response_headers, 1),
997 MockRead(ASYNC, ERR_IO_PENDING, 2),
998 MockRead(ASYNC, 0, 3)};
999 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
1000 1, RequestHeaders(), DEFAULT_PRIORITY, false));
1001 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
1002 SequencedSocketData data(reads, writes);
1003 AddSocketData(&data);
1004 AddSSLSocketData();
1005
1006 EXPECT_CALL(mock_delegate_, OnHeadersSent());
1007 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
1008
1009 base::WeakPtr<SpdySession> session = CreateSpdySession();
1010 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
1011 auto adapter = std::make_unique<WebSocketSpdyStreamAdapter>(
1012 stream, &mock_delegate_, NetLogWithSource());
1013 EXPECT_TRUE(adapter->is_initialized());
1014
1015 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
1016 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1017
1018 // Send headers.
1019 base::RunLoop().RunUntilIdle();
1020
1021 WebSocketSpdyStreamAdapter* adapter_raw = adapter.get();
1022 KillerCallback callback(std::move(adapter));
1023
1024 const int kReadBufSize = 1024;
1025 auto read_buf = base::MakeRefCounted<IOBufferWithSize>(kReadBufSize);
1026 rv = adapter_raw->Read(read_buf.get(), kReadBufSize, callback.callback());
1027 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1028
1029 // Read EOF while read is pending. WebSocketSpdyStreamAdapter::OnClose()
1030 // should not crash if read callback destroys |adapter|.
1031 data.Resume();
1032 rv = callback.WaitForResult();
1033 EXPECT_THAT(rv, IsError(ERR_CONNECTION_CLOSED));
1034
1035 base::RunLoop().RunUntilIdle();
1036 EXPECT_FALSE(session);
1037 EXPECT_FALSE(stream);
1038
1039 EXPECT_TRUE(data.AllReadDataConsumed());
1040 EXPECT_TRUE(data.AllWriteDataConsumed());
1041 }
1042
TEST_F(WebSocketSpdyStreamAdapterTest,WriteCallbackDestroysAdapter)1043 TEST_F(WebSocketSpdyStreamAdapterTest, WriteCallbackDestroysAdapter) {
1044 spdy::SpdySerializedFrame response_headers(
1045 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
1046 MockRead reads[] = {CreateMockRead(response_headers, 1),
1047 MockRead(ASYNC, ERR_IO_PENDING, 2),
1048 MockRead(ASYNC, 0, 3)};
1049 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
1050 1, RequestHeaders(), DEFAULT_PRIORITY, false));
1051 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
1052 SequencedSocketData data(reads, writes);
1053 AddSocketData(&data);
1054 AddSSLSocketData();
1055
1056 EXPECT_CALL(mock_delegate_, OnHeadersSent());
1057 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
1058
1059 base::WeakPtr<SpdySession> session = CreateSpdySession();
1060 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
1061 auto adapter = std::make_unique<WebSocketSpdyStreamAdapter>(
1062 stream, &mock_delegate_, NetLogWithSource());
1063 EXPECT_TRUE(adapter->is_initialized());
1064
1065 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
1066 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1067
1068 // Send headers.
1069 base::RunLoop().RunUntilIdle();
1070
1071 WebSocketSpdyStreamAdapter* adapter_raw = adapter.get();
1072 KillerCallback callback(std::move(adapter));
1073
1074 auto write_buf = base::MakeRefCounted<StringIOBuffer>("foo");
1075 rv = adapter_raw->Write(write_buf.get(), write_buf->size(),
1076 callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
1077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1078
1079 // Read EOF while write is pending. WebSocketSpdyStreamAdapter::OnClose()
1080 // should not crash if write callback destroys |adapter|.
1081 data.Resume();
1082 rv = callback.WaitForResult();
1083 EXPECT_THAT(rv, IsError(ERR_CONNECTION_CLOSED));
1084
1085 base::RunLoop().RunUntilIdle();
1086 EXPECT_FALSE(session);
1087 EXPECT_FALSE(stream);
1088
1089 EXPECT_TRUE(data.AllReadDataConsumed());
1090 EXPECT_TRUE(data.AllWriteDataConsumed());
1091 }
1092
TEST_F(WebSocketSpdyStreamAdapterTest,OnCloseOkShouldBeTranslatedToConnectionClose)1093 TEST_F(WebSocketSpdyStreamAdapterTest,
1094 OnCloseOkShouldBeTranslatedToConnectionClose) {
1095 spdy::SpdySerializedFrame response_headers(
1096 spdy_util_.ConstructSpdyResponseHeaders(1, ResponseHeaders(), false));
1097 spdy::SpdySerializedFrame close(
1098 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_NO_ERROR));
1099 MockRead reads[] = {CreateMockRead(response_headers, 1),
1100 CreateMockRead(close, 2), MockRead(ASYNC, 0, 3)};
1101 spdy::SpdySerializedFrame request_headers(spdy_util_.ConstructSpdyHeaders(
1102 1, RequestHeaders(), DEFAULT_PRIORITY, false));
1103 MockWrite writes[] = {CreateMockWrite(request_headers, 0)};
1104 SequencedSocketData data(reads, writes);
1105 AddSocketData(&data);
1106 AddSSLSocketData();
1107
1108 EXPECT_CALL(mock_delegate_, OnHeadersSent());
1109 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_));
1110
1111 base::WeakPtr<SpdySession> session = CreateSpdySession();
1112 base::WeakPtr<SpdyStream> stream = CreateSpdyStream(session);
1113 WebSocketSpdyStreamAdapter adapter(stream, &mock_delegate_,
1114 NetLogWithSource());
1115 EXPECT_TRUE(adapter.is_initialized());
1116
1117 EXPECT_CALL(mock_delegate_, OnClose(ERR_CONNECTION_CLOSED));
1118
1119 int rv = stream->SendRequestHeaders(RequestHeaders(), MORE_DATA_TO_SEND);
1120 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1121
1122 const int kReadBufSize = 1024;
1123 auto read_buf = base::MakeRefCounted<IOBufferWithSize>(kReadBufSize);
1124 TestCompletionCallback callback;
1125 rv = adapter.Read(read_buf.get(), kReadBufSize, callback.callback());
1126 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1127 rv = callback.WaitForResult();
1128 ASSERT_EQ(ERR_CONNECTION_CLOSED, rv);
1129 }
1130
1131 class MockQuicDelegate : public WebSocketQuicStreamAdapter::Delegate {
1132 public:
1133 ~MockQuicDelegate() override = default;
1134 MOCK_METHOD(void, OnHeadersSent, (), (override));
1135 MOCK_METHOD(void,
1136 OnHeadersReceived,
1137 (const spdy::Http2HeaderBlock&),
1138 (override));
1139 MOCK_METHOD(void, OnClose, (int), (override));
1140 };
1141
1142 class WebSocketQuicStreamAdapterTest
1143 : public TestWithTaskEnvironment,
1144 public ::testing::WithParamInterface<quic::ParsedQuicVersion> {
1145 protected:
RequestHeaders()1146 static spdy::Http2HeaderBlock RequestHeaders() {
1147 return WebSocketHttp2Request("/", "www.example.org:443",
1148 "http://www.example.org", {});
1149 }
WebSocketQuicStreamAdapterTest()1150 WebSocketQuicStreamAdapterTest()
1151 : version_(GetParam()),
1152 mock_quic_data_(version_),
1153 client_data_stream_id1_(quic::QuicUtils::GetFirstBidirectionalStreamId(
1154 version_.transport_version,
1155 quic::Perspective::IS_CLIENT)),
1156 crypto_config_(
1157 quic::test::crypto_test_utils::ProofVerifierForTesting()),
1158 connection_id_(quic::test::TestConnectionId(2)),
1159 client_maker_(version_,
1160 connection_id_,
1161 &clock_,
1162 "mail.example.org",
1163 quic::Perspective::IS_CLIENT),
1164 server_maker_(version_,
1165 connection_id_,
1166 &clock_,
1167 "mail.example.org",
1168 quic::Perspective::IS_SERVER),
1169 peer_addr_(IPAddress(192, 0, 2, 23), 443),
1170 destination_endpoint_(url::kHttpsScheme, "mail.example.org", 80) {}
1171
1172 ~WebSocketQuicStreamAdapterTest() override = default;
1173
SetUp()1174 void SetUp() override {
1175 FLAGS_quic_enable_http3_grease_randomness = false;
1176 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
1177 quic::QuicEnableVersion(version_);
1178 }
1179
TearDown()1180 void TearDown() override {
1181 EXPECT_TRUE(mock_quic_data_.AllReadDataConsumed());
1182 EXPECT_TRUE(mock_quic_data_.AllWriteDataConsumed());
1183 }
1184
GetQuicSessionHandle()1185 net::QuicChromiumClientSession::Handle* GetQuicSessionHandle() {
1186 return session_handle_.get();
1187 }
1188
1189 // Helper functions for constructing packets sent by the client
1190
ConstructSettingsPacket(uint64_t packet_number)1191 std::unique_ptr<quic::QuicReceivedPacket> ConstructSettingsPacket(
1192 uint64_t packet_number) {
1193 return client_maker_.MakeInitialSettingsPacket(packet_number);
1194 }
1195
ConstructServerDataPacket(uint64_t packet_number,base::StringPiece data)1196 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
1197 uint64_t packet_number,
1198 base::StringPiece data) {
1199 DCHECK(version_.HasIetfQuicFrames());
1200 quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
1201 data.size(), quiche::SimpleBufferAllocator::Get());
1202 return server_maker_.MakeDataPacket(
1203 packet_number, client_data_stream_id1_, /*fin=*/false,
1204 base::StrCat({base::StringPiece(buffer.data(), buffer.size()), data}));
1205 }
1206
ConstructRstPacket(uint64_t packet_number,quic::QuicRstStreamErrorCode error_code)1207 std::unique_ptr<quic::QuicReceivedPacket> ConstructRstPacket(
1208 uint64_t packet_number,
1209 quic::QuicRstStreamErrorCode error_code) {
1210 return client_maker_.MakeRstPacket(packet_number, client_data_stream_id1_,
1211 error_code,
1212 /*include_stop_sending_if_v99=*/true);
1213 }
1214
ConstructClientAckPacket(uint64_t packet_number,uint64_t largest_received,uint64_t smallest_received)1215 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
1216 uint64_t packet_number,
1217 uint64_t largest_received,
1218 uint64_t smallest_received) {
1219 return client_maker_.MakeAckPacket(packet_number, largest_received,
1220 smallest_received);
1221 }
1222
ConstructAckAndRstPacket(uint64_t packet_number,quic::QuicRstStreamErrorCode error_code,uint64_t largest_received,uint64_t smallest_received)1223 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstPacket(
1224 uint64_t packet_number,
1225 quic::QuicRstStreamErrorCode error_code,
1226 uint64_t largest_received,
1227 uint64_t smallest_received) {
1228 return client_maker_.MakeAckAndRstPacket(
1229 packet_number, client_data_stream_id1_, error_code, largest_received,
1230 smallest_received,
1231 /*include_stop_sending_if_v99=*/true);
1232 }
1233
Initialize()1234 void Initialize() {
1235 auto socket = std::make_unique<MockUDPClientSocket>(
1236 mock_quic_data_.InitializeAndGetSequencedSocketData(), NetLog::Get());
1237 socket->Connect(peer_addr_);
1238
1239 runner_ = base::MakeRefCounted<TestTaskRunner>(&clock_);
1240 helper_ = std::make_unique<QuicChromiumConnectionHelper>(
1241 &clock_, &random_generator_);
1242 alarm_factory_ =
1243 std::make_unique<QuicChromiumAlarmFactory>(runner_.get(), &clock_);
1244 // Ownership of 'writer' is passed to 'QuicConnection'.
1245 QuicChromiumPacketWriter* writer = new QuicChromiumPacketWriter(
1246 socket.get(), base::SingleThreadTaskRunner::GetCurrentDefault().get());
1247 quic::QuicConnection* connection = new quic::QuicConnection(
1248 connection_id_, quic::QuicSocketAddress(),
1249 net::ToQuicSocketAddress(peer_addr_), helper_.get(),
1250 alarm_factory_.get(), writer, true /* owns_writer */,
1251 quic::Perspective::IS_CLIENT, quic::test::SupportedVersions(version_),
1252 connection_id_generator_);
1253 connection->set_visitor(&visitor_);
1254
1255 // Load a certificate that is valid for *.example.org
1256 scoped_refptr<X509Certificate> test_cert(
1257 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1258 EXPECT_TRUE(test_cert.get());
1259
1260 verify_details_.cert_verify_result.verified_cert = test_cert;
1261 verify_details_.cert_verify_result.is_issued_by_known_root = true;
1262 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
1263
1264 base::TimeTicks dns_end = base::TimeTicks::Now();
1265 base::TimeTicks dns_start = dns_end - base::Milliseconds(1);
1266
1267 session_ = std::make_unique<QuicChromiumClientSession>(
1268 connection, std::move(socket),
1269 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
1270 &transport_security_state_, &ssl_config_service_,
1271 /*server_info=*/nullptr,
1272 QuicSessionKey("mail.example.org", 80, PRIVACY_MODE_DISABLED,
1273 SocketTag(), NetworkAnonymizationKey(),
1274 SecureDnsPolicy::kAllow,
1275 /*require_dns_https_alpn=*/false),
1276 /*require_confirmation=*/false,
1277 /*migrate_session_early_v2=*/false,
1278 /*migrate_session_on_network_change_v2=*/false,
1279 /*default_network=*/handles::kInvalidNetworkHandle,
1280 quic::QuicTime::Delta::FromMilliseconds(
1281 kDefaultRetransmittableOnWireTimeout.InMilliseconds()),
1282 /*migrate_idle_session=*/true, /*allow_port_migration=*/false,
1283 kDefaultIdleSessionMigrationPeriod, /*multi_port_probing_interval=*/0,
1284 kMaxTimeOnNonDefaultNetwork,
1285 kMaxMigrationsToNonDefaultNetworkOnWriteError,
1286 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
1287 kQuicYieldAfterPacketsRead,
1288 quic::QuicTime::Delta::FromMilliseconds(
1289 kQuicYieldAfterDurationMilliseconds),
1290 /*cert_verify_flags=*/0, quic::test::DefaultQuicConfig(),
1291 std::make_unique<TestQuicCryptoClientConfigHandle>(&crypto_config_),
1292 dns_start, dns_end, base::DefaultTickClock::GetInstance(),
1293 base::SingleThreadTaskRunner::GetCurrentDefault().get(),
1294 /*socket_performance_watcher=*/nullptr, HostResolverEndpointResult(),
1295 NetLog::Get());
1296
1297 session_->Initialize();
1298
1299 // Blackhole QPACK decoder stream instead of constructing mock writes.
1300 session_->qpack_decoder()->set_qpack_stream_sender_delegate(
1301 &noop_qpack_stream_sender_delegate_);
1302 TestCompletionCallback callback;
1303 EXPECT_THAT(session_->CryptoConnect(callback.callback()), IsOk());
1304 EXPECT_TRUE(session_->OneRttKeysAvailable());
1305 session_handle_ = session_->CreateHandle(
1306 url::SchemeHostPort(url::kHttpsScheme, "mail.example.org", 80));
1307 }
1308
1309 const quic::ParsedQuicVersion version_;
1310 MockQuicData mock_quic_data_;
1311 StrictMock<MockQuicDelegate> mock_delegate_;
1312 const quic::QuicStreamId client_data_stream_id1_;
1313
1314 private:
1315 quic::QuicCryptoClientConfig crypto_config_;
1316 const quic::QuicConnectionId connection_id_;
1317
1318 protected:
1319 QuicTestPacketMaker client_maker_;
1320 QuicTestPacketMaker server_maker_;
1321 std::unique_ptr<QuicChromiumClientSession> session_;
1322
1323 private:
1324 quic::MockClock clock_;
1325 std::unique_ptr<QuicChromiumClientSession::Handle> session_handle_;
1326 scoped_refptr<TestTaskRunner> runner_;
1327 ProofVerifyDetailsChromium verify_details_;
1328 MockCryptoClientStreamFactory crypto_client_stream_factory_;
1329 SSLConfigServiceDefaults ssl_config_service_;
1330 quic::test::MockConnectionIdGenerator connection_id_generator_;
1331 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
1332 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
1333 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
1334 TransportSecurityState transport_security_state_;
1335 IPAddress ip_;
1336 IPEndPoint peer_addr_;
1337 quic::test::MockRandom random_generator_{0};
1338 url::SchemeHostPort destination_endpoint_;
1339 quic::test::NoopQpackStreamSenderDelegate noop_qpack_stream_sender_delegate_;
1340 };
1341
1342 // Like net::TestCompletionCallback, but for a callback that takes an unbound
1343 // parameter of type WebSocketQuicStreamAdapter.
1344 struct WebSocketQuicStreamAdapterIsPendingHelper {
operator ()net::test::WebSocketQuicStreamAdapterIsPendingHelper1345 bool operator()(
1346 const std::unique_ptr<WebSocketQuicStreamAdapter>& adapter) const {
1347 return !adapter;
1348 }
1349 };
1350
1351 using TestWebSocketQuicStreamAdapterCompletionCallbackBase =
1352 net::internal::TestCompletionCallbackTemplate<
1353 std::unique_ptr<WebSocketQuicStreamAdapter>,
1354 WebSocketQuicStreamAdapterIsPendingHelper>;
1355
1356 class TestWebSocketQuicStreamAdapterCompletionCallback
1357 : public TestWebSocketQuicStreamAdapterCompletionCallbackBase {
1358 public:
1359 base::OnceCallback<void(std::unique_ptr<WebSocketQuicStreamAdapter>)>
1360 callback();
1361 };
1362
1363 base::OnceCallback<void(std::unique_ptr<WebSocketQuicStreamAdapter>)>
callback()1364 TestWebSocketQuicStreamAdapterCompletionCallback::callback() {
1365 return base::BindOnce(
1366 &TestWebSocketQuicStreamAdapterCompletionCallback::SetResult,
1367 base::Unretained(this));
1368 }
1369
1370 INSTANTIATE_TEST_SUITE_P(QuicVersion,
1371 WebSocketQuicStreamAdapterTest,
1372 ::testing::ValuesIn(AllSupportedQuicVersions()),
1373 ::testing::PrintToStringParamName());
1374
TEST_P(WebSocketQuicStreamAdapterTest,Disconnect)1375 TEST_P(WebSocketQuicStreamAdapterTest, Disconnect) {
1376 int packet_number = 1;
1377 mock_quic_data_.AddWrite(SYNCHRONOUS,
1378 ConstructSettingsPacket(packet_number++));
1379
1380 mock_quic_data_.AddWrite(
1381 SYNCHRONOUS,
1382 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
1383
1384 Initialize();
1385
1386 net::QuicChromiumClientSession::Handle* session_handle =
1387 GetQuicSessionHandle();
1388 ASSERT_TRUE(session_handle);
1389
1390 TestWebSocketQuicStreamAdapterCompletionCallback callback;
1391 std::unique_ptr<WebSocketQuicStreamAdapter> adapter =
1392 session_handle->CreateWebSocketQuicStreamAdapter(
1393 &mock_delegate_, callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
1394 ASSERT_TRUE(adapter);
1395 EXPECT_TRUE(adapter->is_initialized());
1396 adapter->Disconnect();
1397 // TODO(momoka): Add tests to test both destruction orders.
1398 }
1399
TEST_P(WebSocketQuicStreamAdapterTest,AsyncAdapterCreation)1400 TEST_P(WebSocketQuicStreamAdapterTest, AsyncAdapterCreation) {
1401 const size_t kMaxOpenStreams = 50;
1402
1403 int packet_number = 1;
1404 mock_quic_data_.AddWrite(SYNCHRONOUS,
1405 ConstructSettingsPacket(packet_number++));
1406
1407 mock_quic_data_.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
1408 packet_number++, kMaxOpenStreams,
1409 /* unidirectional = */ false));
1410
1411 mock_quic_data_.AddRead(
1412 ASYNC, server_maker_.MakeMaxStreamsPacket(1, kMaxOpenStreams + 2,
1413 /* unidirectional = */ false));
1414
1415 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);
1416 mock_quic_data_.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
1417
1418 Initialize();
1419
1420 std::vector<QuicChromiumClientStream*> streams;
1421
1422 for (size_t i = 0; i < kMaxOpenStreams; i++) {
1423 QuicChromiumClientStream* stream =
1424 QuicChromiumClientSessionPeer::CreateOutgoingStream(session_.get());
1425 ASSERT_TRUE(stream);
1426 streams.push_back(stream);
1427 EXPECT_EQ(i + 1, session_->GetNumActiveStreams());
1428 }
1429
1430 net::QuicChromiumClientSession::Handle* session_handle =
1431 GetQuicSessionHandle();
1432 ASSERT_TRUE(session_handle);
1433
1434 // Creating an adapter should fail because of the stream limit.
1435 TestWebSocketQuicStreamAdapterCompletionCallback callback;
1436 std::unique_ptr<WebSocketQuicStreamAdapter> adapter =
1437 session_handle->CreateWebSocketQuicStreamAdapter(
1438 &mock_delegate_, callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
1439 ASSERT_EQ(adapter, nullptr);
1440 EXPECT_FALSE(callback.have_result());
1441 EXPECT_EQ(kMaxOpenStreams, session_->GetNumActiveStreams());
1442
1443 // Read MAX_STREAMS frame that makes it possible to open WebSocket stream.
1444 session_->StartReading();
1445 callback.WaitForResult();
1446 EXPECT_EQ(kMaxOpenStreams + 1, session_->GetNumActiveStreams());
1447
1448 // Close connection.
1449 mock_quic_data_.Resume();
1450 base::RunLoop().RunUntilIdle();
1451 }
1452
TEST_P(WebSocketQuicStreamAdapterTest,SendRequestHeadersThenDisconnect)1453 TEST_P(WebSocketQuicStreamAdapterTest, SendRequestHeadersThenDisconnect) {
1454 int packet_number = 1;
1455 mock_quic_data_.AddWrite(SYNCHRONOUS,
1456 ConstructSettingsPacket(packet_number++));
1457 SpdyTestUtil spdy_util;
1458 spdy::Http2HeaderBlock request_header_block = WebSocketHttp2Request(
1459 "/", "www.example.org:443", "http://www.example.org", {});
1460 mock_quic_data_.AddWrite(
1461 SYNCHRONOUS,
1462 client_maker_.MakeRequestHeadersPacket(
1463 packet_number++, client_data_stream_id1_,
1464 /*fin=*/false, ConvertRequestPriorityToQuicPriority(LOWEST),
1465 std::move(request_header_block), nullptr));
1466
1467 mock_quic_data_.AddWrite(
1468 SYNCHRONOUS,
1469 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
1470
1471 Initialize();
1472
1473 net::QuicChromiumClientSession::Handle* session_handle =
1474 GetQuicSessionHandle();
1475 ASSERT_TRUE(session_handle);
1476 TestWebSocketQuicStreamAdapterCompletionCallback callback;
1477 std::unique_ptr<WebSocketQuicStreamAdapter> adapter =
1478 session_handle->CreateWebSocketQuicStreamAdapter(
1479 &mock_delegate_, callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
1480 ASSERT_TRUE(adapter);
1481 EXPECT_TRUE(adapter->is_initialized());
1482
1483 adapter->WriteHeaders(RequestHeaders(), false);
1484
1485 adapter->Disconnect();
1486 }
1487
TEST_P(WebSocketQuicStreamAdapterTest,OnHeadersReceivedThenDisconnect)1488 TEST_P(WebSocketQuicStreamAdapterTest, OnHeadersReceivedThenDisconnect) {
1489 int packet_number = 1;
1490 mock_quic_data_.AddWrite(SYNCHRONOUS,
1491 ConstructSettingsPacket(packet_number++));
1492
1493 SpdyTestUtil spdy_util;
1494 spdy::Http2HeaderBlock request_header_block = WebSocketHttp2Request(
1495 "/", "www.example.org:443", "http://www.example.org", {});
1496 mock_quic_data_.AddWrite(
1497 SYNCHRONOUS,
1498 client_maker_.MakeRequestHeadersPacket(
1499 packet_number++, client_data_stream_id1_,
1500 /*fin=*/false, ConvertRequestPriorityToQuicPriority(LOWEST),
1501 std::move(request_header_block), nullptr));
1502
1503 spdy::Http2HeaderBlock response_header_block = WebSocketHttp2Response({});
1504 mock_quic_data_.AddRead(
1505 ASYNC, server_maker_.MakeResponseHeadersPacket(
1506 /*packet_number=*/1, client_data_stream_id1_, /*fin=*/false,
1507 std::move(response_header_block),
1508 /*spdy_headers_frame_length=*/nullptr));
1509 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1510 mock_quic_data_.AddWrite(
1511 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1512 quic::QUIC_STREAM_CANCELLED, 1, 0));
1513 base::RunLoop run_loop;
1514 auto quit_closure = run_loop.QuitClosure();
1515 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_)).WillOnce(Invoke([&]() {
1516 std::move(quit_closure).Run();
1517 }));
1518
1519 Initialize();
1520
1521 net::QuicChromiumClientSession::Handle* session_handle =
1522 GetQuicSessionHandle();
1523 ASSERT_TRUE(session_handle);
1524
1525 TestWebSocketQuicStreamAdapterCompletionCallback callback;
1526 std::unique_ptr<WebSocketQuicStreamAdapter> adapter =
1527 session_handle->CreateWebSocketQuicStreamAdapter(
1528 &mock_delegate_, callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
1529 ASSERT_TRUE(adapter);
1530 EXPECT_TRUE(adapter->is_initialized());
1531
1532 adapter->WriteHeaders(RequestHeaders(), false);
1533
1534 session_->StartReading();
1535 run_loop.Run();
1536
1537 adapter->Disconnect();
1538 }
1539
TEST_P(WebSocketQuicStreamAdapterTest,Read)1540 TEST_P(WebSocketQuicStreamAdapterTest, Read) {
1541 int packet_number = 1;
1542 mock_quic_data_.AddWrite(SYNCHRONOUS,
1543 ConstructSettingsPacket(packet_number++));
1544
1545 SpdyTestUtil spdy_util;
1546 spdy::Http2HeaderBlock request_header_block = WebSocketHttp2Request(
1547 "/", "www.example.org:443", "http://www.example.org", {});
1548 mock_quic_data_.AddWrite(
1549 SYNCHRONOUS,
1550 client_maker_.MakeRequestHeadersPacket(
1551 packet_number++, client_data_stream_id1_,
1552 /*fin=*/false, ConvertRequestPriorityToQuicPriority(LOWEST),
1553 std::move(request_header_block), nullptr));
1554
1555 spdy::Http2HeaderBlock response_header_block = WebSocketHttp2Response({});
1556 mock_quic_data_.AddRead(
1557 ASYNC, server_maker_.MakeResponseHeadersPacket(
1558 /*packet_number=*/1, client_data_stream_id1_, /*fin=*/false,
1559 std::move(response_header_block),
1560 /*spdy_headers_frame_length=*/nullptr));
1561 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);
1562
1563 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, "foo"));
1564 mock_quic_data_.AddRead(SYNCHRONOUS,
1565 ConstructServerDataPacket(3, "hogehoge"));
1566 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1567
1568 mock_quic_data_.AddWrite(ASYNC,
1569 ConstructClientAckPacket(packet_number++, 2, 0));
1570 mock_quic_data_.AddWrite(
1571 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1572 quic::QUIC_STREAM_CANCELLED, 3, 0));
1573
1574 base::RunLoop run_loop;
1575 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_)).WillOnce(Invoke([&]() {
1576 run_loop.Quit();
1577 }));
1578
1579 Initialize();
1580
1581 net::QuicChromiumClientSession::Handle* session_handle =
1582 GetQuicSessionHandle();
1583 ASSERT_TRUE(session_handle);
1584
1585 TestWebSocketQuicStreamAdapterCompletionCallback callback;
1586 std::unique_ptr<WebSocketQuicStreamAdapter> adapter =
1587 session_handle->CreateWebSocketQuicStreamAdapter(
1588 &mock_delegate_, callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
1589 ASSERT_TRUE(adapter);
1590 EXPECT_TRUE(adapter->is_initialized());
1591
1592 adapter->WriteHeaders(RequestHeaders(), false);
1593
1594 session_->StartReading();
1595 run_loop.Run();
1596
1597 // Buffer larger than each MockRead.
1598 const int kReadBufSize = 1024;
1599 auto read_buf = base::MakeRefCounted<IOBufferWithSize>(kReadBufSize);
1600 TestCompletionCallback read_callback;
1601
1602 int rv =
1603 adapter->Read(read_buf.get(), kReadBufSize, read_callback.callback());
1604
1605 ASSERT_EQ(ERR_IO_PENDING, rv);
1606
1607 mock_quic_data_.GetSequencedSocketData()->Resume();
1608 base::RunLoop().RunUntilIdle();
1609
1610 rv = read_callback.WaitForResult();
1611 ASSERT_EQ(3, rv);
1612 EXPECT_EQ("foo", base::StringPiece(read_buf->data(), rv));
1613
1614 rv = adapter->Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
1615 ASSERT_EQ(8, rv);
1616 EXPECT_EQ("hogehoge", base::StringPiece(read_buf->data(), rv));
1617
1618 adapter->Disconnect();
1619
1620 EXPECT_TRUE(mock_quic_data_.AllReadDataConsumed());
1621 EXPECT_TRUE(mock_quic_data_.AllWriteDataConsumed());
1622 }
1623
TEST_P(WebSocketQuicStreamAdapterTest,ReadIntoSmallBuffer)1624 TEST_P(WebSocketQuicStreamAdapterTest, ReadIntoSmallBuffer) {
1625 int packet_number = 1;
1626 mock_quic_data_.AddWrite(SYNCHRONOUS,
1627 ConstructSettingsPacket(packet_number++));
1628
1629 SpdyTestUtil spdy_util;
1630 spdy::Http2HeaderBlock request_header_block = WebSocketHttp2Request(
1631 "/", "www.example.org:443", "http://www.example.org", {});
1632 mock_quic_data_.AddWrite(
1633 SYNCHRONOUS,
1634 client_maker_.MakeRequestHeadersPacket(
1635 packet_number++, client_data_stream_id1_,
1636 /*fin=*/false, ConvertRequestPriorityToQuicPriority(LOWEST),
1637 std::move(request_header_block), nullptr));
1638
1639 spdy::Http2HeaderBlock response_header_block = WebSocketHttp2Response({});
1640 mock_quic_data_.AddRead(
1641 ASYNC, server_maker_.MakeResponseHeadersPacket(
1642 /*packet_number=*/1, client_data_stream_id1_, /*fin=*/false,
1643 std::move(response_header_block),
1644 /*spdy_headers_frame_length=*/nullptr));
1645 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);
1646 // First read is the same size as the buffer, next is smaller, last is larger.
1647 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, "abc"));
1648 mock_quic_data_.AddRead(SYNCHRONOUS, ConstructServerDataPacket(3, "12"));
1649 mock_quic_data_.AddRead(SYNCHRONOUS, ConstructServerDataPacket(4, "ABCD"));
1650 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1651
1652 mock_quic_data_.AddWrite(ASYNC,
1653 ConstructClientAckPacket(packet_number++, 2, 0));
1654 mock_quic_data_.AddWrite(
1655 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1656 quic::QUIC_STREAM_CANCELLED, 4, 0));
1657
1658 base::RunLoop run_loop;
1659 EXPECT_CALL(mock_delegate_, OnHeadersReceived(_)).WillOnce(Invoke([&]() {
1660 run_loop.Quit();
1661 }));
1662
1663 Initialize();
1664
1665 net::QuicChromiumClientSession::Handle* session_handle =
1666 GetQuicSessionHandle();
1667 ASSERT_TRUE(session_handle);
1668 TestWebSocketQuicStreamAdapterCompletionCallback callback;
1669 std::unique_ptr<WebSocketQuicStreamAdapter> adapter =
1670 session_handle->CreateWebSocketQuicStreamAdapter(
1671 &mock_delegate_, callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
1672 ASSERT_TRUE(adapter);
1673 EXPECT_TRUE(adapter->is_initialized());
1674
1675 adapter->WriteHeaders(RequestHeaders(), false);
1676
1677 session_->StartReading();
1678 run_loop.Run();
1679
1680 const int kReadBufSize = 3;
1681 auto read_buf = base::MakeRefCounted<IOBufferWithSize>(kReadBufSize);
1682 TestCompletionCallback read_callback;
1683
1684 int rv =
1685 adapter->Read(read_buf.get(), kReadBufSize, read_callback.callback());
1686
1687 ASSERT_EQ(ERR_IO_PENDING, rv);
1688
1689 mock_quic_data_.GetSequencedSocketData()->Resume();
1690 base::RunLoop().RunUntilIdle();
1691
1692 rv = read_callback.WaitForResult();
1693 ASSERT_EQ(3, rv);
1694 EXPECT_EQ("abc", base::StringPiece(read_buf->data(), rv));
1695
1696 rv = adapter->Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
1697 ASSERT_EQ(3, rv);
1698 EXPECT_EQ("12A", base::StringPiece(read_buf->data(), rv));
1699
1700 rv = adapter->Read(read_buf.get(), kReadBufSize, CompletionOnceCallback());
1701 ASSERT_EQ(3, rv);
1702 EXPECT_EQ("BCD", base::StringPiece(read_buf->data(), rv));
1703
1704 adapter->Disconnect();
1705
1706 EXPECT_TRUE(mock_quic_data_.AllReadDataConsumed());
1707 EXPECT_TRUE(mock_quic_data_.AllWriteDataConsumed());
1708 }
1709
1710 } // namespace net::test
1711