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