blob: 7c74191122283d8eb02061d3cafb4ffa3d7d8bed [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"
Ryan Hamilton47cf9d12018-10-17 04:33:0937#include "net/third_party/quic/core/quic_utils.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1638#include "net/third_party/quic/core/tls_client_handshaker.h"
39#include "net/third_party/quic/test_tools/crypto_test_utils.h"
40#include "net/third_party/quic/test_tools/mock_clock.h"
41#include "net/third_party/quic/test_tools/mock_random.h"
42#include "net/third_party/quic/test_tools/quic_connection_peer.h"
43#include "net/third_party/quic/test_tools/quic_test_utils.h"
[email protected]578968d42017-12-13 15:39:3244#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5545#include "testing/gmock/include/gmock/gmock.h"
46#include "testing/gtest/include/gtest/gtest.h"
47
48using testing::_;
49using testing::AnyNumber;
50using testing::Return;
51
52namespace {
53
54static const char kOriginHost[] = "www.google.com";
55static const int kOriginPort = 443;
56static const char kProxyUrl[] = "https://myproxy:6121/";
57static const char kProxyHost[] = "myproxy";
58static const int kProxyPort = 6121;
59static const char kUserAgent[] = "Mozilla/1.0";
60static const char kRedirectUrl[] = "https://example.com/";
61
62static const char kMsg1[] = "\0hello!\xff";
63static const int kLen1 = 8;
64static const char kMsg2[] = "\0a2345678\0";
65static const int kLen2 = 10;
66static const char kMsg3[] = "bye!";
67static const int kLen3 = 4;
68static const char kMsg33[] = "bye!bye!";
69static const int kLen33 = kLen3 + kLen3;
70static const char kMsg333[] = "bye!bye!bye!";
71static const int kLen333 = kLen3 + kLen3 + kLen3;
72
73} // anonymous namespace
74
75namespace net {
76namespace test {
77
Michael Warres74ee3ce2017-10-09 15:26:3778class QuicProxyClientSocketTest
Ryan Hamilton8d9ee76e2018-05-29 23:52:5279 : public ::testing::TestWithParam<
80 std::tuple<quic::QuicTransportVersion, bool>>,
Bence Béky98447b12018-05-08 03:14:0181 public WithScopedTaskEnvironment {
Yixin Wang0d2c6b7e12017-08-16 21:12:5582 protected:
83 static const bool kFin = true;
84 static const bool kIncludeVersion = true;
85 static const bool kIncludeDiversificationNonce = true;
86 static const bool kIncludeCongestionFeedback = true;
87 static const bool kSendFeedback = true;
88
89 static size_t GetStreamFrameDataLengthFromPacketLength(
Ryan Hamilton8d9ee76e2018-05-29 23:52:5290 quic::QuicByteCount packet_length,
91 quic::QuicTransportVersion version,
Yixin Wang0d2c6b7e12017-08-16 21:12:5592 bool include_version,
93 bool include_diversification_nonce,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5294 quic::QuicConnectionIdLength connection_id_length,
95 quic::QuicPacketNumberLength packet_number_length,
96 quic::QuicStreamOffset offset) {
Yixin Wang0d2c6b7e12017-08-16 21:12:5597 size_t min_data_length = 1;
98 size_t min_packet_length =
Ryan Hamilton8d9ee76e2018-05-29 23:52:5299 quic::NullEncrypter(quic::Perspective::IS_CLIENT)
Yixin Wang0d2c6b7e12017-08-16 21:12:55100 .GetCiphertextSize(min_data_length) +
Ryan Hamilton8d9ee76e2018-05-29 23:52:52101 quic::QuicPacketCreator::StreamFramePacketOverhead(
Michael Warres60637ae2018-06-05 20:03:11102 version, quic::PACKET_8BYTE_CONNECTION_ID,
103 quic::PACKET_0BYTE_CONNECTION_ID, include_version,
Yixin Wang0d2c6b7e12017-08-16 21:12:55104 include_diversification_nonce, packet_number_length, offset);
105
106 DCHECK(packet_length >= min_packet_length);
107 return min_data_length + packet_length - min_packet_length;
108 }
109
110 QuicProxyClientSocketTest()
Yixin Wang079ad542018-01-11 04:06:05111 : version_(std::get<0>(GetParam())),
Ryan Hamilton47cf9d12018-10-17 04:33:09112 client_data_stream_id1_(quic::QuicUtils::GetHeadersStreamId(version_) +
113 2),
Yixin Wang079ad542018-01-11 04:06:05114 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52115 crypto_config_(quic::test::crypto_test_utils::ProofVerifierForTesting(),
116 quic::TlsClientHandshaker::CreateSslCtx()),
Yixin Wang0d2c6b7e12017-08-16 21:12:55117 connection_id_(2),
118 client_maker_(version_,
119 connection_id_,
120 &clock_,
121 kProxyHost,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52122 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05123 client_headers_include_h2_stream_dependency_),
Yixin Wang0d2c6b7e12017-08-16 21:12:55124 server_maker_(version_,
125 connection_id_,
126 &clock_,
127 kProxyHost,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52128 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05129 false),
Yixin Wang0d2c6b7e12017-08-16 21:12:55130 random_generator_(0),
131 header_stream_offset_(0),
132 response_offset_(0),
133 user_agent_(kUserAgent),
134 proxy_host_port_(kProxyHost, kProxyPort),
135 endpoint_host_port_(kOriginHost, kOriginPort),
136 host_resolver_(new MockCachingHostResolver()),
137 http_auth_handler_factory_(
138 HttpAuthHandlerFactory::CreateDefault(host_resolver_.get())) {
139 IPAddress ip(192, 0, 2, 33);
140 peer_addr_ = IPEndPoint(ip, 443);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52141 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
Yixin Wang0d2c6b7e12017-08-16 21:12:55142 }
143
144 void SetUp() override {}
145
Yixin Wang2bea3cf2017-11-09 18:11:03146 void TearDown() override {
147 sock_.reset();
148 EXPECT_TRUE(mock_quic_data_.AllReadDataConsumed());
149 EXPECT_TRUE(mock_quic_data_.AllWriteDataConsumed());
150 }
Yixin Wang0d2c6b7e12017-08-16 21:12:55151
152 void Initialize() {
153 std::unique_ptr<MockUDPClientSocket> socket(new MockUDPClientSocket(
154 mock_quic_data_.InitializeAndGetSequencedSocketData(),
155 net_log_.bound().net_log()));
156 socket->Connect(peer_addr_);
157 runner_ = new TestTaskRunner(&clock_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52158 send_algorithm_ = new quic::test::MockSendAlgorithm();
Yixin Wang0d2c6b7e12017-08-16 21:12:55159 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
160 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
161 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
Dan Zhangf11470172017-09-18 22:02:09162 .Times(testing::AtLeast(1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55163 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52164 .WillRepeatedly(Return(quic::kMaxPacketSize));
Yixin Wang0d2c6b7e12017-08-16 21:12:55165 EXPECT_CALL(*send_algorithm_, PacingRate(_))
Ryan Hamilton8d9ee76e2018-05-29 23:52:52166 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Michael Warres74ee3ce2017-10-09 15:26:37167 EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
Yixin Wang0d2c6b7e12017-08-16 21:12:55168 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52169 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Yixin Wang0d2c6b7e12017-08-16 21:12:55170 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
171 EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
172 EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
173 .Times(AnyNumber());
174 helper_.reset(
175 new QuicChromiumConnectionHelper(&clock_, &random_generator_));
176 alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
177
Ryan Hamilton9edcf1a2017-11-22 05:55:17178 QuicChromiumPacketWriter* writer = new QuicChromiumPacketWriter(
179 socket.get(), base::ThreadTaskRunnerHandle::Get().get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52180 quic::QuicConnection* connection = new quic::QuicConnection(
181 connection_id_,
182 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(peer_addr_)),
Yixin Wang0d2c6b7e12017-08-16 21:12:55183 helper_.get(), alarm_factory_.get(), writer, true /* owns_writer */,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52184 quic::Perspective::IS_CLIENT,
185 quic::test::SupportedVersions(
186 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version_)));
Yixin Wang0d2c6b7e12017-08-16 21:12:55187 connection->set_visitor(&visitor_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52188 quic::test::QuicConnectionPeer::SetSendAlgorithm(connection,
189 send_algorithm_);
Yixin Wang0d2c6b7e12017-08-16 21:12:55190
191 // Load a certificate that is valid for *.example.org
192 scoped_refptr<X509Certificate> test_cert(
193 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
194 EXPECT_TRUE(test_cert.get());
195
196 verify_details_.cert_verify_result.verified_cert = test_cert;
197 verify_details_.cert_verify_result.is_issued_by_known_root = true;
198 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
199
200 base::TimeTicks dns_end = base::TimeTicks::Now();
201 base::TimeTicks dns_start = dns_end - base::TimeDelta::FromMilliseconds(1);
202
203 session_.reset(new QuicChromiumClientSession(
204 connection, std::move(socket),
205 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57206 &transport_security_state_, /*ssl_config_service=*/nullptr,
Yixin Wang0d2c6b7e12017-08-16 21:12:55207 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
Paul Jensen8e3c5d32018-02-19 17:06:33208 QuicSessionKey("mail.example.org", 80, PRIVACY_MODE_DISABLED,
209 SocketTag()),
Zhongyi Shi757fcce2018-06-27 05:41:27210 /*require_confirmation=*/false, /*migrate_session_early_v2=*/false,
211 /*migrate_session_on_network_change_v2=*/false,
Renjiea5722ccf2018-08-10 00:18:49212 /*go_away_on_path_degrading*/ false,
Zhongyi Shi757fcce2018-06-27 05:41:27213 /*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(
Ryan Hamilton47cf9d12018-10-17 04:33:09275 packet_number, !kIncludeVersion, client_data_stream_id1_, error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55276 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(
Ryan Hamilton47cf9d12018-10-17 04:33:09287 packet_number, !kIncludeVersion, client_data_stream_id1_, error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55288 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,
Ryan Hamilton47cf9d12018-10-17 04:33:09297 client_data_stream_id1_, error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55298 bytes_written);
299 }
300
Ryan Hamilton8d9ee76e2018-05-29 23:52:52301 std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectRequestPacket(
Lily Chenf11e1292018-11-29 16:42:09302 quic::QuicPacketNumber packet_number,
303 RequestPriority request_priority = LOWEST) {
Ryan Hamilton0239aac2018-05-19 00:03:13304 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55305 PopulateConnectRequestIR(&block);
306 return client_maker_.MakeRequestHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09307 packet_number, client_data_stream_id1_, kIncludeVersion, !kFin,
Lily Chenf11e1292018-11-29 16:42:09308 ConvertRequestPriorityToQuicPriority(request_priority),
309 std::move(block), 0, nullptr, &header_stream_offset_);
Yixin Wang0d2c6b7e12017-08-16 21:12:55310 }
311
Ryan Hamilton8d9ee76e2018-05-29 23:52:52312 std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectAuthRequestPacket(
313 quic::QuicPacketNumber packet_number) {
Ryan Hamilton0239aac2018-05-19 00:03:13314 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55315 PopulateConnectRequestIR(&block);
316 block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
317 return client_maker_.MakeRequestHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09318 packet_number, client_data_stream_id1_, kIncludeVersion, !kFin,
Yixin Wang7a3f1b8d2018-01-17 21:40:48319 ConvertRequestPriorityToQuicPriority(LOWEST), std::move(block), 0,
320 nullptr, &header_stream_offset_);
Yixin Wang0d2c6b7e12017-08-16 21:12:55321 }
322
Ryan Hamilton8d9ee76e2018-05-29 23:52:52323 std::unique_ptr<quic::QuicReceivedPacket> ConstructDataPacket(
324 quic::QuicPacketNumber packet_number,
325 quic::QuicStreamOffset offset,
Yixin Wang0d2c6b7e12017-08-16 21:12:55326 const char* data,
327 int length) {
Ryan Hamilton47cf9d12018-10-17 04:33:09328 return client_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
Yixin Wang0d2c6b7e12017-08-16 21:12:55329 !kIncludeVersion, !kFin, offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52330 quic::QuicStringPiece(data, length));
Yixin Wang0d2c6b7e12017-08-16 21:12:55331 }
332
Ryan Hamilton8d9ee76e2018-05-29 23:52:52333 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndDataPacket(
334 quic::QuicPacketNumber packet_number,
335 quic::QuicPacketNumber largest_received,
336 quic::QuicPacketNumber smallest_received,
337 quic::QuicPacketNumber least_unacked,
338 quic::QuicStreamOffset offset,
Yixin Wang0d2c6b7e12017-08-16 21:12:55339 const char* data,
340 int length) {
341 return client_maker_.MakeAckAndDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09342 packet_number, !kIncludeVersion, client_data_stream_id1_,
343 largest_received, smallest_received, least_unacked, !kFin, offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52344 quic::QuicStringPiece(data, length));
Yixin Wang0d2c6b7e12017-08-16 21:12:55345 }
346
Ryan Hamilton8d9ee76e2018-05-29 23:52:52347 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckPacket(
348 quic::QuicPacketNumber packet_number,
349 quic::QuicPacketNumber largest_received,
350 quic::QuicPacketNumber smallest_received,
351 quic::QuicPacketNumber least_unacked) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55352 return client_maker_.MakeAckPacket(packet_number, largest_received,
353 smallest_received, least_unacked,
354 kSendFeedback);
355 }
356
357 // Helper functions for constructing packets sent by the server
358
Ryan Hamilton8d9ee76e2018-05-29 23:52:52359 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerRstPacket(
360 quic::QuicPacketNumber packet_number,
361 quic::QuicRstStreamErrorCode error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55362 size_t bytes_written) {
363 return server_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton47cf9d12018-10-17 04:33:09364 client_data_stream_id1_, error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55365 bytes_written);
366 }
367
Ryan Hamilton8d9ee76e2018-05-29 23:52:52368 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
369 quic::QuicPacketNumber packet_number,
370 quic::QuicStreamOffset offset,
Yixin Wang0d2c6b7e12017-08-16 21:12:55371 const char* data,
372 int length) {
Ryan Hamilton47cf9d12018-10-17 04:33:09373 return server_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
Yixin Wang0d2c6b7e12017-08-16 21:12:55374 !kIncludeVersion, !kFin, offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52375 quic::QuicStringPiece(data, length));
Yixin Wang0d2c6b7e12017-08-16 21:12:55376 }
377
Ryan Hamilton8d9ee76e2018-05-29 23:52:52378 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataFinPacket(
379 quic::QuicPacketNumber packet_number,
380 quic::QuicStreamOffset offset,
Yixin Wang0d2c6b7e12017-08-16 21:12:55381 const char* data,
382 int length) {
Ryan Hamilton47cf9d12018-10-17 04:33:09383 return server_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
Yixin Wang0d2c6b7e12017-08-16 21:12:55384 !kIncludeVersion, kFin, offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52385 quic::QuicStringPiece(data, length));
Yixin Wang0d2c6b7e12017-08-16 21:12:55386 }
387
Ryan Hamilton8d9ee76e2018-05-29 23:52:52388 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerConnectReplyPacket(
389 quic::QuicPacketNumber packet_number,
Yixin Wang0d2c6b7e12017-08-16 21:12:55390 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13391 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55392 block[":status"] = "200";
393
394 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09395 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Yixin Wang0d2c6b7e12017-08-16 21:12:55396 std::move(block), nullptr, &response_offset_);
397 }
398
Ryan Hamilton8d9ee76e2018-05-29 23:52:52399 std::unique_ptr<quic::QuicReceivedPacket>
400 ConstructServerConnectAuthReplyPacket(quic::QuicPacketNumber packet_number,
401 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13402 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55403 block[":status"] = "407";
404 block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
405 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09406 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Yixin Wang0d2c6b7e12017-08-16 21:12:55407 std::move(block), nullptr, &response_offset_);
408 }
409
Ryan Hamilton8d9ee76e2018-05-29 23:52:52410 std::unique_ptr<quic::QuicReceivedPacket>
411 ConstructServerConnectRedirectReplyPacket(
412 quic::QuicPacketNumber packet_number,
Yixin Wang0d2c6b7e12017-08-16 21:12:55413 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13414 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55415 block[":status"] = "302";
416 block["location"] = kRedirectUrl;
417 block["set-cookie"] = "foo=bar";
418 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09419 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Yixin Wang0d2c6b7e12017-08-16 21:12:55420 std::move(block), nullptr, &response_offset_);
421 }
422
Ryan Hamilton8d9ee76e2018-05-29 23:52:52423 std::unique_ptr<quic::QuicReceivedPacket>
424 ConstructServerConnectErrorReplyPacket(quic::QuicPacketNumber packet_number,
425 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13426 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55427 block[":status"] = "500";
428
429 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09430 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Yixin Wang0d2c6b7e12017-08-16 21:12:55431 std::move(block), nullptr, &response_offset_);
432 }
433
434 void AssertConnectSucceeds() {
435 TestCompletionCallback callback;
436 ASSERT_THAT(sock_->Connect(callback.callback()), IsError(ERR_IO_PENDING));
437 ASSERT_THAT(callback.WaitForResult(), IsOk());
438 }
439
440 void AssertConnectFails(int result) {
441 TestCompletionCallback callback;
442 ASSERT_THAT(sock_->Connect(callback.callback()), IsError(ERR_IO_PENDING));
443 ASSERT_EQ(result, callback.WaitForResult());
444 }
445
446 void ResumeAndRun() {
447 // Run until the pause, if the provider isn't paused yet.
448 SequencedSocketData* data = mock_quic_data_.GetSequencedSocketData();
449 data->RunUntilPaused();
450 data->Resume();
451 base::RunLoop().RunUntilIdle();
452 }
453
454 void AssertWriteReturns(const char* data, int len, int rv) {
Victor Costan9c7302b2018-08-27 16:39:44455 scoped_refptr<IOBufferWithSize> buf =
456 base::MakeRefCounted<IOBufferWithSize>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55457 memcpy(buf->data(), data, len);
458 EXPECT_EQ(rv,
[email protected]578968d42017-12-13 15:39:32459 sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
460 TRAFFIC_ANNOTATION_FOR_TESTS));
Yixin Wang0d2c6b7e12017-08-16 21:12:55461 }
462
463 void AssertSyncWriteSucceeds(const char* data, int len) {
Victor Costan9c7302b2018-08-27 16:39:44464 scoped_refptr<IOBufferWithSize> buf =
465 base::MakeRefCounted<IOBufferWithSize>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55466 memcpy(buf->data(), data, len);
Bence Békyd8a21fc32018-06-27 18:29:58467 EXPECT_EQ(len,
468 sock_->Write(buf.get(), buf->size(), CompletionOnceCallback(),
469 TRAFFIC_ANNOTATION_FOR_TESTS));
Yixin Wang0d2c6b7e12017-08-16 21:12:55470 }
471
472 void AssertSyncReadEquals(const char* data, int len) {
Victor Costan9c7302b2018-08-27 16:39:44473 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(len);
Bence Békyd8a21fc32018-06-27 18:29:58474 ASSERT_EQ(len, sock_->Read(buf.get(), len, CompletionOnceCallback()));
Ryan Hamilton0239aac2018-05-19 00:03:13475 ASSERT_EQ(spdy::SpdyString(data, len), spdy::SpdyString(buf->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55476 ASSERT_TRUE(sock_->IsConnected());
477 }
478
479 void AssertAsyncReadEquals(const char* data, int len) {
Victor Costan9c7302b2018-08-27 16:39:44480 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55481 ASSERT_EQ(ERR_IO_PENDING,
482 sock_->Read(buf.get(), len, read_callback_.callback()));
483 EXPECT_TRUE(sock_->IsConnected());
484
485 ResumeAndRun();
486
487 EXPECT_EQ(len, read_callback_.WaitForResult());
488 EXPECT_TRUE(sock_->IsConnected());
Ryan Hamilton0239aac2018-05-19 00:03:13489 ASSERT_EQ(spdy::SpdyString(data, len), spdy::SpdyString(buf->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55490 }
491
492 void AssertReadStarts(const char* data, int len) {
493 // Issue the read, which will be completed asynchronously.
Victor Costan9c7302b2018-08-27 16:39:44494 read_buf_ = base::MakeRefCounted<IOBuffer>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55495 ASSERT_EQ(ERR_IO_PENDING,
496 sock_->Read(read_buf_.get(), len, read_callback_.callback()));
497 EXPECT_TRUE(sock_->IsConnected());
498 }
499
500 void AssertReadReturns(const char* data, int len) {
501 EXPECT_TRUE(sock_->IsConnected());
502
503 // Now the read will return.
504 EXPECT_EQ(len, read_callback_.WaitForResult());
Ryan Hamilton0239aac2018-05-19 00:03:13505 ASSERT_EQ(spdy::SpdyString(data, len),
506 spdy::SpdyString(read_buf_->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55507 }
508
Ryan Hamilton8d9ee76e2018-05-29 23:52:52509 const quic::QuicTransportVersion version_;
Ryan Hamilton47cf9d12018-10-17 04:33:09510 const quic::QuicStreamId client_data_stream_id1_;
Yixin Wang079ad542018-01-11 04:06:05511 const bool client_headers_include_h2_stream_dependency_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55512
513 // order of destruction of these members matter
Ryan Hamilton8d9ee76e2018-05-29 23:52:52514 quic::MockClock clock_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55515 MockQuicData mock_quic_data_;
516 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
517 std::unique_ptr<QuicChromiumClientSession> session_;
518 std::unique_ptr<QuicChromiumClientSession::Handle> session_handle_;
519 std::unique_ptr<QuicProxyClientSocket> sock_;
520
521 BoundTestNetLog net_log_;
522
Ryan Hamilton8d9ee76e2018-05-29 23:52:52523 quic::test::MockSendAlgorithm* send_algorithm_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55524 scoped_refptr<TestTaskRunner> runner_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55525
526 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52527 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55528 TransportSecurityState transport_security_state_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52529 quic::QuicCryptoClientConfig crypto_config_;
530 quic::QuicClientPushPromiseIndex push_promise_index_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55531
Ryan Hamilton8d9ee76e2018-05-29 23:52:52532 const quic::QuicConnectionId connection_id_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55533 QuicTestPacketMaker client_maker_;
534 QuicTestPacketMaker server_maker_;
535 IPEndPoint peer_addr_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52536 quic::test::MockRandom random_generator_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55537 ProofVerifyDetailsChromium verify_details_;
538 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52539 quic::QuicStreamOffset header_stream_offset_;
540 quic::QuicStreamOffset response_offset_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55541
542 std::string user_agent_;
543 HostPortPair proxy_host_port_;
544 HostPortPair endpoint_host_port_;
545 HttpAuthCache http_auth_cache_;
546 std::unique_ptr<MockHostResolverBase> host_resolver_;
547 std::unique_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory_;
548
549 TestCompletionCallback read_callback_;
550 scoped_refptr<IOBuffer> read_buf_;
551
552 TestCompletionCallback write_callback_;
553
554 DISALLOW_COPY_AND_ASSIGN(QuicProxyClientSocketTest);
555};
556
557TEST_P(QuicProxyClientSocketTest, ConnectSendsCorrectRequest) {
Zhongyi Shi32f2fd02018-04-16 18:23:43558 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
559 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
560 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55561 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
562 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52563 SYNCHRONOUS,
564 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55565
566 Initialize();
567
568 ASSERT_FALSE(sock_->IsConnected());
569
570 AssertConnectSucceeds();
571
572 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
573 ASSERT_TRUE(response != nullptr);
574 ASSERT_EQ(200, response->headers->response_code());
575}
576
577TEST_P(QuicProxyClientSocketTest, ConnectWithAuthRequested) {
Zhongyi Shi32f2fd02018-04-16 18:23:43578 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
579 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
580 mock_quic_data_.AddRead(ASYNC,
581 ConstructServerConnectAuthReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55582 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
583 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52584 SYNCHRONOUS,
585 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55586
587 Initialize();
588
589 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
590
591 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
592 ASSERT_TRUE(response != nullptr);
593 ASSERT_EQ(407, response->headers->response_code());
594}
595
596TEST_P(QuicProxyClientSocketTest, ConnectWithAuthCredentials) {
Zhongyi Shi32f2fd02018-04-16 18:23:43597 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
598 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectAuthRequestPacket(2));
599 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55600 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
601 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52602 SYNCHRONOUS,
603 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55604
605 Initialize();
606
607 // Add auth to cache
608 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
609 const base::string16 kBar(base::ASCIIToUTF16("bar"));
610 http_auth_cache_.Add(GURL(kProxyUrl), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
611 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar),
612 "/");
613
614 AssertConnectSucceeds();
615
616 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
617 ASSERT_TRUE(response != nullptr);
618 ASSERT_EQ(200, response->headers->response_code());
619}
620
621TEST_P(QuicProxyClientSocketTest, ConnectRedirects) {
Zhongyi Shi32f2fd02018-04-16 18:23:43622 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
623 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
624 mock_quic_data_.AddRead(ASYNC,
625 ConstructServerConnectRedirectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55626 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
627 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52628 SYNCHRONOUS,
629 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55630
631 Initialize();
632
633 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
634
635 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
636 ASSERT_TRUE(response != nullptr);
637
638 const HttpResponseHeaders* headers = response->headers.get();
639 ASSERT_EQ(302, headers->response_code());
640 ASSERT_FALSE(headers->HasHeader("set-cookie"));
641 ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
642
643 std::string location;
644 ASSERT_TRUE(headers->IsRedirect(&location));
645 ASSERT_EQ(location, kRedirectUrl);
646}
647
648TEST_P(QuicProxyClientSocketTest, ConnectFails) {
Zhongyi Shi32f2fd02018-04-16 18:23:43649 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
650 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55651 mock_quic_data_.AddRead(ASYNC, 0); // EOF
652
653 Initialize();
654
655 ASSERT_FALSE(sock_->IsConnected());
656
657 AssertConnectFails(ERR_QUIC_PROTOCOL_ERROR);
658
659 ASSERT_FALSE(sock_->IsConnected());
660}
661
662TEST_P(QuicProxyClientSocketTest, WasEverUsedReturnsCorrectValue) {
Zhongyi Shi32f2fd02018-04-16 18:23:43663 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
664 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
665 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55666 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
667 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52668 SYNCHRONOUS,
669 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55670
671 Initialize();
672
673 EXPECT_TRUE(sock_->WasEverUsed()); // Used due to crypto handshake
674 AssertConnectSucceeds();
675 EXPECT_TRUE(sock_->WasEverUsed());
676 sock_->Disconnect();
677 EXPECT_TRUE(sock_->WasEverUsed());
678}
679
680TEST_P(QuicProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
Zhongyi Shi32f2fd02018-04-16 18:23:43681 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
682 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
683 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55684 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
685 mock_quic_data_.AddRead(ASYNC, 0); // EOF
686
687 Initialize();
688
689 IPEndPoint addr;
690 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
691
692 AssertConnectSucceeds();
693 EXPECT_TRUE(sock_->IsConnected());
694 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsOk());
695
696 ResumeAndRun();
697
698 EXPECT_FALSE(sock_->IsConnected());
699 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
700
701 sock_->Disconnect();
702
703 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
704}
705
706TEST_P(QuicProxyClientSocketTest, IsConnectedAndIdle) {
Zhongyi Shi32f2fd02018-04-16 18:23:43707 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
708 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
709 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55710 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
711
Zhongyi Shi32f2fd02018-04-16 18:23:43712 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
713 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55714 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52715 mock_quic_data_.AddWrite(
716 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:55717
718 Initialize();
719
720 EXPECT_FALSE(sock_->IsConnectedAndIdle());
721
722 AssertConnectSucceeds();
723
724 EXPECT_TRUE(sock_->IsConnectedAndIdle());
725
726 // The next read is consumed and buffered.
727 ResumeAndRun();
728
729 EXPECT_FALSE(sock_->IsConnectedAndIdle());
730
731 AssertSyncReadEquals(kMsg1, kLen1);
732
733 EXPECT_TRUE(sock_->IsConnectedAndIdle());
734}
735
736TEST_P(QuicProxyClientSocketTest, GetTotalReceivedBytes) {
Zhongyi Shi32f2fd02018-04-16 18:23:43737 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
738 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
739 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55740 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
741
Zhongyi Shi32f2fd02018-04-16 18:23:43742 mock_quic_data_.AddRead(ASYNC,
743 ConstructServerDataPacket(2, 0, kMsg333, kLen333));
744 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55745 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52746 mock_quic_data_.AddWrite(
747 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:55748
749 Initialize();
750
751 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
752
753 AssertConnectSucceeds();
754
755 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
756
757 // The next read is consumed and buffered.
758 ResumeAndRun();
759
760 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
761
762 // The payload from the single large data frame will be read across
763 // two different reads.
764 AssertSyncReadEquals(kMsg33, kLen33);
765
766 EXPECT_EQ((int64_t)kLen33, sock_->GetTotalReceivedBytes());
767
768 AssertSyncReadEquals(kMsg3, kLen3);
769
770 EXPECT_EQ((int64_t)kLen333, sock_->GetTotalReceivedBytes());
771}
772
Lily Chenf11e1292018-11-29 16:42:09773TEST_P(QuicProxyClientSocketTest, SetStreamPriority) {
774 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
775 mock_quic_data_.AddWrite(SYNCHRONOUS,
776 ConstructConnectRequestPacket(2, HIGHEST));
777 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
778 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
779 mock_quic_data_.AddWrite(
780 SYNCHRONOUS,
781 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
782
783 Initialize();
784
785 sock_->SetStreamPriority(HIGHEST);
786 AssertConnectSucceeds();
787}
Yixin Wang0d2c6b7e12017-08-16 21:12:55788
789TEST_P(QuicProxyClientSocketTest, WriteSendsDataInDataFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:43790 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
791 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
792 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55793 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
794 mock_quic_data_.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43795 SYNCHRONOUS, ConstructAckAndDataPacket(3, 1, 1, 1, 0, kMsg1, kLen1));
796 mock_quic_data_.AddWrite(SYNCHRONOUS,
797 ConstructDataPacket(4, kLen1, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55798 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52799 SYNCHRONOUS,
800 ConstructRstPacket(5, quic::QUIC_STREAM_CANCELLED, kLen1 + kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55801
802 Initialize();
803
804 AssertConnectSucceeds();
805
806 AssertSyncWriteSucceeds(kMsg1, kLen1);
807 AssertSyncWriteSucceeds(kMsg2, kLen2);
808}
809
810TEST_P(QuicProxyClientSocketTest, WriteSplitsLargeDataIntoMultiplePackets) {
Zhongyi Shi32f2fd02018-04-16 18:23:43811 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
812 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
813 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55814 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
815 mock_quic_data_.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43816 SYNCHRONOUS, ConstructAckAndDataPacket(3, 1, 1, 1, 0, kMsg1, kLen1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55817
818 // Expect |kNumDataPackets| data packets, each containing the max possible
819 // amount of data.
820 const int kNumDataPackets = 3;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52821 std::string data(kNumDataPackets * quic::kDefaultMaxPacketSize, 'x');
822 quic::QuicStreamOffset offset = kLen1;
Yixin Wang0d2c6b7e12017-08-16 21:12:55823 size_t total_data_length = 0;
824 for (int i = 0; i < kNumDataPackets; ++i) {
825 size_t max_packet_data_length = GetStreamFrameDataLengthFromPacketLength(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52826 quic::kDefaultMaxPacketSize, version_, !kIncludeVersion,
827 !kIncludeDiversificationNonce, quic::PACKET_8BYTE_CONNECTION_ID,
828 quic::PACKET_1BYTE_PACKET_NUMBER, offset);
Zhongyi Shi32f2fd02018-04-16 18:23:43829 mock_quic_data_.AddWrite(SYNCHRONOUS,
830 ConstructDataPacket(4 + i, offset, data.c_str(),
Yixin Wang0d2c6b7e12017-08-16 21:12:55831 max_packet_data_length));
832 offset += max_packet_data_length;
833 total_data_length += max_packet_data_length;
834 }
835 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52836 SYNCHRONOUS, ConstructRstPacket(4 + kNumDataPackets,
837 quic::QUIC_STREAM_CANCELLED, offset));
Yixin Wang0d2c6b7e12017-08-16 21:12:55838
839 Initialize();
840
841 AssertConnectSucceeds();
842
843 // Make a small write. An ACK and STOP_WAITING will be bundled. This prevents
844 // ACK and STOP_WAITING from being bundled with the subsequent large write.
845 // This allows the test code for computing the size of data sent in each
846 // packet to not become too complicated.
847 AssertSyncWriteSucceeds(kMsg1, kLen1);
848
849 // Make large write that should be split up
850 AssertSyncWriteSucceeds(data.c_str(), total_data_length);
851}
852
853// ----------- Read
854
855TEST_P(QuicProxyClientSocketTest, ReadReadsDataInDataFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:43856 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
857 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
858 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55859 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
860
Zhongyi Shi32f2fd02018-04-16 18:23:43861 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
862 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55863 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52864 mock_quic_data_.AddWrite(
865 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:55866
867 Initialize();
868
869 AssertConnectSucceeds();
870
871 ResumeAndRun();
872 AssertSyncReadEquals(kMsg1, kLen1);
873}
874
875TEST_P(QuicProxyClientSocketTest, ReadDataFromBufferedFrames) {
Zhongyi Shi32f2fd02018-04-16 18:23:43876 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
877 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
878 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55879 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
880
Zhongyi Shi32f2fd02018-04-16 18:23:43881 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
882 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55883 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
884
Zhongyi Shi32f2fd02018-04-16 18:23:43885 mock_quic_data_.AddRead(ASYNC,
886 ConstructServerDataPacket(3, kLen1, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55887 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
888
889 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52890 SYNCHRONOUS,
891 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55892
893 Initialize();
894
895 AssertConnectSucceeds();
896
897 ResumeAndRun();
898 AssertSyncReadEquals(kMsg1, kLen1);
899
900 ResumeAndRun();
901 AssertSyncReadEquals(kMsg2, kLen2);
902}
903
904TEST_P(QuicProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
Zhongyi Shi32f2fd02018-04-16 18:23:43905 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
906 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
907 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55908 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
909
Zhongyi Shi32f2fd02018-04-16 18:23:43910 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
911 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
912 mock_quic_data_.AddRead(ASYNC,
913 ConstructServerDataPacket(3, kLen1, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55914 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
915
916 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52917 SYNCHRONOUS,
918 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55919
920 Initialize();
921
922 AssertConnectSucceeds();
923
924 // The next two reads are consumed and buffered.
925 ResumeAndRun();
926
927 AssertSyncReadEquals(kMsg1, kLen1);
928 AssertSyncReadEquals(kMsg2, kLen2);
929}
930
931TEST_P(QuicProxyClientSocketTest, LargeReadWillMergeDataFromDifferentFrames) {
Zhongyi Shi32f2fd02018-04-16 18:23:43932 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
933 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
934 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55935 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
936
Zhongyi Shi32f2fd02018-04-16 18:23:43937 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg3, kLen3));
938 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
939 mock_quic_data_.AddRead(ASYNC,
940 ConstructServerDataPacket(3, kLen3, kMsg3, kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:55941 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
942
943 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52944 SYNCHRONOUS,
945 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55946
947 Initialize();
948
949 AssertConnectSucceeds();
950
951 // The next two reads are consumed and buffered.
952 ResumeAndRun();
953 // The payload from two data frames, each with kMsg3 will be combined
954 // together into a single read().
955 AssertSyncReadEquals(kMsg33, kLen33);
956}
957
958TEST_P(QuicProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
Zhongyi Shi32f2fd02018-04-16 18:23:43959 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
960 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
961 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55962 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
963
964 int offset = 0;
965
Zhongyi Shi32f2fd02018-04-16 18:23:43966 mock_quic_data_.AddRead(ASYNC,
967 ConstructServerDataPacket(2, offset, kMsg1, kLen1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55968 offset += kLen1;
Zhongyi Shi32f2fd02018-04-16 18:23:43969 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55970
Zhongyi Shi32f2fd02018-04-16 18:23:43971 mock_quic_data_.AddRead(ASYNC,
972 ConstructServerDataPacket(3, offset, kMsg3, kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:55973 offset += kLen3;
Zhongyi Shi32f2fd02018-04-16 18:23:43974 mock_quic_data_.AddRead(ASYNC,
975 ConstructServerDataPacket(4, offset, kMsg3, kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:55976 offset += kLen3;
Zhongyi Shi32f2fd02018-04-16 18:23:43977 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(4, 4, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55978
Zhongyi Shi32f2fd02018-04-16 18:23:43979 mock_quic_data_.AddRead(ASYNC,
980 ConstructServerDataPacket(5, offset, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55981 offset += kLen2;
982 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
983
984 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52985 SYNCHRONOUS,
986 ConstructAckAndRstPacket(5, quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55987
988 Initialize();
989
990 AssertConnectSucceeds();
991
992 // The next 4 reads are consumed and buffered.
993 ResumeAndRun();
994
995 AssertSyncReadEquals(kMsg1, kLen1);
996 // The payload from two data frames, each with kMsg3 will be combined
997 // together into a single read().
998 AssertSyncReadEquals(kMsg33, kLen33);
999 AssertSyncReadEquals(kMsg2, kLen2);
1000}
1001
1002TEST_P(QuicProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:431003 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1004 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1005 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551006 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1007
Zhongyi Shi32f2fd02018-04-16 18:23:431008 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
1009 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
1010 mock_quic_data_.AddRead(ASYNC,
1011 ConstructServerDataPacket(3, kLen1, kMsg33, kLen33));
Yixin Wang0d2c6b7e12017-08-16 21:12:551012 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1013
1014 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521015 SYNCHRONOUS,
1016 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551017
1018 Initialize();
1019
1020 AssertConnectSucceeds();
1021
1022 // The next 2 reads are consumed and buffered.
1023 ResumeAndRun();
1024
1025 AssertSyncReadEquals(kMsg1, kLen1);
1026 // The payload from the single large data frame will be read across
1027 // two different reads.
1028 AssertSyncReadEquals(kMsg3, kLen3);
1029 AssertSyncReadEquals(kMsg3, kLen3);
1030}
1031
1032TEST_P(QuicProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:431033 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1034 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1035 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551036 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1037
Zhongyi Shi32f2fd02018-04-16 18:23:431038 mock_quic_data_.AddRead(ASYNC,
1039 ConstructServerDataPacket(2, 0, kMsg333, kLen333));
1040 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551041 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1042
Ryan Hamilton8d9ee76e2018-05-29 23:52:521043 mock_quic_data_.AddWrite(
1044 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551045
1046 Initialize();
1047
1048 AssertConnectSucceeds();
1049
1050 // The next read is consumed and buffered.
1051 ResumeAndRun();
1052
1053 // The payload from the single large data frame will be read across
1054 // two different reads.
1055 AssertSyncReadEquals(kMsg33, kLen33);
1056
1057 // Now attempt to do a read of more data than remains buffered
Victor Costan9c7302b2018-08-27 16:39:441058 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kLen33);
Bence Békyd8a21fc32018-06-27 18:29:581059 ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, CompletionOnceCallback()));
Ryan Hamilton0239aac2018-05-19 00:03:131060 ASSERT_EQ(spdy::SpdyString(kMsg3, kLen3),
1061 spdy::SpdyString(buf->data(), kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551062 ASSERT_TRUE(sock_->IsConnected());
1063}
1064
1065TEST_P(QuicProxyClientSocketTest, ReadAuthResponseBody) {
Zhongyi Shi32f2fd02018-04-16 18:23:431066 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1067 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1068 mock_quic_data_.AddRead(ASYNC,
1069 ConstructServerConnectAuthReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551070 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1071
Zhongyi Shi32f2fd02018-04-16 18:23:431072 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
1073 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
1074 mock_quic_data_.AddRead(ASYNC,
1075 ConstructServerDataPacket(3, kLen1, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551076 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1077
1078 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521079 SYNCHRONOUS,
1080 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551081
1082 Initialize();
1083
1084 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
1085
1086 // The next two reads are consumed and buffered.
1087 ResumeAndRun();
1088
1089 AssertSyncReadEquals(kMsg1, kLen1);
1090 AssertSyncReadEquals(kMsg2, kLen2);
1091}
1092
1093TEST_P(QuicProxyClientSocketTest, ReadErrorResponseBody) {
Zhongyi Shi32f2fd02018-04-16 18:23:431094 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1095 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1096 mock_quic_data_.AddRead(ASYNC,
1097 ConstructServerConnectErrorReplyPacket(1, !kFin));
1098 mock_quic_data_.AddRead(SYNCHRONOUS,
1099 ConstructServerDataPacket(2, 0, kMsg1, kLen1));
1100 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
1101 mock_quic_data_.AddRead(SYNCHRONOUS,
1102 ConstructServerDataPacket(3, kLen1, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551103 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1104
1105 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521106 SYNCHRONOUS,
1107 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551108 Initialize();
1109
1110 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
1111}
1112
1113// ----------- Reads and Writes
1114
1115TEST_P(QuicProxyClientSocketTest, AsyncReadAroundWrite) {
Zhongyi Shi32f2fd02018-04-16 18:23:431116 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1117 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1118 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551119 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1120
Zhongyi Shi32f2fd02018-04-16 18:23:431121 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
1122 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551123
Zhongyi Shi32f2fd02018-04-16 18:23:431124 mock_quic_data_.AddWrite(SYNCHRONOUS,
1125 ConstructDataPacket(4, 0, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551126
1127 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1128
Zhongyi Shi32f2fd02018-04-16 18:23:431129 mock_quic_data_.AddRead(ASYNC,
1130 ConstructServerDataPacket(3, kLen1, kMsg3, kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551131 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1132
1133 mock_quic_data_.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431134 SYNCHRONOUS,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521135 ConstructAckAndRstPacket(5, quic::QUIC_STREAM_CANCELLED, 3, 3, 1, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551136
1137 Initialize();
1138
1139 AssertConnectSucceeds();
1140
1141 ResumeAndRun();
1142
1143 AssertSyncReadEquals(kMsg1, kLen1);
1144
1145 AssertReadStarts(kMsg3, kLen3);
1146 // Read should block until after the write succeeds.
1147
1148 AssertSyncWriteSucceeds(kMsg2, kLen2);
1149
1150 ASSERT_FALSE(read_callback_.have_result());
1151 ResumeAndRun();
1152
1153 // Now the read will return.
1154 AssertReadReturns(kMsg3, kLen3);
1155}
1156
1157TEST_P(QuicProxyClientSocketTest, AsyncWriteAroundReads) {
Zhongyi Shi32f2fd02018-04-16 18:23:431158 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1159 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1160 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551161 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1162
Zhongyi Shi32f2fd02018-04-16 18:23:431163 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
1164 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551165 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1166
Zhongyi Shi32f2fd02018-04-16 18:23:431167 mock_quic_data_.AddRead(ASYNC,
1168 ConstructServerDataPacket(3, kLen1, kMsg3, kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551169 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1170
1171 mock_quic_data_.AddWrite(ASYNC, ERR_IO_PENDING); // Pause
1172
Zhongyi Shi32f2fd02018-04-16 18:23:431173 mock_quic_data_.AddWrite(ASYNC, ConstructDataPacket(4, 0, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551174 mock_quic_data_.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431175 SYNCHRONOUS, ConstructAckAndDataPacket(5, 3, 3, 1, kLen2, kMsg2, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551176
1177 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521178 SYNCHRONOUS,
1179 ConstructRstPacket(6, quic::QUIC_STREAM_CANCELLED, kLen2 + kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551180
1181 Initialize();
1182
1183 AssertConnectSucceeds();
1184
1185 ResumeAndRun();
1186 AssertSyncReadEquals(kMsg1, kLen1);
1187
1188 // Write should block until the next read completes.
1189 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1190 // asynchronous starting with the second time it's called while the UDP socket
1191 // is write-blocked. Therefore, at least two writes need to be called on
1192 // |sock_| to get an asynchronous one.
Yixin Wangdbbd8752018-01-17 21:50:021193 AssertWriteReturns(kMsg2, kLen2, kLen2);
Yixin Wang0d2c6b7e12017-08-16 21:12:551194 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
1195
1196 AssertAsyncReadEquals(kMsg3, kLen3);
1197
1198 ASSERT_FALSE(write_callback_.have_result());
1199
1200 // Now the write will complete
1201 ResumeAndRun();
Yixin Wangdbbd8752018-01-17 21:50:021202 EXPECT_EQ(kLen2, write_callback_.WaitForResult());
Yixin Wang0d2c6b7e12017-08-16 21:12:551203}
1204
1205// ----------- Reading/Writing on Closed socket
1206
1207// Reading from an already closed socket should return 0
1208TEST_P(QuicProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
Zhongyi Shi32f2fd02018-04-16 18:23:431209 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1210 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1211 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551212 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1213
1214 mock_quic_data_.AddRead(ASYNC, 0); // EOF
1215
1216 Initialize();
1217
1218 AssertConnectSucceeds();
1219
1220 ResumeAndRun();
1221
1222 ASSERT_FALSE(sock_->IsConnected());
Bence Békyd8a21fc32018-06-27 18:29:581223 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
1224 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
1225 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551226 ASSERT_FALSE(sock_->IsConnectedAndIdle());
1227}
1228
1229// Read pending when socket is closed should return 0
1230TEST_P(QuicProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
Zhongyi Shi32f2fd02018-04-16 18:23:431231 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1232 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1233 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551234 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1235
1236 mock_quic_data_.AddRead(ASYNC, 0); // EOF
1237
1238 Initialize();
1239
1240 AssertConnectSucceeds();
1241
1242 AssertReadStarts(kMsg1, kLen1);
1243
1244 ResumeAndRun();
1245
1246 ASSERT_EQ(0, read_callback_.WaitForResult());
1247}
1248
1249// Reading from a disconnected socket is an error
1250TEST_P(QuicProxyClientSocketTest, ReadOnDisconnectSocketReturnsNotConnected) {
Zhongyi Shi32f2fd02018-04-16 18:23:431251 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1252 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1253 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551254 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1255 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521256 SYNCHRONOUS,
1257 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551258
1259 Initialize();
1260
1261 AssertConnectSucceeds();
1262
1263 sock_->Disconnect();
1264
1265 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
Bence Békyd8a21fc32018-06-27 18:29:581266 sock_->Read(nullptr, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551267}
1268
1269// Reading data after receiving FIN should return buffered data received before
1270// FIN, then 0.
1271TEST_P(QuicProxyClientSocketTest, ReadAfterFinReceivedReturnsBufferedData) {
Zhongyi Shi32f2fd02018-04-16 18:23:431272 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1273 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1274 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551275 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1276
Zhongyi Shi32f2fd02018-04-16 18:23:431277 mock_quic_data_.AddRead(ASYNC,
1278 ConstructServerDataFinPacket(2, 0, kMsg1, kLen1));
1279 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551280 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521281 mock_quic_data_.AddWrite(
1282 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551283
1284 Initialize();
1285
1286 AssertConnectSucceeds();
1287
1288 ResumeAndRun();
1289
1290 AssertSyncReadEquals(kMsg1, kLen1);
Bence Békyd8a21fc32018-06-27 18:29:581291 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
1292 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551293
1294 sock_->Disconnect();
1295 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
Bence Békyd8a21fc32018-06-27 18:29:581296 sock_->Read(nullptr, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551297}
1298
1299// Calling Write() on a closed socket is an error.
1300TEST_P(QuicProxyClientSocketTest, WriteOnClosedStream) {
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(ASYNC, ERR_IO_PENDING); // Pause
1305
1306 mock_quic_data_.AddRead(ASYNC, 0); // EOF
1307
1308 Initialize();
1309
1310 AssertConnectSucceeds();
1311
1312 ResumeAndRun();
1313
1314 AssertWriteReturns(kMsg1, kLen1, ERR_QUIC_PROTOCOL_ERROR);
1315}
1316
1317// Calling Write() on a disconnected socket is an error.
1318TEST_P(QuicProxyClientSocketTest, WriteOnDisconnectedSocket) {
Zhongyi Shi32f2fd02018-04-16 18:23:431319 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1320 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1321 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551322 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1323 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521324 SYNCHRONOUS,
1325 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551326
1327 Initialize();
1328
1329 AssertConnectSucceeds();
1330
1331 sock_->Disconnect();
1332
1333 AssertWriteReturns(kMsg1, kLen1, ERR_SOCKET_NOT_CONNECTED);
1334}
1335
1336// If the socket is closed with a pending Write(), the callback should be called
1337// with the same error the session was closed with.
1338TEST_P(QuicProxyClientSocketTest, WritePendingOnClose) {
Zhongyi Shi32f2fd02018-04-16 18:23:431339 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1340 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1341 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551342 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1343 mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
1344
1345 Initialize();
1346
1347 AssertConnectSucceeds();
1348
1349 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1350 // asynchronous starting with the second time it's called while the UDP socket
1351 // is write-blocked. Therefore, at least two writes need to be called on
1352 // |sock_| to get an asynchronous one.
Yixin Wangdbbd8752018-01-17 21:50:021353 AssertWriteReturns(kMsg1, kLen1, kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:551354
1355 // This second write will be async. This is the pending write that's being
1356 // tested.
1357 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1358
1359 // Make sure the write actually starts.
1360 base::RunLoop().RunUntilIdle();
1361
Ryan Hamilton8d9ee76e2018-05-29 23:52:521362 session_->CloseSessionOnError(ERR_CONNECTION_CLOSED,
Renjieba55fae2018-09-20 03:05:161363 quic::QUIC_INTERNAL_ERROR,
1364 quic::ConnectionCloseBehavior::SILENT_CLOSE);
Yixin Wang0d2c6b7e12017-08-16 21:12:551365
1366 EXPECT_THAT(write_callback_.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
1367}
1368
1369TEST_P(QuicProxyClientSocketTest, DisconnectWithWritePending) {
Zhongyi Shi32f2fd02018-04-16 18:23:431370 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1371 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1372 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551373 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1374 mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
1375
1376 Initialize();
1377
1378 AssertConnectSucceeds();
1379
1380 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1381 // asynchronous starting with the second time it's called while the UDP socket
1382 // is write-blocked. Therefore, at least two writes need to be called on
1383 // |sock_| to get an asynchronous one.
Yixin Wangdbbd8752018-01-17 21:50:021384 AssertWriteReturns(kMsg1, kLen1, kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:551385
1386 // This second write will be async. This is the pending write that's being
1387 // tested.
1388 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1389
1390 // Make sure the write actually starts.
1391 base::RunLoop().RunUntilIdle();
1392
1393 sock_->Disconnect();
1394 EXPECT_FALSE(sock_->IsConnected());
1395
1396 base::RunLoop().RunUntilIdle();
1397
1398 EXPECT_FALSE(sock_->IsConnected());
1399 EXPECT_FALSE(write_callback_.have_result());
1400}
1401
1402// If the socket is Disconnected with a pending Read(), the callback
1403// should not be called.
1404TEST_P(QuicProxyClientSocketTest, DisconnectWithReadPending) {
Zhongyi Shi32f2fd02018-04-16 18:23:431405 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1406 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1407 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551408 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1409 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521410 SYNCHRONOUS,
1411 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551412
1413 Initialize();
1414
1415 AssertConnectSucceeds();
1416
1417 EXPECT_TRUE(sock_->IsConnected());
1418
1419 AssertReadStarts(kMsg1, kLen1);
1420
1421 sock_->Disconnect();
1422 EXPECT_FALSE(sock_->IsConnected());
1423
1424 base::RunLoop().RunUntilIdle();
1425
1426 EXPECT_FALSE(sock_->IsConnected());
1427 EXPECT_FALSE(read_callback_.have_result());
1428}
1429
1430// If the socket is Reset when both a read and write are pending,
1431// both should be called back.
1432TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePending) {
Zhongyi Shi32f2fd02018-04-16 18:23:431433 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1434 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1435 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551436 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1437
1438 mock_quic_data_.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521439 ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang2bea3cf2017-11-09 18:11:031440 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431441 mock_quic_data_.AddWrite(
1442 ASYNC, ConstructAckAndDataPacket(3, 1, 1, 1, 0, kMsg2, kLen2));
1443 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521444 SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
1445 2, 2, 1, kLen2));
Yixin Wang0d2c6b7e12017-08-16 21:12:551446
1447 Initialize();
1448
1449 AssertConnectSucceeds();
1450
1451 EXPECT_TRUE(sock_->IsConnected());
1452
1453 AssertReadStarts(kMsg1, kLen1);
1454
1455 // Write should block until the next read completes.
1456 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1457 // asynchronous starting with the second time it's called while the UDP socket
1458 // is write-blocked. Therefore, at least two writes need to be called on
1459 // |sock_| to get an asynchronous one.
Yixin Wangdbbd8752018-01-17 21:50:021460 AssertWriteReturns(kMsg2, kLen2, kLen2);
Yixin Wang0d2c6b7e12017-08-16 21:12:551461 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
1462
1463 ResumeAndRun();
1464
1465 EXPECT_TRUE(read_callback_.have_result());
1466 EXPECT_TRUE(write_callback_.have_result());
1467}
1468
1469// Makes sure the proxy client socket's source gets the expected NetLog events
1470// and only the expected NetLog events (No SpdySession events).
1471TEST_P(QuicProxyClientSocketTest, NetLog) {
Zhongyi Shi32f2fd02018-04-16 18:23:431472 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1473 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1474 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551475 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1476
Zhongyi Shi32f2fd02018-04-16 18:23:431477 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(2, 0, kMsg1, kLen1));
1478 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang2bea3cf2017-11-09 18:11:031479 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521480 mock_quic_data_.AddWrite(
1481 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551482
1483 Initialize();
1484
1485 AssertConnectSucceeds();
1486
1487 ResumeAndRun();
1488 AssertSyncReadEquals(kMsg1, kLen1);
1489
1490 NetLogSource sock_source = sock_->NetLog().source();
1491 sock_.reset();
1492
1493 TestNetLogEntry::List entry_list;
1494 net_log_.GetEntriesForSource(sock_source, &entry_list);
1495
1496 ASSERT_EQ(entry_list.size(), 10u);
1497 EXPECT_TRUE(
1498 LogContainsBeginEvent(entry_list, 0, NetLogEventType::SOCKET_ALIVE));
1499 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1500 NetLogEventType::HTTP2_PROXY_CLIENT_SESSION,
1501 NetLogEventPhase::NONE));
1502 EXPECT_TRUE(LogContainsBeginEvent(
1503 entry_list, 2, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1504 EXPECT_TRUE(LogContainsEvent(
1505 entry_list, 3, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1506 NetLogEventPhase::NONE));
1507 EXPECT_TRUE(LogContainsEndEvent(
1508 entry_list, 4, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1509 EXPECT_TRUE(LogContainsBeginEvent(
1510 entry_list, 5, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1511 EXPECT_TRUE(LogContainsEvent(
1512 entry_list, 6,
1513 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1514 NetLogEventPhase::NONE));
1515 EXPECT_TRUE(LogContainsEndEvent(
1516 entry_list, 7, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1517 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1518 NetLogEventType::SOCKET_BYTES_RECEIVED,
1519 NetLogEventPhase::NONE));
1520 EXPECT_TRUE(
1521 LogContainsEndEvent(entry_list, 9, NetLogEventType::SOCKET_ALIVE));
1522}
1523
Bence Béky8ddc2492018-06-13 01:02:041524// A helper class that will delete |sock| when the callback is invoked.
Yixin Wang0d2c6b7e12017-08-16 21:12:551525class DeleteSockCallback : public TestCompletionCallbackBase {
1526 public:
1527 explicit DeleteSockCallback(std::unique_ptr<QuicProxyClientSocket>* sock)
Bence Béky8ddc2492018-06-13 01:02:041528 : sock_(sock) {}
Yixin Wang0d2c6b7e12017-08-16 21:12:551529
1530 ~DeleteSockCallback() override {}
1531
Bence Béky8ddc2492018-06-13 01:02:041532 CompletionOnceCallback callback() {
1533 return base::BindOnce(&DeleteSockCallback::OnComplete,
1534 base::Unretained(this));
1535 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551536
1537 private:
1538 void OnComplete(int result) {
1539 sock_->reset(NULL);
1540 SetResult(result);
1541 }
1542
1543 std::unique_ptr<QuicProxyClientSocket>* sock_;
Yixin Wang0d2c6b7e12017-08-16 21:12:551544
1545 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1546};
1547
1548// If the socket is reset when both a read and write are pending, and the
1549// read callback causes the socket to be deleted, the write callback should
1550// not be called.
1551TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
Zhongyi Shi32f2fd02018-04-16 18:23:431552 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1553 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1554 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551555 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1556
1557 mock_quic_data_.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521558 ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551559 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431560 mock_quic_data_.AddWrite(
1561 ASYNC, ConstructAckAndDataPacket(3, 1, 1, 1, 0, kMsg1, kLen1));
1562 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521563 SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
1564 2, 2, 1, kLen1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551565
1566 Initialize();
1567
1568 AssertConnectSucceeds();
1569
1570 EXPECT_TRUE(sock_->IsConnected());
1571
1572 DeleteSockCallback read_callback(&sock_);
Victor Costan9c7302b2018-08-27 16:39:441573 scoped_refptr<IOBuffer> read_buf = base::MakeRefCounted<IOBuffer>(kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:551574 ASSERT_EQ(ERR_IO_PENDING,
1575 sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
1576
1577 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1578 // asynchronous starting with the second time it's called while the UDP socket
1579 // is write-blocked. Therefore, at least two writes need to be called on
1580 // |sock_| to get an asynchronous one.
Yixin Wangdbbd8752018-01-17 21:50:021581 AssertWriteReturns(kMsg1, kLen1, kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:551582 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1583
1584 ResumeAndRun();
1585
1586 EXPECT_FALSE(sock_.get());
1587
1588 EXPECT_EQ(0, read_callback.WaitForResult());
1589 EXPECT_FALSE(write_callback_.have_result());
1590}
1591
Yixin Wang079ad542018-01-11 04:06:051592INSTANTIATE_TEST_CASE_P(
Bence Békyce380cb2018-04-26 23:39:551593 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051594 QuicProxyClientSocketTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521595 ::testing::Combine(
1596 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
1597 ::testing::Bool()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551598
1599} // namespace test
Dan Zhangf11470172017-09-18 22:02:091600} // namespace net