blob: 805784e1c567e5a5989308dbdf2b4e5cd003e8d7 [file] [log] [blame]
Yixin Wang0d2c6b7e12017-08-16 21:12:551// Copyright (c) 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ryan Hamiltona3ee93a72018-08-01 22:03:085#include "net/quic/quic_proxy_client_socket.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:556
Bence Béky8f9d7d3952017-10-09 19:58:047#include <memory>
Bence Békyd8a21fc32018-06-27 18:29:588#include <utility>
Bence Béky8f9d7d3952017-10-09 19:58:049
10#include "base/memory/ptr_util.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5511#include "base/run_loop.h"
12#include "base/strings/utf_string_conversions.h"
13#include "net/dns/mock_host_resolver.h"
14#include "net/http/http_auth_cache.h"
15#include "net/http/http_auth_handler_factory.h"
16#include "net/http/http_response_headers.h"
17#include "net/http/transport_security_state.h"
18#include "net/log/test_net_log.h"
19#include "net/log/test_net_log_util.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0820#include "net/quic/crypto/proof_verifier_chromium.h"
21#include "net/quic/mock_crypto_client_stream_factory.h"
22#include "net/quic/mock_quic_data.h"
23#include "net/quic/quic_chromium_alarm_factory.h"
24#include "net/quic/quic_chromium_client_session.h"
25#include "net/quic/quic_chromium_connection_helper.h"
26#include "net/quic/quic_chromium_packet_writer.h"
27#include "net/quic/quic_http_utils.h"
28#include "net/quic/quic_server_info.h"
29#include "net/quic/quic_stream_factory.h"
30#include "net/quic/quic_test_packet_maker.h"
31#include "net/quic/test_task_runner.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5532#include "net/socket/socket_test_util.h"
33#include "net/test/cert_test_util.h"
34#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0135#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1636#include "net/third_party/quic/core/crypto/null_encrypter.h"
37#include "net/third_party/quic/core/tls_client_handshaker.h"
38#include "net/third_party/quic/test_tools/crypto_test_utils.h"
39#include "net/third_party/quic/test_tools/mock_clock.h"
40#include "net/third_party/quic/test_tools/mock_random.h"
41#include "net/third_party/quic/test_tools/quic_connection_peer.h"
42#include "net/third_party/quic/test_tools/quic_test_utils.h"
[email protected]578968d42017-12-13 15:39:3243#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5544#include "testing/gmock/include/gmock/gmock.h"
45#include "testing/gtest/include/gtest/gtest.h"
46
47using testing::_;
48using testing::AnyNumber;
49using testing::Return;
50
51namespace {
52
53static const char kOriginHost[] = "www.google.com";
54static const int kOriginPort = 443;
55static const char kProxyUrl[] = "https://myproxy:6121/";
56static const char kProxyHost[] = "myproxy";
57static const int kProxyPort = 6121;
58static const char kUserAgent[] = "Mozilla/1.0";
59static const char kRedirectUrl[] = "https://example.com/";
60
61static const char kMsg1[] = "\0hello!\xff";
62static const int kLen1 = 8;
63static const char kMsg2[] = "\0a2345678\0";
64static const int kLen2 = 10;
65static const char kMsg3[] = "bye!";
66static const int kLen3 = 4;
67static const char kMsg33[] = "bye!bye!";
68static const int kLen33 = kLen3 + kLen3;
69static const char kMsg333[] = "bye!bye!bye!";
70static const int kLen333 = kLen3 + kLen3 + kLen3;
71
72} // anonymous namespace
73
74namespace net {
75namespace test {
76
77namespace {
Ryan Hamilton8d9ee76e2018-05-29 23:52:5278const quic::QuicStreamId kClientDataStreamId1 = quic::kHeadersStreamId + 2;
Yixin Wang0d2c6b7e12017-08-16 21:12:5579} // namespace
80
Michael Warres74ee3ce2017-10-09 15:26:3781class QuicProxyClientSocketTest
Ryan Hamilton8d9ee76e2018-05-29 23:52:5282 : public ::testing::TestWithParam<
83 std::tuple<quic::QuicTransportVersion, bool>>,
Bence Béky98447b12018-05-08 03:14:0184 public WithScopedTaskEnvironment {
Yixin Wang0d2c6b7e12017-08-16 21:12:5585 protected:
86 static const bool kFin = true;
87 static const bool kIncludeVersion = true;
88 static const bool kIncludeDiversificationNonce = true;
89 static const bool kIncludeCongestionFeedback = true;
90 static const bool kSendFeedback = true;
91
92 static size_t GetStreamFrameDataLengthFromPacketLength(
Ryan Hamilton8d9ee76e2018-05-29 23:52:5293 quic::QuicByteCount packet_length,
94 quic::QuicTransportVersion version,
Yixin Wang0d2c6b7e12017-08-16 21:12:5595 bool include_version,
96 bool include_diversification_nonce,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5297 quic::QuicConnectionIdLength connection_id_length,
98 quic::QuicPacketNumberLength packet_number_length,
99 quic::QuicStreamOffset offset) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55100 size_t min_data_length = 1;
101 size_t min_packet_length =
Ryan Hamilton8d9ee76e2018-05-29 23:52:52102 quic::NullEncrypter(quic::Perspective::IS_CLIENT)
Yixin Wang0d2c6b7e12017-08-16 21:12:55103 .GetCiphertextSize(min_data_length) +
Ryan Hamilton8d9ee76e2018-05-29 23:52:52104 quic::QuicPacketCreator::StreamFramePacketOverhead(
Michael Warres60637ae2018-06-05 20:03:11105 version, quic::PACKET_8BYTE_CONNECTION_ID,
106 quic::PACKET_0BYTE_CONNECTION_ID, include_version,
Yixin Wang0d2c6b7e12017-08-16 21:12:55107 include_diversification_nonce, packet_number_length, offset);
108
109 DCHECK(packet_length >= min_packet_length);
110 return min_data_length + packet_length - min_packet_length;
111 }
112
113 QuicProxyClientSocketTest()
Yixin Wang079ad542018-01-11 04:06:05114 : version_(std::get<0>(GetParam())),
115 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52116 crypto_config_(quic::test::crypto_test_utils::ProofVerifierForTesting(),
117 quic::TlsClientHandshaker::CreateSslCtx()),
Yixin Wang0d2c6b7e12017-08-16 21:12:55118 connection_id_(2),
119 client_maker_(version_,
120 connection_id_,
121 &clock_,
122 kProxyHost,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52123 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05124 client_headers_include_h2_stream_dependency_),
Yixin Wang0d2c6b7e12017-08-16 21:12:55125 server_maker_(version_,
126 connection_id_,
127 &clock_,
128 kProxyHost,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52129 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05130 false),
Yixin Wang0d2c6b7e12017-08-16 21:12:55131 random_generator_(0),
132 header_stream_offset_(0),
133 response_offset_(0),
134 user_agent_(kUserAgent),
135 proxy_host_port_(kProxyHost, kProxyPort),
136 endpoint_host_port_(kOriginHost, kOriginPort),
137 host_resolver_(new MockCachingHostResolver()),
138 http_auth_handler_factory_(
139 HttpAuthHandlerFactory::CreateDefault(host_resolver_.get())) {
140 IPAddress ip(192, 0, 2, 33);
141 peer_addr_ = IPEndPoint(ip, 443);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52142 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
Yixin Wang0d2c6b7e12017-08-16 21:12:55143 }
144
145 void SetUp() override {}
146
Yixin Wang2bea3cf2017-11-09 18:11:03147 void TearDown() override {
148 sock_.reset();
149 EXPECT_TRUE(mock_quic_data_.AllReadDataConsumed());
150 EXPECT_TRUE(mock_quic_data_.AllWriteDataConsumed());
151 }
Yixin Wang0d2c6b7e12017-08-16 21:12:55152
153 void Initialize() {
154 std::unique_ptr<MockUDPClientSocket> socket(new MockUDPClientSocket(
155 mock_quic_data_.InitializeAndGetSequencedSocketData(),
156 net_log_.bound().net_log()));
157 socket->Connect(peer_addr_);
158 runner_ = new TestTaskRunner(&clock_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52159 send_algorithm_ = new quic::test::MockSendAlgorithm();
Yixin Wang0d2c6b7e12017-08-16 21:12:55160 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
161 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
162 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
Dan Zhangf11470172017-09-18 22:02:09163 .Times(testing::AtLeast(1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55164 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52165 .WillRepeatedly(Return(quic::kMaxPacketSize));
Yixin Wang0d2c6b7e12017-08-16 21:12:55166 EXPECT_CALL(*send_algorithm_, PacingRate(_))
Ryan Hamilton8d9ee76e2018-05-29 23:52:52167 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Michael Warres74ee3ce2017-10-09 15:26:37168 EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
Yixin Wang0d2c6b7e12017-08-16 21:12:55169 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52170 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Yixin Wang0d2c6b7e12017-08-16 21:12:55171 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
172 EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
173 EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
174 .Times(AnyNumber());
175 helper_.reset(
176 new QuicChromiumConnectionHelper(&clock_, &random_generator_));
177 alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
178
Ryan Hamilton9edcf1a2017-11-22 05:55:17179 QuicChromiumPacketWriter* writer = new QuicChromiumPacketWriter(
180 socket.get(), base::ThreadTaskRunnerHandle::Get().get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52181 quic::QuicConnection* connection = new quic::QuicConnection(
182 connection_id_,
183 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(peer_addr_)),
Yixin Wang0d2c6b7e12017-08-16 21:12:55184 helper_.get(), alarm_factory_.get(), writer, true /* owns_writer */,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52185 quic::Perspective::IS_CLIENT,
186 quic::test::SupportedVersions(
187 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version_)));
Yixin Wang0d2c6b7e12017-08-16 21:12:55188 connection->set_visitor(&visitor_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52189 quic::test::QuicConnectionPeer::SetSendAlgorithm(connection,
190 send_algorithm_);
Yixin Wang0d2c6b7e12017-08-16 21:12:55191
192 // Load a certificate that is valid for *.example.org
193 scoped_refptr<X509Certificate> test_cert(
194 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
195 EXPECT_TRUE(test_cert.get());
196
197 verify_details_.cert_verify_result.verified_cert = test_cert;
198 verify_details_.cert_verify_result.is_issued_by_known_root = true;
199 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
200
201 base::TimeTicks dns_end = base::TimeTicks::Now();
202 base::TimeTicks dns_start = dns_end - base::TimeDelta::FromMilliseconds(1);
203
204 session_.reset(new QuicChromiumClientSession(
205 connection, std::move(socket),
206 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57207 &transport_security_state_, /*ssl_config_service=*/nullptr,
Yixin Wang0d2c6b7e12017-08-16 21:12:55208 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
Paul Jensen8e3c5d32018-02-19 17:06:33209 QuicSessionKey("mail.example.org", 80, PRIVACY_MODE_DISABLED,
210 SocketTag()),
Zhongyi Shi757fcce2018-06-27 05:41:27211 /*require_confirmation=*/false, /*migrate_session_early_v2=*/false,
212 /*migrate_session_on_network_change_v2=*/false,
213 /*default_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
Zhongyi Shi73f23ca872017-12-13 18:37:13214 base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
Zhongyi Shiee760762018-08-01 00:54:29215 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30216 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17217 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52218 quic::QuicTime::Delta::FromMilliseconds(
219 kQuicYieldAfterDurationMilliseconds),
Yixin Wang079ad542018-01-11 04:06:05220 client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52221 quic::test::DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
222 dns_start, dns_end, &push_promise_index_, nullptr,
Yixin Wang0d2c6b7e12017-08-16 21:12:55223 base::ThreadTaskRunnerHandle::Get().get(),
224 /*socket_performance_watcher=*/nullptr, net_log_.bound().net_log()));
225
226 writer->set_delegate(session_.get());
227
Ryan Hamilton6c2a2a82017-12-15 02:06:28228 session_handle_ =
229 session_->CreateHandle(HostPortPair("mail.example.org", 80));
Yixin Wang0d2c6b7e12017-08-16 21:12:55230
231 session_->Initialize();
232 TestCompletionCallback callback;
233 EXPECT_THAT(session_->CryptoConnect(callback.callback()), IsOk());
234 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
235
Ramin Halavati683bcaa92018-02-14 08:42:39236 EXPECT_THAT(session_handle_->RequestStream(true, callback.callback(),
237 TRAFFIC_ANNOTATION_FOR_TESTS),
Yixin Wang0d2c6b7e12017-08-16 21:12:55238 IsOk());
239 std::unique_ptr<QuicChromiumClientStream::Handle> stream_handle =
240 session_handle_->ReleaseStream();
241 EXPECT_TRUE(stream_handle->IsOpen());
242
243 sock_.reset(new QuicProxyClientSocket(
244 std::move(stream_handle), std::move(session_handle_), user_agent_,
245 endpoint_host_port_, net_log_.bound(),
246 new HttpAuthController(HttpAuth::AUTH_PROXY,
247 GURL("https://" + proxy_host_port_.ToString()),
248 &http_auth_cache_,
249 http_auth_handler_factory_.get())));
250
251 session_->StartReading();
252 }
253
Ryan Hamilton0239aac2018-05-19 00:03:13254 void PopulateConnectRequestIR(spdy::SpdyHeaderBlock* block) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55255 (*block)[":method"] = "CONNECT";
256 (*block)[":authority"] = endpoint_host_port_.ToString();
257 (*block)["user-agent"] = kUserAgent;
258 }
259
260 // Helper functions for constructing packets sent by the client
261
Ryan Hamilton8d9ee76e2018-05-29 23:52:52262 std::unique_ptr<quic::QuicReceivedPacket> ConstructSettingsPacket(
263 quic::QuicPacketNumber packet_number) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55264 return client_maker_.MakeInitialSettingsPacket(packet_number,
265 &header_stream_offset_);
266 }
267
Ryan Hamilton8d9ee76e2018-05-29 23:52:52268 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstPacket(
269 quic::QuicPacketNumber packet_number,
270 quic::QuicRstStreamErrorCode error_code,
271 quic::QuicPacketNumber largest_received,
272 quic::QuicPacketNumber smallest_received,
273 quic::QuicPacketNumber least_unacked) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55274 return client_maker_.MakeAckAndRstPacket(
275 packet_number, !kIncludeVersion, kClientDataStreamId1, error_code,
276 largest_received, smallest_received, least_unacked, kSendFeedback);
277 }
278
Ryan Hamilton8d9ee76e2018-05-29 23:52:52279 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstPacket(
280 quic::QuicPacketNumber packet_number,
281 quic::QuicRstStreamErrorCode error_code,
282 quic::QuicPacketNumber largest_received,
283 quic::QuicPacketNumber smallest_received,
284 quic::QuicPacketNumber least_unacked,
Yixin Wang0d2c6b7e12017-08-16 21:12:55285 size_t bytes_written) {
286 return client_maker_.MakeAckAndRstPacket(
287 packet_number, !kIncludeVersion, kClientDataStreamId1, error_code,
288 largest_received, smallest_received, least_unacked, kSendFeedback,
289 bytes_written);
290 }
291
Ryan Hamilton8d9ee76e2018-05-29 23:52:52292 std::unique_ptr<quic::QuicReceivedPacket> ConstructRstPacket(
293 quic::QuicPacketNumber packet_number,
294 quic::QuicRstStreamErrorCode error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55295 size_t bytes_written) {
296 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
297 kClientDataStreamId1, error_code,
298 bytes_written);
299 }
300
Ryan Hamilton8d9ee76e2018-05-29 23:52:52301 std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectRequestPacket(
302 quic::QuicPacketNumber packet_number) {
Ryan Hamilton0239aac2018-05-19 00:03:13303 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55304 PopulateConnectRequestIR(&block);
305 return client_maker_.MakeRequestHeadersPacket(
306 packet_number, kClientDataStreamId1, kIncludeVersion, !kFin,
Yixin Wang7a3f1b8d2018-01-17 21:40:48307 ConvertRequestPriorityToQuicPriority(LOWEST), std::move(block), 0,
308 nullptr, &header_stream_offset_);
Yixin Wang0d2c6b7e12017-08-16 21:12:55309 }
310
Ryan Hamilton8d9ee76e2018-05-29 23:52:52311 std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectAuthRequestPacket(
312 quic::QuicPacketNumber packet_number) {
Ryan Hamilton0239aac2018-05-19 00:03:13313 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55314 PopulateConnectRequestIR(&block);
315 block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
316 return client_maker_.MakeRequestHeadersPacket(
317 packet_number, kClientDataStreamId1, kIncludeVersion, !kFin,
Yixin Wang7a3f1b8d2018-01-17 21:40:48318 ConvertRequestPriorityToQuicPriority(LOWEST), std::move(block), 0,
319 nullptr, &header_stream_offset_);
Yixin Wang0d2c6b7e12017-08-16 21:12:55320 }
321
Ryan Hamilton8d9ee76e2018-05-29 23:52:52322 std::unique_ptr<quic::QuicReceivedPacket> ConstructDataPacket(
323 quic::QuicPacketNumber packet_number,
324 quic::QuicStreamOffset offset,
Yixin Wang0d2c6b7e12017-08-16 21:12:55325 const char* data,
326 int length) {
327 return client_maker_.MakeDataPacket(packet_number, kClientDataStreamId1,
328 !kIncludeVersion, !kFin, offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52329 quic::QuicStringPiece(data, length));
Yixin Wang0d2c6b7e12017-08-16 21:12:55330 }
331
Ryan Hamilton8d9ee76e2018-05-29 23:52:52332 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndDataPacket(
333 quic::QuicPacketNumber packet_number,
334 quic::QuicPacketNumber largest_received,
335 quic::QuicPacketNumber smallest_received,
336 quic::QuicPacketNumber least_unacked,
337 quic::QuicStreamOffset offset,
Yixin Wang0d2c6b7e12017-08-16 21:12:55338 const char* data,
339 int length) {
340 return client_maker_.MakeAckAndDataPacket(
341 packet_number, !kIncludeVersion, kClientDataStreamId1, largest_received,
342 smallest_received, least_unacked, !kFin, offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52343 quic::QuicStringPiece(data, length));
Yixin Wang0d2c6b7e12017-08-16 21:12:55344 }
345
Ryan Hamilton8d9ee76e2018-05-29 23:52:52346 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckPacket(
347 quic::QuicPacketNumber packet_number,
348 quic::QuicPacketNumber largest_received,
349 quic::QuicPacketNumber smallest_received,
350 quic::QuicPacketNumber least_unacked) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55351 return client_maker_.MakeAckPacket(packet_number, largest_received,
352 smallest_received, least_unacked,
353 kSendFeedback);
354 }
355
356 // Helper functions for constructing packets sent by the server
357
Ryan Hamilton8d9ee76e2018-05-29 23:52:52358 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerRstPacket(
359 quic::QuicPacketNumber packet_number,
360 quic::QuicRstStreamErrorCode error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55361 size_t bytes_written) {
362 return server_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
363 kClientDataStreamId1, error_code,
364 bytes_written);
365 }
366
Ryan Hamilton8d9ee76e2018-05-29 23:52:52367 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
368 quic::QuicPacketNumber packet_number,
369 quic::QuicStreamOffset offset,
Yixin Wang0d2c6b7e12017-08-16 21:12:55370 const char* data,
371 int length) {
372 return server_maker_.MakeDataPacket(packet_number, kClientDataStreamId1,
373 !kIncludeVersion, !kFin, offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52374 quic::QuicStringPiece(data, length));
Yixin Wang0d2c6b7e12017-08-16 21:12:55375 }
376
Ryan Hamilton8d9ee76e2018-05-29 23:52:52377 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataFinPacket(
378 quic::QuicPacketNumber packet_number,
379 quic::QuicStreamOffset offset,
Yixin Wang0d2c6b7e12017-08-16 21:12:55380 const char* data,
381 int length) {
382 return server_maker_.MakeDataPacket(packet_number, kClientDataStreamId1,
383 !kIncludeVersion, kFin, offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52384 quic::QuicStringPiece(data, length));
Yixin Wang0d2c6b7e12017-08-16 21:12:55385 }
386
Ryan Hamilton8d9ee76e2018-05-29 23:52:52387 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerConnectReplyPacket(
388 quic::QuicPacketNumber packet_number,
Yixin Wang0d2c6b7e12017-08-16 21:12:55389 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13390 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55391 block[":status"] = "200";
392
393 return server_maker_.MakeResponseHeadersPacket(
394 packet_number, kClientDataStreamId1, !kIncludeVersion, fin,
395 std::move(block), nullptr, &response_offset_);
396 }
397
Ryan Hamilton8d9ee76e2018-05-29 23:52:52398 std::unique_ptr<quic::QuicReceivedPacket>
399 ConstructServerConnectAuthReplyPacket(quic::QuicPacketNumber packet_number,
400 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13401 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55402 block[":status"] = "407";
403 block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
404 return server_maker_.MakeResponseHeadersPacket(
405 packet_number, kClientDataStreamId1, !kIncludeVersion, fin,
406 std::move(block), nullptr, &response_offset_);
407 }
408
Ryan Hamilton8d9ee76e2018-05-29 23:52:52409 std::unique_ptr<quic::QuicReceivedPacket>
410 ConstructServerConnectRedirectReplyPacket(
411 quic::QuicPacketNumber packet_number,
Yixin Wang0d2c6b7e12017-08-16 21:12:55412 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13413 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55414 block[":status"] = "302";
415 block["location"] = kRedirectUrl;
416 block["set-cookie"] = "foo=bar";
417 return server_maker_.MakeResponseHeadersPacket(
418 packet_number, kClientDataStreamId1, !kIncludeVersion, fin,
419 std::move(block), nullptr, &response_offset_);
420 }
421
Ryan Hamilton8d9ee76e2018-05-29 23:52:52422 std::unique_ptr<quic::QuicReceivedPacket>
423 ConstructServerConnectErrorReplyPacket(quic::QuicPacketNumber packet_number,
424 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13425 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55426 block[":status"] = "500";
427
428 return server_maker_.MakeResponseHeadersPacket(
429 packet_number, kClientDataStreamId1, !kIncludeVersion, fin,
430 std::move(block), nullptr, &response_offset_);
431 }
432
433 void AssertConnectSucceeds() {
434 TestCompletionCallback callback;
435 ASSERT_THAT(sock_->Connect(callback.callback()), IsError(ERR_IO_PENDING));
436 ASSERT_THAT(callback.WaitForResult(), IsOk());
437 }
438
439 void AssertConnectFails(int result) {
440 TestCompletionCallback callback;
441 ASSERT_THAT(sock_->Connect(callback.callback()), IsError(ERR_IO_PENDING));
442 ASSERT_EQ(result, callback.WaitForResult());
443 }
444
445 void ResumeAndRun() {
446 // Run until the pause, if the provider isn't paused yet.
447 SequencedSocketData* data = mock_quic_data_.GetSequencedSocketData();
448 data->RunUntilPaused();
449 data->Resume();
450 base::RunLoop().RunUntilIdle();
451 }
452
453 void AssertWriteReturns(const char* data, int len, int rv) {
454 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(len));
455 memcpy(buf->data(), data, len);
456 EXPECT_EQ(rv,
[email protected]578968d42017-12-13 15:39:32457 sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
458 TRAFFIC_ANNOTATION_FOR_TESTS));
Yixin Wang0d2c6b7e12017-08-16 21:12:55459 }
460
461 void AssertSyncWriteSucceeds(const char* data, int len) {
462 scoped_refptr<IOBufferWithSize> buf(new IOBufferWithSize(len));
463 memcpy(buf->data(), data, len);
Bence Békyd8a21fc32018-06-27 18:29:58464 EXPECT_EQ(len,
465 sock_->Write(buf.get(), buf->size(), CompletionOnceCallback(),
466 TRAFFIC_ANNOTATION_FOR_TESTS));
Yixin Wang0d2c6b7e12017-08-16 21:12:55467 }
468
469 void AssertSyncReadEquals(const char* data, int len) {
470 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
Bence Békyd8a21fc32018-06-27 18:29:58471 ASSERT_EQ(len, sock_->Read(buf.get(), len, CompletionOnceCallback()));
Ryan Hamilton0239aac2018-05-19 00:03:13472 ASSERT_EQ(spdy::SpdyString(data, len), spdy::SpdyString(buf->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55473 ASSERT_TRUE(sock_->IsConnected());
474 }
475
476 void AssertAsyncReadEquals(const char* data, int len) {
477 scoped_refptr<IOBuffer> buf(new IOBuffer(len));
478 ASSERT_EQ(ERR_IO_PENDING,
479 sock_->Read(buf.get(), len, read_callback_.callback()));
480 EXPECT_TRUE(sock_->IsConnected());
481
482 ResumeAndRun();
483
484 EXPECT_EQ(len, read_callback_.WaitForResult());
485 EXPECT_TRUE(sock_->IsConnected());
Ryan Hamilton0239aac2018-05-19 00:03:13486 ASSERT_EQ(spdy::SpdyString(data, len), spdy::SpdyString(buf->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55487 }
488
489 void AssertReadStarts(const char* data, int len) {
490 // Issue the read, which will be completed asynchronously.
491 read_buf_ = new IOBuffer(len);
492 ASSERT_EQ(ERR_IO_PENDING,
493 sock_->Read(read_buf_.get(), len, read_callback_.callback()));
494 EXPECT_TRUE(sock_->IsConnected());
495 }
496
497 void AssertReadReturns(const char* data, int len) {
498 EXPECT_TRUE(sock_->IsConnected());
499
500 // Now the read will return.
501 EXPECT_EQ(len, read_callback_.WaitForResult());
Ryan Hamilton0239aac2018-05-19 00:03:13502 ASSERT_EQ(spdy::SpdyString(data, len),
503 spdy::SpdyString(read_buf_->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55504 }
505
Ryan Hamilton8d9ee76e2018-05-29 23:52:52506 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05507 const bool client_headers_include_h2_stream_dependency_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55508
509 // order of destruction of these members matter
Ryan Hamilton8d9ee76e2018-05-29 23:52:52510 quic::MockClock clock_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55511 MockQuicData mock_quic_data_;
512 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
513 std::unique_ptr<QuicChromiumClientSession> session_;
514 std::unique_ptr<QuicChromiumClientSession::Handle> session_handle_;
515 std::unique_ptr<QuicProxyClientSocket> sock_;
516
517 BoundTestNetLog net_log_;
518
Ryan Hamilton8d9ee76e2018-05-29 23:52:52519 quic::test::MockSendAlgorithm* send_algorithm_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55520 scoped_refptr<TestTaskRunner> runner_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55521
522 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52523 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55524 TransportSecurityState transport_security_state_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52525 quic::QuicCryptoClientConfig crypto_config_;
526 quic::QuicClientPushPromiseIndex push_promise_index_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55527
Ryan Hamilton8d9ee76e2018-05-29 23:52:52528 const quic::QuicConnectionId connection_id_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55529 QuicTestPacketMaker client_maker_;
530 QuicTestPacketMaker server_maker_;
531 IPEndPoint peer_addr_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52532 quic::test::MockRandom random_generator_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55533 ProofVerifyDetailsChromium verify_details_;
534 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52535 quic::QuicStreamOffset header_stream_offset_;
536 quic::QuicStreamOffset response_offset_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55537
538 std::string user_agent_;
539 HostPortPair proxy_host_port_;
540 HostPortPair endpoint_host_port_;
541 HttpAuthCache http_auth_cache_;
542 std::unique_ptr<MockHostResolverBase> host_resolver_;
543 std::unique_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory_;
544
545 TestCompletionCallback read_callback_;
546 scoped_refptr<IOBuffer> read_buf_;
547
548 TestCompletionCallback write_callback_;
549
550 DISALLOW_COPY_AND_ASSIGN(QuicProxyClientSocketTest);
551};
552
553TEST_P(QuicProxyClientSocketTest, ConnectSendsCorrectRequest) {
Zhongyi Shi32f2fd02018-04-16 18:23:43554 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
555 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
556 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55557 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
558 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52559 SYNCHRONOUS,
560 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55561
562 Initialize();
563
564 ASSERT_FALSE(sock_->IsConnected());
565
566 AssertConnectSucceeds();
567
568 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
569 ASSERT_TRUE(response != nullptr);
570 ASSERT_EQ(200, response->headers->response_code());
571}
572
573TEST_P(QuicProxyClientSocketTest, ConnectWithAuthRequested) {
Zhongyi Shi32f2fd02018-04-16 18:23:43574 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
575 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
576 mock_quic_data_.AddRead(ASYNC,
577 ConstructServerConnectAuthReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55578 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
579 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52580 SYNCHRONOUS,
581 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55582
583 Initialize();
584
585 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
586
587 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
588 ASSERT_TRUE(response != nullptr);
589 ASSERT_EQ(407, response->headers->response_code());
590}
591
592TEST_P(QuicProxyClientSocketTest, ConnectWithAuthCredentials) {
Zhongyi Shi32f2fd02018-04-16 18:23:43593 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
594 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectAuthRequestPacket(2));
595 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55596 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
597 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52598 SYNCHRONOUS,
599 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55600
601 Initialize();
602
603 // Add auth to cache
604 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
605 const base::string16 kBar(base::ASCIIToUTF16("bar"));
606 http_auth_cache_.Add(GURL(kProxyUrl), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
607 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar),
608 "/");
609
610 AssertConnectSucceeds();
611
612 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
613 ASSERT_TRUE(response != nullptr);
614 ASSERT_EQ(200, response->headers->response_code());
615}
616
617TEST_P(QuicProxyClientSocketTest, ConnectRedirects) {
Zhongyi Shi32f2fd02018-04-16 18:23:43618 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
619 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
620 mock_quic_data_.AddRead(ASYNC,
621 ConstructServerConnectRedirectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55622 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
623 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52624 SYNCHRONOUS,
625 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55626
627 Initialize();
628
629 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
630
631 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
632 ASSERT_TRUE(response != nullptr);
633
634 const HttpResponseHeaders* headers = response->headers.get();
635 ASSERT_EQ(302, headers->response_code());
636 ASSERT_FALSE(headers->HasHeader("set-cookie"));
637 ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
638
639 std::string location;
640 ASSERT_TRUE(headers->IsRedirect(&location));
641 ASSERT_EQ(location, kRedirectUrl);
642}
643
644TEST_P(QuicProxyClientSocketTest, ConnectFails) {
Zhongyi Shi32f2fd02018-04-16 18:23:43645 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
646 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55647 mock_quic_data_.AddRead(ASYNC, 0); // EOF
648
649 Initialize();
650
651 ASSERT_FALSE(sock_->IsConnected());
652
653 AssertConnectFails(ERR_QUIC_PROTOCOL_ERROR);
654
655 ASSERT_FALSE(sock_->IsConnected());
656}
657
658TEST_P(QuicProxyClientSocketTest, WasEverUsedReturnsCorrectValue) {
Zhongyi Shi32f2fd02018-04-16 18:23:43659 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
660 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
661 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55662 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
663 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52664 SYNCHRONOUS,
665 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55666
667 Initialize();
668
669 EXPECT_TRUE(sock_->WasEverUsed()); // Used due to crypto handshake
670 AssertConnectSucceeds();
671 EXPECT_TRUE(sock_->WasEverUsed());
672 sock_->Disconnect();
673 EXPECT_TRUE(sock_->WasEverUsed());
674}
675
676TEST_P(QuicProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
Zhongyi Shi32f2fd02018-04-16 18:23:43677 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
678 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
679 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55680 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
681 mock_quic_data_.AddRead(ASYNC, 0); // EOF
682
683 Initialize();
684
685 IPEndPoint addr;
686 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
687
688 AssertConnectSucceeds();
689 EXPECT_TRUE(sock_->IsConnected());
690 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsOk());
691
692 ResumeAndRun();
693
694 EXPECT_FALSE(sock_->IsConnected());
695 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
696
697 sock_->Disconnect();
698
699 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
700}
701
702TEST_P(QuicProxyClientSocketTest, IsConnectedAndIdle) {
Zhongyi Shi32f2fd02018-04-16 18:23:43703 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
704 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
705 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55706 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
707
Zhongyi Shi32f2fd02018-04-16 18:23:43708 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
709 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55710 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52711 mock_quic_data_.AddWrite(
712 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:55713
714 Initialize();
715
716 EXPECT_FALSE(sock_->IsConnectedAndIdle());
717
718 AssertConnectSucceeds();
719
720 EXPECT_TRUE(sock_->IsConnectedAndIdle());
721
722 // The next read is consumed and buffered.
723 ResumeAndRun();
724
725 EXPECT_FALSE(sock_->IsConnectedAndIdle());
726
727 AssertSyncReadEquals(kMsg1, kLen1);
728
729 EXPECT_TRUE(sock_->IsConnectedAndIdle());
730}
731
732TEST_P(QuicProxyClientSocketTest, GetTotalReceivedBytes) {
Zhongyi Shi32f2fd02018-04-16 18:23:43733 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
734 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
735 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55736 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
737
Zhongyi Shi32f2fd02018-04-16 18:23:43738 mock_quic_data_.AddRead(ASYNC,
739 ConstructServerDataPacket(2, 0, kMsg333, kLen333));
740 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55741 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52742 mock_quic_data_.AddWrite(
743 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:55744
745 Initialize();
746
747 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
748
749 AssertConnectSucceeds();
750
751 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
752
753 // The next read is consumed and buffered.
754 ResumeAndRun();
755
756 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
757
758 // The payload from the single large data frame will be read across
759 // two different reads.
760 AssertSyncReadEquals(kMsg33, kLen33);
761
762 EXPECT_EQ((int64_t)kLen33, sock_->GetTotalReceivedBytes());
763
764 AssertSyncReadEquals(kMsg3, kLen3);
765
766 EXPECT_EQ((int64_t)kLen333, sock_->GetTotalReceivedBytes());
767}
768
769// ----------- Write
770
771TEST_P(QuicProxyClientSocketTest, WriteSendsDataInDataFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:43772 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
773 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
774 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55775 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
776 mock_quic_data_.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43777 SYNCHRONOUS, ConstructAckAndDataPacket(3, 1, 1, 1, 0, kMsg1, kLen1));
778 mock_quic_data_.AddWrite(SYNCHRONOUS,
779 ConstructDataPacket(4, kLen1, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55780 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52781 SYNCHRONOUS,
782 ConstructRstPacket(5, quic::QUIC_STREAM_CANCELLED, kLen1 + kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55783
784 Initialize();
785
786 AssertConnectSucceeds();
787
788 AssertSyncWriteSucceeds(kMsg1, kLen1);
789 AssertSyncWriteSucceeds(kMsg2, kLen2);
790}
791
792TEST_P(QuicProxyClientSocketTest, WriteSplitsLargeDataIntoMultiplePackets) {
Zhongyi Shi32f2fd02018-04-16 18:23:43793 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
794 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
795 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55796 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
797 mock_quic_data_.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43798 SYNCHRONOUS, ConstructAckAndDataPacket(3, 1, 1, 1, 0, kMsg1, kLen1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55799
800 // Expect |kNumDataPackets| data packets, each containing the max possible
801 // amount of data.
802 const int kNumDataPackets = 3;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52803 std::string data(kNumDataPackets * quic::kDefaultMaxPacketSize, 'x');
804 quic::QuicStreamOffset offset = kLen1;
Yixin Wang0d2c6b7e12017-08-16 21:12:55805 size_t total_data_length = 0;
806 for (int i = 0; i < kNumDataPackets; ++i) {
807 size_t max_packet_data_length = GetStreamFrameDataLengthFromPacketLength(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52808 quic::kDefaultMaxPacketSize, version_, !kIncludeVersion,
809 !kIncludeDiversificationNonce, quic::PACKET_8BYTE_CONNECTION_ID,
810 quic::PACKET_1BYTE_PACKET_NUMBER, offset);
Zhongyi Shi32f2fd02018-04-16 18:23:43811 mock_quic_data_.AddWrite(SYNCHRONOUS,
812 ConstructDataPacket(4 + i, offset, data.c_str(),
Yixin Wang0d2c6b7e12017-08-16 21:12:55813 max_packet_data_length));
814 offset += max_packet_data_length;
815 total_data_length += max_packet_data_length;
816 }
817 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52818 SYNCHRONOUS, ConstructRstPacket(4 + kNumDataPackets,
819 quic::QUIC_STREAM_CANCELLED, offset));
Yixin Wang0d2c6b7e12017-08-16 21:12:55820
821 Initialize();
822
823 AssertConnectSucceeds();
824
825 // Make a small write. An ACK and STOP_WAITING will be bundled. This prevents
826 // ACK and STOP_WAITING from being bundled with the subsequent large write.
827 // This allows the test code for computing the size of data sent in each
828 // packet to not become too complicated.
829 AssertSyncWriteSucceeds(kMsg1, kLen1);
830
831 // Make large write that should be split up
832 AssertSyncWriteSucceeds(data.c_str(), total_data_length);
833}
834
835// ----------- Read
836
837TEST_P(QuicProxyClientSocketTest, ReadReadsDataInDataFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:43838 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
839 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
840 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55841 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
842
Zhongyi Shi32f2fd02018-04-16 18:23:43843 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
844 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55845 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52846 mock_quic_data_.AddWrite(
847 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:55848
849 Initialize();
850
851 AssertConnectSucceeds();
852
853 ResumeAndRun();
854 AssertSyncReadEquals(kMsg1, kLen1);
855}
856
857TEST_P(QuicProxyClientSocketTest, ReadDataFromBufferedFrames) {
Zhongyi Shi32f2fd02018-04-16 18:23:43858 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
859 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
860 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55861 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
862
Zhongyi Shi32f2fd02018-04-16 18:23:43863 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
864 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55865 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
866
Zhongyi Shi32f2fd02018-04-16 18:23:43867 mock_quic_data_.AddRead(ASYNC,
868 ConstructServerDataPacket(3, kLen1, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55869 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
870
871 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52872 SYNCHRONOUS,
873 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55874
875 Initialize();
876
877 AssertConnectSucceeds();
878
879 ResumeAndRun();
880 AssertSyncReadEquals(kMsg1, kLen1);
881
882 ResumeAndRun();
883 AssertSyncReadEquals(kMsg2, kLen2);
884}
885
886TEST_P(QuicProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
Zhongyi Shi32f2fd02018-04-16 18:23:43887 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
888 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
889 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55890 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
891
Zhongyi Shi32f2fd02018-04-16 18:23:43892 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
893 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
894 mock_quic_data_.AddRead(ASYNC,
895 ConstructServerDataPacket(3, kLen1, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55896 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
897
898 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52899 SYNCHRONOUS,
900 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55901
902 Initialize();
903
904 AssertConnectSucceeds();
905
906 // The next two reads are consumed and buffered.
907 ResumeAndRun();
908
909 AssertSyncReadEquals(kMsg1, kLen1);
910 AssertSyncReadEquals(kMsg2, kLen2);
911}
912
913TEST_P(QuicProxyClientSocketTest, LargeReadWillMergeDataFromDifferentFrames) {
Zhongyi Shi32f2fd02018-04-16 18:23:43914 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
915 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
916 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55917 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
918
Zhongyi Shi32f2fd02018-04-16 18:23:43919 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg3, kLen3));
920 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
921 mock_quic_data_.AddRead(ASYNC,
922 ConstructServerDataPacket(3, kLen3, kMsg3, kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:55923 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
924
925 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52926 SYNCHRONOUS,
927 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55928
929 Initialize();
930
931 AssertConnectSucceeds();
932
933 // The next two reads are consumed and buffered.
934 ResumeAndRun();
935 // The payload from two data frames, each with kMsg3 will be combined
936 // together into a single read().
937 AssertSyncReadEquals(kMsg33, kLen33);
938}
939
940TEST_P(QuicProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
Zhongyi Shi32f2fd02018-04-16 18:23:43941 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
942 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
943 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55944 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
945
946 int offset = 0;
947
Zhongyi Shi32f2fd02018-04-16 18:23:43948 mock_quic_data_.AddRead(ASYNC,
949 ConstructServerDataPacket(2, offset, kMsg1, kLen1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55950 offset += kLen1;
Zhongyi Shi32f2fd02018-04-16 18:23:43951 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55952
Zhongyi Shi32f2fd02018-04-16 18:23:43953 mock_quic_data_.AddRead(ASYNC,
954 ConstructServerDataPacket(3, offset, kMsg3, kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:55955 offset += kLen3;
Zhongyi Shi32f2fd02018-04-16 18:23:43956 mock_quic_data_.AddRead(ASYNC,
957 ConstructServerDataPacket(4, offset, kMsg3, kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:55958 offset += kLen3;
Zhongyi Shi32f2fd02018-04-16 18:23:43959 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(4, 4, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55960
Zhongyi Shi32f2fd02018-04-16 18:23:43961 mock_quic_data_.AddRead(ASYNC,
962 ConstructServerDataPacket(5, offset, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55963 offset += kLen2;
964 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
965
966 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52967 SYNCHRONOUS,
968 ConstructAckAndRstPacket(5, quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55969
970 Initialize();
971
972 AssertConnectSucceeds();
973
974 // The next 4 reads are consumed and buffered.
975 ResumeAndRun();
976
977 AssertSyncReadEquals(kMsg1, kLen1);
978 // The payload from two data frames, each with kMsg3 will be combined
979 // together into a single read().
980 AssertSyncReadEquals(kMsg33, kLen33);
981 AssertSyncReadEquals(kMsg2, kLen2);
982}
983
984TEST_P(QuicProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:43985 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
986 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
987 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55988 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
989
Zhongyi Shi32f2fd02018-04-16 18:23:43990 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
991 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
992 mock_quic_data_.AddRead(ASYNC,
993 ConstructServerDataPacket(3, kLen1, kMsg33, kLen33));
Yixin Wang0d2c6b7e12017-08-16 21:12:55994 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
995
996 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52997 SYNCHRONOUS,
998 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55999
1000 Initialize();
1001
1002 AssertConnectSucceeds();
1003
1004 // The next 2 reads are consumed and buffered.
1005 ResumeAndRun();
1006
1007 AssertSyncReadEquals(kMsg1, kLen1);
1008 // The payload from the single large data frame will be read across
1009 // two different reads.
1010 AssertSyncReadEquals(kMsg3, kLen3);
1011 AssertSyncReadEquals(kMsg3, kLen3);
1012}
1013
1014TEST_P(QuicProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:431015 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1016 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1017 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551018 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1019
Zhongyi Shi32f2fd02018-04-16 18:23:431020 mock_quic_data_.AddRead(ASYNC,
1021 ConstructServerDataPacket(2, 0, kMsg333, kLen333));
1022 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551023 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1024
Ryan Hamilton8d9ee76e2018-05-29 23:52:521025 mock_quic_data_.AddWrite(
1026 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551027
1028 Initialize();
1029
1030 AssertConnectSucceeds();
1031
1032 // The next read is consumed and buffered.
1033 ResumeAndRun();
1034
1035 // The payload from the single large data frame will be read across
1036 // two different reads.
1037 AssertSyncReadEquals(kMsg33, kLen33);
1038
1039 // Now attempt to do a read of more data than remains buffered
1040 scoped_refptr<IOBuffer> buf(new IOBuffer(kLen33));
Bence Békyd8a21fc32018-06-27 18:29:581041 ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, CompletionOnceCallback()));
Ryan Hamilton0239aac2018-05-19 00:03:131042 ASSERT_EQ(spdy::SpdyString(kMsg3, kLen3),
1043 spdy::SpdyString(buf->data(), kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551044 ASSERT_TRUE(sock_->IsConnected());
1045}
1046
1047TEST_P(QuicProxyClientSocketTest, ReadAuthResponseBody) {
Zhongyi Shi32f2fd02018-04-16 18:23:431048 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1049 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1050 mock_quic_data_.AddRead(ASYNC,
1051 ConstructServerConnectAuthReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551052 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1053
Zhongyi Shi32f2fd02018-04-16 18:23:431054 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
1055 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
1056 mock_quic_data_.AddRead(ASYNC,
1057 ConstructServerDataPacket(3, kLen1, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551058 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1059
1060 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521061 SYNCHRONOUS,
1062 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551063
1064 Initialize();
1065
1066 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
1067
1068 // The next two reads are consumed and buffered.
1069 ResumeAndRun();
1070
1071 AssertSyncReadEquals(kMsg1, kLen1);
1072 AssertSyncReadEquals(kMsg2, kLen2);
1073}
1074
1075TEST_P(QuicProxyClientSocketTest, ReadErrorResponseBody) {
Zhongyi Shi32f2fd02018-04-16 18:23:431076 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1077 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1078 mock_quic_data_.AddRead(ASYNC,
1079 ConstructServerConnectErrorReplyPacket(1, !kFin));
1080 mock_quic_data_.AddRead(SYNCHRONOUS,
1081 ConstructServerDataPacket(2, 0, kMsg1, kLen1));
1082 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
1083 mock_quic_data_.AddRead(SYNCHRONOUS,
1084 ConstructServerDataPacket(3, kLen1, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551085 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1086
1087 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521088 SYNCHRONOUS,
1089 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551090 Initialize();
1091
1092 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
1093}
1094
1095// ----------- Reads and Writes
1096
1097TEST_P(QuicProxyClientSocketTest, AsyncReadAroundWrite) {
Zhongyi Shi32f2fd02018-04-16 18:23:431098 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1099 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1100 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551101 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1102
Zhongyi Shi32f2fd02018-04-16 18:23:431103 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
1104 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551105
Zhongyi Shi32f2fd02018-04-16 18:23:431106 mock_quic_data_.AddWrite(SYNCHRONOUS,
1107 ConstructDataPacket(4, 0, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551108
1109 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1110
Zhongyi Shi32f2fd02018-04-16 18:23:431111 mock_quic_data_.AddRead(ASYNC,
1112 ConstructServerDataPacket(3, kLen1, kMsg3, kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551113 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1114
1115 mock_quic_data_.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431116 SYNCHRONOUS,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521117 ConstructAckAndRstPacket(5, quic::QUIC_STREAM_CANCELLED, 3, 3, 1, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551118
1119 Initialize();
1120
1121 AssertConnectSucceeds();
1122
1123 ResumeAndRun();
1124
1125 AssertSyncReadEquals(kMsg1, kLen1);
1126
1127 AssertReadStarts(kMsg3, kLen3);
1128 // Read should block until after the write succeeds.
1129
1130 AssertSyncWriteSucceeds(kMsg2, kLen2);
1131
1132 ASSERT_FALSE(read_callback_.have_result());
1133 ResumeAndRun();
1134
1135 // Now the read will return.
1136 AssertReadReturns(kMsg3, kLen3);
1137}
1138
1139TEST_P(QuicProxyClientSocketTest, AsyncWriteAroundReads) {
Zhongyi Shi32f2fd02018-04-16 18:23:431140 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1141 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1142 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551143 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1144
Zhongyi Shi32f2fd02018-04-16 18:23:431145 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
1146 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551147 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1148
Zhongyi Shi32f2fd02018-04-16 18:23:431149 mock_quic_data_.AddRead(ASYNC,
1150 ConstructServerDataPacket(3, kLen1, kMsg3, kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551151 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1152
1153 mock_quic_data_.AddWrite(ASYNC, ERR_IO_PENDING); // Pause
1154
Zhongyi Shi32f2fd02018-04-16 18:23:431155 mock_quic_data_.AddWrite(ASYNC, ConstructDataPacket(4, 0, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551156 mock_quic_data_.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431157 SYNCHRONOUS, ConstructAckAndDataPacket(5, 3, 3, 1, kLen2, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551158
1159 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521160 SYNCHRONOUS,
1161 ConstructRstPacket(6, quic::QUIC_STREAM_CANCELLED, kLen2 + kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551162
1163 Initialize();
1164
1165 AssertConnectSucceeds();
1166
1167 ResumeAndRun();
1168 AssertSyncReadEquals(kMsg1, kLen1);
1169
1170 // Write should block until the next read completes.
1171 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1172 // asynchronous starting with the second time it's called while the UDP socket
1173 // is write-blocked. Therefore, at least two writes need to be called on
1174 // |sock_| to get an asynchronous one.
Yixin Wangdbbd8752018-01-17 21:50:021175 AssertWriteReturns(kMsg2, kLen2, kLen2);
Yixin Wang0d2c6b7e12017-08-16 21:12:551176 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
1177
1178 AssertAsyncReadEquals(kMsg3, kLen3);
1179
1180 ASSERT_FALSE(write_callback_.have_result());
1181
1182 // Now the write will complete
1183 ResumeAndRun();
Yixin Wangdbbd8752018-01-17 21:50:021184 EXPECT_EQ(kLen2, write_callback_.WaitForResult());
Yixin Wang0d2c6b7e12017-08-16 21:12:551185}
1186
1187// ----------- Reading/Writing on Closed socket
1188
1189// Reading from an already closed socket should return 0
1190TEST_P(QuicProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
Zhongyi Shi32f2fd02018-04-16 18:23:431191 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1192 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1193 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551194 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1195
1196 mock_quic_data_.AddRead(ASYNC, 0); // EOF
1197
1198 Initialize();
1199
1200 AssertConnectSucceeds();
1201
1202 ResumeAndRun();
1203
1204 ASSERT_FALSE(sock_->IsConnected());
Bence Békyd8a21fc32018-06-27 18:29:581205 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
1206 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
1207 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551208 ASSERT_FALSE(sock_->IsConnectedAndIdle());
1209}
1210
1211// Read pending when socket is closed should return 0
1212TEST_P(QuicProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
Zhongyi Shi32f2fd02018-04-16 18:23:431213 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1214 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1215 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551216 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1217
1218 mock_quic_data_.AddRead(ASYNC, 0); // EOF
1219
1220 Initialize();
1221
1222 AssertConnectSucceeds();
1223
1224 AssertReadStarts(kMsg1, kLen1);
1225
1226 ResumeAndRun();
1227
1228 ASSERT_EQ(0, read_callback_.WaitForResult());
1229}
1230
1231// Reading from a disconnected socket is an error
1232TEST_P(QuicProxyClientSocketTest, ReadOnDisconnectSocketReturnsNotConnected) {
Zhongyi Shi32f2fd02018-04-16 18:23:431233 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1234 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1235 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551236 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1237 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521238 SYNCHRONOUS,
1239 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551240
1241 Initialize();
1242
1243 AssertConnectSucceeds();
1244
1245 sock_->Disconnect();
1246
1247 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
Bence Békyd8a21fc32018-06-27 18:29:581248 sock_->Read(nullptr, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551249}
1250
1251// Reading data after receiving FIN should return buffered data received before
1252// FIN, then 0.
1253TEST_P(QuicProxyClientSocketTest, ReadAfterFinReceivedReturnsBufferedData) {
Zhongyi Shi32f2fd02018-04-16 18:23:431254 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1255 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1256 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551257 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1258
Zhongyi Shi32f2fd02018-04-16 18:23:431259 mock_quic_data_.AddRead(ASYNC,
1260 ConstructServerDataFinPacket(2, 0, kMsg1, kLen1));
1261 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551262 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521263 mock_quic_data_.AddWrite(
1264 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551265
1266 Initialize();
1267
1268 AssertConnectSucceeds();
1269
1270 ResumeAndRun();
1271
1272 AssertSyncReadEquals(kMsg1, kLen1);
Bence Békyd8a21fc32018-06-27 18:29:581273 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
1274 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551275
1276 sock_->Disconnect();
1277 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
Bence Békyd8a21fc32018-06-27 18:29:581278 sock_->Read(nullptr, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551279}
1280
1281// Calling Write() on a closed socket is an error.
1282TEST_P(QuicProxyClientSocketTest, WriteOnClosedStream) {
Zhongyi Shi32f2fd02018-04-16 18:23:431283 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1284 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1285 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551286 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1287
1288 mock_quic_data_.AddRead(ASYNC, 0); // EOF
1289
1290 Initialize();
1291
1292 AssertConnectSucceeds();
1293
1294 ResumeAndRun();
1295
1296 AssertWriteReturns(kMsg1, kLen1, ERR_QUIC_PROTOCOL_ERROR);
1297}
1298
1299// Calling Write() on a disconnected socket is an error.
1300TEST_P(QuicProxyClientSocketTest, WriteOnDisconnectedSocket) {
Zhongyi Shi32f2fd02018-04-16 18:23:431301 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1302 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1303 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551304 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1305 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521306 SYNCHRONOUS,
1307 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551308
1309 Initialize();
1310
1311 AssertConnectSucceeds();
1312
1313 sock_->Disconnect();
1314
1315 AssertWriteReturns(kMsg1, kLen1, ERR_SOCKET_NOT_CONNECTED);
1316}
1317
1318// If the socket is closed with a pending Write(), the callback should be called
1319// with the same error the session was closed with.
1320TEST_P(QuicProxyClientSocketTest, WritePendingOnClose) {
Zhongyi Shi32f2fd02018-04-16 18:23:431321 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1322 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1323 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551324 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1325 mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
1326
1327 Initialize();
1328
1329 AssertConnectSucceeds();
1330
1331 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1332 // asynchronous starting with the second time it's called while the UDP socket
1333 // is write-blocked. Therefore, at least two writes need to be called on
1334 // |sock_| to get an asynchronous one.
Yixin Wangdbbd8752018-01-17 21:50:021335 AssertWriteReturns(kMsg1, kLen1, kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:551336
1337 // This second write will be async. This is the pending write that's being
1338 // tested.
1339 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1340
1341 // Make sure the write actually starts.
1342 base::RunLoop().RunUntilIdle();
1343
Ryan Hamilton8d9ee76e2018-05-29 23:52:521344 session_->CloseSessionOnError(ERR_CONNECTION_CLOSED,
1345 quic::QUIC_INTERNAL_ERROR);
Yixin Wang0d2c6b7e12017-08-16 21:12:551346
1347 EXPECT_THAT(write_callback_.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
1348}
1349
1350TEST_P(QuicProxyClientSocketTest, DisconnectWithWritePending) {
Zhongyi Shi32f2fd02018-04-16 18:23:431351 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1352 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1353 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551354 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1355 mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
1356
1357 Initialize();
1358
1359 AssertConnectSucceeds();
1360
1361 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1362 // asynchronous starting with the second time it's called while the UDP socket
1363 // is write-blocked. Therefore, at least two writes need to be called on
1364 // |sock_| to get an asynchronous one.
Yixin Wangdbbd8752018-01-17 21:50:021365 AssertWriteReturns(kMsg1, kLen1, kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:551366
1367 // This second write will be async. This is the pending write that's being
1368 // tested.
1369 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1370
1371 // Make sure the write actually starts.
1372 base::RunLoop().RunUntilIdle();
1373
1374 sock_->Disconnect();
1375 EXPECT_FALSE(sock_->IsConnected());
1376
1377 base::RunLoop().RunUntilIdle();
1378
1379 EXPECT_FALSE(sock_->IsConnected());
1380 EXPECT_FALSE(write_callback_.have_result());
1381}
1382
1383// If the socket is Disconnected with a pending Read(), the callback
1384// should not be called.
1385TEST_P(QuicProxyClientSocketTest, DisconnectWithReadPending) {
Zhongyi Shi32f2fd02018-04-16 18:23:431386 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1387 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1388 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551389 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1390 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521391 SYNCHRONOUS,
1392 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551393
1394 Initialize();
1395
1396 AssertConnectSucceeds();
1397
1398 EXPECT_TRUE(sock_->IsConnected());
1399
1400 AssertReadStarts(kMsg1, kLen1);
1401
1402 sock_->Disconnect();
1403 EXPECT_FALSE(sock_->IsConnected());
1404
1405 base::RunLoop().RunUntilIdle();
1406
1407 EXPECT_FALSE(sock_->IsConnected());
1408 EXPECT_FALSE(read_callback_.have_result());
1409}
1410
1411// If the socket is Reset when both a read and write are pending,
1412// both should be called back.
1413TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePending) {
Zhongyi Shi32f2fd02018-04-16 18:23:431414 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1415 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1416 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551417 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1418
1419 mock_quic_data_.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521420 ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang2bea3cf2017-11-09 18:11:031421 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431422 mock_quic_data_.AddWrite(
1423 ASYNC, ConstructAckAndDataPacket(3, 1, 1, 1, 0, kMsg2, kLen2));
1424 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521425 SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
1426 2, 2, 1, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551427
1428 Initialize();
1429
1430 AssertConnectSucceeds();
1431
1432 EXPECT_TRUE(sock_->IsConnected());
1433
1434 AssertReadStarts(kMsg1, kLen1);
1435
1436 // Write should block until the next read completes.
1437 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1438 // asynchronous starting with the second time it's called while the UDP socket
1439 // is write-blocked. Therefore, at least two writes need to be called on
1440 // |sock_| to get an asynchronous one.
Yixin Wangdbbd8752018-01-17 21:50:021441 AssertWriteReturns(kMsg2, kLen2, kLen2);
Yixin Wang0d2c6b7e12017-08-16 21:12:551442 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
1443
1444 ResumeAndRun();
1445
1446 EXPECT_TRUE(read_callback_.have_result());
1447 EXPECT_TRUE(write_callback_.have_result());
1448}
1449
1450// Makes sure the proxy client socket's source gets the expected NetLog events
1451// and only the expected NetLog events (No SpdySession events).
1452TEST_P(QuicProxyClientSocketTest, NetLog) {
Zhongyi Shi32f2fd02018-04-16 18:23:431453 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1454 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1455 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551456 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1457
Zhongyi Shi32f2fd02018-04-16 18:23:431458 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
1459 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang2bea3cf2017-11-09 18:11:031460 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521461 mock_quic_data_.AddWrite(
1462 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551463
1464 Initialize();
1465
1466 AssertConnectSucceeds();
1467
1468 ResumeAndRun();
1469 AssertSyncReadEquals(kMsg1, kLen1);
1470
1471 NetLogSource sock_source = sock_->NetLog().source();
1472 sock_.reset();
1473
1474 TestNetLogEntry::List entry_list;
1475 net_log_.GetEntriesForSource(sock_source, &entry_list);
1476
1477 ASSERT_EQ(entry_list.size(), 10u);
1478 EXPECT_TRUE(
1479 LogContainsBeginEvent(entry_list, 0, NetLogEventType::SOCKET_ALIVE));
1480 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1481 NetLogEventType::HTTP2_PROXY_CLIENT_SESSION,
1482 NetLogEventPhase::NONE));
1483 EXPECT_TRUE(LogContainsBeginEvent(
1484 entry_list, 2, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1485 EXPECT_TRUE(LogContainsEvent(
1486 entry_list, 3, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1487 NetLogEventPhase::NONE));
1488 EXPECT_TRUE(LogContainsEndEvent(
1489 entry_list, 4, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1490 EXPECT_TRUE(LogContainsBeginEvent(
1491 entry_list, 5, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1492 EXPECT_TRUE(LogContainsEvent(
1493 entry_list, 6,
1494 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1495 NetLogEventPhase::NONE));
1496 EXPECT_TRUE(LogContainsEndEvent(
1497 entry_list, 7, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1498 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1499 NetLogEventType::SOCKET_BYTES_RECEIVED,
1500 NetLogEventPhase::NONE));
1501 EXPECT_TRUE(
1502 LogContainsEndEvent(entry_list, 9, NetLogEventType::SOCKET_ALIVE));
1503}
1504
Bence Béky8ddc2492018-06-13 01:02:041505// A helper class that will delete |sock| when the callback is invoked.
Yixin Wang0d2c6b7e12017-08-16 21:12:551506class DeleteSockCallback : public TestCompletionCallbackBase {
1507 public:
1508 explicit DeleteSockCallback(std::unique_ptr<QuicProxyClientSocket>* sock)
Bence Béky8ddc2492018-06-13 01:02:041509 : sock_(sock) {}
Yixin Wang0d2c6b7e12017-08-16 21:12:551510
1511 ~DeleteSockCallback() override {}
1512
Bence Béky8ddc2492018-06-13 01:02:041513 CompletionOnceCallback callback() {
1514 return base::BindOnce(&DeleteSockCallback::OnComplete,
1515 base::Unretained(this));
1516 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551517
1518 private:
1519 void OnComplete(int result) {
1520 sock_->reset(NULL);
1521 SetResult(result);
1522 }
1523
1524 std::unique_ptr<QuicProxyClientSocket>* sock_;
Yixin Wang0d2c6b7e12017-08-16 21:12:551525
1526 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1527};
1528
1529// If the socket is reset when both a read and write are pending, and the
1530// read callback causes the socket to be deleted, the write callback should
1531// not be called.
1532TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
Zhongyi Shi32f2fd02018-04-16 18:23:431533 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1534 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1535 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551536 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1537
1538 mock_quic_data_.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521539 ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551540 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431541 mock_quic_data_.AddWrite(
1542 ASYNC, ConstructAckAndDataPacket(3, 1, 1, 1, 0, kMsg1, kLen1));
1543 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521544 SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
1545 2, 2, 1, kLen1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551546
1547 Initialize();
1548
1549 AssertConnectSucceeds();
1550
1551 EXPECT_TRUE(sock_->IsConnected());
1552
1553 DeleteSockCallback read_callback(&sock_);
1554 scoped_refptr<IOBuffer> read_buf(new IOBuffer(kLen1));
1555 ASSERT_EQ(ERR_IO_PENDING,
1556 sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
1557
1558 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1559 // asynchronous starting with the second time it's called while the UDP socket
1560 // is write-blocked. Therefore, at least two writes need to be called on
1561 // |sock_| to get an asynchronous one.
Yixin Wangdbbd8752018-01-17 21:50:021562 AssertWriteReturns(kMsg1, kLen1, kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:551563 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1564
1565 ResumeAndRun();
1566
1567 EXPECT_FALSE(sock_.get());
1568
1569 EXPECT_EQ(0, read_callback.WaitForResult());
1570 EXPECT_FALSE(write_callback_.have_result());
1571}
1572
Yixin Wang079ad542018-01-11 04:06:051573INSTANTIATE_TEST_CASE_P(
Bence Békyce380cb2018-04-26 23:39:551574 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051575 QuicProxyClientSocketTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521576 ::testing::Combine(
1577 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
1578 ::testing::Bool()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551579
1580} // namespace test
Dan Zhangf11470172017-09-18 22:02:091581} // namespace net