blob: 8641a65ca032378f9c9edaf8118904062c510289 [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
Sebastien Marchand6d0558fd2019-01-25 16:49:3710#include "base/bind.h"
Bence Béky8f9d7d3952017-10-09 19:58:0411#include "base/memory/ptr_util.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5512#include "base/run_loop.h"
13#include "base/strings/utf_string_conversions.h"
14#include "net/dns/mock_host_resolver.h"
15#include "net/http/http_auth_cache.h"
16#include "net/http/http_auth_handler_factory.h"
17#include "net/http/http_response_headers.h"
18#include "net/http/transport_security_state.h"
19#include "net/log/test_net_log.h"
20#include "net/log/test_net_log_util.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0821#include "net/quic/crypto/proof_verifier_chromium.h"
22#include "net/quic/mock_crypto_client_stream_factory.h"
23#include "net/quic/mock_quic_data.h"
24#include "net/quic/quic_chromium_alarm_factory.h"
25#include "net/quic/quic_chromium_client_session.h"
26#include "net/quic/quic_chromium_connection_helper.h"
27#include "net/quic/quic_chromium_packet_writer.h"
28#include "net/quic/quic_http_utils.h"
29#include "net/quic/quic_server_info.h"
30#include "net/quic/quic_stream_factory.h"
31#include "net/quic/quic_test_packet_maker.h"
32#include "net/quic/test_task_runner.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5533#include "net/socket/socket_test_util.h"
34#include "net/test/cert_test_util.h"
35#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0136#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1637#include "net/third_party/quic/core/crypto/null_encrypter.h"
Ryan Hamilton47cf9d12018-10-17 04:33:0938#include "net/third_party/quic/core/quic_utils.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1639#include "net/third_party/quic/core/tls_client_handshaker.h"
40#include "net/third_party/quic/test_tools/crypto_test_utils.h"
41#include "net/third_party/quic/test_tools/mock_clock.h"
42#include "net/third_party/quic/test_tools/mock_random.h"
43#include "net/third_party/quic/test_tools/quic_connection_peer.h"
44#include "net/third_party/quic/test_tools/quic_test_utils.h"
[email protected]578968d42017-12-13 15:39:3245#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5546#include "testing/gmock/include/gmock/gmock.h"
47#include "testing/gtest/include/gtest/gtest.h"
48
49using testing::_;
50using testing::AnyNumber;
51using testing::Return;
52
53namespace {
54
55static const char kOriginHost[] = "www.google.com";
56static const int kOriginPort = 443;
57static const char kProxyUrl[] = "https://myproxy:6121/";
58static const char kProxyHost[] = "myproxy";
59static const int kProxyPort = 6121;
60static const char kUserAgent[] = "Mozilla/1.0";
61static const char kRedirectUrl[] = "https://example.com/";
62
63static const char kMsg1[] = "\0hello!\xff";
64static const int kLen1 = 8;
65static const char kMsg2[] = "\0a2345678\0";
66static const int kLen2 = 10;
67static const char kMsg3[] = "bye!";
68static const int kLen3 = 4;
69static const char kMsg33[] = "bye!bye!";
70static const int kLen33 = kLen3 + kLen3;
71static const char kMsg333[] = "bye!bye!bye!";
72static const int kLen333 = kLen3 + kLen3 + kLen3;
73
74} // anonymous namespace
75
76namespace net {
77namespace test {
78
Michael Warres74ee3ce2017-10-09 15:26:3779class QuicProxyClientSocketTest
Ryan Hamilton8d9ee76e2018-05-29 23:52:5280 : public ::testing::TestWithParam<
81 std::tuple<quic::QuicTransportVersion, bool>>,
Bence Béky98447b12018-05-08 03:14:0182 public WithScopedTaskEnvironment {
Yixin Wang0d2c6b7e12017-08-16 21:12:5583 protected:
84 static const bool kFin = true;
85 static const bool kIncludeVersion = true;
86 static const bool kIncludeDiversificationNonce = true;
87 static const bool kIncludeCongestionFeedback = true;
88 static const bool kSendFeedback = true;
89
90 static size_t GetStreamFrameDataLengthFromPacketLength(
Ryan Hamilton8d9ee76e2018-05-29 23:52:5291 quic::QuicByteCount packet_length,
92 quic::QuicTransportVersion version,
Yixin Wang0d2c6b7e12017-08-16 21:12:5593 bool include_version,
94 bool include_diversification_nonce,
Ryan Hamilton8d9ee76e2018-05-29 23:52:5295 quic::QuicConnectionIdLength connection_id_length,
96 quic::QuicPacketNumberLength packet_number_length,
97 quic::QuicStreamOffset offset) {
Yixin Wang0d2c6b7e12017-08-16 21:12:5598 size_t min_data_length = 1;
99 size_t min_packet_length =
Ryan Hamilton8d9ee76e2018-05-29 23:52:52100 quic::NullEncrypter(quic::Perspective::IS_CLIENT)
Yixin Wang0d2c6b7e12017-08-16 21:12:55101 .GetCiphertextSize(min_data_length) +
Ryan Hamilton8d9ee76e2018-05-29 23:52:52102 quic::QuicPacketCreator::StreamFramePacketOverhead(
Michael Warres60637ae2018-06-05 20:03:11103 version, quic::PACKET_8BYTE_CONNECTION_ID,
104 quic::PACKET_0BYTE_CONNECTION_ID, include_version,
Yixin Wang0d2c6b7e12017-08-16 21:12:55105 include_diversification_nonce, packet_number_length, offset);
106
107 DCHECK(packet_length >= min_packet_length);
108 return min_data_length + packet_length - min_packet_length;
109 }
110
111 QuicProxyClientSocketTest()
Yixin Wang079ad542018-01-11 04:06:05112 : version_(std::get<0>(GetParam())),
Ryan Hamilton47cf9d12018-10-17 04:33:09113 client_data_stream_id1_(quic::QuicUtils::GetHeadersStreamId(version_) +
Fan Yang32c5a112018-12-10 20:06:33114 quic::QuicUtils::StreamIdDelta(version_)),
Yixin Wang079ad542018-01-11 04:06:05115 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52116 crypto_config_(quic::test::crypto_test_utils::ProofVerifierForTesting(),
117 quic::TlsClientHandshaker::CreateSslCtx()),
David Schinazic8281052019-01-24 06:14:17118 connection_id_(quic::test::TestConnectionId(2)),
Yixin Wang0d2c6b7e12017-08-16 21:12:55119 client_maker_(version_,
120 connection_id_,
121 &clock_,
122 kProxyHost,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52123 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05124 client_headers_include_h2_stream_dependency_),
Yixin Wang0d2c6b7e12017-08-16 21:12:55125 server_maker_(version_,
126 connection_id_,
127 &clock_,
128 kProxyHost,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52129 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05130 false),
Yixin Wang0d2c6b7e12017-08-16 21:12:55131 random_generator_(0),
132 header_stream_offset_(0),
133 response_offset_(0),
134 user_agent_(kUserAgent),
135 proxy_host_port_(kProxyHost, kProxyPort),
136 endpoint_host_port_(kOriginHost, kOriginPort),
137 host_resolver_(new MockCachingHostResolver()),
138 http_auth_handler_factory_(
139 HttpAuthHandlerFactory::CreateDefault(host_resolver_.get())) {
140 IPAddress ip(192, 0, 2, 33);
141 peer_addr_ = IPEndPoint(ip, 443);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52142 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
Yixin Wang0d2c6b7e12017-08-16 21:12:55143 }
144
145 void SetUp() override {}
146
Yixin Wang2bea3cf2017-11-09 18:11:03147 void TearDown() override {
148 sock_.reset();
149 EXPECT_TRUE(mock_quic_data_.AllReadDataConsumed());
150 EXPECT_TRUE(mock_quic_data_.AllWriteDataConsumed());
151 }
Yixin Wang0d2c6b7e12017-08-16 21:12:55152
153 void Initialize() {
154 std::unique_ptr<MockUDPClientSocket> socket(new MockUDPClientSocket(
155 mock_quic_data_.InitializeAndGetSequencedSocketData(),
156 net_log_.bound().net_log()));
157 socket->Connect(peer_addr_);
158 runner_ = new TestTaskRunner(&clock_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52159 send_algorithm_ = new quic::test::MockSendAlgorithm();
Yixin Wang0d2c6b7e12017-08-16 21:12:55160 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
161 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
162 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
Dan Zhangf11470172017-09-18 22:02:09163 .Times(testing::AtLeast(1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55164 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52165 .WillRepeatedly(Return(quic::kMaxPacketSize));
Yixin Wang0d2c6b7e12017-08-16 21:12:55166 EXPECT_CALL(*send_algorithm_, PacingRate(_))
Ryan Hamilton8d9ee76e2018-05-29 23:52:52167 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Michael Warres74ee3ce2017-10-09 15:26:37168 EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
Yixin Wang0d2c6b7e12017-08-16 21:12:55169 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52170 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Yixin Wang0d2c6b7e12017-08-16 21:12:55171 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
172 EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
173 EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
174 .Times(AnyNumber());
175 helper_.reset(
176 new QuicChromiumConnectionHelper(&clock_, &random_generator_));
177 alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
178
Ryan Hamilton9edcf1a2017-11-22 05:55:17179 QuicChromiumPacketWriter* writer = new QuicChromiumPacketWriter(
180 socket.get(), base::ThreadTaskRunnerHandle::Get().get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52181 quic::QuicConnection* connection = new quic::QuicConnection(
182 connection_id_,
183 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(peer_addr_)),
Yixin Wang0d2c6b7e12017-08-16 21:12:55184 helper_.get(), alarm_factory_.get(), writer, true /* owns_writer */,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52185 quic::Perspective::IS_CLIENT,
186 quic::test::SupportedVersions(
187 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version_)));
Yixin Wang0d2c6b7e12017-08-16 21:12:55188 connection->set_visitor(&visitor_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52189 quic::test::QuicConnectionPeer::SetSendAlgorithm(connection,
190 send_algorithm_);
Yixin Wang0d2c6b7e12017-08-16 21:12:55191
192 // Load a certificate that is valid for *.example.org
193 scoped_refptr<X509Certificate> test_cert(
194 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
195 EXPECT_TRUE(test_cert.get());
196
197 verify_details_.cert_verify_result.verified_cert = test_cert;
198 verify_details_.cert_verify_result.is_issued_by_known_root = true;
199 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
200
201 base::TimeTicks dns_end = base::TimeTicks::Now();
202 base::TimeTicks dns_start = dns_end - base::TimeDelta::FromMilliseconds(1);
203
204 session_.reset(new QuicChromiumClientSession(
205 connection, std::move(socket),
206 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57207 &transport_security_state_, /*ssl_config_service=*/nullptr,
Yixin Wang0d2c6b7e12017-08-16 21:12:55208 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
Paul Jensen8e3c5d32018-02-19 17:06:33209 QuicSessionKey("mail.example.org", 80, PRIVACY_MODE_DISABLED,
210 SocketTag()),
Zhongyi Shi757fcce2018-06-27 05:41:27211 /*require_confirmation=*/false, /*migrate_session_early_v2=*/false,
212 /*migrate_session_on_network_change_v2=*/false,
Renjiea5722ccf2018-08-10 00:18:49213 /*go_away_on_path_degrading*/ false,
Zhongyi Shi757fcce2018-06-27 05:41:27214 /*default_network=*/NetworkChangeNotifier::kInvalidNetworkHandle,
Zhongyi Shi73f23ca872017-12-13 18:37:13215 base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
Zhongyi Shiee760762018-08-01 00:54:29216 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30217 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17218 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52219 quic::QuicTime::Delta::FromMilliseconds(
220 kQuicYieldAfterDurationMilliseconds),
Yixin Wang079ad542018-01-11 04:06:05221 client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52222 quic::test::DefaultQuicConfig(), &crypto_config_, "CONNECTION_UNKNOWN",
223 dns_start, dns_end, &push_promise_index_, nullptr,
Yixin Wang0d2c6b7e12017-08-16 21:12:55224 base::ThreadTaskRunnerHandle::Get().get(),
225 /*socket_performance_watcher=*/nullptr, net_log_.bound().net_log()));
226
227 writer->set_delegate(session_.get());
228
Ryan Hamilton6c2a2a82017-12-15 02:06:28229 session_handle_ =
230 session_->CreateHandle(HostPortPair("mail.example.org", 80));
Yixin Wang0d2c6b7e12017-08-16 21:12:55231
232 session_->Initialize();
233 TestCompletionCallback callback;
234 EXPECT_THAT(session_->CryptoConnect(callback.callback()), IsOk());
235 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
236
Ramin Halavati683bcaa92018-02-14 08:42:39237 EXPECT_THAT(session_handle_->RequestStream(true, callback.callback(),
238 TRAFFIC_ANNOTATION_FOR_TESTS),
Yixin Wang0d2c6b7e12017-08-16 21:12:55239 IsOk());
240 std::unique_ptr<QuicChromiumClientStream::Handle> stream_handle =
241 session_handle_->ReleaseStream();
242 EXPECT_TRUE(stream_handle->IsOpen());
243
244 sock_.reset(new QuicProxyClientSocket(
245 std::move(stream_handle), std::move(session_handle_), user_agent_,
246 endpoint_host_port_, net_log_.bound(),
247 new HttpAuthController(HttpAuth::AUTH_PROXY,
248 GURL("https://" + proxy_host_port_.ToString()),
249 &http_auth_cache_,
250 http_auth_handler_factory_.get())));
251
252 session_->StartReading();
253 }
254
Ryan Hamilton0239aac2018-05-19 00:03:13255 void PopulateConnectRequestIR(spdy::SpdyHeaderBlock* block) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55256 (*block)[":method"] = "CONNECT";
257 (*block)[":authority"] = endpoint_host_port_.ToString();
258 (*block)["user-agent"] = kUserAgent;
259 }
260
261 // Helper functions for constructing packets sent by the client
262
Ryan Hamilton8d9ee76e2018-05-29 23:52:52263 std::unique_ptr<quic::QuicReceivedPacket> ConstructSettingsPacket(
264 quic::QuicPacketNumber packet_number) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55265 return client_maker_.MakeInitialSettingsPacket(packet_number,
266 &header_stream_offset_);
267 }
268
Ryan Hamilton8d9ee76e2018-05-29 23:52:52269 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstPacket(
270 quic::QuicPacketNumber packet_number,
271 quic::QuicRstStreamErrorCode error_code,
272 quic::QuicPacketNumber largest_received,
273 quic::QuicPacketNumber smallest_received,
274 quic::QuicPacketNumber least_unacked) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55275 return client_maker_.MakeAckAndRstPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09276 packet_number, !kIncludeVersion, client_data_stream_id1_, error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55277 largest_received, smallest_received, least_unacked, kSendFeedback);
278 }
279
Ryan Hamilton8d9ee76e2018-05-29 23:52:52280 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstPacket(
281 quic::QuicPacketNumber packet_number,
282 quic::QuicRstStreamErrorCode error_code,
283 quic::QuicPacketNumber largest_received,
284 quic::QuicPacketNumber smallest_received,
285 quic::QuicPacketNumber least_unacked,
Yixin Wang0d2c6b7e12017-08-16 21:12:55286 size_t bytes_written) {
287 return client_maker_.MakeAckAndRstPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09288 packet_number, !kIncludeVersion, client_data_stream_id1_, error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55289 largest_received, smallest_received, least_unacked, kSendFeedback,
290 bytes_written);
291 }
292
Ryan Hamilton8d9ee76e2018-05-29 23:52:52293 std::unique_ptr<quic::QuicReceivedPacket> ConstructRstPacket(
294 quic::QuicPacketNumber packet_number,
295 quic::QuicRstStreamErrorCode error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55296 size_t bytes_written) {
297 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton47cf9d12018-10-17 04:33:09298 client_data_stream_id1_, error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55299 bytes_written);
300 }
301
Ryan Hamilton8d9ee76e2018-05-29 23:52:52302 std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectRequestPacket(
Lily Chenf11e1292018-11-29 16:42:09303 quic::QuicPacketNumber packet_number,
304 RequestPriority request_priority = LOWEST) {
Ryan Hamilton0239aac2018-05-19 00:03:13305 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55306 PopulateConnectRequestIR(&block);
307 return client_maker_.MakeRequestHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09308 packet_number, client_data_stream_id1_, kIncludeVersion, !kFin,
Lily Chenf11e1292018-11-29 16:42:09309 ConvertRequestPriorityToQuicPriority(request_priority),
310 std::move(block), 0, nullptr, &header_stream_offset_);
Yixin Wang0d2c6b7e12017-08-16 21:12:55311 }
312
Ryan Hamilton8d9ee76e2018-05-29 23:52:52313 std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectAuthRequestPacket(
314 quic::QuicPacketNumber packet_number) {
Ryan Hamilton0239aac2018-05-19 00:03:13315 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55316 PopulateConnectRequestIR(&block);
317 block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
318 return client_maker_.MakeRequestHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09319 packet_number, client_data_stream_id1_, kIncludeVersion, !kFin,
Yixin Wang7a3f1b8d2018-01-17 21:40:48320 ConvertRequestPriorityToQuicPriority(LOWEST), std::move(block), 0,
321 nullptr, &header_stream_offset_);
Yixin Wang0d2c6b7e12017-08-16 21:12:55322 }
323
Ryan Hamilton8d9ee76e2018-05-29 23:52:52324 std::unique_ptr<quic::QuicReceivedPacket> ConstructDataPacket(
325 quic::QuicPacketNumber packet_number,
326 quic::QuicStreamOffset offset,
Renjief49758b2019-01-11 23:32:41327 quic::QuicStringPiece data) {
Ryan Hamilton47cf9d12018-10-17 04:33:09328 return client_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
Renjief49758b2019-01-11 23:32:41329 !kIncludeVersion, !kFin, offset, data);
Yixin Wang0d2c6b7e12017-08-16 21:12:55330 }
331
Renjied172e812019-01-16 05:12:35332 std::unique_ptr<quic::QuicReceivedPacket> ConstructMultipleDataFramesPacket(
333 quic::QuicPacketNumber packet_number,
334 quic::QuicStreamOffset offset,
335 const std::vector<std::string> data_writes) {
336 return client_maker_.MakeMultipleDataFramesPacket(
337 packet_number, client_data_stream_id1_, !kIncludeVersion, !kFin, offset,
338 data_writes);
339 }
340
Ryan Hamilton8d9ee76e2018-05-29 23:52:52341 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndDataPacket(
342 quic::QuicPacketNumber packet_number,
343 quic::QuicPacketNumber largest_received,
344 quic::QuicPacketNumber smallest_received,
345 quic::QuicPacketNumber least_unacked,
346 quic::QuicStreamOffset offset,
Renjief49758b2019-01-11 23:32:41347 quic::QuicStringPiece data) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55348 return client_maker_.MakeAckAndDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09349 packet_number, !kIncludeVersion, client_data_stream_id1_,
350 largest_received, smallest_received, least_unacked, !kFin, offset,
Renjief49758b2019-01-11 23:32:41351 data);
Yixin Wang0d2c6b7e12017-08-16 21:12:55352 }
353
Renjied172e812019-01-16 05:12:35354 std::unique_ptr<quic::QuicReceivedPacket>
355 ConstructAckAndMultipleDataFramesPacket(
356 quic::QuicPacketNumber packet_number,
357 quic::QuicPacketNumber largest_received,
358 quic::QuicPacketNumber smallest_received,
359 quic::QuicPacketNumber least_unacked,
360 quic::QuicStreamOffset offset,
361 const std::vector<std::string> data_writes) {
362 return client_maker_.MakeAckAndMultipleDataFramesPacket(
363 packet_number, !kIncludeVersion, client_data_stream_id1_,
364 largest_received, smallest_received, least_unacked, !kFin, offset,
365 data_writes);
366 }
367
Ryan Hamilton8d9ee76e2018-05-29 23:52:52368 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckPacket(
369 quic::QuicPacketNumber packet_number,
370 quic::QuicPacketNumber largest_received,
371 quic::QuicPacketNumber smallest_received,
372 quic::QuicPacketNumber least_unacked) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55373 return client_maker_.MakeAckPacket(packet_number, largest_received,
374 smallest_received, least_unacked,
375 kSendFeedback);
376 }
377
378 // Helper functions for constructing packets sent by the server
379
Ryan Hamilton8d9ee76e2018-05-29 23:52:52380 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerRstPacket(
381 quic::QuicPacketNumber packet_number,
382 quic::QuicRstStreamErrorCode error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55383 size_t bytes_written) {
384 return server_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton47cf9d12018-10-17 04:33:09385 client_data_stream_id1_, error_code,
Yixin Wang0d2c6b7e12017-08-16 21:12:55386 bytes_written);
387 }
388
Ryan Hamilton8d9ee76e2018-05-29 23:52:52389 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
390 quic::QuicPacketNumber packet_number,
391 quic::QuicStreamOffset offset,
Renjief49758b2019-01-11 23:32:41392 quic::QuicStringPiece data) {
Ryan Hamilton47cf9d12018-10-17 04:33:09393 return server_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
Renjief49758b2019-01-11 23:32:41394 !kIncludeVersion, !kFin, offset, data);
Yixin Wang0d2c6b7e12017-08-16 21:12:55395 }
396
Ryan Hamilton8d9ee76e2018-05-29 23:52:52397 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataFinPacket(
398 quic::QuicPacketNumber packet_number,
399 quic::QuicStreamOffset offset,
Renjief49758b2019-01-11 23:32:41400 quic::QuicStringPiece data) {
Ryan Hamilton47cf9d12018-10-17 04:33:09401 return server_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
Renjief49758b2019-01-11 23:32:41402 !kIncludeVersion, kFin, offset, data);
Yixin Wang0d2c6b7e12017-08-16 21:12:55403 }
404
Ryan Hamilton8d9ee76e2018-05-29 23:52:52405 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerConnectReplyPacket(
406 quic::QuicPacketNumber packet_number,
Yixin Wang0d2c6b7e12017-08-16 21:12:55407 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13408 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55409 block[":status"] = "200";
410
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 ConstructServerConnectAuthReplyPacket(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"] = "407";
421 block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
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
Ryan Hamilton8d9ee76e2018-05-29 23:52:52427 std::unique_ptr<quic::QuicReceivedPacket>
428 ConstructServerConnectRedirectReplyPacket(
429 quic::QuicPacketNumber packet_number,
Yixin Wang0d2c6b7e12017-08-16 21:12:55430 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13431 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55432 block[":status"] = "302";
433 block["location"] = kRedirectUrl;
434 block["set-cookie"] = "foo=bar";
435 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09436 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Yixin Wang0d2c6b7e12017-08-16 21:12:55437 std::move(block), nullptr, &response_offset_);
438 }
439
Ryan Hamilton8d9ee76e2018-05-29 23:52:52440 std::unique_ptr<quic::QuicReceivedPacket>
441 ConstructServerConnectErrorReplyPacket(quic::QuicPacketNumber packet_number,
442 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13443 spdy::SpdyHeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55444 block[":status"] = "500";
445
446 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09447 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Yixin Wang0d2c6b7e12017-08-16 21:12:55448 std::move(block), nullptr, &response_offset_);
449 }
450
451 void AssertConnectSucceeds() {
452 TestCompletionCallback callback;
453 ASSERT_THAT(sock_->Connect(callback.callback()), IsError(ERR_IO_PENDING));
454 ASSERT_THAT(callback.WaitForResult(), IsOk());
455 }
456
457 void AssertConnectFails(int result) {
458 TestCompletionCallback callback;
459 ASSERT_THAT(sock_->Connect(callback.callback()), IsError(ERR_IO_PENDING));
460 ASSERT_EQ(result, callback.WaitForResult());
461 }
462
463 void ResumeAndRun() {
464 // Run until the pause, if the provider isn't paused yet.
465 SequencedSocketData* data = mock_quic_data_.GetSequencedSocketData();
466 data->RunUntilPaused();
467 data->Resume();
468 base::RunLoop().RunUntilIdle();
469 }
470
471 void AssertWriteReturns(const char* data, int len, int rv) {
Victor Costan9c7302b2018-08-27 16:39:44472 scoped_refptr<IOBufferWithSize> buf =
473 base::MakeRefCounted<IOBufferWithSize>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55474 memcpy(buf->data(), data, len);
475 EXPECT_EQ(rv,
[email protected]578968d42017-12-13 15:39:32476 sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
477 TRAFFIC_ANNOTATION_FOR_TESTS));
Yixin Wang0d2c6b7e12017-08-16 21:12:55478 }
479
480 void AssertSyncWriteSucceeds(const char* data, int len) {
Victor Costan9c7302b2018-08-27 16:39:44481 scoped_refptr<IOBufferWithSize> buf =
482 base::MakeRefCounted<IOBufferWithSize>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55483 memcpy(buf->data(), data, len);
Bence Békyd8a21fc32018-06-27 18:29:58484 EXPECT_EQ(len,
485 sock_->Write(buf.get(), buf->size(), CompletionOnceCallback(),
486 TRAFFIC_ANNOTATION_FOR_TESTS));
Yixin Wang0d2c6b7e12017-08-16 21:12:55487 }
488
489 void AssertSyncReadEquals(const char* data, int len) {
Victor Costan9c7302b2018-08-27 16:39:44490 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(len);
Bence Békyd8a21fc32018-06-27 18:29:58491 ASSERT_EQ(len, sock_->Read(buf.get(), len, CompletionOnceCallback()));
Ryan Hamilton0239aac2018-05-19 00:03:13492 ASSERT_EQ(spdy::SpdyString(data, len), spdy::SpdyString(buf->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55493 ASSERT_TRUE(sock_->IsConnected());
494 }
495
496 void AssertAsyncReadEquals(const char* data, int len) {
Victor Costan9c7302b2018-08-27 16:39:44497 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55498 ASSERT_EQ(ERR_IO_PENDING,
499 sock_->Read(buf.get(), len, read_callback_.callback()));
500 EXPECT_TRUE(sock_->IsConnected());
501
502 ResumeAndRun();
503
504 EXPECT_EQ(len, read_callback_.WaitForResult());
505 EXPECT_TRUE(sock_->IsConnected());
Ryan Hamilton0239aac2018-05-19 00:03:13506 ASSERT_EQ(spdy::SpdyString(data, len), spdy::SpdyString(buf->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55507 }
508
509 void AssertReadStarts(const char* data, int len) {
510 // Issue the read, which will be completed asynchronously.
Victor Costan9c7302b2018-08-27 16:39:44511 read_buf_ = base::MakeRefCounted<IOBuffer>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55512 ASSERT_EQ(ERR_IO_PENDING,
513 sock_->Read(read_buf_.get(), len, read_callback_.callback()));
514 EXPECT_TRUE(sock_->IsConnected());
515 }
516
517 void AssertReadReturns(const char* data, int len) {
518 EXPECT_TRUE(sock_->IsConnected());
519
520 // Now the read will return.
521 EXPECT_EQ(len, read_callback_.WaitForResult());
Ryan Hamilton0239aac2018-05-19 00:03:13522 ASSERT_EQ(spdy::SpdyString(data, len),
523 spdy::SpdyString(read_buf_->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55524 }
525
Renjief49758b2019-01-11 23:32:41526 quic::QuicString ConstructDataHeader(size_t body_len) {
527 if (version_ != quic::QUIC_VERSION_99) {
528 return "";
529 }
530 quic::HttpEncoder encoder;
531 std::unique_ptr<char[]> buffer;
532 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
533 return quic::QuicString(buffer.get(), header_length);
534 }
535
Ryan Hamilton8d9ee76e2018-05-29 23:52:52536 const quic::QuicTransportVersion version_;
Ryan Hamilton47cf9d12018-10-17 04:33:09537 const quic::QuicStreamId client_data_stream_id1_;
Yixin Wang079ad542018-01-11 04:06:05538 const bool client_headers_include_h2_stream_dependency_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55539
540 // order of destruction of these members matter
Ryan Hamilton8d9ee76e2018-05-29 23:52:52541 quic::MockClock clock_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55542 MockQuicData mock_quic_data_;
543 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
544 std::unique_ptr<QuicChromiumClientSession> session_;
545 std::unique_ptr<QuicChromiumClientSession::Handle> session_handle_;
546 std::unique_ptr<QuicProxyClientSocket> sock_;
547
548 BoundTestNetLog net_log_;
549
Ryan Hamilton8d9ee76e2018-05-29 23:52:52550 quic::test::MockSendAlgorithm* send_algorithm_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55551 scoped_refptr<TestTaskRunner> runner_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55552
553 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52554 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55555 TransportSecurityState transport_security_state_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52556 quic::QuicCryptoClientConfig crypto_config_;
557 quic::QuicClientPushPromiseIndex push_promise_index_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55558
Ryan Hamilton8d9ee76e2018-05-29 23:52:52559 const quic::QuicConnectionId connection_id_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55560 QuicTestPacketMaker client_maker_;
561 QuicTestPacketMaker server_maker_;
562 IPEndPoint peer_addr_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52563 quic::test::MockRandom random_generator_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55564 ProofVerifyDetailsChromium verify_details_;
565 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52566 quic::QuicStreamOffset header_stream_offset_;
567 quic::QuicStreamOffset response_offset_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55568
569 std::string user_agent_;
570 HostPortPair proxy_host_port_;
571 HostPortPair endpoint_host_port_;
572 HttpAuthCache http_auth_cache_;
573 std::unique_ptr<MockHostResolverBase> host_resolver_;
574 std::unique_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory_;
575
576 TestCompletionCallback read_callback_;
577 scoped_refptr<IOBuffer> read_buf_;
578
579 TestCompletionCallback write_callback_;
580
581 DISALLOW_COPY_AND_ASSIGN(QuicProxyClientSocketTest);
582};
583
584TEST_P(QuicProxyClientSocketTest, ConnectSendsCorrectRequest) {
Zhongyi Shi32f2fd02018-04-16 18:23:43585 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
586 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
587 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55588 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
589 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52590 SYNCHRONOUS,
591 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55592
593 Initialize();
594
595 ASSERT_FALSE(sock_->IsConnected());
596
597 AssertConnectSucceeds();
598
599 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
600 ASSERT_TRUE(response != nullptr);
601 ASSERT_EQ(200, response->headers->response_code());
602}
603
604TEST_P(QuicProxyClientSocketTest, ConnectWithAuthRequested) {
Zhongyi Shi32f2fd02018-04-16 18:23:43605 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
606 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
607 mock_quic_data_.AddRead(ASYNC,
608 ConstructServerConnectAuthReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55609 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
610 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52611 SYNCHRONOUS,
612 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55613
614 Initialize();
615
616 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
617
618 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
619 ASSERT_TRUE(response != nullptr);
620 ASSERT_EQ(407, response->headers->response_code());
621}
622
623TEST_P(QuicProxyClientSocketTest, ConnectWithAuthCredentials) {
Zhongyi Shi32f2fd02018-04-16 18:23:43624 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
625 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectAuthRequestPacket(2));
626 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55627 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
628 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52629 SYNCHRONOUS,
630 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55631
632 Initialize();
633
634 // Add auth to cache
635 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
636 const base::string16 kBar(base::ASCIIToUTF16("bar"));
637 http_auth_cache_.Add(GURL(kProxyUrl), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
638 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar),
639 "/");
640
641 AssertConnectSucceeds();
642
643 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
644 ASSERT_TRUE(response != nullptr);
645 ASSERT_EQ(200, response->headers->response_code());
646}
647
648TEST_P(QuicProxyClientSocketTest, ConnectRedirects) {
Zhongyi Shi32f2fd02018-04-16 18:23:43649 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
650 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
651 mock_quic_data_.AddRead(ASYNC,
652 ConstructServerConnectRedirectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55653 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
654 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52655 SYNCHRONOUS,
656 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55657
658 Initialize();
659
660 AssertConnectFails(ERR_HTTPS_PROXY_TUNNEL_RESPONSE);
661
662 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
663 ASSERT_TRUE(response != nullptr);
664
665 const HttpResponseHeaders* headers = response->headers.get();
666 ASSERT_EQ(302, headers->response_code());
667 ASSERT_FALSE(headers->HasHeader("set-cookie"));
668 ASSERT_TRUE(headers->HasHeaderValue("content-length", "0"));
669
670 std::string location;
671 ASSERT_TRUE(headers->IsRedirect(&location));
672 ASSERT_EQ(location, kRedirectUrl);
673}
674
675TEST_P(QuicProxyClientSocketTest, ConnectFails) {
Zhongyi Shi32f2fd02018-04-16 18:23:43676 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
677 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
Yixin Wang0d2c6b7e12017-08-16 21:12:55678 mock_quic_data_.AddRead(ASYNC, 0); // EOF
679
680 Initialize();
681
682 ASSERT_FALSE(sock_->IsConnected());
683
684 AssertConnectFails(ERR_QUIC_PROTOCOL_ERROR);
685
686 ASSERT_FALSE(sock_->IsConnected());
687}
688
689TEST_P(QuicProxyClientSocketTest, WasEverUsedReturnsCorrectValue) {
Zhongyi Shi32f2fd02018-04-16 18:23:43690 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
691 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
692 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55693 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
694 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52695 SYNCHRONOUS,
696 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55697
698 Initialize();
699
700 EXPECT_TRUE(sock_->WasEverUsed()); // Used due to crypto handshake
701 AssertConnectSucceeds();
702 EXPECT_TRUE(sock_->WasEverUsed());
703 sock_->Disconnect();
704 EXPECT_TRUE(sock_->WasEverUsed());
705}
706
707TEST_P(QuicProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
Zhongyi Shi32f2fd02018-04-16 18:23:43708 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
709 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
710 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55711 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
712 mock_quic_data_.AddRead(ASYNC, 0); // EOF
713
714 Initialize();
715
716 IPEndPoint addr;
717 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
718
719 AssertConnectSucceeds();
720 EXPECT_TRUE(sock_->IsConnected());
721 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsOk());
722
723 ResumeAndRun();
724
725 EXPECT_FALSE(sock_->IsConnected());
726 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
727
728 sock_->Disconnect();
729
730 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
731}
732
733TEST_P(QuicProxyClientSocketTest, IsConnectedAndIdle) {
Zhongyi Shi32f2fd02018-04-16 18:23:43734 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
735 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
736 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55737 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
738
Renjief49758b2019-01-11 23:32:41739 quic::QuicString header = ConstructDataHeader(kLen1);
740 mock_quic_data_.AddRead(
741 ASYNC,
742 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:43743 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55744 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52745 mock_quic_data_.AddWrite(
746 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:55747
748 Initialize();
749
750 EXPECT_FALSE(sock_->IsConnectedAndIdle());
751
752 AssertConnectSucceeds();
753
754 EXPECT_TRUE(sock_->IsConnectedAndIdle());
755
756 // The next read is consumed and buffered.
757 ResumeAndRun();
758
759 EXPECT_FALSE(sock_->IsConnectedAndIdle());
760
761 AssertSyncReadEquals(kMsg1, kLen1);
762
763 EXPECT_TRUE(sock_->IsConnectedAndIdle());
764}
765
766TEST_P(QuicProxyClientSocketTest, GetTotalReceivedBytes) {
Zhongyi Shi32f2fd02018-04-16 18:23:43767 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
768 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
769 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55770 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
771
Renjief49758b2019-01-11 23:32:41772 quic::QuicString header = ConstructDataHeader(kLen333);
773 mock_quic_data_.AddRead(
774 ASYNC, ConstructServerDataPacket(
775 2, 0, header + quic::QuicString(kMsg333, kLen333)));
Zhongyi Shi32f2fd02018-04-16 18:23:43776 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55777 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52778 mock_quic_data_.AddWrite(
779 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:55780
781 Initialize();
782
783 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
784
785 AssertConnectSucceeds();
786
787 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
788
789 // The next read is consumed and buffered.
790 ResumeAndRun();
791
792 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
793
794 // The payload from the single large data frame will be read across
795 // two different reads.
796 AssertSyncReadEquals(kMsg33, kLen33);
797
Renjief49758b2019-01-11 23:32:41798 EXPECT_EQ((int64_t)(kLen33 + header.length()),
799 sock_->GetTotalReceivedBytes());
Yixin Wang0d2c6b7e12017-08-16 21:12:55800
801 AssertSyncReadEquals(kMsg3, kLen3);
802
Renjief49758b2019-01-11 23:32:41803 EXPECT_EQ((int64_t)(kLen333 + header.length()),
804 sock_->GetTotalReceivedBytes());
Yixin Wang0d2c6b7e12017-08-16 21:12:55805}
806
Lily Chenf11e1292018-11-29 16:42:09807TEST_P(QuicProxyClientSocketTest, SetStreamPriority) {
808 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
809 mock_quic_data_.AddWrite(SYNCHRONOUS,
810 ConstructConnectRequestPacket(2, HIGHEST));
811 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
812 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
813 mock_quic_data_.AddWrite(
814 SYNCHRONOUS,
815 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
816
817 Initialize();
818
819 sock_->SetStreamPriority(HIGHEST);
820 AssertConnectSucceeds();
821}
Yixin Wang0d2c6b7e12017-08-16 21:12:55822
823TEST_P(QuicProxyClientSocketTest, WriteSendsDataInDataFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:43824 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
825 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
826 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55827 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjief49758b2019-01-11 23:32:41828 if (version_ == quic::QUIC_VERSION_99) {
829 quic::QuicString header = ConstructDataHeader(kLen1);
Renjief49758b2019-01-11 23:32:41830 mock_quic_data_.AddWrite(
Renjied172e812019-01-16 05:12:35831 SYNCHRONOUS,
832 ConstructAckAndMultipleDataFramesPacket(
833 3, 1, 1, 1, 0, {header, quic::QuicString(kMsg1, kLen1)}));
Renjief49758b2019-01-11 23:32:41834 quic::QuicString header2 = ConstructDataHeader(kLen2);
Renjied172e812019-01-16 05:12:35835 mock_quic_data_.AddWrite(SYNCHRONOUS,
836 ConstructMultipleDataFramesPacket(
837 4, kLen1 + header.length(),
838 {header2, quic::QuicString(kMsg2, kLen2)}));
Renjief49758b2019-01-11 23:32:41839 mock_quic_data_.AddWrite(
840 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:35841 ConstructRstPacket(5, quic::QUIC_STREAM_CANCELLED,
Renjief49758b2019-01-11 23:32:41842 kLen1 + kLen2 + header.length() + header2.length()));
843 } else {
844 mock_quic_data_.AddWrite(
845 SYNCHRONOUS, ConstructAckAndDataPacket(3, 1, 1, 1, 0,
846 quic::QuicString(kMsg1, kLen1)));
847 mock_quic_data_.AddWrite(
848 SYNCHRONOUS,
849 ConstructDataPacket(4, kLen1, quic::QuicString(kMsg2, kLen2)));
850 mock_quic_data_.AddWrite(
851 SYNCHRONOUS,
852 ConstructRstPacket(5, quic::QUIC_STREAM_CANCELLED, kLen1 + kLen2));
853 }
Yixin Wang0d2c6b7e12017-08-16 21:12:55854
855 Initialize();
856
857 AssertConnectSucceeds();
858
859 AssertSyncWriteSucceeds(kMsg1, kLen1);
860 AssertSyncWriteSucceeds(kMsg2, kLen2);
861}
862
863TEST_P(QuicProxyClientSocketTest, WriteSplitsLargeDataIntoMultiplePackets) {
Renjief49758b2019-01-11 23:32:41864 int write_packet_index = 1;
865 mock_quic_data_.AddWrite(SYNCHRONOUS,
866 ConstructSettingsPacket(write_packet_index++));
867 mock_quic_data_.AddWrite(SYNCHRONOUS,
868 ConstructConnectRequestPacket(write_packet_index++));
Zhongyi Shi32f2fd02018-04-16 18:23:43869 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55870 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjief49758b2019-01-11 23:32:41871 quic::QuicString header = ConstructDataHeader(kLen1);
872 if (version_ != quic::QUIC_VERSION_99) {
873 mock_quic_data_.AddWrite(
874 SYNCHRONOUS, ConstructAckAndDataPacket(write_packet_index++, 1, 1, 1, 0,
875 quic::QuicString(kMsg1, kLen1)));
876 } else {
Renjied172e812019-01-16 05:12:35877 mock_quic_data_.AddWrite(SYNCHRONOUS,
878 ConstructAckAndMultipleDataFramesPacket(
879 write_packet_index++, 1, 1, 1, 0,
880 {header, quic::QuicString(kMsg1, kLen1)}));
Renjief49758b2019-01-11 23:32:41881 }
Yixin Wang0d2c6b7e12017-08-16 21:12:55882
883 // Expect |kNumDataPackets| data packets, each containing the max possible
884 // amount of data.
Renjied172e812019-01-16 05:12:35885 int numDataPackets = 3;
886 std::string data(numDataPackets * quic::kDefaultMaxPacketSize, 'x');
Renjief49758b2019-01-11 23:32:41887 quic::QuicStreamOffset offset = kLen1 + header.length();
Renjied172e812019-01-16 05:12:35888
Renjief49758b2019-01-11 23:32:41889 if (version_ == quic::QUIC_VERSION_99) {
Renjied172e812019-01-16 05:12:35890 numDataPackets++;
Renjief49758b2019-01-11 23:32:41891 }
Renjied172e812019-01-16 05:12:35892 size_t total_data_length = 0;
893 for (int i = 0; i < numDataPackets; ++i) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55894 size_t max_packet_data_length = GetStreamFrameDataLengthFromPacketLength(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52895 quic::kDefaultMaxPacketSize, version_, !kIncludeVersion,
896 !kIncludeDiversificationNonce, quic::PACKET_8BYTE_CONNECTION_ID,
897 quic::PACKET_1BYTE_PACKET_NUMBER, offset);
Renjied172e812019-01-16 05:12:35898 if (version_ == quic::QUIC_VERSION_99 && i == 0) {
899 // 3973 is the data frame length from packet length.
900 quic::QuicString header2 = ConstructDataHeader(3973);
901 mock_quic_data_.AddWrite(
902 SYNCHRONOUS,
903 ConstructMultipleDataFramesPacket(
904 write_packet_index++, offset,
905 {header2,
906 quic::QuicString(data.c_str(), max_packet_data_length - 7)}));
907 offset += max_packet_data_length - header2.length() - 1;
908 } else if (version_ == quic::QUIC_VERSION_99 && i == numDataPackets - 1) {
909 mock_quic_data_.AddWrite(
910 SYNCHRONOUS, ConstructDataPacket(write_packet_index++, offset,
911 quic::QuicString(data.c_str(), 7)));
912 offset += 7;
913 } else {
914 mock_quic_data_.AddWrite(
915 SYNCHRONOUS,
916 ConstructDataPacket(
917 write_packet_index++, offset,
918 quic::QuicString(data.c_str(), max_packet_data_length)));
919 offset += max_packet_data_length;
920 }
921 if (i != 3) {
922 total_data_length += max_packet_data_length;
923 }
Yixin Wang0d2c6b7e12017-08-16 21:12:55924 }
Renjied172e812019-01-16 05:12:35925
Yixin Wang0d2c6b7e12017-08-16 21:12:55926 mock_quic_data_.AddWrite(
Renjief49758b2019-01-11 23:32:41927 SYNCHRONOUS, ConstructRstPacket(write_packet_index++,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52928 quic::QUIC_STREAM_CANCELLED, offset));
Yixin Wang0d2c6b7e12017-08-16 21:12:55929
930 Initialize();
931
932 AssertConnectSucceeds();
933
934 // Make a small write. An ACK and STOP_WAITING will be bundled. This prevents
935 // ACK and STOP_WAITING from being bundled with the subsequent large write.
936 // This allows the test code for computing the size of data sent in each
937 // packet to not become too complicated.
938 AssertSyncWriteSucceeds(kMsg1, kLen1);
939
940 // Make large write that should be split up
941 AssertSyncWriteSucceeds(data.c_str(), total_data_length);
942}
943
944// ----------- Read
945
946TEST_P(QuicProxyClientSocketTest, ReadReadsDataInDataFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:43947 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
948 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
949 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55950 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
951
Renjief49758b2019-01-11 23:32:41952 quic::QuicString header = ConstructDataHeader(kLen1);
953 mock_quic_data_.AddRead(
954 ASYNC,
955 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:43956 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55957 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52958 mock_quic_data_.AddWrite(
959 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:55960
961 Initialize();
962
963 AssertConnectSucceeds();
964
965 ResumeAndRun();
966 AssertSyncReadEquals(kMsg1, kLen1);
967}
968
969TEST_P(QuicProxyClientSocketTest, ReadDataFromBufferedFrames) {
Zhongyi Shi32f2fd02018-04-16 18:23:43970 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
971 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
972 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55973 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
974
Renjief49758b2019-01-11 23:32:41975 quic::QuicString header = ConstructDataHeader(kLen1);
976 mock_quic_data_.AddRead(
977 ASYNC,
978 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:43979 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55980 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
981
Renjief49758b2019-01-11 23:32:41982 quic::QuicString header2 = ConstructDataHeader(kLen2);
983 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
984 3, kLen1 + header.length(),
985 header2 + quic::QuicString(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:55986 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
987
988 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52989 SYNCHRONOUS,
990 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55991
992 Initialize();
993
994 AssertConnectSucceeds();
995
996 ResumeAndRun();
997 AssertSyncReadEquals(kMsg1, kLen1);
998
999 ResumeAndRun();
1000 AssertSyncReadEquals(kMsg2, kLen2);
1001}
1002
1003TEST_P(QuicProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
Zhongyi Shi32f2fd02018-04-16 18:23:431004 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1005 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1006 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551007 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1008
Renjief49758b2019-01-11 23:32:411009 quic::QuicString header = ConstructDataHeader(kLen1);
1010 mock_quic_data_.AddRead(
1011 ASYNC,
1012 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431013 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:411014 quic::QuicString header2 = ConstructDataHeader(kLen2);
1015 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
1016 3, kLen1 + header.length(),
1017 header2 + quic::QuicString(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551018 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1019
1020 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521021 SYNCHRONOUS,
1022 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551023
1024 Initialize();
1025
1026 AssertConnectSucceeds();
1027
1028 // The next two reads are consumed and buffered.
1029 ResumeAndRun();
1030
1031 AssertSyncReadEquals(kMsg1, kLen1);
1032 AssertSyncReadEquals(kMsg2, kLen2);
1033}
1034
1035TEST_P(QuicProxyClientSocketTest, LargeReadWillMergeDataFromDifferentFrames) {
Zhongyi Shi32f2fd02018-04-16 18:23:431036 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1037 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1038 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551039 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1040
Renjief49758b2019-01-11 23:32:411041 quic::QuicString header = ConstructDataHeader(kLen3);
1042 mock_quic_data_.AddRead(
1043 ASYNC,
1044 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg3, kLen3)));
Zhongyi Shi32f2fd02018-04-16 18:23:431045 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:411046 quic::QuicString header2 = ConstructDataHeader(kLen3);
1047 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
1048 3, kLen3 + header.length(),
1049 header2 + quic::QuicString(kMsg3, kLen3)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551050 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1051
1052 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521053 SYNCHRONOUS,
1054 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551055
1056 Initialize();
1057
1058 AssertConnectSucceeds();
1059
1060 // The next two reads are consumed and buffered.
1061 ResumeAndRun();
1062 // The payload from two data frames, each with kMsg3 will be combined
1063 // together into a single read().
1064 AssertSyncReadEquals(kMsg33, kLen33);
1065}
1066
1067TEST_P(QuicProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
Zhongyi Shi32f2fd02018-04-16 18:23:431068 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1069 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1070 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551071 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1072
1073 int offset = 0;
1074
Renjief49758b2019-01-11 23:32:411075 quic::QuicString header = ConstructDataHeader(kLen1);
1076 mock_quic_data_.AddRead(
1077 ASYNC, ConstructServerDataPacket(
1078 2, offset, header + quic::QuicString(kMsg1, kLen1)));
1079 offset += kLen1 + header.length();
Zhongyi Shi32f2fd02018-04-16 18:23:431080 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551081
Renjief49758b2019-01-11 23:32:411082 quic::QuicString header2 = ConstructDataHeader(kLen3);
1083 mock_quic_data_.AddRead(
1084 ASYNC, ConstructServerDataPacket(
1085 3, offset, header2 + quic::QuicString(kMsg3, kLen3)));
1086 offset += kLen3 + header2.length();
1087 mock_quic_data_.AddRead(
1088 ASYNC, ConstructServerDataPacket(
1089 4, offset, header2 + quic::QuicString(kMsg3, kLen3)));
1090 offset += kLen3 + header2.length();
Zhongyi Shi32f2fd02018-04-16 18:23:431091 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(4, 4, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551092
Renjief49758b2019-01-11 23:32:411093 quic::QuicString header3 = ConstructDataHeader(kLen2);
1094 mock_quic_data_.AddRead(
1095 ASYNC, ConstructServerDataPacket(
1096 5, offset, header3 + quic::QuicString(kMsg2, kLen2)));
1097 offset += kLen2 + header3.length();
Yixin Wang0d2c6b7e12017-08-16 21:12:551098 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1099
1100 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521101 SYNCHRONOUS,
1102 ConstructAckAndRstPacket(5, quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551103
1104 Initialize();
1105
1106 AssertConnectSucceeds();
1107
1108 // The next 4 reads are consumed and buffered.
1109 ResumeAndRun();
1110
1111 AssertSyncReadEquals(kMsg1, kLen1);
1112 // The payload from two data frames, each with kMsg3 will be combined
1113 // together into a single read().
1114 AssertSyncReadEquals(kMsg33, kLen33);
1115 AssertSyncReadEquals(kMsg2, kLen2);
1116}
1117
1118TEST_P(QuicProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
Zhongyi Shi32f2fd02018-04-16 18:23:431119 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1120 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1121 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551122 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1123
Renjief49758b2019-01-11 23:32:411124 quic::QuicString header = ConstructDataHeader(kLen1);
1125 mock_quic_data_.AddRead(
1126 ASYNC,
1127 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431128 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:411129 quic::QuicString header2 = ConstructDataHeader(kLen33);
1130 mock_quic_data_.AddRead(
1131 ASYNC,
1132 ConstructServerDataPacket(3, kLen1 + header.length(),
1133 header2 + quic::QuicString(kMsg33, kLen33)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551134 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1135
1136 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521137 SYNCHRONOUS,
1138 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551139
1140 Initialize();
1141
1142 AssertConnectSucceeds();
1143
1144 // The next 2 reads are consumed and buffered.
1145 ResumeAndRun();
1146
1147 AssertSyncReadEquals(kMsg1, kLen1);
1148 // The payload from the single large data frame will be read across
1149 // two different reads.
1150 AssertSyncReadEquals(kMsg3, kLen3);
1151 AssertSyncReadEquals(kMsg3, kLen3);
1152}
1153
1154TEST_P(QuicProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
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, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551158 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1159
Renjief49758b2019-01-11 23:32:411160 quic::QuicString header = ConstructDataHeader(kLen333);
1161 mock_quic_data_.AddRead(
1162 ASYNC, ConstructServerDataPacket(
1163 2, 0, header + quic::QuicString(kMsg333, kLen333)));
Zhongyi Shi32f2fd02018-04-16 18:23:431164 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551165 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1166
Ryan Hamilton8d9ee76e2018-05-29 23:52:521167 mock_quic_data_.AddWrite(
1168 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551169
1170 Initialize();
1171
1172 AssertConnectSucceeds();
1173
1174 // The next read is consumed and buffered.
1175 ResumeAndRun();
1176
1177 // The payload from the single large data frame will be read across
1178 // two different reads.
1179 AssertSyncReadEquals(kMsg33, kLen33);
1180
1181 // Now attempt to do a read of more data than remains buffered
Victor Costan9c7302b2018-08-27 16:39:441182 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kLen33);
Bence Békyd8a21fc32018-06-27 18:29:581183 ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, CompletionOnceCallback()));
Ryan Hamilton0239aac2018-05-19 00:03:131184 ASSERT_EQ(spdy::SpdyString(kMsg3, kLen3),
1185 spdy::SpdyString(buf->data(), kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551186 ASSERT_TRUE(sock_->IsConnected());
1187}
1188
1189TEST_P(QuicProxyClientSocketTest, ReadAuthResponseBody) {
Zhongyi Shi32f2fd02018-04-16 18:23:431190 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1191 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1192 mock_quic_data_.AddRead(ASYNC,
1193 ConstructServerConnectAuthReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551194 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1195
Renjief49758b2019-01-11 23:32:411196 quic::QuicString header = ConstructDataHeader(kLen1);
1197 mock_quic_data_.AddRead(
1198 ASYNC,
1199 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431200 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:411201 quic::QuicString header2 = ConstructDataHeader(kLen2);
1202 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
1203 3, kLen1 + header.length(),
1204 header2 + quic::QuicString(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551205 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1206
1207 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521208 SYNCHRONOUS,
1209 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551210
1211 Initialize();
1212
1213 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
1214
1215 // The next two reads are consumed and buffered.
1216 ResumeAndRun();
1217
1218 AssertSyncReadEquals(kMsg1, kLen1);
1219 AssertSyncReadEquals(kMsg2, kLen2);
1220}
1221
1222TEST_P(QuicProxyClientSocketTest, ReadErrorResponseBody) {
Zhongyi Shi32f2fd02018-04-16 18:23:431223 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1224 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1225 mock_quic_data_.AddRead(ASYNC,
1226 ConstructServerConnectErrorReplyPacket(1, !kFin));
Renjief49758b2019-01-11 23:32:411227 quic::QuicString header = ConstructDataHeader(kLen1);
1228 mock_quic_data_.AddRead(
1229 SYNCHRONOUS,
1230 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431231 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:411232 quic::QuicString header2 = ConstructDataHeader(kLen2);
1233 mock_quic_data_.AddRead(
1234 SYNCHRONOUS,
1235 ConstructServerDataPacket(3, kLen1 + header.length(),
1236 header2 + quic::QuicString(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551237 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1238
1239 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521240 SYNCHRONOUS,
1241 ConstructAckAndRstPacket(4, quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551242 Initialize();
1243
1244 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
1245}
1246
1247// ----------- Reads and Writes
1248
1249TEST_P(QuicProxyClientSocketTest, AsyncReadAroundWrite) {
Renjief49758b2019-01-11 23:32:411250 int write_packet_index = 1;
1251 mock_quic_data_.AddWrite(SYNCHRONOUS,
1252 ConstructSettingsPacket(write_packet_index++));
1253 mock_quic_data_.AddWrite(SYNCHRONOUS,
1254 ConstructConnectRequestPacket(write_packet_index++));
Zhongyi Shi32f2fd02018-04-16 18:23:431255 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551256 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1257
Renjief49758b2019-01-11 23:32:411258 quic::QuicString header = ConstructDataHeader(kLen1);
1259 mock_quic_data_.AddRead(
1260 ASYNC,
1261 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431262 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:411263 ConstructAckPacket(write_packet_index++, 2, 1, 1));
1264
1265 quic::QuicString header2 = ConstructDataHeader(kLen2);
1266 if (version_ == quic::QUIC_VERSION_99) {
Renjied172e812019-01-16 05:12:351267 mock_quic_data_.AddWrite(SYNCHRONOUS,
1268 ConstructMultipleDataFramesPacket(
1269 write_packet_index++, 0,
1270 {header2, quic::QuicString(kMsg2, kLen2)}));
1271 } else {
Renjief49758b2019-01-11 23:32:411272 mock_quic_data_.AddWrite(
Renjief49758b2019-01-11 23:32:411273 SYNCHRONOUS, ConstructDataPacket(write_packet_index++, header2.length(),
1274 quic::QuicString(kMsg2, kLen2)));
Renjied172e812019-01-16 05:12:351275 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551276
1277 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1278
Renjief49758b2019-01-11 23:32:411279 quic::QuicString header3 = ConstructDataHeader(kLen3);
1280 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
1281 3, kLen1 + header.length(),
1282 header3 + quic::QuicString(kMsg3, kLen3)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551283 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1284
1285 mock_quic_data_.AddWrite(
Renjief49758b2019-01-11 23:32:411286 SYNCHRONOUS, ConstructAckAndRstPacket(write_packet_index++,
1287 quic::QUIC_STREAM_CANCELLED, 3, 3,
1288 1, kLen2 + header2.length()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551289
1290 Initialize();
1291
1292 AssertConnectSucceeds();
1293
1294 ResumeAndRun();
1295
1296 AssertSyncReadEquals(kMsg1, kLen1);
1297
1298 AssertReadStarts(kMsg3, kLen3);
1299 // Read should block until after the write succeeds.
1300
1301 AssertSyncWriteSucceeds(kMsg2, kLen2);
1302
1303 ASSERT_FALSE(read_callback_.have_result());
1304 ResumeAndRun();
1305
1306 // Now the read will return.
1307 AssertReadReturns(kMsg3, kLen3);
1308}
1309
1310TEST_P(QuicProxyClientSocketTest, AsyncWriteAroundReads) {
Renjied172e812019-01-16 05:12:351311 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1312 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
Zhongyi Shi32f2fd02018-04-16 18:23:431313 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551314 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1315
Renjief49758b2019-01-11 23:32:411316 quic::QuicString header = ConstructDataHeader(kLen1);
1317 mock_quic_data_.AddRead(
1318 ASYNC,
1319 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Renjied172e812019-01-16 05:12:351320 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551321 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1322
Renjief49758b2019-01-11 23:32:411323 quic::QuicString header2 = ConstructDataHeader(kLen3);
1324 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
1325 3, kLen1 + header.length(),
1326 header2 + quic::QuicString(kMsg3, kLen3)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551327 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1328
1329 mock_quic_data_.AddWrite(ASYNC, ERR_IO_PENDING); // Pause
1330
Renjief49758b2019-01-11 23:32:411331 quic::QuicString header3 = ConstructDataHeader(kLen2);
1332 if (version_ != quic::QUIC_VERSION_99) {
1333 mock_quic_data_.AddWrite(
Renjied172e812019-01-16 05:12:351334 ASYNC, ConstructDataPacket(4, 0, quic::QuicString(kMsg2, kLen2)));
Renjief49758b2019-01-11 23:32:411335 mock_quic_data_.AddWrite(
Renjied172e812019-01-16 05:12:351336 SYNCHRONOUS, ConstructAckAndDataPacket(5, 3, 3, 1, kLen2,
1337 quic::QuicString(kMsg2, kLen2)));
Renjief49758b2019-01-11 23:32:411338 } else {
1339 mock_quic_data_.AddWrite(
Renjied172e812019-01-16 05:12:351340 ASYNC, ConstructMultipleDataFramesPacket(
1341 4, 0, {header3, quic::QuicString(kMsg2, kLen2)}));
Renjief49758b2019-01-11 23:32:411342 mock_quic_data_.AddWrite(
Renjied172e812019-01-16 05:12:351343 ASYNC,
1344 ConstructAckAndDataPacket(5, 3, 3, 1, header3.length() + kLen2,
1345 header3 + quic::QuicString(kMsg2, kLen2)));
Renjief49758b2019-01-11 23:32:411346 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551347
Renjied172e812019-01-16 05:12:351348 mock_quic_data_.AddWrite(
1349 SYNCHRONOUS, ConstructRstPacket(6, quic::QUIC_STREAM_CANCELLED,
1350 kLen2 + kLen2 + 2 * header3.length()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551351
1352 Initialize();
1353
1354 AssertConnectSucceeds();
1355
1356 ResumeAndRun();
1357 AssertSyncReadEquals(kMsg1, kLen1);
1358
1359 // Write should block until the next read completes.
1360 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1361 // asynchronous starting with the second time it's called while the UDP socket
1362 // is write-blocked. Therefore, at least two writes need to be called on
1363 // |sock_| to get an asynchronous one.
Renjied172e812019-01-16 05:12:351364 AssertWriteReturns(kMsg2, kLen2, kLen2);
Yixin Wang0d2c6b7e12017-08-16 21:12:551365 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
1366
1367 AssertAsyncReadEquals(kMsg3, kLen3);
1368
1369 ASSERT_FALSE(write_callback_.have_result());
1370
1371 // Now the write will complete
1372 ResumeAndRun();
Yixin Wangdbbd8752018-01-17 21:50:021373 EXPECT_EQ(kLen2, write_callback_.WaitForResult());
Yixin Wang0d2c6b7e12017-08-16 21:12:551374}
1375
1376// ----------- Reading/Writing on Closed socket
1377
1378// Reading from an already closed socket should return 0
1379TEST_P(QuicProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
Zhongyi Shi32f2fd02018-04-16 18:23:431380 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1381 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1382 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551383 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1384
1385 mock_quic_data_.AddRead(ASYNC, 0); // EOF
1386
1387 Initialize();
1388
1389 AssertConnectSucceeds();
1390
1391 ResumeAndRun();
1392
1393 ASSERT_FALSE(sock_->IsConnected());
Bence Békyd8a21fc32018-06-27 18:29:581394 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
1395 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
1396 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551397 ASSERT_FALSE(sock_->IsConnectedAndIdle());
1398}
1399
1400// Read pending when socket is closed should return 0
1401TEST_P(QuicProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
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(ASYNC, ERR_IO_PENDING); // Pause
1406
1407 mock_quic_data_.AddRead(ASYNC, 0); // EOF
1408
1409 Initialize();
1410
1411 AssertConnectSucceeds();
1412
1413 AssertReadStarts(kMsg1, kLen1);
1414
1415 ResumeAndRun();
1416
1417 ASSERT_EQ(0, read_callback_.WaitForResult());
1418}
1419
1420// Reading from a disconnected socket is an error
1421TEST_P(QuicProxyClientSocketTest, ReadOnDisconnectSocketReturnsNotConnected) {
Zhongyi Shi32f2fd02018-04-16 18:23:431422 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1423 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1424 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551425 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1426 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521427 SYNCHRONOUS,
1428 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551429
1430 Initialize();
1431
1432 AssertConnectSucceeds();
1433
1434 sock_->Disconnect();
1435
1436 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
Bence Békyd8a21fc32018-06-27 18:29:581437 sock_->Read(nullptr, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551438}
1439
1440// Reading data after receiving FIN should return buffered data received before
1441// FIN, then 0.
1442TEST_P(QuicProxyClientSocketTest, ReadAfterFinReceivedReturnsBufferedData) {
Zhongyi Shi32f2fd02018-04-16 18:23:431443 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1444 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1445 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551446 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1447
Renjief49758b2019-01-11 23:32:411448 quic::QuicString header = ConstructDataHeader(kLen1);
Zhongyi Shi32f2fd02018-04-16 18:23:431449 mock_quic_data_.AddRead(ASYNC,
Renjief49758b2019-01-11 23:32:411450 ConstructServerDataFinPacket(
1451 2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431452 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551453 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521454 mock_quic_data_.AddWrite(
1455 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551456
1457 Initialize();
1458
1459 AssertConnectSucceeds();
1460
1461 ResumeAndRun();
1462
1463 AssertSyncReadEquals(kMsg1, kLen1);
Bence Békyd8a21fc32018-06-27 18:29:581464 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
1465 ASSERT_EQ(0, sock_->Read(NULL, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551466
1467 sock_->Disconnect();
1468 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
Bence Békyd8a21fc32018-06-27 18:29:581469 sock_->Read(nullptr, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551470}
1471
1472// Calling Write() on a closed socket is an error.
1473TEST_P(QuicProxyClientSocketTest, WriteOnClosedStream) {
Zhongyi Shi32f2fd02018-04-16 18:23:431474 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1475 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1476 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551477 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1478
1479 mock_quic_data_.AddRead(ASYNC, 0); // EOF
1480
1481 Initialize();
1482
1483 AssertConnectSucceeds();
1484
1485 ResumeAndRun();
1486
1487 AssertWriteReturns(kMsg1, kLen1, ERR_QUIC_PROTOCOL_ERROR);
1488}
1489
1490// Calling Write() on a disconnected socket is an error.
1491TEST_P(QuicProxyClientSocketTest, WriteOnDisconnectedSocket) {
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(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521497 SYNCHRONOUS,
1498 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551499
1500 Initialize();
1501
1502 AssertConnectSucceeds();
1503
1504 sock_->Disconnect();
1505
1506 AssertWriteReturns(kMsg1, kLen1, ERR_SOCKET_NOT_CONNECTED);
1507}
1508
1509// If the socket is closed with a pending Write(), the callback should be called
1510// with the same error the session was closed with.
1511TEST_P(QuicProxyClientSocketTest, WritePendingOnClose) {
Zhongyi Shi32f2fd02018-04-16 18:23:431512 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1513 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1514 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551515 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1516 mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
1517
1518 Initialize();
1519
1520 AssertConnectSucceeds();
1521
1522 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1523 // asynchronous starting with the second time it's called while the UDP socket
1524 // is write-blocked. Therefore, at least two writes need to be called on
1525 // |sock_| to get an asynchronous one.
Renjied172e812019-01-16 05:12:351526 AssertWriteReturns(kMsg1, kLen1, kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:551527
1528 // This second write will be async. This is the pending write that's being
1529 // tested.
1530 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1531
1532 // Make sure the write actually starts.
1533 base::RunLoop().RunUntilIdle();
1534
Ryan Hamilton8d9ee76e2018-05-29 23:52:521535 session_->CloseSessionOnError(ERR_CONNECTION_CLOSED,
Renjieba55fae2018-09-20 03:05:161536 quic::QUIC_INTERNAL_ERROR,
1537 quic::ConnectionCloseBehavior::SILENT_CLOSE);
Yixin Wang0d2c6b7e12017-08-16 21:12:551538
1539 EXPECT_THAT(write_callback_.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
1540}
1541
1542TEST_P(QuicProxyClientSocketTest, DisconnectWithWritePending) {
Zhongyi Shi32f2fd02018-04-16 18:23:431543 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1544 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1545 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551546 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1547 mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
1548
1549 Initialize();
1550
1551 AssertConnectSucceeds();
1552
1553 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1554 // asynchronous starting with the second time it's called while the UDP socket
1555 // is write-blocked. Therefore, at least two writes need to be called on
1556 // |sock_| to get an asynchronous one.
Renjied172e812019-01-16 05:12:351557 AssertWriteReturns(kMsg1, kLen1, kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:551558
1559 // This second write will be async. This is the pending write that's being
1560 // tested.
1561 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1562
1563 // Make sure the write actually starts.
1564 base::RunLoop().RunUntilIdle();
1565
1566 sock_->Disconnect();
1567 EXPECT_FALSE(sock_->IsConnected());
1568
1569 base::RunLoop().RunUntilIdle();
1570
1571 EXPECT_FALSE(sock_->IsConnected());
1572 EXPECT_FALSE(write_callback_.have_result());
1573}
1574
1575// If the socket is Disconnected with a pending Read(), the callback
1576// should not be called.
1577TEST_P(QuicProxyClientSocketTest, DisconnectWithReadPending) {
Zhongyi Shi32f2fd02018-04-16 18:23:431578 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1579 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1580 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551581 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1582 mock_quic_data_.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521583 SYNCHRONOUS,
1584 ConstructAckAndRstPacket(3, quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551585
1586 Initialize();
1587
1588 AssertConnectSucceeds();
1589
1590 EXPECT_TRUE(sock_->IsConnected());
1591
1592 AssertReadStarts(kMsg1, kLen1);
1593
1594 sock_->Disconnect();
1595 EXPECT_FALSE(sock_->IsConnected());
1596
1597 base::RunLoop().RunUntilIdle();
1598
1599 EXPECT_FALSE(sock_->IsConnected());
1600 EXPECT_FALSE(read_callback_.have_result());
1601}
1602
1603// If the socket is Reset when both a read and write are pending,
1604// both should be called back.
1605TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePending) {
Zhongyi Shi32f2fd02018-04-16 18:23:431606 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1607 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1608 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551609 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1610
1611 mock_quic_data_.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521612 ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang2bea3cf2017-11-09 18:11:031613 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjief49758b2019-01-11 23:32:411614 quic::QuicString header = ConstructDataHeader(kLen2);
1615 if (version_ != quic::QUIC_VERSION_99) {
1616 mock_quic_data_.AddWrite(
1617 ASYNC, ConstructAckAndDataPacket(3, 1, 1, 1, 0,
1618 quic::QuicString(kMsg2, kLen2)));
1619 mock_quic_data_.AddWrite(
1620 SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
1621 2, 2, 1, kLen2));
1622 } else {
Renjief49758b2019-01-11 23:32:411623 mock_quic_data_.AddWrite(
Renjied172e812019-01-16 05:12:351624 ASYNC, ConstructAckAndMultipleDataFramesPacket(
1625 3, 1, 1, 1, 0, {header, quic::QuicString(kMsg2, kLen2)}));
1626 mock_quic_data_.AddWrite(
1627 SYNCHRONOUS,
1628 ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT, 2, 2, 1,
1629 header.length() + kLen2));
Renjief49758b2019-01-11 23:32:411630 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551631
1632 Initialize();
1633
1634 AssertConnectSucceeds();
1635
1636 EXPECT_TRUE(sock_->IsConnected());
1637
1638 AssertReadStarts(kMsg1, kLen1);
1639
1640 // Write should block until the next read completes.
1641 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1642 // asynchronous starting with the second time it's called while the UDP socket
1643 // is write-blocked. Therefore, at least two writes need to be called on
1644 // |sock_| to get an asynchronous one.
Renjied172e812019-01-16 05:12:351645 AssertWriteReturns(kMsg2, kLen2, kLen2);
Renjief49758b2019-01-11 23:32:411646
Yixin Wang0d2c6b7e12017-08-16 21:12:551647 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
1648
1649 ResumeAndRun();
1650
1651 EXPECT_TRUE(read_callback_.have_result());
1652 EXPECT_TRUE(write_callback_.have_result());
1653}
1654
1655// Makes sure the proxy client socket's source gets the expected NetLog events
1656// and only the expected NetLog events (No SpdySession events).
1657TEST_P(QuicProxyClientSocketTest, NetLog) {
Zhongyi Shi32f2fd02018-04-16 18:23:431658 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1659 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1660 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551661 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1662
Renjief49758b2019-01-11 23:32:411663 quic::QuicString header = ConstructDataHeader(kLen1);
1664 mock_quic_data_.AddRead(
1665 ASYNC,
1666 ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431667 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
Yixin Wang2bea3cf2017-11-09 18:11:031668 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521669 mock_quic_data_.AddWrite(
1670 SYNCHRONOUS, ConstructRstPacket(4, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551671
1672 Initialize();
1673
1674 AssertConnectSucceeds();
1675
1676 ResumeAndRun();
1677 AssertSyncReadEquals(kMsg1, kLen1);
1678
1679 NetLogSource sock_source = sock_->NetLog().source();
1680 sock_.reset();
1681
1682 TestNetLogEntry::List entry_list;
1683 net_log_.GetEntriesForSource(sock_source, &entry_list);
1684
1685 ASSERT_EQ(entry_list.size(), 10u);
1686 EXPECT_TRUE(
1687 LogContainsBeginEvent(entry_list, 0, NetLogEventType::SOCKET_ALIVE));
1688 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1689 NetLogEventType::HTTP2_PROXY_CLIENT_SESSION,
1690 NetLogEventPhase::NONE));
1691 EXPECT_TRUE(LogContainsBeginEvent(
1692 entry_list, 2, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1693 EXPECT_TRUE(LogContainsEvent(
1694 entry_list, 3, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1695 NetLogEventPhase::NONE));
1696 EXPECT_TRUE(LogContainsEndEvent(
1697 entry_list, 4, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1698 EXPECT_TRUE(LogContainsBeginEvent(
1699 entry_list, 5, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1700 EXPECT_TRUE(LogContainsEvent(
1701 entry_list, 6,
1702 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1703 NetLogEventPhase::NONE));
1704 EXPECT_TRUE(LogContainsEndEvent(
1705 entry_list, 7, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1706 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1707 NetLogEventType::SOCKET_BYTES_RECEIVED,
1708 NetLogEventPhase::NONE));
1709 EXPECT_TRUE(
1710 LogContainsEndEvent(entry_list, 9, NetLogEventType::SOCKET_ALIVE));
1711}
1712
Bence Béky8ddc2492018-06-13 01:02:041713// A helper class that will delete |sock| when the callback is invoked.
Yixin Wang0d2c6b7e12017-08-16 21:12:551714class DeleteSockCallback : public TestCompletionCallbackBase {
1715 public:
1716 explicit DeleteSockCallback(std::unique_ptr<QuicProxyClientSocket>* sock)
Bence Béky8ddc2492018-06-13 01:02:041717 : sock_(sock) {}
Yixin Wang0d2c6b7e12017-08-16 21:12:551718
1719 ~DeleteSockCallback() override {}
1720
Bence Béky8ddc2492018-06-13 01:02:041721 CompletionOnceCallback callback() {
1722 return base::BindOnce(&DeleteSockCallback::OnComplete,
1723 base::Unretained(this));
1724 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551725
1726 private:
1727 void OnComplete(int result) {
1728 sock_->reset(NULL);
1729 SetResult(result);
1730 }
1731
1732 std::unique_ptr<QuicProxyClientSocket>* sock_;
Yixin Wang0d2c6b7e12017-08-16 21:12:551733
1734 DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback);
1735};
1736
1737// If the socket is reset when both a read and write are pending, and the
1738// read callback causes the socket to be deleted, the write callback should
1739// not be called.
1740TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
Zhongyi Shi32f2fd02018-04-16 18:23:431741 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructSettingsPacket(1));
1742 mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
1743 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551744 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1745
1746 mock_quic_data_.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521747 ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED, 0));
Yixin Wang0d2c6b7e12017-08-16 21:12:551748 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjief49758b2019-01-11 23:32:411749 if (version_ != quic::QUIC_VERSION_99) {
1750 mock_quic_data_.AddWrite(
1751 ASYNC, ConstructAckAndDataPacket(3, 1, 1, 1, 0,
1752 quic::QuicString(kMsg1, kLen1)));
1753 mock_quic_data_.AddWrite(
1754 SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
1755 2, 2, 1, kLen1));
1756 } else {
1757 quic::QuicString header = ConstructDataHeader(kLen1);
Renjief49758b2019-01-11 23:32:411758 mock_quic_data_.AddWrite(
Renjied172e812019-01-16 05:12:351759 ASYNC, ConstructAckAndMultipleDataFramesPacket(
1760 3, 1, 1, 1, 0, {header, quic::QuicString(kMsg1, kLen1)}));
1761 mock_quic_data_.AddWrite(
1762 SYNCHRONOUS,
1763 ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT, 2, 2, 1,
1764 header.length() + kLen1));
Renjief49758b2019-01-11 23:32:411765 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551766
1767 Initialize();
1768
1769 AssertConnectSucceeds();
1770
1771 EXPECT_TRUE(sock_->IsConnected());
1772
1773 DeleteSockCallback read_callback(&sock_);
Victor Costan9c7302b2018-08-27 16:39:441774 scoped_refptr<IOBuffer> read_buf = base::MakeRefCounted<IOBuffer>(kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:551775 ASSERT_EQ(ERR_IO_PENDING,
1776 sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
1777
1778 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1779 // asynchronous starting with the second time it's called while the UDP socket
1780 // is write-blocked. Therefore, at least two writes need to be called on
1781 // |sock_| to get an asynchronous one.
Renjied172e812019-01-16 05:12:351782 AssertWriteReturns(kMsg1, kLen1, kLen1);
Renjief49758b2019-01-11 23:32:411783
Yixin Wang0d2c6b7e12017-08-16 21:12:551784 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1785
1786 ResumeAndRun();
1787
1788 EXPECT_FALSE(sock_.get());
1789
1790 EXPECT_EQ(0, read_callback.WaitForResult());
1791 EXPECT_FALSE(write_callback_.have_result());
1792}
1793
Victor Costane635086f2019-01-27 05:20:301794INSTANTIATE_TEST_SUITE_P(
Bence Békyce380cb2018-04-26 23:39:551795 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051796 QuicProxyClientSocketTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521797 ::testing::Combine(
1798 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
1799 ::testing::Bool()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551800
1801} // namespace test
Dan Zhangf11470172017-09-18 22:02:091802} // namespace net