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