xref: /aosp_15_r20/external/cronet/net/websockets/websocket_basic_stream_adapters_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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