1 // Copyright 2017 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/quic/quic_proxy_client_socket.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "base/functional/bind.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/memory/raw_ptr.h"
13 #include "base/run_loop.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/task/single_thread_task_runner.h"
16 #include "net/base/network_anonymization_key.h"
17 #include "net/base/proxy_chain.h"
18 #include "net/base/proxy_server.h"
19 #include "net/base/proxy_string_util.h"
20 #include "net/base/test_proxy_delegate.h"
21 #include "net/http/http_response_headers.h"
22 #include "net/log/net_log.h"
23 #include "net/log/test_net_log.h"
24 #include "net/log/test_net_log_util.h"
25 #include "net/quic/quic_chromium_client_session.h"
26 #include "net/quic/quic_http_utils.h"
27 #include "net/quic/quic_proxy_client_socket_test_base.h"
28 #include "net/quic/test_quic_crypto_client_config_handle.h"
29 #include "net/quic/test_task_runner.h"
30 #include "net/ssl/ssl_config_service_defaults.h"
31 #include "net/test/gtest_util.h"
32 #include "net/test/test_data_directory.h"
33 #include "net/test/test_with_task_environment.h"
34 #include "net/third_party/quiche/src/quiche/quic/test_tools/qpack/qpack_test_utils.h"
35 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
36 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
37 #include "testing/gmock/include/gmock/gmock.h"
38 #include "testing/gtest/include/gtest/gtest.h"
39 #include "url/gurl.h"
40 #include "url/scheme_host_port.h"
41
42 using testing::_;
43 using testing::AnyNumber;
44 using testing::Return;
45
46 namespace net::test {
47
48 class QuicProxyClientSocketTest : public QuicProxyClientSocketTestBase {
49 public:
TearDown()50 void TearDown() override {
51 sock_.reset();
52 EXPECT_TRUE(mock_quic_data_.AllReadDataConsumed());
53 EXPECT_TRUE(mock_quic_data_.AllWriteDataConsumed());
54 }
55
InitializeClientSocket()56 void InitializeClientSocket() override {
57 sock_ = std::make_unique<QuicProxyClientSocket>(
58 std::move(stream_handle_), std::move(session_handle_),
59 // TODO(crbug.com/1206799) Construct `ProxyChain` with plain
60 // `proxy_endpoint_` once it supports `url::SchemeHostPort`.
61 ProxyChain(ProxyServer::SCHEME_HTTPS,
62 HostPortPair::FromSchemeHostPort(proxy_endpoint_)),
63 /*proxy_chain_index=*/0, user_agent_,
64 // TODO(crbug.com/1206799) Construct `QuicProxyClientSocket` with plain
65 // `proxy_endpoint_` once it supports `url::SchemeHostPort`.
66 HostPortPair::FromSchemeHostPort(destination_endpoint_),
67 NetLogWithSource::Make(NetLogSourceType::NONE),
68 base::MakeRefCounted<HttpAuthController>(
69 HttpAuth::AUTH_PROXY, proxy_endpoint_.GetURL(),
70 NetworkAnonymizationKey(), &http_auth_cache_,
71 http_auth_handler_factory_.get(), host_resolver_.get()),
72 proxy_delegate_.get());
73
74 session_->StartReading();
75 }
76
PopulateConnectRequestIR(spdy::Http2HeaderBlock * block,std::optional<const HttpRequestHeaders> extra_headers)77 void PopulateConnectRequestIR(
78 spdy::Http2HeaderBlock* block,
79 std::optional<const HttpRequestHeaders> extra_headers) override {
80 (*block)[":method"] = "CONNECT";
81 (*block)[":authority"] =
82 HostPortPair::FromSchemeHostPort(destination_endpoint_).ToString();
83 (*block)["user-agent"] = kUserAgent;
84 if (extra_headers) {
85 HttpRequestHeaders::Iterator it(*extra_headers);
86 while (it.GetNext()) {
87 std::string name = base::ToLowerASCII(it.name());
88 (*block)[name] = it.value();
89 }
90 }
91 }
92
AssertConnectSucceeds()93 void AssertConnectSucceeds() override {
94 TestCompletionCallback callback;
95 ASSERT_THAT(sock_->Connect(callback.callback()),
96 test::IsError(ERR_IO_PENDING));
97 ASSERT_THAT(callback.WaitForResult(), test::IsOk());
98 }
99
AssertConnectFails(int result)100 void AssertConnectFails(int result) override {
101 TestCompletionCallback callback;
102 ASSERT_THAT(sock_->Connect(callback.callback()),
103 test::IsError(ERR_IO_PENDING));
104 EXPECT_EQ(result, callback.WaitForResult());
105 }
106
AssertWriteReturns(const char * data,int len,int rv)107 void AssertWriteReturns(const char* data, int len, int rv) override {
108 auto buf = base::MakeRefCounted<IOBufferWithSize>(len);
109 memcpy(buf->data(), data, len);
110 EXPECT_EQ(rv,
111 sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
112 TRAFFIC_ANNOTATION_FOR_TESTS));
113 }
114
AssertSyncWriteSucceeds(const char * data,int len)115 void AssertSyncWriteSucceeds(const char* data, int len) override {
116 auto buf = base::MakeRefCounted<IOBufferWithSize>(len);
117 memcpy(buf->data(), data, len);
118 EXPECT_EQ(len,
119 sock_->Write(buf.get(), buf->size(), CompletionOnceCallback(),
120 TRAFFIC_ANNOTATION_FOR_TESTS));
121 }
122
AssertSyncReadEquals(const char * data,int len)123 void AssertSyncReadEquals(const char* data, int len) override {
124 auto buf = base::MakeRefCounted<IOBufferWithSize>(len);
125 EXPECT_EQ(len, sock_->Read(buf.get(), len, CompletionOnceCallback()));
126 EXPECT_EQ(std::string(data, len), std::string(buf->data(), len));
127 ASSERT_TRUE(sock_->IsConnected());
128 }
129
AssertAsyncReadEquals(const char * data,int len)130 void AssertAsyncReadEquals(const char* data, int len) override {
131 auto buf = base::MakeRefCounted<IOBufferWithSize>(len);
132 ASSERT_EQ(ERR_IO_PENDING,
133 sock_->Read(buf.get(), len, read_callback_.callback()));
134 EXPECT_TRUE(sock_->IsConnected());
135
136 ResumeAndRun();
137
138 EXPECT_EQ(len, read_callback_.WaitForResult());
139 EXPECT_TRUE(sock_->IsConnected());
140 EXPECT_EQ(std::string(data, len), std::string(buf->data(), len));
141 }
142
AssertReadStarts(const char * data,int len)143 void AssertReadStarts(const char* data, int len) override {
144 // Issue the read, which will be completed asynchronously.
145 read_buf_ = base::MakeRefCounted<IOBufferWithSize>(len);
146 ASSERT_EQ(ERR_IO_PENDING,
147 sock_->Read(read_buf_.get(), len, read_callback_.callback()));
148 EXPECT_TRUE(sock_->IsConnected());
149 }
150
AssertReadReturns(const char * data,int len)151 void AssertReadReturns(const char* data, int len) override {
152 EXPECT_TRUE(sock_->IsConnected());
153
154 // Now the read will return.
155 EXPECT_EQ(len, read_callback_.WaitForResult());
156 EXPECT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
157 }
158
159 protected:
160 std::unique_ptr<QuicProxyClientSocket> sock_;
161 };
162
TEST_P(QuicProxyClientSocketTest,ConnectSendsCorrectRequest)163 TEST_P(QuicProxyClientSocketTest, ConnectSendsCorrectRequest) {
164 int packet_number = 1;
165 mock_quic_data_.AddWrite(SYNCHRONOUS,
166 ConstructSettingsPacket(packet_number++));
167 mock_quic_data_.AddWrite(SYNCHRONOUS,
168 ConstructConnectRequestPacket(packet_number++));
169 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
170 mock_quic_data_.AddReadPauseForever();
171 mock_quic_data_.AddWrite(
172 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
173 quic::QUIC_STREAM_CANCELLED, 1, 1));
174
175 InitializeSession();
176 InitializeClientSocket();
177
178 ASSERT_FALSE(sock_->IsConnected());
179
180 AssertConnectSucceeds();
181
182 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
183 ASSERT_TRUE(response != nullptr);
184 ASSERT_EQ(200, response->headers->response_code());
185
186 // Although the underlying HTTP/3 connection uses TLS and negotiates ALPN, the
187 // tunnel itself is a TCP connection to the origin and should not report these
188 // values.
189 net::SSLInfo ssl_info;
190 EXPECT_FALSE(sock_->GetSSLInfo(&ssl_info));
191 EXPECT_EQ(sock_->GetNegotiatedProtocol(), NextProto::kProtoUnknown);
192 }
193
TEST_P(QuicProxyClientSocketTest,ProxyDelegateExtraHeaders)194 TEST_P(QuicProxyClientSocketTest, ProxyDelegateExtraHeaders) {
195 // TODO(https://crbug.com/1491092): Add a version of this test for multi-hop.
196 proxy_delegate_ = std::make_unique<TestProxyDelegate>();
197 proxy_delegate_->set_extra_header_name(kTestHeaderName);
198 // TODO(crbug.com/1206799) Construct `proxy_chain` with plain
199 // `proxy_endpoint_` once it supports `url::SchemeHostPort`.
200 ProxyChain proxy_chain(ProxyServer::SCHEME_HTTPS,
201 HostPortPair::FromSchemeHostPort(proxy_endpoint_));
202
203 const char kResponseHeaderName[] = "bar";
204 const char kResponseHeaderValue[] = "testing";
205
206 int packet_number = 1;
207 mock_quic_data_.AddWrite(SYNCHRONOUS,
208 ConstructSettingsPacket(packet_number++));
209 mock_quic_data_.AddWrite(
210 SYNCHRONOUS,
211 ConstructConnectRequestPacketWithExtraHeaders(
212 packet_number++,
213 // Order matters! Keep these alphabetical.
214 {{kTestQuicHeaderName, ProxyServerToProxyUri(proxy_chain.First())},
215 {"user-agent", kUserAgent}}));
216 mock_quic_data_.AddRead(
217 ASYNC, ConstructServerConnectReplyPacketWithExtraHeaders(
218 1, !kFin, {{kResponseHeaderName, kResponseHeaderValue}}));
219 mock_quic_data_.AddReadPauseForever();
220 mock_quic_data_.AddWrite(
221 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
222 quic::QUIC_STREAM_CANCELLED, 1, 1));
223
224 InitializeSession();
225 InitializeClientSocket();
226
227 ASSERT_FALSE(sock_->IsConnected());
228
229 AssertConnectSucceeds();
230
231 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
232 ASSERT_TRUE(response != nullptr);
233 ASSERT_EQ(200, response->headers->response_code());
234
235 ASSERT_EQ(proxy_delegate_->on_tunnel_headers_received_call_count(), 1u);
236 proxy_delegate_->VerifyOnTunnelHeadersReceived(proxy_chain, /*chain_index=*/0,
237 kResponseHeaderName,
238 kResponseHeaderValue);
239 }
240
TEST_P(QuicProxyClientSocketTest,ConnectWithAuthRequested)241 TEST_P(QuicProxyClientSocketTest, ConnectWithAuthRequested) {
242 int packet_number = 1;
243 mock_quic_data_.AddWrite(SYNCHRONOUS,
244 ConstructSettingsPacket(packet_number++));
245 mock_quic_data_.AddWrite(SYNCHRONOUS,
246 ConstructConnectRequestPacket(packet_number++));
247 mock_quic_data_.AddRead(ASYNC,
248 ConstructServerConnectAuthReplyPacket(1, !kFin));
249 mock_quic_data_.AddReadPauseForever();
250 mock_quic_data_.AddWrite(
251 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
252 quic::QUIC_STREAM_CANCELLED, 1, 1));
253
254 InitializeSession();
255 InitializeClientSocket();
256
257 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
258
259 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
260 ASSERT_TRUE(response != nullptr);
261 ASSERT_EQ(407, response->headers->response_code());
262 }
263
TEST_P(QuicProxyClientSocketTest,ConnectWithAuthCredentials)264 TEST_P(QuicProxyClientSocketTest, ConnectWithAuthCredentials) {
265 int packet_number = 1;
266 mock_quic_data_.AddWrite(SYNCHRONOUS,
267 ConstructSettingsPacket(packet_number++));
268 mock_quic_data_.AddWrite(SYNCHRONOUS,
269 ConstructConnectAuthRequestPacket(packet_number++));
270 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
271 mock_quic_data_.AddReadPauseForever();
272 mock_quic_data_.AddWrite(
273 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
274 quic::QUIC_STREAM_CANCELLED, 1, 1));
275
276 InitializeSession();
277 InitializeClientSocket();
278
279 // Add auth to cache
280 const std::u16string kFoo(u"foo");
281 const std::u16string kBar(u"bar");
282 http_auth_cache_.Add(
283 url::SchemeHostPort(GURL(kProxyUrl)), HttpAuth::AUTH_PROXY, "MyRealm1",
284 HttpAuth::AUTH_SCHEME_BASIC, NetworkAnonymizationKey(),
285 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
286
287 AssertConnectSucceeds();
288
289 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
290 ASSERT_TRUE(response != nullptr);
291 ASSERT_EQ(200, response->headers->response_code());
292 }
293
294 // Tests that a redirect response from a CONNECT fails.
TEST_P(QuicProxyClientSocketTest,ConnectRedirects)295 TEST_P(QuicProxyClientSocketTest, ConnectRedirects) {
296 int packet_number = 1;
297 mock_quic_data_.AddWrite(SYNCHRONOUS,
298 ConstructSettingsPacket(packet_number++));
299 mock_quic_data_.AddWrite(SYNCHRONOUS,
300 ConstructConnectRequestPacket(packet_number++));
301 mock_quic_data_.AddRead(ASYNC,
302 ConstructServerConnectRedirectReplyPacket(1, !kFin));
303 mock_quic_data_.AddReadPauseForever();
304 mock_quic_data_.AddWrite(
305 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
306 quic::QUIC_STREAM_CANCELLED, 1, 1));
307
308 InitializeSession();
309 InitializeClientSocket();
310
311 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
312
313 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
314 ASSERT_TRUE(response != nullptr);
315
316 const HttpResponseHeaders* headers = response->headers.get();
317 ASSERT_EQ(302, headers->response_code());
318 ASSERT_TRUE(headers->HasHeader("set-cookie"));
319
320 std::string location;
321 ASSERT_TRUE(headers->IsRedirect(&location));
322 ASSERT_EQ(location, kRedirectUrl);
323 }
324
TEST_P(QuicProxyClientSocketTest,ConnectFails)325 TEST_P(QuicProxyClientSocketTest, ConnectFails) {
326 int packet_number = 1;
327 mock_quic_data_.AddWrite(SYNCHRONOUS,
328 ConstructSettingsPacket(packet_number++));
329 mock_quic_data_.AddWrite(SYNCHRONOUS,
330 ConstructConnectRequestPacket(packet_number++));
331 mock_quic_data_.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
332
333 InitializeSession();
334 InitializeClientSocket();
335
336 ASSERT_FALSE(sock_->IsConnected());
337
338 AssertConnectFails(ERR_QUIC_PROTOCOL_ERROR);
339
340 ASSERT_FALSE(sock_->IsConnected());
341 }
342
TEST_P(QuicProxyClientSocketTest,WasEverUsedReturnsCorrectValue)343 TEST_P(QuicProxyClientSocketTest, WasEverUsedReturnsCorrectValue) {
344 int packet_number = 1;
345 mock_quic_data_.AddWrite(SYNCHRONOUS,
346 ConstructSettingsPacket(packet_number++));
347 mock_quic_data_.AddWrite(SYNCHRONOUS,
348 ConstructConnectRequestPacket(packet_number++));
349 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
350 mock_quic_data_.AddReadPauseForever();
351 mock_quic_data_.AddWrite(
352 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
353 quic::QUIC_STREAM_CANCELLED, 1, 1));
354
355 InitializeSession();
356 InitializeClientSocket();
357
358 EXPECT_TRUE(sock_->WasEverUsed()); // Used due to crypto handshake
359 AssertConnectSucceeds();
360 EXPECT_TRUE(sock_->WasEverUsed());
361 sock_->Disconnect();
362 EXPECT_TRUE(sock_->WasEverUsed());
363 }
364
TEST_P(QuicProxyClientSocketTest,GetPeerAddressReturnsCorrectValues)365 TEST_P(QuicProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
366 int packet_number = 1;
367 mock_quic_data_.AddWrite(SYNCHRONOUS,
368 ConstructSettingsPacket(packet_number++));
369 mock_quic_data_.AddWrite(SYNCHRONOUS,
370 ConstructConnectRequestPacket(packet_number++));
371 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
372 mock_quic_data_.AddReadPause();
373 mock_quic_data_.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
374
375 InitializeSession();
376 InitializeClientSocket();
377
378 IPEndPoint addr;
379 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
380
381 AssertConnectSucceeds();
382 EXPECT_TRUE(sock_->IsConnected());
383 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsOk());
384
385 ResumeAndRun();
386
387 EXPECT_FALSE(sock_->IsConnected());
388 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
389
390 sock_->Disconnect();
391
392 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
393 }
394
TEST_P(QuicProxyClientSocketTest,IsConnectedAndIdle)395 TEST_P(QuicProxyClientSocketTest, IsConnectedAndIdle) {
396 int packet_number = 1;
397 mock_quic_data_.AddWrite(SYNCHRONOUS,
398 ConstructSettingsPacket(packet_number++));
399 mock_quic_data_.AddWrite(SYNCHRONOUS,
400 ConstructConnectRequestPacket(packet_number++));
401 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
402 mock_quic_data_.AddReadPause();
403
404 std::string header = ConstructDataHeader(kLen1);
405 mock_quic_data_.AddRead(
406 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
407 mock_quic_data_.AddWrite(SYNCHRONOUS,
408 ConstructAckPacket(packet_number++, 2, 1));
409 mock_quic_data_.AddReadPauseForever();
410 mock_quic_data_.AddWrite(
411 SYNCHRONOUS,
412 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
413
414 InitializeSession();
415 InitializeClientSocket();
416
417 EXPECT_FALSE(sock_->IsConnectedAndIdle());
418
419 AssertConnectSucceeds();
420
421 EXPECT_TRUE(sock_->IsConnectedAndIdle());
422
423 // The next read is consumed and buffered.
424 ResumeAndRun();
425
426 EXPECT_FALSE(sock_->IsConnectedAndIdle());
427
428 AssertSyncReadEquals(kMsg1, kLen1);
429
430 EXPECT_TRUE(sock_->IsConnectedAndIdle());
431 }
432
TEST_P(QuicProxyClientSocketTest,GetTotalReceivedBytes)433 TEST_P(QuicProxyClientSocketTest, GetTotalReceivedBytes) {
434 int packet_number = 1;
435 mock_quic_data_.AddWrite(SYNCHRONOUS,
436 ConstructSettingsPacket(packet_number++));
437 size_t header_length;
438 mock_quic_data_.AddWrite(SYNCHRONOUS,
439 ConstructConnectRequestPacket(packet_number++));
440 mock_quic_data_.AddRead(
441 ASYNC, ConstructServerConnectReplyPacket(1, !kFin, &header_length));
442 mock_quic_data_.AddReadPause();
443
444 std::string data_header = ConstructDataHeader(kLen333);
445 mock_quic_data_.AddRead(ASYNC,
446 ConstructServerDataPacket(
447 2, data_header + std::string(kMsg333, kLen333)));
448 mock_quic_data_.AddWrite(SYNCHRONOUS,
449 ConstructAckPacket(packet_number++, 2, 1));
450 mock_quic_data_.AddReadPauseForever();
451 mock_quic_data_.AddWrite(
452 SYNCHRONOUS,
453 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
454
455 InitializeSession();
456 InitializeClientSocket();
457
458 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
459
460 AssertConnectSucceeds();
461
462 EXPECT_EQ((int64_t)(header_length), sock_->GetTotalReceivedBytes());
463
464 // The next read is consumed and buffered.
465 ResumeAndRun();
466
467 EXPECT_EQ((int64_t)(header_length + data_header.length()),
468 sock_->GetTotalReceivedBytes());
469
470 // The payload from the single large data frame will be read across
471 // two different reads.
472 AssertSyncReadEquals(kMsg33, kLen33);
473
474 EXPECT_EQ((int64_t)(header_length + data_header.length() + kLen33),
475 sock_->GetTotalReceivedBytes());
476
477 AssertSyncReadEquals(kMsg3, kLen3);
478
479 EXPECT_EQ((int64_t)(header_length + kLen333 + data_header.length()),
480 sock_->GetTotalReceivedBytes());
481 }
482
TEST_P(QuicProxyClientSocketTest,SetStreamPriority)483 TEST_P(QuicProxyClientSocketTest, SetStreamPriority) {
484 int packet_number = 1;
485 mock_quic_data_.AddWrite(SYNCHRONOUS,
486 ConstructSettingsPacket(packet_number++));
487 // Despite setting the priority to HIGHEST, the requests initial priority of
488 // LOWEST is used.
489 mock_quic_data_.AddWrite(
490 SYNCHRONOUS,
491 ConstructConnectRequestPacket(packet_number++,
492 /*extra_headers=*/std::nullopt, LOWEST));
493 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
494 mock_quic_data_.AddReadPauseForever();
495 mock_quic_data_.AddWrite(
496 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
497 quic::QUIC_STREAM_CANCELLED, 1, 1));
498
499 InitializeSession();
500 InitializeClientSocket();
501
502 sock_->SetStreamPriority(HIGHEST);
503 AssertConnectSucceeds();
504 }
505
TEST_P(QuicProxyClientSocketTest,WriteSendsDataInDataFrame)506 TEST_P(QuicProxyClientSocketTest, WriteSendsDataInDataFrame) {
507 int packet_number = 1;
508 mock_quic_data_.AddWrite(SYNCHRONOUS,
509 ConstructSettingsPacket(packet_number++));
510 mock_quic_data_.AddWrite(SYNCHRONOUS,
511 ConstructConnectRequestPacket(packet_number++));
512 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
513 mock_quic_data_.AddReadPauseForever();
514 std::string header = ConstructDataHeader(kLen1);
515 mock_quic_data_.AddWrite(
516 SYNCHRONOUS,
517 ConstructAckAndDataPacket(packet_number++, 1, 1,
518 {header + std::string(kMsg1, kLen1)}));
519 std::string header2 = ConstructDataHeader(kLen2);
520 mock_quic_data_.AddWrite(
521 SYNCHRONOUS, ConstructDataPacket(packet_number++,
522 {header2 + std::string(kMsg2, kLen2)}));
523 mock_quic_data_.AddWrite(
524 SYNCHRONOUS,
525 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
526
527 InitializeSession();
528 InitializeClientSocket();
529
530 AssertConnectSucceeds();
531
532 AssertSyncWriteSucceeds(kMsg1, kLen1);
533 AssertSyncWriteSucceeds(kMsg2, kLen2);
534 }
535
TEST_P(QuicProxyClientSocketTest,WriteSplitsLargeDataIntoMultiplePackets)536 TEST_P(QuicProxyClientSocketTest, WriteSplitsLargeDataIntoMultiplePackets) {
537 int write_packet_index = 1;
538 mock_quic_data_.AddWrite(SYNCHRONOUS,
539 ConstructSettingsPacket(write_packet_index++));
540 mock_quic_data_.AddWrite(SYNCHRONOUS,
541 ConstructConnectRequestPacket(write_packet_index++));
542 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
543 mock_quic_data_.AddReadPauseForever();
544 std::string header = ConstructDataHeader(kLen1);
545 mock_quic_data_.AddWrite(
546 SYNCHRONOUS,
547 ConstructAckAndDataPacket(write_packet_index++, 1, 1,
548 {header + std::string(kMsg1, kLen1)}));
549
550 // Expect |kNumDataPackets| data packets, each containing the max possible
551 // amount of data.
552 int numDataPackets = 3;
553 std::string data(numDataPackets * quic::kDefaultMaxPacketSize, 'x');
554 quic::QuicStreamOffset offset = kLen1 + header.length();
555
556 numDataPackets++;
557 size_t total_data_length = 0;
558 for (int i = 0; i < numDataPackets; ++i) {
559 size_t max_packet_data_length = GetStreamFrameDataLengthFromPacketLength(
560 quic::kDefaultMaxPacketSize, version_, !kIncludeVersion,
561 !kIncludeDiversificationNonce, k8ByteConnectionId,
562 quic::PACKET_1BYTE_PACKET_NUMBER, offset);
563 if (i == 0) {
564 // 3661 is the data frame length from packet length.
565 std::string header2 = ConstructDataHeader(3661);
566 mock_quic_data_.AddWrite(
567 SYNCHRONOUS,
568 ConstructDataPacket(
569 write_packet_index++,
570 {header2 +
571 std::string(data.c_str(), max_packet_data_length - 7)}));
572 offset += max_packet_data_length - header2.length() - 1;
573 } else if (i == numDataPackets - 1) {
574 mock_quic_data_.AddWrite(
575 SYNCHRONOUS, ConstructDataPacket(write_packet_index++,
576 std::string(data.c_str(), 7)));
577 offset += 7;
578 } else {
579 mock_quic_data_.AddWrite(
580 SYNCHRONOUS, ConstructDataPacket(
581 write_packet_index++,
582 std::string(data.c_str(), max_packet_data_length)));
583 offset += max_packet_data_length;
584 }
585 if (i != 3) {
586 total_data_length += max_packet_data_length;
587 }
588 }
589
590 mock_quic_data_.AddWrite(
591 SYNCHRONOUS,
592 ConstructRstPacket(write_packet_index++, quic::QUIC_STREAM_CANCELLED));
593
594 InitializeSession();
595 InitializeClientSocket();
596
597 AssertConnectSucceeds();
598
599 // Make a small write. An ACK and STOP_WAITING will be bundled. This prevents
600 // ACK and STOP_WAITING from being bundled with the subsequent large write.
601 // This allows the test code for computing the size of data sent in each
602 // packet to not become too complicated.
603 AssertSyncWriteSucceeds(kMsg1, kLen1);
604
605 // Make large write that should be split up
606 AssertSyncWriteSucceeds(data.c_str(), total_data_length);
607 }
608
609 // ----------- Read
610
TEST_P(QuicProxyClientSocketTest,ReadReadsDataInDataFrame)611 TEST_P(QuicProxyClientSocketTest, ReadReadsDataInDataFrame) {
612 int packet_number = 1;
613 mock_quic_data_.AddWrite(SYNCHRONOUS,
614 ConstructSettingsPacket(packet_number++));
615 mock_quic_data_.AddWrite(SYNCHRONOUS,
616 ConstructConnectRequestPacket(packet_number++));
617 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
618 mock_quic_data_.AddReadPause();
619
620 std::string header = ConstructDataHeader(kLen1);
621 mock_quic_data_.AddRead(
622 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
623 mock_quic_data_.AddWrite(SYNCHRONOUS,
624 ConstructAckPacket(packet_number++, 2, 1));
625 mock_quic_data_.AddReadPauseForever();
626 mock_quic_data_.AddWrite(
627 SYNCHRONOUS,
628 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
629
630 InitializeSession();
631 InitializeClientSocket();
632
633 AssertConnectSucceeds();
634
635 ResumeAndRun();
636 AssertSyncReadEquals(kMsg1, kLen1);
637 }
638
TEST_P(QuicProxyClientSocketTest,ReadDataFromBufferedFrames)639 TEST_P(QuicProxyClientSocketTest, ReadDataFromBufferedFrames) {
640 int packet_number = 1;
641 mock_quic_data_.AddWrite(SYNCHRONOUS,
642 ConstructSettingsPacket(packet_number++));
643 mock_quic_data_.AddWrite(SYNCHRONOUS,
644 ConstructConnectRequestPacket(packet_number++));
645 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
646 mock_quic_data_.AddReadPause();
647
648 std::string header = ConstructDataHeader(kLen1);
649 mock_quic_data_.AddRead(
650 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
651 mock_quic_data_.AddWrite(SYNCHRONOUS,
652 ConstructAckPacket(packet_number++, 2, 1));
653 mock_quic_data_.AddReadPause();
654
655 std::string header2 = ConstructDataHeader(kLen2);
656 mock_quic_data_.AddRead(
657 ASYNC, ConstructServerDataPacket(3, header2 + std::string(kMsg2, kLen2)));
658 mock_quic_data_.AddReadPauseForever();
659
660 mock_quic_data_.AddWrite(
661 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
662 quic::QUIC_STREAM_CANCELLED, 3, 3));
663
664 InitializeSession();
665 InitializeClientSocket();
666
667 AssertConnectSucceeds();
668
669 ResumeAndRun();
670 AssertSyncReadEquals(kMsg1, kLen1);
671
672 ResumeAndRun();
673 AssertSyncReadEquals(kMsg2, kLen2);
674 }
675
TEST_P(QuicProxyClientSocketTest,ReadDataMultipleBufferedFrames)676 TEST_P(QuicProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
677 int packet_number = 1;
678 mock_quic_data_.AddWrite(SYNCHRONOUS,
679 ConstructSettingsPacket(packet_number++));
680 mock_quic_data_.AddWrite(SYNCHRONOUS,
681 ConstructConnectRequestPacket(packet_number++));
682 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
683 mock_quic_data_.AddReadPause();
684
685 std::string header = ConstructDataHeader(kLen1);
686 mock_quic_data_.AddRead(
687 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
688 mock_quic_data_.AddWrite(SYNCHRONOUS,
689 ConstructAckPacket(packet_number++, 2, 1));
690 std::string header2 = ConstructDataHeader(kLen2);
691 mock_quic_data_.AddRead(
692 ASYNC, ConstructServerDataPacket(3, header2 + std::string(kMsg2, kLen2)));
693 mock_quic_data_.AddReadPauseForever();
694
695 mock_quic_data_.AddWrite(
696 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
697 quic::QUIC_STREAM_CANCELLED, 3, 3));
698
699 InitializeSession();
700 InitializeClientSocket();
701
702 AssertConnectSucceeds();
703
704 // The next two reads are consumed and buffered.
705 ResumeAndRun();
706
707 AssertSyncReadEquals(kMsg1, kLen1);
708 AssertSyncReadEquals(kMsg2, kLen2);
709 }
710
TEST_P(QuicProxyClientSocketTest,LargeReadWillMergeDataFromDifferentFrames)711 TEST_P(QuicProxyClientSocketTest, LargeReadWillMergeDataFromDifferentFrames) {
712 int packet_number = 1;
713 mock_quic_data_.AddWrite(SYNCHRONOUS,
714 ConstructSettingsPacket(packet_number++));
715 mock_quic_data_.AddWrite(SYNCHRONOUS,
716 ConstructConnectRequestPacket(packet_number++));
717 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
718 mock_quic_data_.AddReadPause();
719
720 std::string header = ConstructDataHeader(kLen3);
721 mock_quic_data_.AddRead(
722 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg3, kLen3)));
723 mock_quic_data_.AddWrite(SYNCHRONOUS,
724 ConstructAckPacket(packet_number++, 2, 1));
725 std::string header2 = ConstructDataHeader(kLen3);
726 mock_quic_data_.AddRead(
727 ASYNC, ConstructServerDataPacket(3, header2 + std::string(kMsg3, kLen3)));
728 mock_quic_data_.AddReadPauseForever();
729
730 mock_quic_data_.AddWrite(
731 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
732 quic::QUIC_STREAM_CANCELLED, 3, 3));
733
734 InitializeSession();
735 InitializeClientSocket();
736
737 AssertConnectSucceeds();
738
739 // The next two reads are consumed and buffered.
740 ResumeAndRun();
741 // The payload from two data frames, each with kMsg3 will be combined
742 // together into a single read().
743 AssertSyncReadEquals(kMsg33, kLen33);
744 }
745
TEST_P(QuicProxyClientSocketTest,MultipleShortReadsThenMoreRead)746 TEST_P(QuicProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
747 int packet_number = 1;
748 mock_quic_data_.AddWrite(SYNCHRONOUS,
749 ConstructSettingsPacket(packet_number++));
750 mock_quic_data_.AddWrite(SYNCHRONOUS,
751 ConstructConnectRequestPacket(packet_number++));
752 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
753 mock_quic_data_.AddReadPause();
754
755 std::string header = ConstructDataHeader(kLen1);
756 mock_quic_data_.AddRead(
757 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
758 mock_quic_data_.AddWrite(SYNCHRONOUS,
759 ConstructAckPacket(packet_number++, 2, 1));
760
761 std::string header2 = ConstructDataHeader(kLen3);
762 mock_quic_data_.AddRead(
763 ASYNC, ConstructServerDataPacket(3, header2 + std::string(kMsg3, kLen3)));
764 mock_quic_data_.AddRead(
765 ASYNC, ConstructServerDataPacket(4, header2 + std::string(kMsg3, kLen3)));
766 mock_quic_data_.AddWrite(SYNCHRONOUS,
767 ConstructAckPacket(packet_number++, 4, 3));
768
769 std::string header3 = ConstructDataHeader(kLen2);
770 mock_quic_data_.AddRead(
771 ASYNC, ConstructServerDataPacket(5, header3 + std::string(kMsg2, kLen2)));
772 mock_quic_data_.AddReadPauseForever();
773
774 mock_quic_data_.AddWrite(
775 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
776 quic::QUIC_STREAM_CANCELLED, 5, 5));
777
778 InitializeSession();
779 InitializeClientSocket();
780
781 AssertConnectSucceeds();
782
783 // The next 4 reads are consumed and buffered.
784 ResumeAndRun();
785
786 AssertSyncReadEquals(kMsg1, kLen1);
787 // The payload from two data frames, each with kMsg3 will be combined
788 // together into a single read().
789 AssertSyncReadEquals(kMsg33, kLen33);
790 AssertSyncReadEquals(kMsg2, kLen2);
791 }
792
TEST_P(QuicProxyClientSocketTest,ReadWillSplitDataFromLargeFrame)793 TEST_P(QuicProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
794 int packet_number = 1;
795 mock_quic_data_.AddWrite(SYNCHRONOUS,
796 ConstructSettingsPacket(packet_number++));
797 mock_quic_data_.AddWrite(SYNCHRONOUS,
798 ConstructConnectRequestPacket(packet_number++));
799 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
800 mock_quic_data_.AddReadPause();
801
802 std::string header = ConstructDataHeader(kLen1);
803 mock_quic_data_.AddRead(
804 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
805 mock_quic_data_.AddWrite(SYNCHRONOUS,
806 ConstructAckPacket(packet_number++, 2, 1));
807 std::string header2 = ConstructDataHeader(kLen33);
808 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
809 3, header2 + std::string(kMsg33, kLen33)));
810 mock_quic_data_.AddReadPauseForever();
811
812 mock_quic_data_.AddWrite(
813 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
814 quic::QUIC_STREAM_CANCELLED, 3, 3));
815
816 InitializeSession();
817 InitializeClientSocket();
818
819 AssertConnectSucceeds();
820
821 // The next 2 reads are consumed and buffered.
822 ResumeAndRun();
823
824 AssertSyncReadEquals(kMsg1, kLen1);
825 // The payload from the single large data frame will be read across
826 // two different reads.
827 AssertSyncReadEquals(kMsg3, kLen3);
828 AssertSyncReadEquals(kMsg3, kLen3);
829 }
830
TEST_P(QuicProxyClientSocketTest,MultipleReadsFromSameLargeFrame)831 TEST_P(QuicProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
832 int packet_number = 1;
833 mock_quic_data_.AddWrite(SYNCHRONOUS,
834 ConstructSettingsPacket(packet_number++));
835 mock_quic_data_.AddWrite(SYNCHRONOUS,
836 ConstructConnectRequestPacket(packet_number++));
837 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
838 mock_quic_data_.AddReadPause();
839
840 std::string header = ConstructDataHeader(kLen333);
841 mock_quic_data_.AddRead(
842 ASYNC,
843 ConstructServerDataPacket(2, header + std::string(kMsg333, kLen333)));
844 mock_quic_data_.AddWrite(SYNCHRONOUS,
845 ConstructAckPacket(packet_number++, 2, 1));
846 mock_quic_data_.AddReadPauseForever();
847
848 mock_quic_data_.AddWrite(
849 SYNCHRONOUS,
850 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
851
852 InitializeSession();
853 InitializeClientSocket();
854
855 AssertConnectSucceeds();
856
857 // The next read is consumed and buffered.
858 ResumeAndRun();
859
860 // The payload from the single large data frame will be read across
861 // two different reads.
862 AssertSyncReadEquals(kMsg33, kLen33);
863
864 // Now attempt to do a read of more data than remains buffered
865 auto buf = base::MakeRefCounted<IOBufferWithSize>(kLen33);
866 ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, CompletionOnceCallback()));
867 ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
868 ASSERT_TRUE(sock_->IsConnected());
869 }
870
TEST_P(QuicProxyClientSocketTest,ReadAuthResponseBody)871 TEST_P(QuicProxyClientSocketTest, ReadAuthResponseBody) {
872 int packet_number = 1;
873 mock_quic_data_.AddWrite(SYNCHRONOUS,
874 ConstructSettingsPacket(packet_number++));
875 mock_quic_data_.AddWrite(SYNCHRONOUS,
876 ConstructConnectRequestPacket(packet_number++));
877 mock_quic_data_.AddRead(ASYNC,
878 ConstructServerConnectAuthReplyPacket(1, !kFin));
879 mock_quic_data_.AddReadPause();
880
881 std::string header = ConstructDataHeader(kLen1);
882 mock_quic_data_.AddRead(
883 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
884 mock_quic_data_.AddWrite(SYNCHRONOUS,
885 ConstructAckPacket(packet_number++, 2, 1));
886 std::string header2 = ConstructDataHeader(kLen2);
887 mock_quic_data_.AddRead(
888 ASYNC, ConstructServerDataPacket(3, header2 + std::string(kMsg2, kLen2)));
889 mock_quic_data_.AddReadPauseForever();
890
891 mock_quic_data_.AddWrite(
892 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
893 quic::QUIC_STREAM_CANCELLED, 3, 3));
894
895 InitializeSession();
896 InitializeClientSocket();
897
898 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
899
900 // The next two reads are consumed and buffered.
901 ResumeAndRun();
902
903 AssertSyncReadEquals(kMsg1, kLen1);
904 AssertSyncReadEquals(kMsg2, kLen2);
905 }
906
TEST_P(QuicProxyClientSocketTest,ReadErrorResponseBody)907 TEST_P(QuicProxyClientSocketTest, ReadErrorResponseBody) {
908 int packet_number = 1;
909 mock_quic_data_.AddWrite(SYNCHRONOUS,
910 ConstructSettingsPacket(packet_number++));
911 mock_quic_data_.AddWrite(SYNCHRONOUS,
912 ConstructConnectRequestPacket(packet_number++));
913 mock_quic_data_.AddRead(ASYNC,
914 ConstructServerConnectErrorReplyPacket(1, !kFin));
915 std::string header = ConstructDataHeader(kLen1);
916 mock_quic_data_.AddRead(
917 SYNCHRONOUS,
918 ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
919 mock_quic_data_.AddWrite(SYNCHRONOUS,
920 ConstructAckPacket(packet_number++, 2, 1));
921 std::string header2 = ConstructDataHeader(kLen2);
922 mock_quic_data_.AddRead(
923 SYNCHRONOUS,
924 ConstructServerDataPacket(3, header2 + std::string(kMsg2, kLen2)));
925 mock_quic_data_.AddReadPauseForever();
926
927 mock_quic_data_.AddWrite(
928 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
929 quic::QUIC_STREAM_CANCELLED, 3, 3));
930 InitializeSession();
931 InitializeClientSocket();
932
933 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
934 }
935
936 // ----------- Reads and Writes
937
TEST_P(QuicProxyClientSocketTest,AsyncReadAroundWrite)938 TEST_P(QuicProxyClientSocketTest, AsyncReadAroundWrite) {
939 int write_packet_index = 1;
940 mock_quic_data_.AddWrite(SYNCHRONOUS,
941 ConstructSettingsPacket(write_packet_index++));
942 mock_quic_data_.AddWrite(SYNCHRONOUS,
943 ConstructConnectRequestPacket(write_packet_index++));
944 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
945 mock_quic_data_.AddReadPause();
946
947 std::string header = ConstructDataHeader(kLen1);
948 mock_quic_data_.AddRead(
949 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
950 mock_quic_data_.AddWrite(SYNCHRONOUS,
951 ConstructAckPacket(write_packet_index++, 2, 1));
952
953 std::string header2 = ConstructDataHeader(kLen2);
954 mock_quic_data_.AddWrite(
955 SYNCHRONOUS, ConstructDataPacket(write_packet_index++,
956 {header2 + std::string(kMsg2, kLen2)}));
957
958 mock_quic_data_.AddReadPause();
959
960 std::string header3 = ConstructDataHeader(kLen3);
961 mock_quic_data_.AddRead(
962 ASYNC, ConstructServerDataPacket(3, header3 + std::string(kMsg3, kLen3)));
963 mock_quic_data_.AddReadPauseForever();
964
965 mock_quic_data_.AddWrite(
966 SYNCHRONOUS, ConstructAckAndRstPacket(write_packet_index++,
967 quic::QUIC_STREAM_CANCELLED, 3, 3));
968
969 InitializeSession();
970 InitializeClientSocket();
971
972 AssertConnectSucceeds();
973
974 ResumeAndRun();
975
976 AssertSyncReadEquals(kMsg1, kLen1);
977
978 AssertReadStarts(kMsg3, kLen3);
979 // Read should block until after the write succeeds.
980
981 AssertSyncWriteSucceeds(kMsg2, kLen2);
982
983 ASSERT_FALSE(read_callback_.have_result());
984 ResumeAndRun();
985
986 // Now the read will return.
987 AssertReadReturns(kMsg3, kLen3);
988 }
989
TEST_P(QuicProxyClientSocketTest,AsyncWriteAroundReads)990 TEST_P(QuicProxyClientSocketTest, AsyncWriteAroundReads) {
991 int packet_number = 1;
992 mock_quic_data_.AddWrite(SYNCHRONOUS,
993 ConstructSettingsPacket(packet_number++));
994 mock_quic_data_.AddWrite(SYNCHRONOUS,
995 ConstructConnectRequestPacket(packet_number++));
996 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
997 mock_quic_data_.AddReadPause();
998
999 std::string header = ConstructDataHeader(kLen1);
1000 mock_quic_data_.AddRead(
1001 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
1002 mock_quic_data_.AddWrite(SYNCHRONOUS,
1003 ConstructAckPacket(packet_number++, 2, 1));
1004 mock_quic_data_.AddReadPause();
1005
1006 std::string header2 = ConstructDataHeader(kLen3);
1007 mock_quic_data_.AddRead(
1008 ASYNC, ConstructServerDataPacket(3, header2 + std::string(kMsg3, kLen3)));
1009 mock_quic_data_.AddReadPauseForever();
1010
1011 mock_quic_data_.AddWritePause();
1012
1013 std::string header3 = ConstructDataHeader(kLen2);
1014 mock_quic_data_.AddWrite(
1015 ASYNC, ConstructDataPacket(packet_number++,
1016 {header3 + std::string(kMsg2, kLen2)}));
1017 mock_quic_data_.AddWrite(
1018 ASYNC, ConstructAckAndDataPacket(packet_number++, 3, 3,
1019 header3 + std::string(kMsg2, kLen2)));
1020
1021 mock_quic_data_.AddWrite(
1022 SYNCHRONOUS,
1023 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
1024
1025 InitializeSession();
1026 InitializeClientSocket();
1027
1028 AssertConnectSucceeds();
1029
1030 ResumeAndRun();
1031 AssertSyncReadEquals(kMsg1, kLen1);
1032
1033 // Write should block until the next read completes.
1034 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1035 // asynchronous starting with the second time it's called while the UDP socket
1036 // is write-blocked. Therefore, at least two writes need to be called on
1037 // |sock_| to get an asynchronous one.
1038 AssertWriteReturns(kMsg2, kLen2, kLen2);
1039 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
1040
1041 AssertAsyncReadEquals(kMsg3, kLen3);
1042
1043 ASSERT_FALSE(write_callback_.have_result());
1044
1045 // Now the write will complete
1046 ResumeAndRun();
1047 EXPECT_EQ(kLen2, write_callback_.WaitForResult());
1048 }
1049
1050 // ----------- Reading/Writing on Closed socket
1051
1052 // Reading from an already closed socket should return 0
TEST_P(QuicProxyClientSocketTest,ReadOnClosedSocketReturnsZero)1053 TEST_P(QuicProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
1054 int packet_number = 1;
1055 mock_quic_data_.AddWrite(SYNCHRONOUS,
1056 ConstructSettingsPacket(packet_number++));
1057 mock_quic_data_.AddWrite(SYNCHRONOUS,
1058 ConstructConnectRequestPacket(packet_number++));
1059 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
1060 mock_quic_data_.AddReadPause();
1061 mock_quic_data_.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
1062
1063 InitializeSession();
1064 InitializeClientSocket();
1065
1066 AssertConnectSucceeds();
1067
1068 ResumeAndRun();
1069
1070 ASSERT_FALSE(sock_->IsConnected());
1071 ASSERT_EQ(0, sock_->Read(nullptr, 1, CompletionOnceCallback()));
1072 ASSERT_EQ(0, sock_->Read(nullptr, 1, CompletionOnceCallback()));
1073 ASSERT_EQ(0, sock_->Read(nullptr, 1, CompletionOnceCallback()));
1074 ASSERT_FALSE(sock_->IsConnectedAndIdle());
1075 }
1076
1077 // Read pending when socket is closed should return 0
TEST_P(QuicProxyClientSocketTest,PendingReadOnCloseReturnsZero)1078 TEST_P(QuicProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
1079 int packet_number = 1;
1080 mock_quic_data_.AddWrite(SYNCHRONOUS,
1081 ConstructSettingsPacket(packet_number++));
1082 mock_quic_data_.AddWrite(SYNCHRONOUS,
1083 ConstructConnectRequestPacket(packet_number++));
1084 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
1085 mock_quic_data_.AddReadPause();
1086 mock_quic_data_.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
1087
1088 InitializeSession();
1089 InitializeClientSocket();
1090
1091 AssertConnectSucceeds();
1092
1093 AssertReadStarts(kMsg1, kLen1);
1094
1095 ResumeAndRun();
1096
1097 ASSERT_EQ(0, read_callback_.WaitForResult());
1098 }
1099
1100 // Reading from a disconnected socket is an error
TEST_P(QuicProxyClientSocketTest,ReadOnDisconnectSocketReturnsNotConnected)1101 TEST_P(QuicProxyClientSocketTest, ReadOnDisconnectSocketReturnsNotConnected) {
1102 int packet_number = 1;
1103 mock_quic_data_.AddWrite(SYNCHRONOUS,
1104 ConstructSettingsPacket(packet_number++));
1105 mock_quic_data_.AddWrite(SYNCHRONOUS,
1106 ConstructConnectRequestPacket(packet_number++));
1107 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
1108 mock_quic_data_.AddReadPauseForever();
1109 mock_quic_data_.AddWrite(
1110 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1111 quic::QUIC_STREAM_CANCELLED, 1, 1));
1112
1113 InitializeSession();
1114 InitializeClientSocket();
1115
1116 AssertConnectSucceeds();
1117
1118 sock_->Disconnect();
1119
1120 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1121 sock_->Read(nullptr, 1, CompletionOnceCallback()));
1122 }
1123
1124 // Reading data after receiving FIN should return buffered data received before
1125 // FIN, then 0.
TEST_P(QuicProxyClientSocketTest,ReadAfterFinReceivedReturnsBufferedData)1126 TEST_P(QuicProxyClientSocketTest, ReadAfterFinReceivedReturnsBufferedData) {
1127 int packet_number = 1;
1128 mock_quic_data_.AddWrite(SYNCHRONOUS,
1129 ConstructSettingsPacket(packet_number++));
1130 mock_quic_data_.AddWrite(SYNCHRONOUS,
1131 ConstructConnectRequestPacket(packet_number++));
1132 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
1133 mock_quic_data_.AddReadPause();
1134
1135 std::string header = ConstructDataHeader(kLen1);
1136 mock_quic_data_.AddRead(ASYNC, ConstructServerDataFinPacket(
1137 2, header + std::string(kMsg1, kLen1)));
1138 mock_quic_data_.AddWrite(SYNCHRONOUS,
1139 ConstructAckPacket(packet_number++, 2, 1));
1140 mock_quic_data_.AddReadPauseForever();
1141 mock_quic_data_.AddWrite(
1142 SYNCHRONOUS,
1143 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
1144
1145 InitializeSession();
1146 InitializeClientSocket();
1147
1148 AssertConnectSucceeds();
1149
1150 ResumeAndRun();
1151
1152 AssertSyncReadEquals(kMsg1, kLen1);
1153 ASSERT_EQ(0, sock_->Read(nullptr, 1, CompletionOnceCallback()));
1154 ASSERT_EQ(0, sock_->Read(nullptr, 1, CompletionOnceCallback()));
1155
1156 sock_->Disconnect();
1157 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
1158 sock_->Read(nullptr, 1, CompletionOnceCallback()));
1159 }
1160
1161 // Calling Write() on a closed socket is an error.
TEST_P(QuicProxyClientSocketTest,WriteOnClosedStream)1162 TEST_P(QuicProxyClientSocketTest, WriteOnClosedStream) {
1163 int packet_number = 1;
1164 mock_quic_data_.AddWrite(SYNCHRONOUS,
1165 ConstructSettingsPacket(packet_number++));
1166 mock_quic_data_.AddWrite(SYNCHRONOUS,
1167 ConstructConnectRequestPacket(packet_number++));
1168 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
1169 mock_quic_data_.AddReadPause();
1170 mock_quic_data_.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
1171
1172 InitializeSession();
1173 InitializeClientSocket();
1174
1175 AssertConnectSucceeds();
1176
1177 ResumeAndRun();
1178
1179 AssertWriteReturns(kMsg1, kLen1, ERR_QUIC_PROTOCOL_ERROR);
1180 }
1181
1182 // Calling Write() on a disconnected socket is an error.
TEST_P(QuicProxyClientSocketTest,WriteOnDisconnectedSocket)1183 TEST_P(QuicProxyClientSocketTest, WriteOnDisconnectedSocket) {
1184 int packet_number = 1;
1185 mock_quic_data_.AddWrite(SYNCHRONOUS,
1186 ConstructSettingsPacket(packet_number++));
1187 mock_quic_data_.AddWrite(SYNCHRONOUS,
1188 ConstructConnectRequestPacket(packet_number++));
1189 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
1190 mock_quic_data_.AddReadPauseForever();
1191 mock_quic_data_.AddWrite(
1192 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1193 quic::QUIC_STREAM_CANCELLED, 1, 1));
1194
1195 InitializeSession();
1196 InitializeClientSocket();
1197
1198 AssertConnectSucceeds();
1199
1200 sock_->Disconnect();
1201
1202 AssertWriteReturns(kMsg1, kLen1, ERR_SOCKET_NOT_CONNECTED);
1203 }
1204
1205 // If the socket is closed with a pending Write(), the callback should be called
1206 // with the same error the session was closed with.
TEST_P(QuicProxyClientSocketTest,WritePendingOnClose)1207 TEST_P(QuicProxyClientSocketTest, WritePendingOnClose) {
1208 int packet_number = 1;
1209 mock_quic_data_.AddWrite(SYNCHRONOUS,
1210 ConstructSettingsPacket(packet_number++));
1211 mock_quic_data_.AddWrite(SYNCHRONOUS,
1212 ConstructConnectRequestPacket(packet_number++));
1213 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
1214 mock_quic_data_.AddReadPauseForever();
1215 mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
1216
1217 InitializeSession();
1218 InitializeClientSocket();
1219
1220 AssertConnectSucceeds();
1221
1222 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1223 // asynchronous starting with the second time it's called while the UDP socket
1224 // is write-blocked. Therefore, at least two writes need to be called on
1225 // |sock_| to get an asynchronous one.
1226 AssertWriteReturns(kMsg1, kLen1, kLen1);
1227
1228 // This second write will be async. This is the pending write that's being
1229 // tested.
1230 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1231
1232 // Make sure the write actually starts.
1233 base::RunLoop().RunUntilIdle();
1234
1235 session_->CloseSessionOnError(ERR_CONNECTION_CLOSED,
1236 quic::QUIC_INTERNAL_ERROR,
1237 quic::ConnectionCloseBehavior::SILENT_CLOSE);
1238
1239 EXPECT_THAT(write_callback_.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
1240 }
1241
TEST_P(QuicProxyClientSocketTest,DisconnectWithWritePending)1242 TEST_P(QuicProxyClientSocketTest, DisconnectWithWritePending) {
1243 int packet_number = 1;
1244 mock_quic_data_.AddWrite(SYNCHRONOUS,
1245 ConstructSettingsPacket(packet_number++));
1246 mock_quic_data_.AddWrite(SYNCHRONOUS,
1247 ConstructConnectRequestPacket(packet_number++));
1248 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
1249 mock_quic_data_.AddReadPauseForever();
1250 mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
1251
1252 InitializeSession();
1253 InitializeClientSocket();
1254
1255 AssertConnectSucceeds();
1256
1257 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1258 // asynchronous starting with the second time it's called while the UDP socket
1259 // is write-blocked. Therefore, at least two writes need to be called on
1260 // |sock_| to get an asynchronous one.
1261 AssertWriteReturns(kMsg1, kLen1, kLen1);
1262
1263 // This second write will be async. This is the pending write that's being
1264 // tested.
1265 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1266
1267 // Make sure the write actually starts.
1268 base::RunLoop().RunUntilIdle();
1269
1270 sock_->Disconnect();
1271 EXPECT_FALSE(sock_->IsConnected());
1272
1273 base::RunLoop().RunUntilIdle();
1274
1275 EXPECT_FALSE(sock_->IsConnected());
1276 EXPECT_FALSE(write_callback_.have_result());
1277 }
1278
1279 // If the socket is Disconnected with a pending Read(), the callback
1280 // should not be called.
TEST_P(QuicProxyClientSocketTest,DisconnectWithReadPending)1281 TEST_P(QuicProxyClientSocketTest, DisconnectWithReadPending) {
1282 int packet_number = 1;
1283 mock_quic_data_.AddWrite(SYNCHRONOUS,
1284 ConstructSettingsPacket(packet_number++));
1285 mock_quic_data_.AddWrite(SYNCHRONOUS,
1286 ConstructConnectRequestPacket(packet_number++));
1287 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
1288 mock_quic_data_.AddReadPauseForever();
1289 mock_quic_data_.AddWrite(
1290 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1291 quic::QUIC_STREAM_CANCELLED, 1, 1));
1292
1293 InitializeSession();
1294 InitializeClientSocket();
1295
1296 AssertConnectSucceeds();
1297
1298 EXPECT_TRUE(sock_->IsConnected());
1299
1300 AssertReadStarts(kMsg1, kLen1);
1301
1302 sock_->Disconnect();
1303 EXPECT_FALSE(sock_->IsConnected());
1304
1305 base::RunLoop().RunUntilIdle();
1306
1307 EXPECT_FALSE(sock_->IsConnected());
1308 EXPECT_FALSE(read_callback_.have_result());
1309 }
1310
1311 // If the socket is Reset when both a read and write are pending,
1312 // both should be called back.
TEST_P(QuicProxyClientSocketTest,RstWithReadAndWritePending)1313 TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePending) {
1314 int packet_number = 1;
1315 mock_quic_data_.AddWrite(SYNCHRONOUS,
1316 ConstructSettingsPacket(packet_number++));
1317 mock_quic_data_.AddWrite(SYNCHRONOUS,
1318 ConstructConnectRequestPacket(packet_number++));
1319 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
1320 mock_quic_data_.AddReadPause();
1321
1322 mock_quic_data_.AddRead(
1323 ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED));
1324 mock_quic_data_.AddReadPauseForever();
1325 std::string header = ConstructDataHeader(kLen2);
1326 mock_quic_data_.AddWrite(
1327 ASYNC, ConstructAckAndDataPacket(packet_number++, 1, 1,
1328 {header + std::string(kMsg2, kLen2)}));
1329 mock_quic_data_.AddWrite(
1330 SYNCHRONOUS, ConstructAckAndRstOnlyPacket(
1331 packet_number++, quic::QUIC_STREAM_CANCELLED, 2, 2));
1332
1333 InitializeSession();
1334 InitializeClientSocket();
1335
1336 AssertConnectSucceeds();
1337
1338 EXPECT_TRUE(sock_->IsConnected());
1339
1340 AssertReadStarts(kMsg1, kLen1);
1341
1342 // Write should block until the next read completes.
1343 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1344 // asynchronous starting with the second time it's called while the UDP socket
1345 // is write-blocked. Therefore, at least two writes need to be called on
1346 // |sock_| to get an asynchronous one.
1347 AssertWriteReturns(kMsg2, kLen2, kLen2);
1348
1349 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
1350
1351 ResumeAndRun();
1352
1353 EXPECT_TRUE(read_callback_.have_result());
1354 EXPECT_TRUE(write_callback_.have_result());
1355 }
1356
1357 // Makes sure the proxy client socket's source gets the expected NetLog events
1358 // and only the expected NetLog events (No SpdySession events).
TEST_P(QuicProxyClientSocketTest,NetLog)1359 TEST_P(QuicProxyClientSocketTest, NetLog) {
1360 int packet_number = 1;
1361 mock_quic_data_.AddWrite(SYNCHRONOUS,
1362 ConstructSettingsPacket(packet_number++));
1363 mock_quic_data_.AddWrite(SYNCHRONOUS,
1364 ConstructConnectRequestPacket(packet_number++));
1365 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
1366 mock_quic_data_.AddReadPause();
1367
1368 std::string header = ConstructDataHeader(kLen1);
1369 mock_quic_data_.AddRead(
1370 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
1371 mock_quic_data_.AddWrite(SYNCHRONOUS,
1372 ConstructAckPacket(packet_number++, 2, 1));
1373 mock_quic_data_.AddReadPauseForever();
1374 mock_quic_data_.AddWrite(
1375 SYNCHRONOUS,
1376 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
1377
1378 InitializeSession();
1379 InitializeClientSocket();
1380
1381 AssertConnectSucceeds();
1382
1383 ResumeAndRun();
1384 AssertSyncReadEquals(kMsg1, kLen1);
1385
1386 NetLogSource sock_source = sock_->NetLog().source();
1387 sock_.reset();
1388
1389 auto entry_list = net_log_observer_.GetEntriesForSource(sock_source);
1390
1391 ASSERT_EQ(entry_list.size(), 10u);
1392 EXPECT_TRUE(
1393 LogContainsBeginEvent(entry_list, 0, NetLogEventType::SOCKET_ALIVE));
1394 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1395 NetLogEventType::HTTP2_PROXY_CLIENT_SESSION,
1396 NetLogEventPhase::NONE));
1397 EXPECT_TRUE(LogContainsBeginEvent(
1398 entry_list, 2, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1399 EXPECT_TRUE(LogContainsEvent(
1400 entry_list, 3, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1401 NetLogEventPhase::NONE));
1402 EXPECT_TRUE(LogContainsEndEvent(
1403 entry_list, 4, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1404 EXPECT_TRUE(LogContainsBeginEvent(
1405 entry_list, 5, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1406 EXPECT_TRUE(LogContainsEvent(
1407 entry_list, 6,
1408 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1409 NetLogEventPhase::NONE));
1410 EXPECT_TRUE(LogContainsEndEvent(
1411 entry_list, 7, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1412 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1413 NetLogEventType::SOCKET_BYTES_RECEIVED,
1414 NetLogEventPhase::NONE));
1415 EXPECT_TRUE(
1416 LogContainsEndEvent(entry_list, 9, NetLogEventType::SOCKET_ALIVE));
1417 }
1418
1419 // A helper class that will delete |sock| when the callback is invoked.
1420 class DeleteSockCallback : public TestCompletionCallbackBase {
1421 public:
DeleteSockCallback(std::unique_ptr<QuicProxyClientSocket> * sock)1422 explicit DeleteSockCallback(std::unique_ptr<QuicProxyClientSocket>* sock)
1423 : sock_(sock) {}
1424
1425 DeleteSockCallback(const DeleteSockCallback&) = delete;
1426 DeleteSockCallback& operator=(const DeleteSockCallback&) = delete;
1427
1428 ~DeleteSockCallback() override = default;
1429
callback()1430 CompletionOnceCallback callback() {
1431 return base::BindOnce(&DeleteSockCallback::OnComplete,
1432 base::Unretained(this));
1433 }
1434
1435 private:
OnComplete(int result)1436 void OnComplete(int result) {
1437 sock_->reset(nullptr);
1438 SetResult(result);
1439 }
1440
1441 raw_ptr<std::unique_ptr<QuicProxyClientSocket>> sock_;
1442 };
1443
1444 // If the socket is reset when both a read and write are pending, and the
1445 // read callback causes the socket to be deleted, the write callback should
1446 // not be called.
TEST_P(QuicProxyClientSocketTest,RstWithReadAndWritePendingDelete)1447 TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
1448 int packet_number = 1;
1449 mock_quic_data_.AddWrite(SYNCHRONOUS,
1450 ConstructSettingsPacket(packet_number++));
1451 mock_quic_data_.AddWrite(SYNCHRONOUS,
1452 ConstructConnectRequestPacket(packet_number++));
1453 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
1454 mock_quic_data_.AddReadPause();
1455
1456 mock_quic_data_.AddRead(
1457 ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED));
1458 mock_quic_data_.AddReadPauseForever();
1459 std::string header = ConstructDataHeader(kLen1);
1460 mock_quic_data_.AddWrite(
1461 ASYNC, ConstructAckAndDataPacket(packet_number++, 1, 1,
1462 {header + std::string(kMsg1, kLen1)}));
1463 mock_quic_data_.AddWrite(
1464 SYNCHRONOUS, ConstructAckAndRstOnlyPacket(
1465 packet_number++, quic::QUIC_STREAM_CANCELLED, 2, 2));
1466
1467 InitializeSession();
1468 InitializeClientSocket();
1469
1470 AssertConnectSucceeds();
1471
1472 EXPECT_TRUE(sock_->IsConnected());
1473
1474 DeleteSockCallback read_callback(&sock_);
1475 auto read_buf = base::MakeRefCounted<IOBufferWithSize>(kLen1);
1476 ASSERT_EQ(ERR_IO_PENDING,
1477 sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
1478
1479 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1480 // asynchronous starting with the second time it's called while the UDP socket
1481 // is write-blocked. Therefore, at least two writes need to be called on
1482 // |sock_| to get an asynchronous one.
1483 AssertWriteReturns(kMsg1, kLen1, kLen1);
1484
1485 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1486
1487 ResumeAndRun();
1488
1489 EXPECT_FALSE(sock_.get());
1490
1491 EXPECT_EQ(0, read_callback.WaitForResult());
1492 EXPECT_FALSE(write_callback_.have_result());
1493 }
1494
1495 INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1496 QuicProxyClientSocketTest,
1497 ::testing::ValuesIn(AllSupportedQuicVersions()),
1498 ::testing::PrintToStringParamName());
1499
1500 } // namespace net::test
1501