blob: 66fd2c9c82eb5ac0c2ae897e534e02bab7cb7c33 [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_) +
Fan Yang32c5a112018-12-10 20:06:33113 quic::QuicUtils::StreamIdDelta(version_)),
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()),
Fan Yang32c5a112018-12-10 20:06:33117 connection_id_(quic::QuicConnectionIdFromUInt64(2)),
Yixin Wang0d2c6b7e12017-08-16 21:12:55118 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,
Renjief49758b2019-01-11 23:32:41326 quic::QuicStringPiece data) {
Ryan Hamilton47cf9d12018-10-17 04:33:09327 return client_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
Renjief49758b2019-01-11 23:32:41328 !kIncludeVersion, !kFin, offset, data);
Yixin Wang0d2c6b7e12017-08-16 21:12:55329 }
330
Ryan Hamilton8d9ee76e2018-05-29 23:52:52331 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndDataPacket(
332 quic::QuicPacketNumber packet_number,
333 quic::QuicPacketNumber largest_received,
334 quic::QuicPacketNumber smallest_received,
335 quic::QuicPacketNumber least_unacked,
336 quic::QuicStreamOffset offset,
Renjief49758b2019-01-11 23:32:41337 quic::QuicStringPiece data) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55338 return client_maker_.MakeAckAndDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09339 packet_number, !kIncludeVersion, client_data_stream_id1_,
340 largest_received, smallest_received, least_unacked, !kFin, offset,
Renjief49758b2019-01-11 23:32:41341 data);
Yixin Wang0d2c6b7e12017-08-16 21:12:55342 }
343
Ryan Hamilton8d9ee76e2018-05-29 23:52:52344 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckPacket(
345 quic::QuicPacketNumber packet_number,
346 quic::QuicPacketNumber largest_received,
347 quic::QuicPacketNumber smallest_received,
348 quic::QuicPacketNumber least_unacked) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55349 return client_maker_.MakeAckPacket(packet_number, largest_received,
350 smallest_received, least_unacked,
351 kSendFeedback);
352 }
353
354 // Helper functions for constructing packets sent by the server
355
Ryan Hamilton8d9ee76e2018-05-29 23:52:52356 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerRstPacket(
357 quic::QuicPacketNumber packet_number,
358 quic::QuicRstStreamErrorCode error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55359 size_t bytes_written) {
360 return server_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton47cf9d12018-10-17 04:33:09361 client_data_stream_id1_, error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55362 bytes_written);
363 }
364
Ryan Hamilton8d9ee76e2018-05-29 23:52:52365 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
366 quic::QuicPacketNumber packet_number,
367 quic::QuicStreamOffset offset,
Renjief49758b2019-01-11 23:32:41368 quic::QuicStringPiece data) {
Ryan Hamilton47cf9d12018-10-17 04:33:09369 return server_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
Renjief49758b2019-01-11 23:32:41370 !kIncludeVersion, !kFin, offset, data);
Yixin Wang0d2c6b7e12017-08-16 21:12:55371 }
372
Ryan Hamilton8d9ee76e2018-05-29 23:52:52373 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataFinPacket(
374 quic::QuicPacketNumber packet_number,
375 quic::QuicStreamOffset offset,
Renjief49758b2019-01-11 23:32:41376 quic::QuicStringPiece data) {
Ryan Hamilton47cf9d12018-10-17 04:33:09377 return server_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
Renjief49758b2019-01-11 23:32:41378 !kIncludeVersion, kFin, offset, data);
Yixin Wang0d2c6b7e12017-08-16 21:12:55379 }
380
Ryan Hamilton8d9ee76e2018-05-29 23:52:52381 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerConnectReplyPacket(
382 quic::QuicPacketNumber packet_number,
Yixin Wang0d2c6b7e12017-08-16 21:12:55383 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13384 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55385 block[":status"] = "200";
386
387 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09388 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Yixin Wang0d2c6b7e12017-08-16 21:12:55389 std::move(block), nullptr, &response_offset_);
390 }
391
Ryan Hamilton8d9ee76e2018-05-29 23:52:52392 std::unique_ptr<quic::QuicReceivedPacket>
393 ConstructServerConnectAuthReplyPacket(quic::QuicPacketNumber packet_number,
394 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13395 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55396 block[":status"] = "407";
397 block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
398 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09399 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Yixin Wang0d2c6b7e12017-08-16 21:12:55400 std::move(block), nullptr, &response_offset_);
401 }
402
Ryan Hamilton8d9ee76e2018-05-29 23:52:52403 std::unique_ptr<quic::QuicReceivedPacket>
404 ConstructServerConnectRedirectReplyPacket(
405 quic::QuicPacketNumber packet_number,
Yixin Wang0d2c6b7e12017-08-16 21:12:55406 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13407 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55408 block[":status"] = "302";
409 block["location"] = kRedirectUrl;
410 block["set-cookie"] = "foo=bar";
411 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09412 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Yixin Wang0d2c6b7e12017-08-16 21:12:55413 std::move(block), nullptr, &response_offset_);
414 }
415
Ryan Hamilton8d9ee76e2018-05-29 23:52:52416 std::unique_ptr<quic::QuicReceivedPacket>
417 ConstructServerConnectErrorReplyPacket(quic::QuicPacketNumber packet_number,
418 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13419 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55420 block[":status"] = "500";
421
422 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09423 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Yixin Wang0d2c6b7e12017-08-16 21:12:55424 std::move(block), nullptr, &response_offset_);
425 }
426
427 void AssertConnectSucceeds() {
428 TestCompletionCallback callback;
429 ASSERT_THAT(sock_->Connect(callback.callback()), IsError(ERR_IO_PENDING));
430 ASSERT_THAT(callback.WaitForResult(), IsOk());
431 }
432
433 void AssertConnectFails(int result) {
434 TestCompletionCallback callback;
435 ASSERT_THAT(sock_->Connect(callback.callback()), IsError(ERR_IO_PENDING));
436 ASSERT_EQ(result, callback.WaitForResult());
437 }
438
439 void ResumeAndRun() {
440 // Run until the pause, if the provider isn't paused yet.
441 SequencedSocketData* data = mock_quic_data_.GetSequencedSocketData();
442 data->RunUntilPaused();
443 data->Resume();
444 base::RunLoop().RunUntilIdle();
445 }
446
447 void AssertWriteReturns(const char* data, int len, int rv) {
Victor Costan9c7302b2018-08-27 16:39:44448 scoped_refptr<IOBufferWithSize> buf =
449 base::MakeRefCounted<IOBufferWithSize>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55450 memcpy(buf->data(), data, len);
451 EXPECT_EQ(rv,
[email protected]578968d42017-12-13 15:39:32452 sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
453 TRAFFIC_ANNOTATION_FOR_TESTS));
Yixin Wang0d2c6b7e12017-08-16 21:12:55454 }
455
456 void AssertSyncWriteSucceeds(const char* data, int len) {
Victor Costan9c7302b2018-08-27 16:39:44457 scoped_refptr<IOBufferWithSize> buf =
458 base::MakeRefCounted<IOBufferWithSize>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55459 memcpy(buf->data(), data, len);
Bence Békyd8a21fc32018-06-27 18:29:58460 EXPECT_EQ(len,
461 sock_->Write(buf.get(), buf->size(), CompletionOnceCallback(),
462 TRAFFIC_ANNOTATION_FOR_TESTS));
Yixin Wang0d2c6b7e12017-08-16 21:12:55463 }
464
465 void AssertSyncReadEquals(const char* data, int len) {
Victor Costan9c7302b2018-08-27 16:39:44466 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(len);
Bence Békyd8a21fc32018-06-27 18:29:58467 ASSERT_EQ(len, sock_->Read(buf.get(), len, CompletionOnceCallback()));
Ryan Hamilton0239aac2018-05-19 00:03:13468 ASSERT_EQ(spdy::SpdyString(data, len), spdy::SpdyString(buf->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55469 ASSERT_TRUE(sock_->IsConnected());
470 }
471
472 void AssertAsyncReadEquals(const char* data, int len) {
Victor Costan9c7302b2018-08-27 16:39:44473 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55474 ASSERT_EQ(ERR_IO_PENDING,
475 sock_->Read(buf.get(), len, read_callback_.callback()));
476 EXPECT_TRUE(sock_->IsConnected());
477
478 ResumeAndRun();
479
480 EXPECT_EQ(len, read_callback_.WaitForResult());
481 EXPECT_TRUE(sock_->IsConnected());
Ryan Hamilton0239aac2018-05-19 00:03:13482 ASSERT_EQ(spdy::SpdyString(data, len), spdy::SpdyString(buf->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55483 }
484
485 void AssertReadStarts(const char* data, int len) {
486 // Issue the read, which will be completed asynchronously.
Victor Costan9c7302b2018-08-27 16:39:44487 read_buf_ = base::MakeRefCounted<IOBuffer>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55488 ASSERT_EQ(ERR_IO_PENDING,
489 sock_->Read(read_buf_.get(), len, read_callback_.callback()));
490 EXPECT_TRUE(sock_->IsConnected());
491 }
492
493 void AssertReadReturns(const char* data, int len) {
494 EXPECT_TRUE(sock_->IsConnected());
495
496 // Now the read will return.
497 EXPECT_EQ(len, read_callback_.WaitForResult());
Ryan Hamilton0239aac2018-05-19 00:03:13498 ASSERT_EQ(spdy::SpdyString(data, len),
499 spdy::SpdyString(read_buf_->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55500 }
501
Renjief49758b2019-01-11 23:32:41502 quic::QuicString ConstructDataHeader(size_t body_len) {
503 if (version_ != quic::QUIC_VERSION_99) {
504 return "";
505 }
506 quic::HttpEncoder encoder;
507 std::unique_ptr<char[]> buffer;
508 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
509 return quic::QuicString(buffer.get(), header_length);
510 }
511
Ryan Hamilton8d9ee76e2018-05-29 23:52:52512 const quic::QuicTransportVersion version_;
Ryan Hamilton47cf9d12018-10-17 04:33:09513 const quic::QuicStreamId client_data_stream_id1_;
Yixin Wang079ad542018-01-11 04:06:05514 const bool client_headers_include_h2_stream_dependency_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55515
516 // order of destruction of these members matter
Ryan Hamilton8d9ee76e2018-05-29 23:52:52517 quic::MockClock clock_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55518 MockQuicData mock_quic_data_;
519 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
520 std::unique_ptr<QuicChromiumClientSession> session_;
521 std::unique_ptr<QuicChromiumClientSession::Handle> session_handle_;
522 std::unique_ptr<QuicProxyClientSocket> sock_;
523
524 BoundTestNetLog net_log_;
525
Ryan Hamilton8d9ee76e2018-05-29 23:52:52526 quic::test::MockSendAlgorithm* send_algorithm_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55527 scoped_refptr<TestTaskRunner> runner_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55528
529 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52530 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55531 TransportSecurityState transport_security_state_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52532 quic::QuicCryptoClientConfig crypto_config_;
533 quic::QuicClientPushPromiseIndex push_promise_index_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55534
Ryan Hamilton8d9ee76e2018-05-29 23:52:52535 const quic::QuicConnectionId connection_id_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55536 QuicTestPacketMaker client_maker_;
537 QuicTestPacketMaker server_maker_;
538 IPEndPoint peer_addr_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52539 quic::test::MockRandom random_generator_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55540 ProofVerifyDetailsChromium verify_details_;
541 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52542 quic::QuicStreamOffset header_stream_offset_;
543 quic::QuicStreamOffset response_offset_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55544
545 std::string user_agent_;
546 HostPortPair proxy_host_port_;
547 HostPortPair endpoint_host_port_;
548 HttpAuthCache http_auth_cache_;
549 std::unique_ptr<MockHostResolverBase> host_resolver_;
550 std::unique_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory_;
551
552 TestCompletionCallback read_callback_;
553 scoped_refptr<IOBuffer> read_buf_;
554
555 TestCompletionCallback write_callback_;
556
557 DISALLOW_COPY_AND_ASSIGN(QuicProxyClientSocketTest);
558};
559
560TEST_P(QuicProxyClientSocketTest, ConnectSendsCorrectRequest) {
Zhongyi Shi32f2fd02018-04-16 18:23:43561 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
562 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
563 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55564 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
565 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52566 SYNCHRONOUS,
567 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55568
569 Initialize();
570
571 ASSERT_FALSE(sock_->IsConnected());
572
573 AssertConnectSucceeds();
574
575 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
576 ASSERT_TRUE(response != nullptr);
577 ASSERT_EQ(200, response->headers->response_code());
578}
579
580TEST_P(QuicProxyClientSocketTest, ConnectWithAuthRequested) {
Zhongyi Shi32f2fd02018-04-16 18:23:43581 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
582 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
583 mock_quic_data_.AddRead(ASYNC,
584 ConstructServerConnectAuthReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55585 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
586 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52587 SYNCHRONOUS,
588 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55589
590 Initialize();
591
592 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
593
594 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
595 ASSERT_TRUE(response != nullptr);
596 ASSERT_EQ(407, response->headers->response_code());
597}
598
599TEST_P(QuicProxyClientSocketTest, ConnectWithAuthCredentials) {
Zhongyi Shi32f2fd02018-04-16 18:23:43600 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
601 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectAuthRequestPacket(2));
602 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55603 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
604 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52605 SYNCHRONOUS,
606 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55607
608 Initialize();
609
610 // Add auth to cache
611 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
612 const base::string16 kBar(base::ASCIIToUTF16("bar"));
613 http_auth_cache_.Add(GURL(kProxyUrl), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
614 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar),
615 "/");
616
617 AssertConnectSucceeds();
618
619 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
620 ASSERT_TRUE(response != nullptr);
621 ASSERT_EQ(200, response->headers->response_code());
622}
623
624TEST_P(QuicProxyClientSocketTest, ConnectRedirects) {
Zhongyi Shi32f2fd02018-04-16 18:23:43625 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
626 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
627 mock_quic_data_.AddRead(ASYNC,
628 ConstructServerConnectRedirectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55629 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
630 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52631 SYNCHRONOUS,
632 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55633
634 Initialize();
635
636 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
637
638 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
639 ASSERT_TRUE(response != nullptr);
640
641 const HttpResponseHeaders* headers = response->headers.get();
642 ASSERT_EQ(302, headers->response_code());
643 ASSERT_FALSE(headers->HasHeader("set-cookie"));
644 ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
645
646 std::string location;
647 ASSERT_TRUE(headers->IsRedirect(&location));
648 ASSERT_EQ(location, kRedirectUrl);
649}
650
651TEST_P(QuicProxyClientSocketTest, ConnectFails) {
Zhongyi Shi32f2fd02018-04-16 18:23:43652 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
653 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55654 mock_quic_data_.AddRead(ASYNC, 0); // EOF
655
656 Initialize();
657
658 ASSERT_FALSE(sock_->IsConnected());
659
660 AssertConnectFails(ERR_QUIC_PROTOCOL_ERROR);
661
662 ASSERT_FALSE(sock_->IsConnected());
663}
664
665TEST_P(QuicProxyClientSocketTest, WasEverUsedReturnsCorrectValue) {
Zhongyi Shi32f2fd02018-04-16 18:23:43666 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
667 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
668 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55669 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
670 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52671 SYNCHRONOUS,
672 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55673
674 Initialize();
675
676 EXPECT_TRUE(sock_->WasEverUsed()); // Used due to crypto handshake
677 AssertConnectSucceeds();
678 EXPECT_TRUE(sock_->WasEverUsed());
679 sock_->Disconnect();
680 EXPECT_TRUE(sock_->WasEverUsed());
681}
682
683TEST_P(QuicProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
Zhongyi Shi32f2fd02018-04-16 18:23:43684 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
685 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
686 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55687 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
688 mock_quic_data_.AddRead(ASYNC, 0); // EOF
689
690 Initialize();
691
692 IPEndPoint addr;
693 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
694
695 AssertConnectSucceeds();
696 EXPECT_TRUE(sock_->IsConnected());
697 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsOk());
698
699 ResumeAndRun();
700
701 EXPECT_FALSE(sock_->IsConnected());
702 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
703
704 sock_->Disconnect();
705
706 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
707}
708
709TEST_P(QuicProxyClientSocketTest, IsConnectedAndIdle) {
Zhongyi Shi32f2fd02018-04-16 18:23:43710 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
711 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
712 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55713 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
714
Renjief49758b2019-01-11 23:32:41715 quic::QuicString header = ConstructDataHeader(kLen1);
716 mock_quic_data_.AddRead(
717 ASYNC,
718 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:43719 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55720 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52721 mock_quic_data_.AddWrite(
722 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:55723
724 Initialize();
725
726 EXPECT_FALSE(sock_->IsConnectedAndIdle());
727
728 AssertConnectSucceeds();
729
730 EXPECT_TRUE(sock_->IsConnectedAndIdle());
731
732 // The next read is consumed and buffered.
733 ResumeAndRun();
734
735 EXPECT_FALSE(sock_->IsConnectedAndIdle());
736
737 AssertSyncReadEquals(kMsg1, kLen1);
738
739 EXPECT_TRUE(sock_->IsConnectedAndIdle());
740}
741
742TEST_P(QuicProxyClientSocketTest, GetTotalReceivedBytes) {
Zhongyi Shi32f2fd02018-04-16 18:23:43743 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
744 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
745 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55746 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
747
Renjief49758b2019-01-11 23:32:41748 quic::QuicString header = ConstructDataHeader(kLen333);
749 mock_quic_data_.AddRead(
750 ASYNC, ConstructServerDataPacket(
751 2, 0, header + quic::QuicString(kMsg333, kLen333)));
Zhongyi Shi32f2fd02018-04-16 18:23:43752 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55753 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52754 mock_quic_data_.AddWrite(
755 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:55756
757 Initialize();
758
759 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
760
761 AssertConnectSucceeds();
762
763 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
764
765 // The next read is consumed and buffered.
766 ResumeAndRun();
767
768 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
769
770 // The payload from the single large data frame will be read across
771 // two different reads.
772 AssertSyncReadEquals(kMsg33, kLen33);
773
Renjief49758b2019-01-11 23:32:41774 EXPECT_EQ((int64_t)(kLen33 + header.length()),
775 sock_->GetTotalReceivedBytes());
Yixin Wang0d2c6b7e12017-08-16 21:12:55776
777 AssertSyncReadEquals(kMsg3, kLen3);
778
Renjief49758b2019-01-11 23:32:41779 EXPECT_EQ((int64_t)(kLen333 + header.length()),
780 sock_->GetTotalReceivedBytes());
Yixin Wang0d2c6b7e12017-08-16 21:12:55781}
782
Lily Chenf11e1292018-11-29 16:42:09783TEST_P(QuicProxyClientSocketTest, SetStreamPriority) {
784 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
785 mock_quic_data_.AddWrite(SYNCHRONOUS,
786 ConstructConnectRequestPacket(2, HIGHEST));
787 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
788 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
789 mock_quic_data_.AddWrite(
790 SYNCHRONOUS,
791 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
792
793 Initialize();
794
795 sock_->SetStreamPriority(HIGHEST);
796 AssertConnectSucceeds();
797}
Yixin Wang0d2c6b7e12017-08-16 21:12:55798
799TEST_P(QuicProxyClientSocketTest, WriteSendsDataInDataFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:43800 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
801 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
802 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55803 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjief49758b2019-01-11 23:32:41804 if (version_ == quic::QUIC_VERSION_99) {
805 quic::QuicString header = ConstructDataHeader(kLen1);
806 mock_quic_data_.AddWrite(SYNCHRONOUS,
807 ConstructAckAndDataPacket(3, 1, 1, 1, 0, header));
808 mock_quic_data_.AddWrite(
809 SYNCHRONOUS, ConstructDataPacket(4, header.length(),
810 quic::QuicString(kMsg1, kLen1)));
811 quic::QuicString header2 = ConstructDataHeader(kLen2);
812 mock_quic_data_.AddWrite(
813 SYNCHRONOUS, ConstructDataPacket(5, kLen1 + header.length(), header2));
814 mock_quic_data_.AddWrite(
815 SYNCHRONOUS,
816 ConstructDataPacket(6, kLen1 + header.length() + header2.length(),
817 quic::QuicString(kMsg2, kLen2)));
818 mock_quic_data_.AddWrite(
819 SYNCHRONOUS,
820 ConstructRstPacket(7, quic::QUIC_STREAM_CANCELLED,
821 kLen1 + kLen2 + header.length() + header2.length()));
822 } else {
823 mock_quic_data_.AddWrite(
824 SYNCHRONOUS, ConstructAckAndDataPacket(3, 1, 1, 1, 0,
825 quic::QuicString(kMsg1, kLen1)));
826 mock_quic_data_.AddWrite(
827 SYNCHRONOUS,
828 ConstructDataPacket(4, kLen1, quic::QuicString(kMsg2, kLen2)));
829 mock_quic_data_.AddWrite(
830 SYNCHRONOUS,
831 ConstructRstPacket(5, quic::QUIC_STREAM_CANCELLED, kLen1 + kLen2));
832 }
Yixin Wang0d2c6b7e12017-08-16 21:12:55833
834 Initialize();
835
836 AssertConnectSucceeds();
837
838 AssertSyncWriteSucceeds(kMsg1, kLen1);
839 AssertSyncWriteSucceeds(kMsg2, kLen2);
840}
841
842TEST_P(QuicProxyClientSocketTest, WriteSplitsLargeDataIntoMultiplePackets) {
Renjief49758b2019-01-11 23:32:41843 int write_packet_index = 1;
844 mock_quic_data_.AddWrite(SYNCHRONOUS,
845 ConstructSettingsPacket(write_packet_index++));
846 mock_quic_data_.AddWrite(SYNCHRONOUS,
847 ConstructConnectRequestPacket(write_packet_index++));
Zhongyi Shi32f2fd02018-04-16 18:23:43848 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55849 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjief49758b2019-01-11 23:32:41850 quic::QuicString header = ConstructDataHeader(kLen1);
851 if (version_ != quic::QUIC_VERSION_99) {
852 mock_quic_data_.AddWrite(
853 SYNCHRONOUS, ConstructAckAndDataPacket(write_packet_index++, 1, 1, 1, 0,
854 quic::QuicString(kMsg1, kLen1)));
855 } else {
856 mock_quic_data_.AddWrite(
857 SYNCHRONOUS,
858 ConstructAckAndDataPacket(write_packet_index++, 1, 1, 1, 0, header));
859 mock_quic_data_.AddWrite(
860 SYNCHRONOUS, ConstructDataPacket(write_packet_index++, header.length(),
861 quic::QuicString(kMsg1, kLen1)));
862 }
Yixin Wang0d2c6b7e12017-08-16 21:12:55863
864 // Expect |kNumDataPackets| data packets, each containing the max possible
865 // amount of data.
866 const int kNumDataPackets = 3;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52867 std::string data(kNumDataPackets * quic::kDefaultMaxPacketSize, 'x');
Renjief49758b2019-01-11 23:32:41868 quic::QuicStreamOffset offset = kLen1 + header.length();
Yixin Wang0d2c6b7e12017-08-16 21:12:55869 size_t total_data_length = 0;
Renjief49758b2019-01-11 23:32:41870 if (version_ == quic::QUIC_VERSION_99) {
871 // 3973 is the data frame length from packet length.
872 quic::QuicString header2 = ConstructDataHeader(3973);
873 mock_quic_data_.AddWrite(
874 SYNCHRONOUS,
875 ConstructDataPacket(write_packet_index++, offset, header2));
876 offset += header2.length();
877 }
Yixin Wang0d2c6b7e12017-08-16 21:12:55878 for (int i = 0; i < kNumDataPackets; ++i) {
879 size_t max_packet_data_length = GetStreamFrameDataLengthFromPacketLength(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52880 quic::kDefaultMaxPacketSize, version_, !kIncludeVersion,
881 !kIncludeDiversificationNonce, quic::PACKET_8BYTE_CONNECTION_ID,
882 quic::PACKET_1BYTE_PACKET_NUMBER, offset);
Renjief49758b2019-01-11 23:32:41883 mock_quic_data_.AddWrite(
884 SYNCHRONOUS,
885 ConstructDataPacket(
886 write_packet_index++, offset,
887 quic::QuicString(data.c_str(), max_packet_data_length)));
Yixin Wang0d2c6b7e12017-08-16 21:12:55888 offset += max_packet_data_length;
889 total_data_length += max_packet_data_length;
890 }
891 mock_quic_data_.AddWrite(
Renjief49758b2019-01-11 23:32:41892 SYNCHRONOUS, ConstructRstPacket(write_packet_index++,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52893 quic::QUIC_STREAM_CANCELLED, offset));
Yixin Wang0d2c6b7e12017-08-16 21:12:55894
895 Initialize();
896
897 AssertConnectSucceeds();
898
899 // Make a small write. An ACK and STOP_WAITING will be bundled. This prevents
900 // ACK and STOP_WAITING from being bundled with the subsequent large write.
901 // This allows the test code for computing the size of data sent in each
902 // packet to not become too complicated.
903 AssertSyncWriteSucceeds(kMsg1, kLen1);
904
905 // Make large write that should be split up
906 AssertSyncWriteSucceeds(data.c_str(), total_data_length);
907}
908
909// ----------- Read
910
911TEST_P(QuicProxyClientSocketTest, ReadReadsDataInDataFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:43912 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
913 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
914 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55915 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
916
Renjief49758b2019-01-11 23:32:41917 quic::QuicString header = ConstructDataHeader(kLen1);
918 mock_quic_data_.AddRead(
919 ASYNC,
920 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:43921 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55922 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52923 mock_quic_data_.AddWrite(
924 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:55925
926 Initialize();
927
928 AssertConnectSucceeds();
929
930 ResumeAndRun();
931 AssertSyncReadEquals(kMsg1, kLen1);
932}
933
934TEST_P(QuicProxyClientSocketTest, ReadDataFromBufferedFrames) {
Zhongyi Shi32f2fd02018-04-16 18:23:43935 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
936 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
937 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55938 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
939
Renjief49758b2019-01-11 23:32:41940 quic::QuicString header = ConstructDataHeader(kLen1);
941 mock_quic_data_.AddRead(
942 ASYNC,
943 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:43944 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55945 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
946
Renjief49758b2019-01-11 23:32:41947 quic::QuicString header2 = ConstructDataHeader(kLen2);
948 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
949 3, kLen1 + header.length(),
950 header2 + quic::QuicString(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:55951 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
952
953 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52954 SYNCHRONOUS,
955 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55956
957 Initialize();
958
959 AssertConnectSucceeds();
960
961 ResumeAndRun();
962 AssertSyncReadEquals(kMsg1, kLen1);
963
964 ResumeAndRun();
965 AssertSyncReadEquals(kMsg2, kLen2);
966}
967
968TEST_P(QuicProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
Zhongyi Shi32f2fd02018-04-16 18:23:43969 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
970 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
971 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55972 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
973
Renjief49758b2019-01-11 23:32:41974 quic::QuicString header = ConstructDataHeader(kLen1);
975 mock_quic_data_.AddRead(
976 ASYNC,
977 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:43978 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:41979 quic::QuicString header2 = ConstructDataHeader(kLen2);
980 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
981 3, kLen1 + header.length(),
982 header2 + quic::QuicString(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:55983 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
984
985 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52986 SYNCHRONOUS,
987 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55988
989 Initialize();
990
991 AssertConnectSucceeds();
992
993 // The next two reads are consumed and buffered.
994 ResumeAndRun();
995
996 AssertSyncReadEquals(kMsg1, kLen1);
997 AssertSyncReadEquals(kMsg2, kLen2);
998}
999
1000TEST_P(QuicProxyClientSocketTest, LargeReadWillMergeDataFromDifferentFrames) {
Zhongyi Shi32f2fd02018-04-16 18:23:431001 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1002 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1003 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551004 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1005
Renjief49758b2019-01-11 23:32:411006 quic::QuicString header = ConstructDataHeader(kLen3);
1007 mock_quic_data_.AddRead(
1008 ASYNC,
1009 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg3, kLen3)));
Zhongyi Shi32f2fd02018-04-16 18:23:431010 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:411011 quic::QuicString header2 = ConstructDataHeader(kLen3);
1012 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
1013 3, kLen3 + header.length(),
1014 header2 + quic::QuicString(kMsg3, kLen3)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551015 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1016
1017 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521018 SYNCHRONOUS,
1019 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551020
1021 Initialize();
1022
1023 AssertConnectSucceeds();
1024
1025 // The next two reads are consumed and buffered.
1026 ResumeAndRun();
1027 // The payload from two data frames, each with kMsg3 will be combined
1028 // together into a single read().
1029 AssertSyncReadEquals(kMsg33, kLen33);
1030}
1031
1032TEST_P(QuicProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
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
1038 int offset = 0;
1039
Renjief49758b2019-01-11 23:32:411040 quic::QuicString header = ConstructDataHeader(kLen1);
1041 mock_quic_data_.AddRead(
1042 ASYNC, ConstructServerDataPacket(
1043 2, offset, header + quic::QuicString(kMsg1, kLen1)));
1044 offset += kLen1 + header.length();
Zhongyi Shi32f2fd02018-04-16 18:23:431045 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551046
Renjief49758b2019-01-11 23:32:411047 quic::QuicString header2 = ConstructDataHeader(kLen3);
1048 mock_quic_data_.AddRead(
1049 ASYNC, ConstructServerDataPacket(
1050 3, offset, header2 + quic::QuicString(kMsg3, kLen3)));
1051 offset += kLen3 + header2.length();
1052 mock_quic_data_.AddRead(
1053 ASYNC, ConstructServerDataPacket(
1054 4, offset, header2 + quic::QuicString(kMsg3, kLen3)));
1055 offset += kLen3 + header2.length();
Zhongyi Shi32f2fd02018-04-16 18:23:431056 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(4, 4, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551057
Renjief49758b2019-01-11 23:32:411058 quic::QuicString header3 = ConstructDataHeader(kLen2);
1059 mock_quic_data_.AddRead(
1060 ASYNC, ConstructServerDataPacket(
1061 5, offset, header3 + quic::QuicString(kMsg2, kLen2)));
1062 offset += kLen2 + header3.length();
Yixin Wang0d2c6b7e12017-08-16 21:12:551063 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1064
1065 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521066 SYNCHRONOUS,
1067 ConstructAckAndRstPacket(5, quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551068
1069 Initialize();
1070
1071 AssertConnectSucceeds();
1072
1073 // The next 4 reads are consumed and buffered.
1074 ResumeAndRun();
1075
1076 AssertSyncReadEquals(kMsg1, kLen1);
1077 // The payload from two data frames, each with kMsg3 will be combined
1078 // together into a single read().
1079 AssertSyncReadEquals(kMsg33, kLen33);
1080 AssertSyncReadEquals(kMsg2, kLen2);
1081}
1082
1083TEST_P(QuicProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:431084 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1085 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1086 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551087 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1088
Renjief49758b2019-01-11 23:32:411089 quic::QuicString header = ConstructDataHeader(kLen1);
1090 mock_quic_data_.AddRead(
1091 ASYNC,
1092 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431093 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:411094 quic::QuicString header2 = ConstructDataHeader(kLen33);
1095 mock_quic_data_.AddRead(
1096 ASYNC,
1097 ConstructServerDataPacket(3, kLen1 + header.length(),
1098 header2 + quic::QuicString(kMsg33, kLen33)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551099 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1100
1101 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521102 SYNCHRONOUS,
1103 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551104
1105 Initialize();
1106
1107 AssertConnectSucceeds();
1108
1109 // The next 2 reads are consumed and buffered.
1110 ResumeAndRun();
1111
1112 AssertSyncReadEquals(kMsg1, kLen1);
1113 // The payload from the single large data frame will be read across
1114 // two different reads.
1115 AssertSyncReadEquals(kMsg3, kLen3);
1116 AssertSyncReadEquals(kMsg3, kLen3);
1117}
1118
1119TEST_P(QuicProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:431120 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1121 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1122 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551123 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1124
Renjief49758b2019-01-11 23:32:411125 quic::QuicString header = ConstructDataHeader(kLen333);
1126 mock_quic_data_.AddRead(
1127 ASYNC, ConstructServerDataPacket(
1128 2, 0, header + quic::QuicString(kMsg333, kLen333)));
Zhongyi Shi32f2fd02018-04-16 18:23:431129 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551130 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1131
Ryan Hamilton8d9ee76e2018-05-29 23:52:521132 mock_quic_data_.AddWrite(
1133 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551134
1135 Initialize();
1136
1137 AssertConnectSucceeds();
1138
1139 // The next read is consumed and buffered.
1140 ResumeAndRun();
1141
1142 // The payload from the single large data frame will be read across
1143 // two different reads.
1144 AssertSyncReadEquals(kMsg33, kLen33);
1145
1146 // Now attempt to do a read of more data than remains buffered
Victor Costan9c7302b2018-08-27 16:39:441147 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kLen33);
Bence Békyd8a21fc32018-06-27 18:29:581148 ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, CompletionOnceCallback()));
Ryan Hamilton0239aac2018-05-19 00:03:131149 ASSERT_EQ(spdy::SpdyString(kMsg3, kLen3),
1150 spdy::SpdyString(buf->data(), kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551151 ASSERT_TRUE(sock_->IsConnected());
1152}
1153
1154TEST_P(QuicProxyClientSocketTest, ReadAuthResponseBody) {
Zhongyi Shi32f2fd02018-04-16 18:23:431155 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1156 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1157 mock_quic_data_.AddRead(ASYNC,
1158 ConstructServerConnectAuthReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551159 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1160
Renjief49758b2019-01-11 23:32:411161 quic::QuicString header = ConstructDataHeader(kLen1);
1162 mock_quic_data_.AddRead(
1163 ASYNC,
1164 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431165 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:411166 quic::QuicString header2 = ConstructDataHeader(kLen2);
1167 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
1168 3, kLen1 + header.length(),
1169 header2 + quic::QuicString(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551170 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1171
1172 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521173 SYNCHRONOUS,
1174 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551175
1176 Initialize();
1177
1178 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
1179
1180 // The next two reads are consumed and buffered.
1181 ResumeAndRun();
1182
1183 AssertSyncReadEquals(kMsg1, kLen1);
1184 AssertSyncReadEquals(kMsg2, kLen2);
1185}
1186
1187TEST_P(QuicProxyClientSocketTest, ReadErrorResponseBody) {
Zhongyi Shi32f2fd02018-04-16 18:23:431188 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1189 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1190 mock_quic_data_.AddRead(ASYNC,
1191 ConstructServerConnectErrorReplyPacket(1, !kFin));
Renjief49758b2019-01-11 23:32:411192 quic::QuicString header = ConstructDataHeader(kLen1);
1193 mock_quic_data_.AddRead(
1194 SYNCHRONOUS,
1195 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431196 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:411197 quic::QuicString header2 = ConstructDataHeader(kLen2);
1198 mock_quic_data_.AddRead(
1199 SYNCHRONOUS,
1200 ConstructServerDataPacket(3, kLen1 + header.length(),
1201 header2 + quic::QuicString(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551202 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1203
1204 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521205 SYNCHRONOUS,
1206 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551207 Initialize();
1208
1209 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
1210}
1211
1212// ----------- Reads and Writes
1213
1214TEST_P(QuicProxyClientSocketTest, AsyncReadAroundWrite) {
Renjief49758b2019-01-11 23:32:411215 int write_packet_index = 1;
1216 mock_quic_data_.AddWrite(SYNCHRONOUS,
1217 ConstructSettingsPacket(write_packet_index++));
1218 mock_quic_data_.AddWrite(SYNCHRONOUS,
1219 ConstructConnectRequestPacket(write_packet_index++));
Zhongyi Shi32f2fd02018-04-16 18:23:431220 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551221 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1222
Renjief49758b2019-01-11 23:32:411223 quic::QuicString header = ConstructDataHeader(kLen1);
1224 mock_quic_data_.AddRead(
1225 ASYNC,
1226 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431227 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:411228 ConstructAckPacket(write_packet_index++, 2, 1, 1));
1229
1230 quic::QuicString header2 = ConstructDataHeader(kLen2);
1231 if (version_ == quic::QUIC_VERSION_99) {
1232 mock_quic_data_.AddWrite(
1233 SYNCHRONOUS, ConstructDataPacket(write_packet_index++, 0, header2));
1234 }
1235 mock_quic_data_.AddWrite(
1236 SYNCHRONOUS, ConstructDataPacket(write_packet_index++, header2.length(),
1237 quic::QuicString(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551238
1239 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1240
Renjief49758b2019-01-11 23:32:411241 quic::QuicString header3 = ConstructDataHeader(kLen3);
1242 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
1243 3, kLen1 + header.length(),
1244 header3 + quic::QuicString(kMsg3, kLen3)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551245 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1246
1247 mock_quic_data_.AddWrite(
Renjief49758b2019-01-11 23:32:411248 SYNCHRONOUS, ConstructAckAndRstPacket(write_packet_index++,
1249 quic::QUIC_STREAM_CANCELLED, 3, 3,
1250 1, kLen2 + header2.length()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551251
1252 Initialize();
1253
1254 AssertConnectSucceeds();
1255
1256 ResumeAndRun();
1257
1258 AssertSyncReadEquals(kMsg1, kLen1);
1259
1260 AssertReadStarts(kMsg3, kLen3);
1261 // Read should block until after the write succeeds.
1262
1263 AssertSyncWriteSucceeds(kMsg2, kLen2);
1264
1265 ASSERT_FALSE(read_callback_.have_result());
1266 ResumeAndRun();
1267
1268 // Now the read will return.
1269 AssertReadReturns(kMsg3, kLen3);
1270}
1271
1272TEST_P(QuicProxyClientSocketTest, AsyncWriteAroundReads) {
Renjief49758b2019-01-11 23:32:411273 int write_packet_index = 1;
1274 mock_quic_data_.AddWrite(SYNCHRONOUS,
1275 ConstructSettingsPacket(write_packet_index++));
1276 mock_quic_data_.AddWrite(SYNCHRONOUS,
1277 ConstructConnectRequestPacket(write_packet_index++));
Zhongyi Shi32f2fd02018-04-16 18:23:431278 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551279 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1280
Renjief49758b2019-01-11 23:32:411281 quic::QuicString header = ConstructDataHeader(kLen1);
1282 mock_quic_data_.AddRead(
1283 ASYNC,
1284 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
1285 mock_quic_data_.AddWrite(SYNCHRONOUS,
1286 ConstructAckPacket(write_packet_index++, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551287 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1288
Renjief49758b2019-01-11 23:32:411289 quic::QuicString header2 = ConstructDataHeader(kLen3);
1290 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
1291 3, kLen1 + header.length(),
1292 header2 + quic::QuicString(kMsg3, kLen3)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551293 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1294
1295 mock_quic_data_.AddWrite(ASYNC, ERR_IO_PENDING); // Pause
1296
Renjief49758b2019-01-11 23:32:411297 quic::QuicString header3 = ConstructDataHeader(kLen2);
1298 if (version_ != quic::QUIC_VERSION_99) {
1299 mock_quic_data_.AddWrite(
1300 ASYNC, ConstructDataPacket(write_packet_index++, 0,
1301 quic::QuicString(kMsg2, kLen2)));
1302 mock_quic_data_.AddWrite(
1303 SYNCHRONOUS,
1304 ConstructAckAndDataPacket(write_packet_index++, 3, 3, 1, kLen2,
1305 quic::QuicString(kMsg2, kLen2)));
1306 } else {
1307 mock_quic_data_.AddWrite(
1308 ASYNC, ConstructDataPacket(write_packet_index++, 0, header3));
1309 mock_quic_data_.AddWrite(
1310 ASYNC, ConstructAckAndDataPacket(write_packet_index++, 3, 3, 1,
1311 header3.length(),
1312 quic::QuicString(kMsg2, kLen2)));
1313 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551314
Renjief49758b2019-01-11 23:32:411315 if (version_ == quic::QUIC_VERSION_99) {
1316 mock_quic_data_.AddWrite(
1317 SYNCHRONOUS,
1318 ConstructRstPacket(write_packet_index++, quic::QUIC_STREAM_CANCELLED,
1319 kLen2 + header3.length()));
1320 } else {
1321 mock_quic_data_.AddWrite(
1322 SYNCHRONOUS,
1323 ConstructRstPacket(write_packet_index++, quic::QUIC_STREAM_CANCELLED,
1324 kLen2 + kLen2));
1325 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551326
1327 Initialize();
1328
1329 AssertConnectSucceeds();
1330
1331 ResumeAndRun();
1332 AssertSyncReadEquals(kMsg1, kLen1);
1333
1334 // Write should block until the next read completes.
1335 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1336 // asynchronous starting with the second time it's called while the UDP socket
1337 // is write-blocked. Therefore, at least two writes need to be called on
1338 // |sock_| to get an asynchronous one.
Renjief49758b2019-01-11 23:32:411339
1340 // In version 99, two actual writes(header, body) will be done for each
1341 // WriteStreamData, so we don't need 2 calls here.
1342 if (version_ != quic::QUIC_VERSION_99) {
1343 AssertWriteReturns(kMsg2, kLen2, kLen2);
1344 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551345 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
1346
1347 AssertAsyncReadEquals(kMsg3, kLen3);
1348
1349 ASSERT_FALSE(write_callback_.have_result());
1350
1351 // Now the write will complete
1352 ResumeAndRun();
Yixin Wangdbbd8752018-01-17 21:50:021353 EXPECT_EQ(kLen2, write_callback_.WaitForResult());
Yixin Wang0d2c6b7e12017-08-16 21:12:551354}
1355
1356// ----------- Reading/Writing on Closed socket
1357
1358// Reading from an already closed socket should return 0
1359TEST_P(QuicProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
Zhongyi Shi32f2fd02018-04-16 18:23:431360 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1361 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1362 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551363 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1364
1365 mock_quic_data_.AddRead(ASYNC, 0); // EOF
1366
1367 Initialize();
1368
1369 AssertConnectSucceeds();
1370
1371 ResumeAndRun();
1372
1373 ASSERT_FALSE(sock_->IsConnected());
Bence Békyd8a21fc32018-06-27 18:29:581374 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
1375 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
1376 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551377 ASSERT_FALSE(sock_->IsConnectedAndIdle());
1378}
1379
1380// Read pending when socket is closed should return 0
1381TEST_P(QuicProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
Zhongyi Shi32f2fd02018-04-16 18:23:431382 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1383 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1384 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551385 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1386
1387 mock_quic_data_.AddRead(ASYNC, 0); // EOF
1388
1389 Initialize();
1390
1391 AssertConnectSucceeds();
1392
1393 AssertReadStarts(kMsg1, kLen1);
1394
1395 ResumeAndRun();
1396
1397 ASSERT_EQ(0, read_callback_.WaitForResult());
1398}
1399
1400// Reading from a disconnected socket is an error
1401TEST_P(QuicProxyClientSocketTest, ReadOnDisconnectSocketReturnsNotConnected) {
Zhongyi Shi32f2fd02018-04-16 18:23:431402 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1403 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1404 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551405 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1406 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521407 SYNCHRONOUS,
1408 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551409
1410 Initialize();
1411
1412 AssertConnectSucceeds();
1413
1414 sock_->Disconnect();
1415
1416 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
Bence Békyd8a21fc32018-06-27 18:29:581417 sock_->Read(nullptr, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551418}
1419
1420// Reading data after receiving FIN should return buffered data received before
1421// FIN, then 0.
1422TEST_P(QuicProxyClientSocketTest, ReadAfterFinReceivedReturnsBufferedData) {
Zhongyi Shi32f2fd02018-04-16 18:23:431423 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1424 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1425 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551426 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1427
Renjief49758b2019-01-11 23:32:411428 quic::QuicString header = ConstructDataHeader(kLen1);
Zhongyi Shi32f2fd02018-04-16 18:23:431429 mock_quic_data_.AddRead(ASYNC,
Renjief49758b2019-01-11 23:32:411430 ConstructServerDataFinPacket(
1431 2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431432 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551433 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521434 mock_quic_data_.AddWrite(
1435 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551436
1437 Initialize();
1438
1439 AssertConnectSucceeds();
1440
1441 ResumeAndRun();
1442
1443 AssertSyncReadEquals(kMsg1, kLen1);
Bence Békyd8a21fc32018-06-27 18:29:581444 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
1445 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551446
1447 sock_->Disconnect();
1448 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
Bence Békyd8a21fc32018-06-27 18:29:581449 sock_->Read(nullptr, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551450}
1451
1452// Calling Write() on a closed socket is an error.
1453TEST_P(QuicProxyClientSocketTest, WriteOnClosedStream) {
Zhongyi Shi32f2fd02018-04-16 18:23:431454 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1455 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1456 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551457 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1458
1459 mock_quic_data_.AddRead(ASYNC, 0); // EOF
1460
1461 Initialize();
1462
1463 AssertConnectSucceeds();
1464
1465 ResumeAndRun();
1466
1467 AssertWriteReturns(kMsg1, kLen1, ERR_QUIC_PROTOCOL_ERROR);
1468}
1469
1470// Calling Write() on a disconnected socket is an error.
1471TEST_P(QuicProxyClientSocketTest, WriteOnDisconnectedSocket) {
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(SYNCHRONOUS, ERR_IO_PENDING);
1476 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521477 SYNCHRONOUS,
1478 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551479
1480 Initialize();
1481
1482 AssertConnectSucceeds();
1483
1484 sock_->Disconnect();
1485
1486 AssertWriteReturns(kMsg1, kLen1, ERR_SOCKET_NOT_CONNECTED);
1487}
1488
1489// If the socket is closed with a pending Write(), the callback should be called
1490// with the same error the session was closed with.
1491TEST_P(QuicProxyClientSocketTest, WritePendingOnClose) {
Zhongyi Shi32f2fd02018-04-16 18:23:431492 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1493 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1494 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551495 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1496 mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
1497
1498 Initialize();
1499
1500 AssertConnectSucceeds();
1501
1502 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1503 // asynchronous starting with the second time it's called while the UDP socket
1504 // is write-blocked. Therefore, at least two writes need to be called on
1505 // |sock_| to get an asynchronous one.
Renjief49758b2019-01-11 23:32:411506
1507 // In version 99, 2 writes(header, body) will be called for each
1508 // WriteStreamData, so only 1 Write call is needed here.
1509 if (version_ != quic::QUIC_VERSION_99) {
1510 AssertWriteReturns(kMsg1, kLen1, kLen1);
1511 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551512
1513 // This second write will be async. This is the pending write that's being
1514 // tested.
1515 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1516
1517 // Make sure the write actually starts.
1518 base::RunLoop().RunUntilIdle();
1519
Ryan Hamilton8d9ee76e2018-05-29 23:52:521520 session_->CloseSessionOnError(ERR_CONNECTION_CLOSED,
Renjieba55fae2018-09-20 03:05:161521 quic::QUIC_INTERNAL_ERROR,
1522 quic::ConnectionCloseBehavior::SILENT_CLOSE);
Yixin Wang0d2c6b7e12017-08-16 21:12:551523
1524 EXPECT_THAT(write_callback_.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
1525}
1526
1527TEST_P(QuicProxyClientSocketTest, DisconnectWithWritePending) {
Zhongyi Shi32f2fd02018-04-16 18:23:431528 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1529 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1530 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551531 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1532 mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
1533
1534 Initialize();
1535
1536 AssertConnectSucceeds();
1537
1538 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1539 // asynchronous starting with the second time it's called while the UDP socket
1540 // is write-blocked. Therefore, at least two writes need to be called on
1541 // |sock_| to get an asynchronous one.
Renjief49758b2019-01-11 23:32:411542
1543 // In version 99, 2 writes(header, body) will be called for each
1544 // WriteStreamData, so only 1 Write call is needed here.
1545 if (version_ != quic::QUIC_VERSION_99) {
1546 AssertWriteReturns(kMsg1, kLen1, kLen1);
1547 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551548
1549 // This second write will be async. This is the pending write that's being
1550 // tested.
1551 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1552
1553 // Make sure the write actually starts.
1554 base::RunLoop().RunUntilIdle();
1555
1556 sock_->Disconnect();
1557 EXPECT_FALSE(sock_->IsConnected());
1558
1559 base::RunLoop().RunUntilIdle();
1560
1561 EXPECT_FALSE(sock_->IsConnected());
1562 EXPECT_FALSE(write_callback_.have_result());
1563}
1564
1565// If the socket is Disconnected with a pending Read(), the callback
1566// should not be called.
1567TEST_P(QuicProxyClientSocketTest, DisconnectWithReadPending) {
Zhongyi Shi32f2fd02018-04-16 18:23:431568 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1569 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1570 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551571 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1572 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521573 SYNCHRONOUS,
1574 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551575
1576 Initialize();
1577
1578 AssertConnectSucceeds();
1579
1580 EXPECT_TRUE(sock_->IsConnected());
1581
1582 AssertReadStarts(kMsg1, kLen1);
1583
1584 sock_->Disconnect();
1585 EXPECT_FALSE(sock_->IsConnected());
1586
1587 base::RunLoop().RunUntilIdle();
1588
1589 EXPECT_FALSE(sock_->IsConnected());
1590 EXPECT_FALSE(read_callback_.have_result());
1591}
1592
1593// If the socket is Reset when both a read and write are pending,
1594// both should be called back.
1595TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePending) {
Zhongyi Shi32f2fd02018-04-16 18:23:431596 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1597 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1598 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551599 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1600
1601 mock_quic_data_.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521602 ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang2bea3cf2017-11-09 18:11:031603 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjief49758b2019-01-11 23:32:411604 quic::QuicString header = ConstructDataHeader(kLen2);
1605 if (version_ != quic::QUIC_VERSION_99) {
1606 mock_quic_data_.AddWrite(
1607 ASYNC, ConstructAckAndDataPacket(3, 1, 1, 1, 0,
1608 quic::QuicString(kMsg2, kLen2)));
1609 mock_quic_data_.AddWrite(
1610 SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
1611 2, 2, 1, kLen2));
1612 } else {
1613 mock_quic_data_.AddWrite(ASYNC,
1614 ConstructAckAndDataPacket(3, 1, 1, 1, 0, header));
1615 mock_quic_data_.AddWrite(
1616 SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
1617 2, 2, 1, header.length()));
1618 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551619
1620 Initialize();
1621
1622 AssertConnectSucceeds();
1623
1624 EXPECT_TRUE(sock_->IsConnected());
1625
1626 AssertReadStarts(kMsg1, kLen1);
1627
1628 // Write should block until the next read completes.
1629 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1630 // asynchronous starting with the second time it's called while the UDP socket
1631 // is write-blocked. Therefore, at least two writes need to be called on
1632 // |sock_| to get an asynchronous one.
Renjief49758b2019-01-11 23:32:411633
1634 // In version 99, 2 writes(header, body) will be called for each
1635 // WriteStreamData, so only 1 Write call is needed here.
1636 if (version_ != quic::QUIC_VERSION_99) {
1637 AssertWriteReturns(kMsg2, kLen2, kLen2);
1638 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551639 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
1640
1641 ResumeAndRun();
1642
1643 EXPECT_TRUE(read_callback_.have_result());
1644 EXPECT_TRUE(write_callback_.have_result());
1645}
1646
1647// Makes sure the proxy client socket's source gets the expected NetLog events
1648// and only the expected NetLog events (No SpdySession events).
1649TEST_P(QuicProxyClientSocketTest, NetLog) {
Zhongyi Shi32f2fd02018-04-16 18:23:431650 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1651 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1652 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551653 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1654
Renjief49758b2019-01-11 23:32:411655 quic::QuicString header = ConstructDataHeader(kLen1);
1656 mock_quic_data_.AddRead(
1657 ASYNC,
1658 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431659 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang2bea3cf2017-11-09 18:11:031660 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521661 mock_quic_data_.AddWrite(
1662 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551663
1664 Initialize();
1665
1666 AssertConnectSucceeds();
1667
1668 ResumeAndRun();
1669 AssertSyncReadEquals(kMsg1, kLen1);
1670
1671 NetLogSource sock_source = sock_->NetLog().source();
1672 sock_.reset();
1673
1674 TestNetLogEntry::List entry_list;
1675 net_log_.GetEntriesForSource(sock_source, &entry_list);
1676
1677 ASSERT_EQ(entry_list.size(), 10u);
1678 EXPECT_TRUE(
1679 LogContainsBeginEvent(entry_list, 0, NetLogEventType::SOCKET_ALIVE));
1680 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1681 NetLogEventType::HTTP2_PROXY_CLIENT_SESSION,
1682 NetLogEventPhase::NONE));
1683 EXPECT_TRUE(LogContainsBeginEvent(
1684 entry_list, 2, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1685 EXPECT_TRUE(LogContainsEvent(
1686 entry_list, 3, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1687 NetLogEventPhase::NONE));
1688 EXPECT_TRUE(LogContainsEndEvent(
1689 entry_list, 4, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1690 EXPECT_TRUE(LogContainsBeginEvent(
1691 entry_list, 5, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1692 EXPECT_TRUE(LogContainsEvent(
1693 entry_list, 6,
1694 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1695 NetLogEventPhase::NONE));
1696 EXPECT_TRUE(LogContainsEndEvent(
1697 entry_list, 7, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1698 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1699 NetLogEventType::SOCKET_BYTES_RECEIVED,
1700 NetLogEventPhase::NONE));
1701 EXPECT_TRUE(
1702 LogContainsEndEvent(entry_list, 9, NetLogEventType::SOCKET_ALIVE));
1703}
1704
Bence Béky8ddc2492018-06-13 01:02:041705// A helper class that will delete |sock| when the callback is invoked.
Yixin Wang0d2c6b7e12017-08-16 21:12:551706class DeleteSockCallback : public TestCompletionCallbackBase {
1707 public:
1708 explicit DeleteSockCallback(std::unique_ptr<QuicProxyClientSocket>* sock)
Bence Béky8ddc2492018-06-13 01:02:041709 : sock_(sock) {}
Yixin Wang0d2c6b7e12017-08-16 21:12:551710
1711 ~DeleteSockCallback() override {}
1712
Bence Béky8ddc2492018-06-13 01:02:041713 CompletionOnceCallback callback() {
1714 return base::BindOnce(&DeleteSockCallback::OnComplete,
1715 base::Unretained(this));
1716 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551717
1718 private:
1719 void OnComplete(int result) {
1720 sock_->reset(NULL);
1721 SetResult(result);
1722 }
1723
1724 std::unique_ptr<QuicProxyClientSocket>* sock_;
Yixin Wang0d2c6b7e12017-08-16 21:12:551725
1726 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1727};
1728
1729// If the socket is reset when both a read and write are pending, and the
1730// read callback causes the socket to be deleted, the write callback should
1731// not be called.
1732TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
Zhongyi Shi32f2fd02018-04-16 18:23:431733 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1734 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1735 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551736 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1737
1738 mock_quic_data_.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521739 ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551740 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjief49758b2019-01-11 23:32:411741 if (version_ != quic::QUIC_VERSION_99) {
1742 mock_quic_data_.AddWrite(
1743 ASYNC, ConstructAckAndDataPacket(3, 1, 1, 1, 0,
1744 quic::QuicString(kMsg1, kLen1)));
1745 mock_quic_data_.AddWrite(
1746 SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
1747 2, 2, 1, kLen1));
1748 } else {
1749 quic::QuicString header = ConstructDataHeader(kLen1);
1750 mock_quic_data_.AddWrite(ASYNC,
1751 ConstructAckAndDataPacket(3, 1, 1, 1, 0, header));
1752 mock_quic_data_.AddWrite(
1753 SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
1754 2, 2, 1, header.length()));
1755 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551756
1757 Initialize();
1758
1759 AssertConnectSucceeds();
1760
1761 EXPECT_TRUE(sock_->IsConnected());
1762
1763 DeleteSockCallback read_callback(&sock_);
Victor Costan9c7302b2018-08-27 16:39:441764 scoped_refptr<IOBuffer> read_buf = base::MakeRefCounted<IOBuffer>(kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:551765 ASSERT_EQ(ERR_IO_PENDING,
1766 sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
1767
1768 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1769 // asynchronous starting with the second time it's called while the UDP socket
1770 // is write-blocked. Therefore, at least two writes need to be called on
1771 // |sock_| to get an asynchronous one.
Renjief49758b2019-01-11 23:32:411772
1773 // In version 99, 2 writes(header, body) will be called for each
1774 // WriteStreamData, so only 1 write call is needed here.
1775 if (version_ != quic::QUIC_VERSION_99) {
1776 AssertWriteReturns(kMsg1, kLen1, kLen1);
1777 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551778 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1779
1780 ResumeAndRun();
1781
1782 EXPECT_FALSE(sock_.get());
1783
1784 EXPECT_EQ(0, read_callback.WaitForResult());
1785 EXPECT_FALSE(write_callback_.have_result());
1786}
1787
Yixin Wang079ad542018-01-11 04:06:051788INSTANTIATE_TEST_CASE_P(
Bence Békyce380cb2018-04-26 23:39:551789 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051790 QuicProxyClientSocketTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521791 ::testing::Combine(
1792 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
1793 ::testing::Bool()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551794
1795} // namespace test
Dan Zhangf11470172017-09-18 22:02:091796} // namespace net