blob: ed3a3b4959b2b8616cd9e65a9d6e45fa8a2152f8 [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>
Eric Orthbe2efac2019-03-06 01:11:118#include <tuple>
Bence Békyd8a21fc32018-06-27 18:29:589#include <utility>
Eric Orthbe2efac2019-03-06 01:11:1110#include <vector>
Bence Béky8f9d7d3952017-10-09 19:58:0411
Sebastien Marchand6d0558fd2019-01-25 16:49:3712#include "base/bind.h"
Bence Béky8f9d7d3952017-10-09 19:58:0413#include "base/memory/ptr_util.h"
Keishi Hattori0e45c022021-11-27 09:25:5214#include "base/memory/raw_ptr.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5515#include "base/run_loop.h"
Victor Vasiliev62c09dc2020-11-06 18:18:2916#include "base/strings/strcat.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5517#include "base/strings/utf_string_conversions.h"
Lei Zhang52637ed2019-02-20 01:38:3718#include "base/threading/thread_task_runner_handle.h"
Zhongyi Shic16b4102019-02-12 00:37:4019#include "base/time/default_tick_clock.h"
Eric Orth5ccc3f02021-09-23 00:01:5720#include "net/base/proxy_server.h"
21#include "net/base/proxy_string_util.h"
Robert Ogden78d4f9eb2020-03-17 20:56:3822#include "net/base/test_proxy_delegate.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5523#include "net/dns/mock_host_resolver.h"
Ben Schwartz3ff4dc1e62021-04-27 21:15:2324#include "net/dns/public/secure_dns_policy.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5525#include "net/http/http_auth_cache.h"
26#include "net/http/http_auth_handler_factory.h"
27#include "net/http/http_response_headers.h"
28#include "net/http/transport_security_state.h"
Matt Reichhoff0049a0b72021-10-20 20:44:2629#include "net/log/net_log.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5530#include "net/log/test_net_log.h"
31#include "net/log/test_net_log_util.h"
Victor Vasiliev4f6fb892019-05-31 16:58:3132#include "net/quic/address_utils.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0833#include "net/quic/crypto/proof_verifier_chromium.h"
34#include "net/quic/mock_crypto_client_stream_factory.h"
35#include "net/quic/mock_quic_data.h"
36#include "net/quic/quic_chromium_alarm_factory.h"
37#include "net/quic/quic_chromium_client_session.h"
38#include "net/quic/quic_chromium_connection_helper.h"
39#include "net/quic/quic_chromium_packet_writer.h"
Matt Menkefca05b62019-09-20 23:15:5640#include "net/quic/quic_crypto_client_config_handle.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0841#include "net/quic/quic_http_utils.h"
42#include "net/quic/quic_server_info.h"
43#include "net/quic/quic_stream_factory.h"
44#include "net/quic/quic_test_packet_maker.h"
Matt Menkefca05b62019-09-20 23:15:5645#include "net/quic/test_quic_crypto_client_config_handle.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0846#include "net/quic/test_task_runner.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5547#include "net/socket/socket_test_util.h"
48#include "net/test/cert_test_util.h"
Victor Vasilievdcdb6192019-02-25 19:49:5649#include "net/test/gtest_util.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5550#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4051#include "net/test/test_with_task_environment.h"
Ryan Hamiltonea4fa192022-04-12 18:30:4952#include "net/third_party/quiche/src/quiche/quic/core/crypto/null_encrypter.h"
53#include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
54#include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
55#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_clock.h"
Nidhi Jaju7135c5e2022-09-03 04:39:5756#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_connection_id_generator.h"
Ryan Hamiltonea4fa192022-04-12 18:30:4957#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
58#include "net/third_party/quiche/src/quiche/quic/test_tools/qpack/qpack_test_utils.h"
59#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.h"
60#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
[email protected]578968d42017-12-13 15:39:3261#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5562#include "testing/gmock/include/gmock/gmock.h"
63#include "testing/gtest/include/gtest/gtest.h"
Matt Menke8db2ff52021-11-23 20:17:4664#include "url/gurl.h"
Dan McArdle68a5f622021-07-09 20:56:5365#include "url/scheme_host_port.h"
66#include "url/url_constants.h"
Yixin Wang0d2c6b7e12017-08-16 21:12:5567
68using testing::_;
69using testing::AnyNumber;
70using testing::Return;
71
Tsuyoshi Horo4f516be2022-06-14 11:53:1372namespace net::test {
David Schinazi09e9a6012019-10-03 17:37:5773
Yixin Wang0d2c6b7e12017-08-16 21:12:5574namespace {
75
76static const char kOriginHost[] = "www.google.com";
77static const int kOriginPort = 443;
78static const char kProxyUrl[] = "https://myproxy:6121/";
79static const char kProxyHost[] = "myproxy";
80static const int kProxyPort = 6121;
81static const char kUserAgent[] = "Mozilla/1.0";
82static const char kRedirectUrl[] = "https://example.com/";
83
84static const char kMsg1[] = "\0hello!\xff";
85static const int kLen1 = 8;
86static const char kMsg2[] = "\0a2345678\0";
87static const int kLen2 = 10;
88static const char kMsg3[] = "bye!";
89static const int kLen3 = 4;
90static const char kMsg33[] = "bye!bye!";
91static const int kLen33 = kLen3 + kLen3;
92static const char kMsg333[] = "bye!bye!bye!";
93static const int kLen333 = kLen3 + kLen3 + kLen3;
94
David Schinazi09e9a6012019-10-03 17:37:5795struct TestParams {
96 quic::ParsedQuicVersion version;
97 bool client_headers_include_h2_stream_dependency;
98};
99
100// Used by ::testing::PrintToStringParamName().
101std::string PrintToString(const TestParams& p) {
Victor Vasiliev62c09dc2020-11-06 18:18:29102 return base::StrCat(
103 {ParsedQuicVersionToString(p.version), "_",
104 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
105 "Dependency"});
David Schinazi09e9a6012019-10-03 17:37:57106}
107
108std::vector<TestParams> GetTestParams() {
109 std::vector<TestParams> params;
110 quic::ParsedQuicVersionVector all_supported_versions =
111 quic::AllSupportedVersions();
112 for (const auto& version : all_supported_versions) {
Renjie Tang1085bf52019-11-20 00:10:53113 params.push_back(TestParams{version, false});
114 params.push_back(TestParams{version, true});
David Schinazi09e9a6012019-10-03 17:37:57115 }
116 return params;
117}
118
Yixin Wang0d2c6b7e12017-08-16 21:12:55119} // anonymous namespace
120
David Schinazi09e9a6012019-10-03 17:37:57121class QuicProxyClientSocketTest : public ::testing::TestWithParam<TestParams>,
122 public WithTaskEnvironment {
Yixin Wang0d2c6b7e12017-08-16 21:12:55123 protected:
124 static const bool kFin = true;
125 static const bool kIncludeVersion = true;
126 static const bool kIncludeDiversificationNonce = true;
Yixin Wang0d2c6b7e12017-08-16 21:12:55127
128 static size_t GetStreamFrameDataLengthFromPacketLength(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52129 quic::QuicByteCount packet_length,
Nick Harper23290b82019-05-02 00:02:56130 quic::ParsedQuicVersion version,
Yixin Wang0d2c6b7e12017-08-16 21:12:55131 bool include_version,
132 bool include_diversification_nonce,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52133 quic::QuicConnectionIdLength connection_id_length,
134 quic::QuicPacketNumberLength packet_number_length,
135 quic::QuicStreamOffset offset) {
Victor Vasiliev6522c3a2022-08-22 00:27:14136 quiche::QuicheVariableLengthIntegerLength retry_token_length_length =
137 quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
138 quiche::QuicheVariableLengthIntegerLength length_length =
Nick Harper23290b82019-05-02 00:02:56139 quic::QuicVersionHasLongHeaderLengths(version.transport_version) &&
140 include_version
Victor Vasiliev6522c3a2022-08-22 00:27:14141 ? quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2
142 : quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
Yixin Wang0d2c6b7e12017-08-16 21:12:55143 size_t min_data_length = 1;
144 size_t min_packet_length =
Ryan Hamilton8d9ee76e2018-05-29 23:52:52145 quic::NullEncrypter(quic::Perspective::IS_CLIENT)
Yixin Wang0d2c6b7e12017-08-16 21:12:55146 .GetCiphertextSize(min_data_length) +
Ryan Hamilton8d9ee76e2018-05-29 23:52:52147 quic::QuicPacketCreator::StreamFramePacketOverhead(
Nick Harper23290b82019-05-02 00:02:56148 version.transport_version, quic::PACKET_8BYTE_CONNECTION_ID,
Michael Warres60637ae2018-06-05 20:03:11149 quic::PACKET_0BYTE_CONNECTION_ID, include_version,
Michael Warres167db3e2019-03-01 21:38:03150 include_diversification_nonce, packet_number_length,
151 retry_token_length_length, length_length, offset);
Yixin Wang0d2c6b7e12017-08-16 21:12:55152
153 DCHECK(packet_length >= min_packet_length);
154 return min_data_length + packet_length - min_packet_length;
155 }
156
157 QuicProxyClientSocketTest()
David Schinazi09e9a6012019-10-03 17:37:57158 : version_(GetParam().version),
Nick Harper23290b82019-05-02 00:02:56159 client_data_stream_id1_(
Renjie Tang1085bf52019-11-20 00:10:53160 quic::VersionUsesHttp3(version_.transport_version)
161 ? quic::QuicUtils::GetFirstBidirectionalStreamId(
162 version_.transport_version,
163 quic::Perspective::IS_CLIENT)
164 : quic::QuicUtils::GetFirstBidirectionalStreamId(
165 version_.transport_version,
166 quic::Perspective::IS_CLIENT) +
167 quic::QuicUtils::StreamIdDelta(
168 version_.transport_version)),
David Schinazi09e9a6012019-10-03 17:37:57169 client_headers_include_h2_stream_dependency_(
170 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamiltonabad59e2019-06-06 04:02:59171 mock_quic_data_(version_),
Nick Harpera598fc5f2019-06-21 08:46:50172 crypto_config_(
173 quic::test::crypto_test_utils::ProofVerifierForTesting()),
David Schinazic8281052019-01-24 06:14:17174 connection_id_(quic::test::TestConnectionId(2)),
Yixin Wang0d2c6b7e12017-08-16 21:12:55175 client_maker_(version_,
176 connection_id_,
177 &clock_,
178 kProxyHost,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52179 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05180 client_headers_include_h2_stream_dependency_),
Yixin Wang0d2c6b7e12017-08-16 21:12:55181 server_maker_(version_,
182 connection_id_,
183 &clock_,
184 kProxyHost,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52185 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05186 false),
Yixin Wang0d2c6b7e12017-08-16 21:12:55187 user_agent_(kUserAgent),
Dan McArdle68a5f622021-07-09 20:56:53188 proxy_endpoint_(url::kHttpsScheme, kProxyHost, kProxyPort),
189 destination_endpoint_(url::kHttpsScheme, kOriginHost, kOriginPort),
Matt Menkebe090422019-10-18 20:25:26190 http_auth_cache_(
191 false /* key_server_entries_by_network_isolation_key */),
Tsuyoshi Horof8861cb2022-07-05 23:50:20192 host_resolver_(std::make_unique<MockCachingHostResolver>()),
Eric Orthbe2efac2019-03-06 01:11:11193 http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()) {
Renjie Tang98b4d512020-02-08 01:24:19194 FLAGS_quic_enable_http3_grease_randomness = false;
Yixin Wang0d2c6b7e12017-08-16 21:12:55195 IPAddress ip(192, 0, 2, 33);
196 peer_addr_ = IPEndPoint(ip, 443);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52197 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
David Schinazi84c58bb2020-06-04 20:14:33198 quic::QuicEnableVersion(version_);
Yixin Wang0d2c6b7e12017-08-16 21:12:55199 }
200
Peter Boström407869b2021-10-07 04:42:48201 QuicProxyClientSocketTest(const QuicProxyClientSocketTest&) = delete;
202 QuicProxyClientSocketTest& operator=(const QuicProxyClientSocketTest&) =
203 delete;
204
Yixin Wang0d2c6b7e12017-08-16 21:12:55205 void SetUp() override {}
206
Yixin Wang2bea3cf2017-11-09 18:11:03207 void TearDown() override {
208 sock_.reset();
209 EXPECT_TRUE(mock_quic_data_.AllReadDataConsumed());
210 EXPECT_TRUE(mock_quic_data_.AllWriteDataConsumed());
211 }
Yixin Wang0d2c6b7e12017-08-16 21:12:55212
213 void Initialize() {
Tsuyoshi Horof8861cb2022-07-05 23:50:20214 auto socket = std::make_unique<MockUDPClientSocket>(
215 mock_quic_data_.InitializeAndGetSequencedSocketData(), NetLog::Get());
Yixin Wang0d2c6b7e12017-08-16 21:12:55216 socket->Connect(peer_addr_);
Tsuyoshi Horo2c0a5042022-07-06 05:53:07217 runner_ = base::MakeRefCounted<TestTaskRunner>(&clock_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52218 send_algorithm_ = new quic::test::MockSendAlgorithm();
Yixin Wang0d2c6b7e12017-08-16 21:12:55219 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
220 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
221 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
Dan Zhangf11470172017-09-18 22:02:09222 .Times(testing::AtLeast(1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55223 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
Zhongyi Shica576df2019-04-12 17:43:40224 .WillRepeatedly(Return(quic::kMaxOutgoingPacketSize));
Yixin Wang0d2c6b7e12017-08-16 21:12:55225 EXPECT_CALL(*send_algorithm_, PacingRate(_))
Ryan Hamilton8d9ee76e2018-05-29 23:52:52226 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Michael Warres74ee3ce2017-10-09 15:26:37227 EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
Yixin Wang0d2c6b7e12017-08-16 21:12:55228 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
Ryan Hamilton8d9ee76e2018-05-29 23:52:52229 .WillRepeatedly(Return(quic::QuicBandwidth::Zero()));
Yixin Wang0d2c6b7e12017-08-16 21:12:55230 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
231 EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
232 EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
233 .Times(AnyNumber());
Peter Boström8a7540692021-04-05 20:48:20234 helper_ = std::make_unique<QuicChromiumConnectionHelper>(
235 &clock_, &random_generator_);
Renjie Tang6ff9a9b2021-02-03 22:11:09236 alarm_factory_ =
237 std::make_unique<QuicChromiumAlarmFactory>(runner_.get(), &clock_);
Yixin Wang0d2c6b7e12017-08-16 21:12:55238
Ryan Hamilton9edcf1a2017-11-22 05:55:17239 QuicChromiumPacketWriter* writer = new QuicChromiumPacketWriter(
240 socket.get(), base::ThreadTaskRunnerHandle::Get().get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52241 quic::QuicConnection* connection = new quic::QuicConnection(
Nick Harperd049f192020-10-02 02:56:10242 connection_id_, quic::QuicSocketAddress(),
243 net::ToQuicSocketAddress(peer_addr_), helper_.get(),
Victor Vasiliev4f6fb892019-05-31 16:58:31244 alarm_factory_.get(), writer, true /* owns_writer */,
Nidhi Jaju7135c5e2022-09-03 04:39:57245 quic::Perspective::IS_CLIENT, quic::test::SupportedVersions(version_),
246 connection_id_generator_);
Yixin Wang0d2c6b7e12017-08-16 21:12:55247 connection->set_visitor(&visitor_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52248 quic::test::QuicConnectionPeer::SetSendAlgorithm(connection,
249 send_algorithm_);
Yixin Wang0d2c6b7e12017-08-16 21:12:55250
251 // Load a certificate that is valid for *.example.org
252 scoped_refptr<X509Certificate> test_cert(
253 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
254 EXPECT_TRUE(test_cert.get());
255
256 verify_details_.cert_verify_result.verified_cert = test_cert;
257 verify_details_.cert_verify_result.is_issued_by_known_root = true;
258 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
259
260 base::TimeTicks dns_end = base::TimeTicks::Now();
Peter Kastinge5a38ed2021-10-02 03:06:35261 base::TimeTicks dns_start = dns_end - base::Milliseconds(1);
Yixin Wang0d2c6b7e12017-08-16 21:12:55262
Renjie Tang6ff9a9b2021-02-03 22:11:09263 session_ = std::make_unique<QuicChromiumClientSession>(
Yixin Wang0d2c6b7e12017-08-16 21:12:55264 connection, std::move(socket),
265 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
Nick Harper89bc7212018-07-31 19:07:57266 &transport_security_state_, /*ssl_config_service=*/nullptr,
Yixin Wang0d2c6b7e12017-08-16 21:12:55267 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
Paul Jensen8e3c5d32018-02-19 17:06:33268 QuicSessionKey("mail.example.org", 80, PRIVACY_MODE_DISABLED,
dalyk51ab46b2019-10-15 15:14:34269 SocketTag(), NetworkIsolationKey(),
Tsuyoshi Horo7acebce2022-05-12 06:13:23270 SecureDnsPolicy::kAllow,
271 /*require_dns_https_alpn=*/false),
Bence Béky1ceba552019-07-19 17:11:05272 /*require_confirmation=*/false,
Bence Béky1ceba552019-07-19 17:11:05273 /*migrate_session_early_v2=*/false,
Zhongyi Shi757fcce2018-06-27 05:41:27274 /*migrate_session_on_network_change_v2=*/false,
Stefano Duo6527ed42022-07-29 09:25:44275 /*default_network=*/handles::kInvalidNetworkHandle,
Zhongyi Shie01f2db2019-02-22 19:53:23276 quic::QuicTime::Delta::FromMilliseconds(
Ryan Sleevi2e8255b2019-07-17 21:02:21277 kDefaultRetransmittableOnWireTimeout.InMilliseconds()),
Zhongyi Shiaf38c4e42019-08-29 22:49:05278 /*migrate_idle_session=*/true, /*allow_port_migration=*/false,
279 kDefaultIdleSessionMigrationPeriod, kMaxTimeOnNonDefaultNetwork,
Zhongyi Shiee760762018-08-01 00:54:29280 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30281 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Zhongyi Shi5f587cc2017-11-21 23:24:17282 kQuicYieldAfterPacketsRead,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52283 quic::QuicTime::Delta::FromMilliseconds(
284 kQuicYieldAfterDurationMilliseconds),
Yixin Wang079ad542018-01-11 04:06:05285 client_headers_include_h2_stream_dependency_, /*cert_verify_flags=*/0,
Matt Menkefca05b62019-09-20 23:15:56286 quic::test::DefaultQuicConfig(),
287 std::make_unique<TestQuicCryptoClientConfigHandle>(&crypto_config_),
Matt Menked804aaf2020-07-21 21:25:48288 "CONNECTION_UNKNOWN", dns_start, dns_end,
289 std::make_unique<quic::QuicClientPushPromiseIndex>(), nullptr,
Zhongyi Shic16b4102019-02-12 00:37:40290 base::DefaultTickClock::GetInstance(),
Yixin Wang0d2c6b7e12017-08-16 21:12:55291 base::ThreadTaskRunnerHandle::Get().get(),
Matt Reichhoff0049a0b72021-10-20 20:44:26292 /*socket_performance_watcher=*/nullptr, NetLog::Get());
Yixin Wang0d2c6b7e12017-08-16 21:12:55293
294 writer->set_delegate(session_.get());
295
Yixin Wang0d2c6b7e12017-08-16 21:12:55296 session_->Initialize();
Bence Béky6e243aa2019-12-13 19:01:07297
298 // Blackhole QPACK decoder stream instead of constructing mock writes.
299 if (VersionUsesHttp3(version_.transport_version)) {
300 session_->qpack_decoder()->set_qpack_stream_sender_delegate(
301 &noop_qpack_stream_sender_delegate_);
302 }
303
Yixin Wang0d2c6b7e12017-08-16 21:12:55304 TestCompletionCallback callback;
305 EXPECT_THAT(session_->CryptoConnect(callback.callback()), IsOk());
Victor Vasiliev29197e22020-01-16 20:48:32306 EXPECT_TRUE(session_->OneRttKeysAvailable());
Yixin Wang0d2c6b7e12017-08-16 21:12:55307
David Benjamin854a9922022-01-22 01:25:10308 session_handle_ = session_->CreateHandle(
309 url::SchemeHostPort(url::kHttpsScheme, "mail.example.org", 80));
Ramin Halavati683bcaa92018-02-14 08:42:39310 EXPECT_THAT(session_handle_->RequestStream(true, callback.callback(),
311 TRAFFIC_ANNOTATION_FOR_TESTS),
Yixin Wang0d2c6b7e12017-08-16 21:12:55312 IsOk());
313 std::unique_ptr<QuicChromiumClientStream::Handle> stream_handle =
314 session_handle_->ReleaseStream();
315 EXPECT_TRUE(stream_handle->IsOpen());
316
Renjie Tang6ff9a9b2021-02-03 22:11:09317 sock_ = std::make_unique<QuicProxyClientSocket>(
Robert Ogden78d4f9eb2020-03-17 20:56:38318 std::move(stream_handle), std::move(session_handle_),
Dan McArdle68a5f622021-07-09 20:56:53319 // TODO(crbug.com/1206799) Construct `ProxyServer` with plain
320 // `proxy_endpoint_` once it supports `url::SchemeHostPort`.
321 ProxyServer(ProxyServer::SCHEME_HTTPS,
322 HostPortPair::FromSchemeHostPort(proxy_endpoint_)),
323 user_agent_,
324 // TODO(crbug.com/1206799) Construct `QuicProxyClientSocket` with plain
325 // `proxy_endpoint_` once it supports `url::SchemeHostPort`.
326 HostPortPair::FromSchemeHostPort(destination_endpoint_),
Matt Reichhoff0049a0b72021-10-20 20:44:26327 NetLogWithSource::Make(NetLogSourceType::NONE),
Tsuyoshi Horo5c935982022-07-11 02:01:42328 base::MakeRefCounted<HttpAuthController>(
329 HttpAuth::AUTH_PROXY, proxy_endpoint_.GetURL(),
330 NetworkIsolationKey(), &http_auth_cache_,
331 http_auth_handler_factory_.get(), host_resolver_.get()),
Renjie Tang6ff9a9b2021-02-03 22:11:09332 proxy_delegate_.get());
Yixin Wang0d2c6b7e12017-08-16 21:12:55333
334 session_->StartReading();
335 }
336
Bence Béky4c325e52020-10-22 20:48:01337 void PopulateConnectRequestIR(spdy::Http2HeaderBlock* block) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55338 (*block)[":method"] = "CONNECT";
Dan McArdle68a5f622021-07-09 20:56:53339 (*block)[":authority"] =
340 HostPortPair::FromSchemeHostPort(destination_endpoint_).ToString();
Yixin Wang0d2c6b7e12017-08-16 21:12:55341 (*block)["user-agent"] = kUserAgent;
342 }
343
344 // Helper functions for constructing packets sent by the client
345
Ryan Hamilton8d9ee76e2018-05-29 23:52:52346 std::unique_ptr<quic::QuicReceivedPacket> ConstructSettingsPacket(
Fan Yangac867502019-01-28 21:10:23347 uint64_t packet_number) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02348 return client_maker_.MakeInitialSettingsPacket(packet_number);
Yixin Wang0d2c6b7e12017-08-16 21:12:55349 }
350
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41351 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstOnlyPacket(
Fan Yangac867502019-01-28 21:10:23352 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52353 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23354 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34355 uint64_t smallest_received) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55356 return client_maker_.MakeAckAndRstPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09357 packet_number, !kIncludeVersion, client_data_stream_id1_, error_code,
Renjie Tangcd594f32020-07-11 20:18:34358 largest_received, smallest_received,
Tsuyoshi Horoab70886d2022-06-29 08:42:52359 /*include_stop_sending_if_v99=*/false);
Frank Kastenholz684ea412019-02-13 18:48:18360 }
361
Ryan Hamilton8d9ee76e2018-05-29 23:52:52362 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23363 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52364 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23365 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34366 uint64_t smallest_received) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55367 return client_maker_.MakeAckAndRstPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09368 packet_number, !kIncludeVersion, client_data_stream_id1_, error_code,
Renjie Tangcd594f32020-07-11 20:18:34369 largest_received, smallest_received,
Frank Kastenholz684ea412019-02-13 18:48:18370 /*include_stop_sending_if_v99=*/true);
Yixin Wang0d2c6b7e12017-08-16 21:12:55371 }
372
Ryan Hamilton8d9ee76e2018-05-29 23:52:52373 std::unique_ptr<quic::QuicReceivedPacket> ConstructRstPacket(
Fan Yangac867502019-01-28 21:10:23374 uint64_t packet_number,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41375 quic::QuicRstStreamErrorCode error_code) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55376 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton47cf9d12018-10-17 04:33:09377 client_data_stream_id1_, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18378 /*include_stop_sending_if_v99=*/true);
Yixin Wang0d2c6b7e12017-08-16 21:12:55379 }
380
Ryan Hamilton8d9ee76e2018-05-29 23:52:52381 std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectRequestPacket(
Fan Yangac867502019-01-28 21:10:23382 uint64_t packet_number,
Lily Chenf11e1292018-11-29 16:42:09383 RequestPriority request_priority = LOWEST) {
Bence Béky4c325e52020-10-22 20:48:01384 spdy::Http2HeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55385 PopulateConnectRequestIR(&block);
386 return client_maker_.MakeRequestHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09387 packet_number, client_data_stream_id1_, kIncludeVersion, !kFin,
Lily Chenf11e1292018-11-29 16:42:09388 ConvertRequestPriorityToQuicPriority(request_priority),
Ryan Hamilton0d65a8c2019-06-07 00:46:02389 std::move(block), 0, nullptr);
Yixin Wang0d2c6b7e12017-08-16 21:12:55390 }
391
Robert Ogden78d4f9eb2020-03-17 20:56:38392 std::unique_ptr<quic::QuicReceivedPacket>
393 ConstructConnectRequestPacketWithExtraHeaders(
394 uint64_t packet_number,
395 std::vector<std::pair<std::string, std::string>> extra_headers,
396 RequestPriority request_priority = LOWEST) {
Bence Béky4c325e52020-10-22 20:48:01397 spdy::Http2HeaderBlock block;
Robert Ogden78d4f9eb2020-03-17 20:56:38398 block[":method"] = "CONNECT";
Dan McArdle68a5f622021-07-09 20:56:53399 block[":authority"] =
400 HostPortPair::FromSchemeHostPort(destination_endpoint_).ToString();
Robert Ogden78d4f9eb2020-03-17 20:56:38401 for (const auto& header : extra_headers) {
402 block[header.first] = header.second;
403 }
Robert Ogden78d4f9eb2020-03-17 20:56:38404 return client_maker_.MakeRequestHeadersPacket(
405 packet_number, client_data_stream_id1_, kIncludeVersion, !kFin,
406 ConvertRequestPriorityToQuicPriority(request_priority),
407 std::move(block), 0, nullptr);
408 }
409
Ryan Hamilton8d9ee76e2018-05-29 23:52:52410 std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectAuthRequestPacket(
Fan Yangac867502019-01-28 21:10:23411 uint64_t packet_number) {
Renjie Tangee921d12020-02-06 00:41:49412 RequestPriority request_priority = LOWEST;
Bence Béky4c325e52020-10-22 20:48:01413 spdy::Http2HeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55414 PopulateConnectRequestIR(&block);
415 block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
416 return client_maker_.MakeRequestHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09417 packet_number, client_data_stream_id1_, kIncludeVersion, !kFin,
Renjie Tangee921d12020-02-06 00:41:49418 ConvertRequestPriorityToQuicPriority(request_priority),
419 std::move(block), 0, nullptr);
Yixin Wang0d2c6b7e12017-08-16 21:12:55420 }
421
Ryan Hamilton8d9ee76e2018-05-29 23:52:52422 std::unique_ptr<quic::QuicReceivedPacket> ConstructDataPacket(
Fan Yangac867502019-01-28 21:10:23423 uint64_t packet_number,
Victor Vasiliev47ecb6a2020-10-14 17:22:10424 absl::string_view data) {
Ryan Hamilton47cf9d12018-10-17 04:33:09425 return client_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
Ryan Hamilton7505eb92019-06-08 00:22:17426 !kIncludeVersion, !kFin, data);
Yixin Wang0d2c6b7e12017-08-16 21:12:55427 }
428
Ryan Hamilton8d9ee76e2018-05-29 23:52:52429 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23430 uint64_t packet_number,
431 uint64_t largest_received,
432 uint64_t smallest_received,
Victor Vasiliev47ecb6a2020-10-14 17:22:10433 absl::string_view data) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55434 return client_maker_.MakeAckAndDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09435 packet_number, !kIncludeVersion, client_data_stream_id1_,
Renjie Tangcd594f32020-07-11 20:18:34436 largest_received, smallest_received, !kFin, data);
Yixin Wang0d2c6b7e12017-08-16 21:12:55437 }
438
Ryan Hamilton8d9ee76e2018-05-29 23:52:52439 std::unique_ptr<quic::QuicReceivedPacket> ConstructAckPacket(
Fan Yangac867502019-01-28 21:10:23440 uint64_t packet_number,
441 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34442 uint64_t smallest_received) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55443 return client_maker_.MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34444 smallest_received);
Yixin Wang0d2c6b7e12017-08-16 21:12:55445 }
446
447 // Helper functions for constructing packets sent by the server
448
Ryan Hamilton8d9ee76e2018-05-29 23:52:52449 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23450 uint64_t packet_number,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41451 quic::QuicRstStreamErrorCode error_code) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55452 return server_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
Ryan Hamilton47cf9d12018-10-17 04:33:09453 client_data_stream_id1_, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18454 /*include_stop_sending_if_v99=*/true);
Yixin Wang0d2c6b7e12017-08-16 21:12:55455 }
456
Ryan Hamilton8d9ee76e2018-05-29 23:52:52457 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23458 uint64_t packet_number,
Victor Vasiliev47ecb6a2020-10-14 17:22:10459 absl::string_view data) {
Ryan Hamilton47cf9d12018-10-17 04:33:09460 return server_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
Ryan Hamilton7505eb92019-06-08 00:22:17461 !kIncludeVersion, !kFin, data);
Yixin Wang0d2c6b7e12017-08-16 21:12:55462 }
463
Ryan Hamilton8d9ee76e2018-05-29 23:52:52464 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataFinPacket(
Fan Yangac867502019-01-28 21:10:23465 uint64_t packet_number,
Victor Vasiliev47ecb6a2020-10-14 17:22:10466 absl::string_view data) {
Ryan Hamilton47cf9d12018-10-17 04:33:09467 return server_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
Ryan Hamilton7505eb92019-06-08 00:22:17468 !kIncludeVersion, kFin, data);
Yixin Wang0d2c6b7e12017-08-16 21:12:55469 }
470
Ryan Hamilton8d9ee76e2018-05-29 23:52:52471 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerConnectReplyPacket(
Fan Yangac867502019-01-28 21:10:23472 uint64_t packet_number,
Renjie Tang1085bf52019-11-20 00:10:53473 bool fin,
474 size_t* header_length = nullptr) {
Bence Béky4c325e52020-10-22 20:48:01475 spdy::Http2HeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55476 block[":status"] = "200";
477
478 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09479 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Renjie Tang1085bf52019-11-20 00:10:53480 std::move(block), header_length);
Yixin Wang0d2c6b7e12017-08-16 21:12:55481 }
482
Ryan Hamilton8d9ee76e2018-05-29 23:52:52483 std::unique_ptr<quic::QuicReceivedPacket>
Robert Ogden78d4f9eb2020-03-17 20:56:38484 ConstructServerConnectReplyPacketWithExtraHeaders(
485 uint64_t packet_number,
486 bool fin,
487 std::vector<std::pair<std::string, std::string>> extra_headers) {
Bence Béky4c325e52020-10-22 20:48:01488 spdy::Http2HeaderBlock block;
Robert Ogden78d4f9eb2020-03-17 20:56:38489 block[":status"] = "200";
490 for (const auto& header : extra_headers) {
491 block[header.first] = header.second;
492 }
493
494 return server_maker_.MakeResponseHeadersPacket(
495 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
496 std::move(block), nullptr);
497 }
498
499 std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23500 ConstructServerConnectAuthReplyPacket(uint64_t packet_number, bool fin) {
Bence Béky4c325e52020-10-22 20:48:01501 spdy::Http2HeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55502 block[":status"] = "407";
503 block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
504 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09505 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02506 std::move(block), nullptr);
Yixin Wang0d2c6b7e12017-08-16 21:12:55507 }
508
Ryan Hamilton8d9ee76e2018-05-29 23:52:52509 std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23510 ConstructServerConnectRedirectReplyPacket(uint64_t packet_number, bool fin) {
Bence Béky4c325e52020-10-22 20:48:01511 spdy::Http2HeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55512 block[":status"] = "302";
513 block["location"] = kRedirectUrl;
514 block["set-cookie"] = "foo=bar";
515 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09516 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02517 std::move(block), nullptr);
Yixin Wang0d2c6b7e12017-08-16 21:12:55518 }
519
Ryan Hamilton8d9ee76e2018-05-29 23:52:52520 std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23521 ConstructServerConnectErrorReplyPacket(uint64_t packet_number, bool fin) {
Bence Béky4c325e52020-10-22 20:48:01522 spdy::Http2HeaderBlock block;
Yixin Wang0d2c6b7e12017-08-16 21:12:55523 block[":status"] = "500";
524
525 return server_maker_.MakeResponseHeadersPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:09526 packet_number, client_data_stream_id1_, !kIncludeVersion, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02527 std::move(block), nullptr);
Yixin Wang0d2c6b7e12017-08-16 21:12:55528 }
529
530 void AssertConnectSucceeds() {
531 TestCompletionCallback callback;
532 ASSERT_THAT(sock_->Connect(callback.callback()), IsError(ERR_IO_PENDING));
533 ASSERT_THAT(callback.WaitForResult(), IsOk());
534 }
535
536 void AssertConnectFails(int result) {
537 TestCompletionCallback callback;
538 ASSERT_THAT(sock_->Connect(callback.callback()), IsError(ERR_IO_PENDING));
539 ASSERT_EQ(result, callback.WaitForResult());
540 }
541
542 void ResumeAndRun() {
543 // Run until the pause, if the provider isn't paused yet.
544 SequencedSocketData* data = mock_quic_data_.GetSequencedSocketData();
545 data->RunUntilPaused();
546 data->Resume();
547 base::RunLoop().RunUntilIdle();
548 }
549
550 void AssertWriteReturns(const char* data, int len, int rv) {
Victor Costan9c7302b2018-08-27 16:39:44551 scoped_refptr<IOBufferWithSize> buf =
552 base::MakeRefCounted<IOBufferWithSize>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55553 memcpy(buf->data(), data, len);
554 EXPECT_EQ(rv,
[email protected]578968d42017-12-13 15:39:32555 sock_->Write(buf.get(), buf->size(), write_callback_.callback(),
556 TRAFFIC_ANNOTATION_FOR_TESTS));
Yixin Wang0d2c6b7e12017-08-16 21:12:55557 }
558
559 void AssertSyncWriteSucceeds(const char* data, int len) {
Victor Costan9c7302b2018-08-27 16:39:44560 scoped_refptr<IOBufferWithSize> buf =
561 base::MakeRefCounted<IOBufferWithSize>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55562 memcpy(buf->data(), data, len);
Bence Békyd8a21fc32018-06-27 18:29:58563 EXPECT_EQ(len,
564 sock_->Write(buf.get(), buf->size(), CompletionOnceCallback(),
565 TRAFFIC_ANNOTATION_FOR_TESTS));
Yixin Wang0d2c6b7e12017-08-16 21:12:55566 }
567
568 void AssertSyncReadEquals(const char* data, int len) {
Victor Costan9c7302b2018-08-27 16:39:44569 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(len);
Bence Békyd8a21fc32018-06-27 18:29:58570 ASSERT_EQ(len, sock_->Read(buf.get(), len, CompletionOnceCallback()));
Ian Swett59044a642019-08-19 16:51:15571 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55572 ASSERT_TRUE(sock_->IsConnected());
573 }
574
575 void AssertAsyncReadEquals(const char* data, int len) {
Victor Costan9c7302b2018-08-27 16:39:44576 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55577 ASSERT_EQ(ERR_IO_PENDING,
578 sock_->Read(buf.get(), len, read_callback_.callback()));
579 EXPECT_TRUE(sock_->IsConnected());
580
581 ResumeAndRun();
582
583 EXPECT_EQ(len, read_callback_.WaitForResult());
584 EXPECT_TRUE(sock_->IsConnected());
Ian Swett59044a642019-08-19 16:51:15585 ASSERT_EQ(std::string(data, len), std::string(buf->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55586 }
587
588 void AssertReadStarts(const char* data, int len) {
589 // Issue the read, which will be completed asynchronously.
Victor Costan9c7302b2018-08-27 16:39:44590 read_buf_ = base::MakeRefCounted<IOBuffer>(len);
Yixin Wang0d2c6b7e12017-08-16 21:12:55591 ASSERT_EQ(ERR_IO_PENDING,
592 sock_->Read(read_buf_.get(), len, read_callback_.callback()));
593 EXPECT_TRUE(sock_->IsConnected());
594 }
595
596 void AssertReadReturns(const char* data, int len) {
597 EXPECT_TRUE(sock_->IsConnected());
598
599 // Now the read will return.
600 EXPECT_EQ(len, read_callback_.WaitForResult());
Ian Swett59044a642019-08-19 16:51:15601 ASSERT_EQ(std::string(data, len), std::string(read_buf_->data(), len));
Yixin Wang0d2c6b7e12017-08-16 21:12:55602 }
603
Victor Vasiliev076657c2019-03-12 02:46:43604 std::string ConstructDataHeader(size_t body_len) {
Nick Harperc6cb7a612020-02-24 20:03:32605 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:41606 return "";
607 }
Victor Vasilievc617d452022-03-07 15:54:25608 quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
609 body_len, quiche::SimpleBufferAllocator::Get());
Ian Swett17d4d1c02021-06-08 19:52:41610 return std::string(buffer.data(), buffer.size());
Renjief49758b2019-01-11 23:32:41611 }
612
Matt Reichhoff0049a0b72021-10-20 20:44:26613 RecordingNetLogObserver net_log_observer_;
Patrick Meenan0041f332022-05-19 23:48:35614 quic::test::QuicFlagSaver saver_;
Nick Harper23290b82019-05-02 00:02:56615 const quic::ParsedQuicVersion version_;
Ryan Hamilton47cf9d12018-10-17 04:33:09616 const quic::QuicStreamId client_data_stream_id1_;
Yixin Wang079ad542018-01-11 04:06:05617 const bool client_headers_include_h2_stream_dependency_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55618
619 // order of destruction of these members matter
Ryan Hamilton8d9ee76e2018-05-29 23:52:52620 quic::MockClock clock_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55621 MockQuicData mock_quic_data_;
622 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
623 std::unique_ptr<QuicChromiumClientSession> session_;
624 std::unique_ptr<QuicChromiumClientSession::Handle> session_handle_;
625 std::unique_ptr<QuicProxyClientSocket> sock_;
Robert Ogden78d4f9eb2020-03-17 20:56:38626 std::unique_ptr<TestProxyDelegate> proxy_delegate_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55627
Keishi Hattori0e45c022021-11-27 09:25:52628 raw_ptr<quic::test::MockSendAlgorithm> send_algorithm_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55629 scoped_refptr<TestTaskRunner> runner_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55630
631 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52632 testing::StrictMock<quic::test::MockQuicConnectionVisitor> visitor_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55633 TransportSecurityState transport_security_state_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52634 quic::QuicCryptoClientConfig crypto_config_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55635
Ryan Hamilton8d9ee76e2018-05-29 23:52:52636 const quic::QuicConnectionId connection_id_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55637 QuicTestPacketMaker client_maker_;
638 QuicTestPacketMaker server_maker_;
639 IPEndPoint peer_addr_;
Tsuyoshi Horo432981d52022-06-09 09:50:13640 quic::test::MockRandom random_generator_{0};
Yixin Wang0d2c6b7e12017-08-16 21:12:55641 ProofVerifyDetailsChromium verify_details_;
642 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Nidhi Jaju7135c5e2022-09-03 04:39:57643 quic::test::MockConnectionIdGenerator connection_id_generator_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55644
645 std::string user_agent_;
Dan McArdle68a5f622021-07-09 20:56:53646 url::SchemeHostPort proxy_endpoint_;
647 url::SchemeHostPort destination_endpoint_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55648 HttpAuthCache http_auth_cache_;
649 std::unique_ptr<MockHostResolverBase> host_resolver_;
650 std::unique_ptr<HttpAuthHandlerRegistryFactory> http_auth_handler_factory_;
651
652 TestCompletionCallback read_callback_;
653 scoped_refptr<IOBuffer> read_buf_;
654
655 TestCompletionCallback write_callback_;
656
Bence Béky6e243aa2019-12-13 19:01:07657 quic::test::NoopQpackStreamSenderDelegate noop_qpack_stream_sender_delegate_;
Yixin Wang0d2c6b7e12017-08-16 21:12:55658};
659
660TEST_P(QuicProxyClientSocketTest, ConnectSendsCorrectRequest) {
Renjie Tangaadb84b2019-08-31 01:00:23661 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25662 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:23663 mock_quic_data_.AddWrite(SYNCHRONOUS,
664 ConstructSettingsPacket(packet_number++));
665 }
666 mock_quic_data_.AddWrite(SYNCHRONOUS,
667 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:43668 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(
Renjie Tangcd594f32020-07-11 20:18:34671 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
672 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55673
674 Initialize();
675
676 ASSERT_FALSE(sock_->IsConnected());
677
678 AssertConnectSucceeds();
679
680 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
681 ASSERT_TRUE(response != nullptr);
682 ASSERT_EQ(200, response->headers->response_code());
David Benjamin854a9922022-01-22 01:25:10683
684 // Although the underlying HTTP/3 connection uses TLS and negotiates ALPN, the
685 // tunnel itself is a TCP connection to the origin and should not report these
686 // values.
687 net::SSLInfo ssl_info;
688 EXPECT_FALSE(sock_->GetSSLInfo(&ssl_info));
689 EXPECT_FALSE(sock_->WasAlpnNegotiated());
690 EXPECT_EQ(sock_->GetNegotiatedProtocol(), NextProto::kProtoUnknown);
Yixin Wang0d2c6b7e12017-08-16 21:12:55691}
692
Robert Ogden78d4f9eb2020-03-17 20:56:38693TEST_P(QuicProxyClientSocketTest, ProxyDelegateExtraHeaders) {
694 proxy_delegate_ = std::make_unique<TestProxyDelegate>();
Dan McArdle68a5f622021-07-09 20:56:53695 // TODO(crbug.com/1206799) Construct `ProxyServer` with plain
696 // `proxy_endpoint_` once it supports `url::SchemeHostPort`.
697 ProxyServer proxy_server(ProxyServer::SCHEME_HTTPS,
698 HostPortPair::FromSchemeHostPort(proxy_endpoint_));
Robert Ogden78d4f9eb2020-03-17 20:56:38699
700 const char kResponseHeaderName[] = "foo";
701 const char kResponseHeaderValue[] = "testing";
702
703 int packet_number = 1;
704 if (VersionUsesHttp3(version_.transport_version)) {
705 mock_quic_data_.AddWrite(SYNCHRONOUS,
706 ConstructSettingsPacket(packet_number++));
707 }
Eric Orth5ccc3f02021-09-23 00:01:57708 mock_quic_data_.AddWrite(SYNCHRONOUS,
709 ConstructConnectRequestPacketWithExtraHeaders(
710 packet_number++,
711 // Order matters! Keep these alphabetical.
712 {{"foo", ProxyServerToProxyUri(proxy_server)},
713 {"user-agent", kUserAgent}}));
Robert Ogden78d4f9eb2020-03-17 20:56:38714 mock_quic_data_.AddRead(
715 ASYNC, ConstructServerConnectReplyPacketWithExtraHeaders(
716 1, !kFin, {{kResponseHeaderName, kResponseHeaderValue}}));
717 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
718 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:34719 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
720 quic::QUIC_STREAM_CANCELLED, 1, 1));
Robert Ogden78d4f9eb2020-03-17 20:56:38721
722 Initialize();
723
724 ASSERT_FALSE(sock_->IsConnected());
725
726 AssertConnectSucceeds();
727
728 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
729 ASSERT_TRUE(response != nullptr);
730 ASSERT_EQ(200, response->headers->response_code());
731 proxy_delegate_->VerifyOnTunnelHeadersReceived(
732 proxy_server, kResponseHeaderName, kResponseHeaderValue);
733}
734
Yixin Wang0d2c6b7e12017-08-16 21:12:55735TEST_P(QuicProxyClientSocketTest, ConnectWithAuthRequested) {
Renjie Tangaadb84b2019-08-31 01:00:23736 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25737 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:23738 mock_quic_data_.AddWrite(SYNCHRONOUS,
739 ConstructSettingsPacket(packet_number++));
740 }
741 mock_quic_data_.AddWrite(SYNCHRONOUS,
742 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:43743 mock_quic_data_.AddRead(ASYNC,
744 ConstructServerConnectAuthReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55745 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
746 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:34747 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
748 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55749
750 Initialize();
751
752 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
753
754 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
755 ASSERT_TRUE(response != nullptr);
756 ASSERT_EQ(407, response->headers->response_code());
757}
758
759TEST_P(QuicProxyClientSocketTest, ConnectWithAuthCredentials) {
Renjie Tangaadb84b2019-08-31 01:00:23760 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25761 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:23762 mock_quic_data_.AddWrite(SYNCHRONOUS,
763 ConstructSettingsPacket(packet_number++));
764 }
765 mock_quic_data_.AddWrite(SYNCHRONOUS,
766 ConstructConnectAuthRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:43767 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55768 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
769 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:34770 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
771 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55772
773 Initialize();
774
775 // Add auth to cache
Jan Wilken Dörriec92a6d7242021-03-23 17:43:48776 const std::u16string kFoo(u"foo");
777 const std::u16string kBar(u"bar");
Matt Menke8db2ff52021-11-23 20:17:46778 http_auth_cache_.Add(
779 url::SchemeHostPort(GURL(kProxyUrl)), HttpAuth::AUTH_PROXY, "MyRealm1",
780 HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
781 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
Yixin Wang0d2c6b7e12017-08-16 21:12:55782
783 AssertConnectSucceeds();
784
785 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
786 ASSERT_TRUE(response != nullptr);
787 ASSERT_EQ(200, response->headers->response_code());
788}
789
Eric Roman96c5b292019-04-23 18:04:59790// Tests that a redirect response from a CONNECT fails.
Yixin Wang0d2c6b7e12017-08-16 21:12:55791TEST_P(QuicProxyClientSocketTest, ConnectRedirects) {
Renjie Tangaadb84b2019-08-31 01:00:23792 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25793 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:23794 mock_quic_data_.AddWrite(SYNCHRONOUS,
795 ConstructSettingsPacket(packet_number++));
796 }
797 mock_quic_data_.AddWrite(SYNCHRONOUS,
798 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:43799 mock_quic_data_.AddRead(ASYNC,
800 ConstructServerConnectRedirectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55801 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
802 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:34803 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
804 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55805
806 Initialize();
807
Eric Roman96c5b292019-04-23 18:04:59808 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
Yixin Wang0d2c6b7e12017-08-16 21:12:55809
810 const HttpResponseInfo* response = sock_->GetConnectResponseInfo();
811 ASSERT_TRUE(response != nullptr);
812
813 const HttpResponseHeaders* headers = response->headers.get();
814 ASSERT_EQ(302, headers->response_code());
Eric Roman96c5b292019-04-23 18:04:59815 ASSERT_TRUE(headers->HasHeader("set-cookie"));
Yixin Wang0d2c6b7e12017-08-16 21:12:55816
817 std::string location;
818 ASSERT_TRUE(headers->IsRedirect(&location));
819 ASSERT_EQ(location, kRedirectUrl);
820}
821
822TEST_P(QuicProxyClientSocketTest, ConnectFails) {
Renjie Tangaadb84b2019-08-31 01:00:23823 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25824 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:23825 mock_quic_data_.AddWrite(SYNCHRONOUS,
826 ConstructSettingsPacket(packet_number++));
827 }
828 mock_quic_data_.AddWrite(SYNCHRONOUS,
829 ConstructConnectRequestPacket(packet_number++));
David Schinazi395918c2021-02-05 18:56:21830 mock_quic_data_.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang0d2c6b7e12017-08-16 21:12:55831
832 Initialize();
833
834 ASSERT_FALSE(sock_->IsConnected());
835
836 AssertConnectFails(ERR_QUIC_PROTOCOL_ERROR);
837
838 ASSERT_FALSE(sock_->IsConnected());
839}
840
841TEST_P(QuicProxyClientSocketTest, WasEverUsedReturnsCorrectValue) {
Renjie Tangaadb84b2019-08-31 01:00:23842 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25843 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:23844 mock_quic_data_.AddWrite(SYNCHRONOUS,
845 ConstructSettingsPacket(packet_number++));
846 }
847 mock_quic_data_.AddWrite(SYNCHRONOUS,
848 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:43849 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55850 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
851 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:34852 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
853 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:55854
855 Initialize();
856
Victor Vasiliev7da08172019-10-14 06:04:25857 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:23858 EXPECT_TRUE(sock_->WasEverUsed()); // Used due to crypto handshake
Yixin Wang0d2c6b7e12017-08-16 21:12:55859 AssertConnectSucceeds();
860 EXPECT_TRUE(sock_->WasEverUsed());
861 sock_->Disconnect();
862 EXPECT_TRUE(sock_->WasEverUsed());
863}
864
865TEST_P(QuicProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
Renjie Tangaadb84b2019-08-31 01:00:23866 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25867 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:23868 mock_quic_data_.AddWrite(SYNCHRONOUS,
869 ConstructSettingsPacket(packet_number++));
870 }
871 mock_quic_data_.AddWrite(SYNCHRONOUS,
872 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:43873 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55874 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:21875 mock_quic_data_.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang0d2c6b7e12017-08-16 21:12:55876
877 Initialize();
878
879 IPEndPoint addr;
880 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
881
882 AssertConnectSucceeds();
883 EXPECT_TRUE(sock_->IsConnected());
884 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsOk());
885
886 ResumeAndRun();
887
888 EXPECT_FALSE(sock_->IsConnected());
889 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
890
891 sock_->Disconnect();
892
893 EXPECT_THAT(sock_->GetPeerAddress(&addr), IsError(ERR_SOCKET_NOT_CONNECTED));
894}
895
896TEST_P(QuicProxyClientSocketTest, IsConnectedAndIdle) {
Renjie Tangaadb84b2019-08-31 01:00:23897 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25898 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:23899 mock_quic_data_.AddWrite(SYNCHRONOUS,
900 ConstructSettingsPacket(packet_number++));
901 }
902 mock_quic_data_.AddWrite(SYNCHRONOUS,
903 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:43904 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:55905 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
906
Victor Vasiliev076657c2019-03-12 02:46:43907 std::string header = ConstructDataHeader(kLen1);
Ryan Hamilton7505eb92019-06-08 00:22:17908 mock_quic_data_.AddRead(
909 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41910 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:34911 ConstructAckPacket(packet_number++, 2, 1));
Renjie Tangaadb84b2019-08-31 01:00:23912 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
913 mock_quic_data_.AddWrite(
914 SYNCHRONOUS,
915 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
Yixin Wang0d2c6b7e12017-08-16 21:12:55916
917 Initialize();
918
919 EXPECT_FALSE(sock_->IsConnectedAndIdle());
920
921 AssertConnectSucceeds();
922
923 EXPECT_TRUE(sock_->IsConnectedAndIdle());
924
925 // The next read is consumed and buffered.
926 ResumeAndRun();
927
928 EXPECT_FALSE(sock_->IsConnectedAndIdle());
929
930 AssertSyncReadEquals(kMsg1, kLen1);
931
932 EXPECT_TRUE(sock_->IsConnectedAndIdle());
933}
934
935TEST_P(QuicProxyClientSocketTest, GetTotalReceivedBytes) {
Renjie Tangaadb84b2019-08-31 01:00:23936 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25937 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:23938 mock_quic_data_.AddWrite(SYNCHRONOUS,
939 ConstructSettingsPacket(packet_number++));
940 }
Renjie Tang1085bf52019-11-20 00:10:53941 size_t header_length;
Renjie Tangaadb84b2019-08-31 01:00:23942 mock_quic_data_.AddWrite(SYNCHRONOUS,
943 ConstructConnectRequestPacket(packet_number++));
Renjie Tang1085bf52019-11-20 00:10:53944 mock_quic_data_.AddRead(
945 ASYNC, ConstructServerConnectReplyPacket(1, !kFin, &header_length));
Yixin Wang0d2c6b7e12017-08-16 21:12:55946 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
947
Renjie Tang1085bf52019-11-20 00:10:53948 std::string data_header = ConstructDataHeader(kLen333);
949 mock_quic_data_.AddRead(ASYNC,
950 ConstructServerDataPacket(
951 2, data_header + std::string(kMsg333, kLen333)));
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41952 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:34953 ConstructAckPacket(packet_number++, 2, 1));
Renjie Tangaadb84b2019-08-31 01:00:23954 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
955 mock_quic_data_.AddWrite(
956 SYNCHRONOUS,
957 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
Yixin Wang0d2c6b7e12017-08-16 21:12:55958
959 Initialize();
960
961 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
962
963 AssertConnectSucceeds();
964
Renjie Tang1085bf52019-11-20 00:10:53965 if (!VersionUsesHttp3(version_.transport_version)) {
966 header_length = 0;
967 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
968 } else {
969 // HTTP/3 sends and receives HTTP headers on the request stream.
970 EXPECT_EQ((int64_t)(header_length), sock_->GetTotalReceivedBytes());
971 }
Yixin Wang0d2c6b7e12017-08-16 21:12:55972
973 // The next read is consumed and buffered.
974 ResumeAndRun();
975
Renjie Tang1085bf52019-11-20 00:10:53976 if (!VersionUsesHttp3(version_.transport_version)) {
977 EXPECT_EQ(0, sock_->GetTotalReceivedBytes());
978 } else {
979 // HTTP/3 encodes data with DATA frame. The header is consumed.
980 EXPECT_EQ((int64_t)(header_length + data_header.length()),
981 sock_->GetTotalReceivedBytes());
982 }
Yixin Wang0d2c6b7e12017-08-16 21:12:55983
984 // The payload from the single large data frame will be read across
985 // two different reads.
986 AssertSyncReadEquals(kMsg33, kLen33);
987
Renjie Tang1085bf52019-11-20 00:10:53988 EXPECT_EQ((int64_t)(header_length + data_header.length() + kLen33),
Renjief49758b2019-01-11 23:32:41989 sock_->GetTotalReceivedBytes());
Yixin Wang0d2c6b7e12017-08-16 21:12:55990
991 AssertSyncReadEquals(kMsg3, kLen3);
992
Renjie Tang1085bf52019-11-20 00:10:53993 EXPECT_EQ((int64_t)(header_length + kLen333 + data_header.length()),
Renjief49758b2019-01-11 23:32:41994 sock_->GetTotalReceivedBytes());
Yixin Wang0d2c6b7e12017-08-16 21:12:55995}
996
Lily Chenf11e1292018-11-29 16:42:09997TEST_P(QuicProxyClientSocketTest, SetStreamPriority) {
Renjie Tangaadb84b2019-08-31 01:00:23998 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:25999 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang1085bf52019-11-20 00:10:531000 mock_quic_data_.AddWrite(SYNCHRONOUS,
1001 ConstructSettingsPacket(packet_number++));
Renjie Tangaadb84b2019-08-31 01:00:231002 }
Matt Menkeedaf3b82019-03-14 21:39:441003 // Despite setting the priority to HIGHEST, the requets initial priority of
1004 // LOWEST is used.
Renjie Tangaadb84b2019-08-31 01:00:231005 mock_quic_data_.AddWrite(
1006 SYNCHRONOUS, ConstructConnectRequestPacket(packet_number++, LOWEST));
Lily Chenf11e1292018-11-29 16:42:091007 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
1008 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1009 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341010 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1011 quic::QUIC_STREAM_CANCELLED, 1, 1));
Lily Chenf11e1292018-11-29 16:42:091012
1013 Initialize();
1014
1015 sock_->SetStreamPriority(HIGHEST);
1016 AssertConnectSucceeds();
1017}
Yixin Wang0d2c6b7e12017-08-16 21:12:551018
1019TEST_P(QuicProxyClientSocketTest, WriteSendsDataInDataFrame) {
Renjie Tangaadb84b2019-08-31 01:00:231020 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251021 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231022 mock_quic_data_.AddWrite(SYNCHRONOUS,
1023 ConstructSettingsPacket(packet_number++));
1024 }
1025 mock_quic_data_.AddWrite(SYNCHRONOUS,
1026 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431027 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551028 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Nick Harperc6cb7a612020-02-24 20:03:321029 if (version_.HasIetfQuicFrames()) {
Victor Vasiliev076657c2019-03-12 02:46:431030 std::string header = ConstructDataHeader(kLen1);
1031 mock_quic_data_.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231032 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341033 ConstructAckAndDataPacket(packet_number++, 1, 1,
Renjie Tangd5133972019-12-06 00:20:281034 {header + std::string(kMsg1, kLen1)}));
Victor Vasiliev076657c2019-03-12 02:46:431035 std::string header2 = ConstructDataHeader(kLen2);
Renjief49758b2019-01-11 23:32:411036 mock_quic_data_.AddWrite(
Renjief49758b2019-01-11 23:32:411037 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:281038 ConstructDataPacket(packet_number++,
1039 {header2 + std::string(kMsg2, kLen2)}));
Renjief49758b2019-01-11 23:32:411040 mock_quic_data_.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231041 SYNCHRONOUS,
1042 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
1043 } else {
1044 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341045 SYNCHRONOUS, ConstructAckAndDataPacket(packet_number++, 1, 1,
Renjie Tangaadb84b2019-08-31 01:00:231046 std::string(kMsg1, kLen1)));
1047 mock_quic_data_.AddWrite(
1048 SYNCHRONOUS,
1049 ConstructDataPacket(packet_number++, std::string(kMsg2, kLen2)));
1050 mock_quic_data_.AddWrite(
1051 SYNCHRONOUS,
1052 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
Renjief49758b2019-01-11 23:32:411053 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551054
1055 Initialize();
1056
1057 AssertConnectSucceeds();
1058
1059 AssertSyncWriteSucceeds(kMsg1, kLen1);
1060 AssertSyncWriteSucceeds(kMsg2, kLen2);
1061}
1062
1063TEST_P(QuicProxyClientSocketTest, WriteSplitsLargeDataIntoMultiplePackets) {
Renjief49758b2019-01-11 23:32:411064 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:251065 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231066 mock_quic_data_.AddWrite(SYNCHRONOUS,
1067 ConstructSettingsPacket(write_packet_index++));
1068 }
Renjief49758b2019-01-11 23:32:411069 mock_quic_data_.AddWrite(SYNCHRONOUS,
1070 ConstructConnectRequestPacket(write_packet_index++));
Zhongyi Shi32f2fd02018-04-16 18:23:431071 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551072 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Victor Vasiliev076657c2019-03-12 02:46:431073 std::string header = ConstructDataHeader(kLen1);
Nick Harperc6cb7a612020-02-24 20:03:321074 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:411075 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341076 SYNCHRONOUS, ConstructAckAndDataPacket(write_packet_index++, 1, 1,
Victor Vasiliev076657c2019-03-12 02:46:431077 std::string(kMsg1, kLen1)));
Renjief49758b2019-01-11 23:32:411078 } else {
Renjie Tangd5133972019-12-06 00:20:281079 mock_quic_data_.AddWrite(
1080 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341081 ConstructAckAndDataPacket(write_packet_index++, 1, 1,
Renjie Tangd5133972019-12-06 00:20:281082 {header + std::string(kMsg1, kLen1)}));
Renjief49758b2019-01-11 23:32:411083 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551084
1085 // Expect |kNumDataPackets| data packets, each containing the max possible
1086 // amount of data.
Renjied172e812019-01-16 05:12:351087 int numDataPackets = 3;
1088 std::string data(numDataPackets * quic::kDefaultMaxPacketSize, 'x');
Renjief49758b2019-01-11 23:32:411089 quic::QuicStreamOffset offset = kLen1 + header.length();
Renjied172e812019-01-16 05:12:351090
Nick Harperc6cb7a612020-02-24 20:03:321091 if (version_.HasIetfQuicFrames()) {
Renjied172e812019-01-16 05:12:351092 numDataPackets++;
Renjief49758b2019-01-11 23:32:411093 }
Renjied172e812019-01-16 05:12:351094 size_t total_data_length = 0;
1095 for (int i = 0; i < numDataPackets; ++i) {
Yixin Wang0d2c6b7e12017-08-16 21:12:551096 size_t max_packet_data_length = GetStreamFrameDataLengthFromPacketLength(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521097 quic::kDefaultMaxPacketSize, version_, !kIncludeVersion,
1098 !kIncludeDiversificationNonce, quic::PACKET_8BYTE_CONNECTION_ID,
1099 quic::PACKET_1BYTE_PACKET_NUMBER, offset);
Nick Harperc6cb7a612020-02-24 20:03:321100 if (version_.HasIetfQuicFrames() && i == 0) {
Victor Vasiliev39caecf2021-09-28 03:06:031101 // 3673 is the data frame length from packet length.
1102 std::string header2 = ConstructDataHeader(3673);
Renjied172e812019-01-16 05:12:351103 mock_quic_data_.AddWrite(
Renjie Tangd5133972019-12-06 00:20:281104 SYNCHRONOUS,
1105 ConstructDataPacket(
1106 write_packet_index++,
1107 {header2 +
1108 std::string(data.c_str(), max_packet_data_length - 7)}));
Renjied172e812019-01-16 05:12:351109 offset += max_packet_data_length - header2.length() - 1;
Nick Harperc6cb7a612020-02-24 20:03:321110 } else if (version_.HasIetfQuicFrames() && i == numDataPackets - 1) {
Renjied172e812019-01-16 05:12:351111 mock_quic_data_.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:171112 SYNCHRONOUS, ConstructDataPacket(write_packet_index++,
Victor Vasiliev076657c2019-03-12 02:46:431113 std::string(data.c_str(), 7)));
Renjied172e812019-01-16 05:12:351114 offset += 7;
1115 } else {
1116 mock_quic_data_.AddWrite(
Victor Vasiliev076657c2019-03-12 02:46:431117 SYNCHRONOUS, ConstructDataPacket(
Ryan Hamilton7505eb92019-06-08 00:22:171118 write_packet_index++,
Victor Vasiliev076657c2019-03-12 02:46:431119 std::string(data.c_str(), max_packet_data_length)));
Renjied172e812019-01-16 05:12:351120 offset += max_packet_data_length;
1121 }
1122 if (i != 3) {
1123 total_data_length += max_packet_data_length;
1124 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551125 }
Renjied172e812019-01-16 05:12:351126
Yixin Wang0d2c6b7e12017-08-16 21:12:551127 mock_quic_data_.AddWrite(
Ryan Hamiltonb5d4c5a2019-06-21 22:08:411128 SYNCHRONOUS,
1129 ConstructRstPacket(write_packet_index++, quic::QUIC_STREAM_CANCELLED));
Yixin Wang0d2c6b7e12017-08-16 21:12:551130
1131 Initialize();
1132
1133 AssertConnectSucceeds();
1134
1135 // Make a small write. An ACK and STOP_WAITING will be bundled. This prevents
1136 // ACK and STOP_WAITING from being bundled with the subsequent large write.
1137 // This allows the test code for computing the size of data sent in each
1138 // packet to not become too complicated.
1139 AssertSyncWriteSucceeds(kMsg1, kLen1);
1140
1141 // Make large write that should be split up
1142 AssertSyncWriteSucceeds(data.c_str(), total_data_length);
1143}
1144
1145// ----------- Read
1146
1147TEST_P(QuicProxyClientSocketTest, ReadReadsDataInDataFrame) {
Renjie Tangaadb84b2019-08-31 01:00:231148 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251149 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231150 mock_quic_data_.AddWrite(SYNCHRONOUS,
1151 ConstructSettingsPacket(packet_number++));
1152 }
1153 mock_quic_data_.AddWrite(SYNCHRONOUS,
1154 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431155 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551156 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1157
Victor Vasiliev076657c2019-03-12 02:46:431158 std::string header = ConstructDataHeader(kLen1);
Ryan Hamilton7505eb92019-06-08 00:22:171159 mock_quic_data_.AddRead(
1160 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
Ryan Hamiltonb5d4c5a2019-06-21 22:08:411161 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341162 ConstructAckPacket(packet_number++, 2, 1));
Renjie Tangaadb84b2019-08-31 01:00:231163 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1164 mock_quic_data_.AddWrite(
1165 SYNCHRONOUS,
1166 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
Yixin Wang0d2c6b7e12017-08-16 21:12:551167
1168 Initialize();
1169
1170 AssertConnectSucceeds();
1171
1172 ResumeAndRun();
1173 AssertSyncReadEquals(kMsg1, kLen1);
1174}
1175
1176TEST_P(QuicProxyClientSocketTest, ReadDataFromBufferedFrames) {
Renjie Tangaadb84b2019-08-31 01:00:231177 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251178 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231179 mock_quic_data_.AddWrite(SYNCHRONOUS,
1180 ConstructSettingsPacket(packet_number++));
1181 }
1182 mock_quic_data_.AddWrite(SYNCHRONOUS,
1183 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431184 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551185 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1186
Victor Vasiliev076657c2019-03-12 02:46:431187 std::string header = ConstructDataHeader(kLen1);
Ryan Hamilton7505eb92019-06-08 00:22:171188 mock_quic_data_.AddRead(
1189 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
Renjie Tangaadb84b2019-08-31 01:00:231190 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341191 ConstructAckPacket(packet_number++, 2, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551192 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1193
Victor Vasiliev076657c2019-03-12 02:46:431194 std::string header2 = ConstructDataHeader(kLen2);
1195 mock_quic_data_.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:171196 ASYNC, ConstructServerDataPacket(3, header2 + std::string(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551197 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1198
1199 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341200 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1201 quic::QUIC_STREAM_CANCELLED, 3, 3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551202
1203 Initialize();
1204
1205 AssertConnectSucceeds();
1206
1207 ResumeAndRun();
1208 AssertSyncReadEquals(kMsg1, kLen1);
1209
1210 ResumeAndRun();
1211 AssertSyncReadEquals(kMsg2, kLen2);
1212}
1213
1214TEST_P(QuicProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
Renjie Tangaadb84b2019-08-31 01:00:231215 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251216 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231217 mock_quic_data_.AddWrite(SYNCHRONOUS,
1218 ConstructSettingsPacket(packet_number++));
1219 }
1220 mock_quic_data_.AddWrite(SYNCHRONOUS,
1221 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431222 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551223 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1224
Victor Vasiliev076657c2019-03-12 02:46:431225 std::string header = ConstructDataHeader(kLen1);
Ryan Hamilton7505eb92019-06-08 00:22:171226 mock_quic_data_.AddRead(
1227 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
Renjie Tangaadb84b2019-08-31 01:00:231228 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341229 ConstructAckPacket(packet_number++, 2, 1));
Victor Vasiliev076657c2019-03-12 02:46:431230 std::string header2 = ConstructDataHeader(kLen2);
1231 mock_quic_data_.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:171232 ASYNC, ConstructServerDataPacket(3, header2 + std::string(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551233 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1234
1235 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341236 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1237 quic::QUIC_STREAM_CANCELLED, 3, 3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551238
1239 Initialize();
1240
1241 AssertConnectSucceeds();
1242
1243 // The next two reads are consumed and buffered.
1244 ResumeAndRun();
1245
1246 AssertSyncReadEquals(kMsg1, kLen1);
1247 AssertSyncReadEquals(kMsg2, kLen2);
1248}
1249
1250TEST_P(QuicProxyClientSocketTest, LargeReadWillMergeDataFromDifferentFrames) {
Renjie Tangaadb84b2019-08-31 01:00:231251 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251252 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231253 mock_quic_data_.AddWrite(SYNCHRONOUS,
1254 ConstructSettingsPacket(packet_number++));
1255 }
1256 mock_quic_data_.AddWrite(SYNCHRONOUS,
1257 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431258 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551259 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1260
Victor Vasiliev076657c2019-03-12 02:46:431261 std::string header = ConstructDataHeader(kLen3);
Ryan Hamilton7505eb92019-06-08 00:22:171262 mock_quic_data_.AddRead(
1263 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg3, kLen3)));
Renjie Tangaadb84b2019-08-31 01:00:231264 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341265 ConstructAckPacket(packet_number++, 2, 1));
Victor Vasiliev076657c2019-03-12 02:46:431266 std::string header2 = ConstructDataHeader(kLen3);
1267 mock_quic_data_.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:171268 ASYNC, ConstructServerDataPacket(3, header2 + std::string(kMsg3, kLen3)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551269 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1270
1271 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341272 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1273 quic::QUIC_STREAM_CANCELLED, 3, 3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551274
1275 Initialize();
1276
1277 AssertConnectSucceeds();
1278
1279 // The next two reads are consumed and buffered.
1280 ResumeAndRun();
1281 // The payload from two data frames, each with kMsg3 will be combined
1282 // together into a single read().
1283 AssertSyncReadEquals(kMsg33, kLen33);
1284}
1285
1286TEST_P(QuicProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
Renjie Tangaadb84b2019-08-31 01:00:231287 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251288 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231289 mock_quic_data_.AddWrite(SYNCHRONOUS,
1290 ConstructSettingsPacket(packet_number++));
1291 }
1292 mock_quic_data_.AddWrite(SYNCHRONOUS,
1293 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431294 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551295 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1296
Victor Vasiliev076657c2019-03-12 02:46:431297 std::string header = ConstructDataHeader(kLen1);
Renjief49758b2019-01-11 23:32:411298 mock_quic_data_.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:171299 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
Renjie Tangaadb84b2019-08-31 01:00:231300 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341301 ConstructAckPacket(packet_number++, 2, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551302
Victor Vasiliev076657c2019-03-12 02:46:431303 std::string header2 = ConstructDataHeader(kLen3);
Renjief49758b2019-01-11 23:32:411304 mock_quic_data_.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:171305 ASYNC, ConstructServerDataPacket(3, header2 + std::string(kMsg3, kLen3)));
Renjief49758b2019-01-11 23:32:411306 mock_quic_data_.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:171307 ASYNC, ConstructServerDataPacket(4, header2 + std::string(kMsg3, kLen3)));
Renjie Tangaadb84b2019-08-31 01:00:231308 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341309 ConstructAckPacket(packet_number++, 4, 3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551310
Victor Vasiliev076657c2019-03-12 02:46:431311 std::string header3 = ConstructDataHeader(kLen2);
Renjief49758b2019-01-11 23:32:411312 mock_quic_data_.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:171313 ASYNC, ConstructServerDataPacket(5, header3 + std::string(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551314 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1315
1316 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341317 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1318 quic::QUIC_STREAM_CANCELLED, 5, 5));
Yixin Wang0d2c6b7e12017-08-16 21:12:551319
1320 Initialize();
1321
1322 AssertConnectSucceeds();
1323
1324 // The next 4 reads are consumed and buffered.
1325 ResumeAndRun();
1326
1327 AssertSyncReadEquals(kMsg1, kLen1);
1328 // The payload from two data frames, each with kMsg3 will be combined
1329 // together into a single read().
1330 AssertSyncReadEquals(kMsg33, kLen33);
1331 AssertSyncReadEquals(kMsg2, kLen2);
1332}
1333
1334TEST_P(QuicProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
Renjie Tangaadb84b2019-08-31 01:00:231335 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251336 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231337 mock_quic_data_.AddWrite(SYNCHRONOUS,
1338 ConstructSettingsPacket(packet_number++));
1339 }
1340 mock_quic_data_.AddWrite(SYNCHRONOUS,
1341 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431342 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551343 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1344
Victor Vasiliev076657c2019-03-12 02:46:431345 std::string header = ConstructDataHeader(kLen1);
Ryan Hamilton7505eb92019-06-08 00:22:171346 mock_quic_data_.AddRead(
1347 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
Renjie Tangaadb84b2019-08-31 01:00:231348 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341349 ConstructAckPacket(packet_number++, 2, 1));
Victor Vasiliev076657c2019-03-12 02:46:431350 std::string header2 = ConstructDataHeader(kLen33);
Ryan Hamilton7505eb92019-06-08 00:22:171351 mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
1352 3, header2 + std::string(kMsg33, kLen33)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551353 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1354
1355 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341356 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1357 quic::QUIC_STREAM_CANCELLED, 3, 3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551358
1359 Initialize();
1360
1361 AssertConnectSucceeds();
1362
1363 // The next 2 reads are consumed and buffered.
1364 ResumeAndRun();
1365
1366 AssertSyncReadEquals(kMsg1, kLen1);
1367 // The payload from the single large data frame will be read across
1368 // two different reads.
1369 AssertSyncReadEquals(kMsg3, kLen3);
1370 AssertSyncReadEquals(kMsg3, kLen3);
1371}
1372
1373TEST_P(QuicProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
Renjie Tangaadb84b2019-08-31 01:00:231374 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251375 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231376 mock_quic_data_.AddWrite(SYNCHRONOUS,
1377 ConstructSettingsPacket(packet_number++));
1378 }
1379 mock_quic_data_.AddWrite(SYNCHRONOUS,
1380 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431381 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551382 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1383
Victor Vasiliev076657c2019-03-12 02:46:431384 std::string header = ConstructDataHeader(kLen333);
Renjief49758b2019-01-11 23:32:411385 mock_quic_data_.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:431386 ASYNC,
Ryan Hamilton7505eb92019-06-08 00:22:171387 ConstructServerDataPacket(2, header + std::string(kMsg333, kLen333)));
Renjie Tangaadb84b2019-08-31 01:00:231388 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341389 ConstructAckPacket(packet_number++, 2, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551390 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1391
Renjie Tangaadb84b2019-08-31 01:00:231392 mock_quic_data_.AddWrite(
1393 SYNCHRONOUS,
1394 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
Yixin Wang0d2c6b7e12017-08-16 21:12:551395
1396 Initialize();
1397
1398 AssertConnectSucceeds();
1399
1400 // The next read is consumed and buffered.
1401 ResumeAndRun();
1402
1403 // The payload from the single large data frame will be read across
1404 // two different reads.
1405 AssertSyncReadEquals(kMsg33, kLen33);
1406
1407 // Now attempt to do a read of more data than remains buffered
Victor Costan9c7302b2018-08-27 16:39:441408 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(kLen33);
Bence Békyd8a21fc32018-06-27 18:29:581409 ASSERT_EQ(kLen3, sock_->Read(buf.get(), kLen33, CompletionOnceCallback()));
Ian Swett59044a642019-08-19 16:51:151410 ASSERT_EQ(std::string(kMsg3, kLen3), std::string(buf->data(), kLen3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551411 ASSERT_TRUE(sock_->IsConnected());
1412}
1413
1414TEST_P(QuicProxyClientSocketTest, ReadAuthResponseBody) {
Renjie Tangaadb84b2019-08-31 01:00:231415 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251416 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231417 mock_quic_data_.AddWrite(SYNCHRONOUS,
1418 ConstructSettingsPacket(packet_number++));
1419 }
1420 mock_quic_data_.AddWrite(SYNCHRONOUS,
1421 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431422 mock_quic_data_.AddRead(ASYNC,
1423 ConstructServerConnectAuthReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551424 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1425
Victor Vasiliev076657c2019-03-12 02:46:431426 std::string header = ConstructDataHeader(kLen1);
Ryan Hamilton7505eb92019-06-08 00:22:171427 mock_quic_data_.AddRead(
1428 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
Renjie Tangaadb84b2019-08-31 01:00:231429 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341430 ConstructAckPacket(packet_number++, 2, 1));
Victor Vasiliev076657c2019-03-12 02:46:431431 std::string header2 = ConstructDataHeader(kLen2);
1432 mock_quic_data_.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:171433 ASYNC, ConstructServerDataPacket(3, header2 + std::string(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551434 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1435
1436 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341437 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1438 quic::QUIC_STREAM_CANCELLED, 3, 3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551439
1440 Initialize();
1441
1442 AssertConnectFails(ERR_PROXY_AUTH_REQUESTED);
1443
1444 // The next two reads are consumed and buffered.
1445 ResumeAndRun();
1446
1447 AssertSyncReadEquals(kMsg1, kLen1);
1448 AssertSyncReadEquals(kMsg2, kLen2);
1449}
1450
1451TEST_P(QuicProxyClientSocketTest, ReadErrorResponseBody) {
Renjie Tangaadb84b2019-08-31 01:00:231452 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251453 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231454 mock_quic_data_.AddWrite(SYNCHRONOUS,
1455 ConstructSettingsPacket(packet_number++));
1456 }
1457 mock_quic_data_.AddWrite(SYNCHRONOUS,
1458 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431459 mock_quic_data_.AddRead(ASYNC,
1460 ConstructServerConnectErrorReplyPacket(1, !kFin));
Victor Vasiliev076657c2019-03-12 02:46:431461 std::string header = ConstructDataHeader(kLen1);
Renjief49758b2019-01-11 23:32:411462 mock_quic_data_.AddRead(
1463 SYNCHRONOUS,
Ryan Hamilton7505eb92019-06-08 00:22:171464 ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
Renjie Tangaadb84b2019-08-31 01:00:231465 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341466 ConstructAckPacket(packet_number++, 2, 1));
Victor Vasiliev076657c2019-03-12 02:46:431467 std::string header2 = ConstructDataHeader(kLen2);
Renjief49758b2019-01-11 23:32:411468 mock_quic_data_.AddRead(
1469 SYNCHRONOUS,
Ryan Hamilton7505eb92019-06-08 00:22:171470 ConstructServerDataPacket(3, header2 + std::string(kMsg2, kLen2)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551471 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1472
1473 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341474 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1475 quic::QUIC_STREAM_CANCELLED, 3, 3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551476 Initialize();
1477
1478 AssertConnectFails(ERR_TUNNEL_CONNECTION_FAILED);
1479}
1480
1481// ----------- Reads and Writes
1482
1483TEST_P(QuicProxyClientSocketTest, AsyncReadAroundWrite) {
Renjief49758b2019-01-11 23:32:411484 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:251485 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231486 mock_quic_data_.AddWrite(SYNCHRONOUS,
1487 ConstructSettingsPacket(write_packet_index++));
1488 }
Renjief49758b2019-01-11 23:32:411489 mock_quic_data_.AddWrite(SYNCHRONOUS,
1490 ConstructConnectRequestPacket(write_packet_index++));
Zhongyi Shi32f2fd02018-04-16 18:23:431491 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551492 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1493
Victor Vasiliev076657c2019-03-12 02:46:431494 std::string header = ConstructDataHeader(kLen1);
Ryan Hamilton7505eb92019-06-08 00:22:171495 mock_quic_data_.AddRead(
1496 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
Zhongyi Shi32f2fd02018-04-16 18:23:431497 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341498 ConstructAckPacket(write_packet_index++, 2, 1));
Renjief49758b2019-01-11 23:32:411499
Victor Vasiliev076657c2019-03-12 02:46:431500 std::string header2 = ConstructDataHeader(kLen2);
Nick Harperc6cb7a612020-02-24 20:03:321501 if (version_.HasIetfQuicFrames()) {
Victor Vasiliev076657c2019-03-12 02:46:431502 mock_quic_data_.AddWrite(
1503 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:281504 ConstructDataPacket(write_packet_index++,
1505 {header2 + std::string(kMsg2, kLen2)}));
Renjied172e812019-01-16 05:12:351506 } else {
Renjief49758b2019-01-11 23:32:411507 mock_quic_data_.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:171508 SYNCHRONOUS,
1509 ConstructDataPacket(write_packet_index++, std::string(kMsg2, kLen2)));
Renjied172e812019-01-16 05:12:351510 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551511
1512 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1513
Victor Vasiliev076657c2019-03-12 02:46:431514 std::string header3 = ConstructDataHeader(kLen3);
1515 mock_quic_data_.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:171516 ASYNC, ConstructServerDataPacket(3, header3 + std::string(kMsg3, kLen3)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551517 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1518
1519 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341520 SYNCHRONOUS, ConstructAckAndRstPacket(write_packet_index++,
1521 quic::QUIC_STREAM_CANCELLED, 3, 3));
Yixin Wang0d2c6b7e12017-08-16 21:12:551522
1523 Initialize();
1524
1525 AssertConnectSucceeds();
1526
1527 ResumeAndRun();
1528
1529 AssertSyncReadEquals(kMsg1, kLen1);
1530
1531 AssertReadStarts(kMsg3, kLen3);
1532 // Read should block until after the write succeeds.
1533
1534 AssertSyncWriteSucceeds(kMsg2, kLen2);
1535
1536 ASSERT_FALSE(read_callback_.have_result());
1537 ResumeAndRun();
1538
1539 // Now the read will return.
1540 AssertReadReturns(kMsg3, kLen3);
1541}
1542
1543TEST_P(QuicProxyClientSocketTest, AsyncWriteAroundReads) {
Renjie Tangaadb84b2019-08-31 01:00:231544 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251545 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231546 mock_quic_data_.AddWrite(SYNCHRONOUS,
1547 ConstructSettingsPacket(packet_number++));
1548 }
1549 mock_quic_data_.AddWrite(SYNCHRONOUS,
1550 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431551 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551552 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1553
Victor Vasiliev076657c2019-03-12 02:46:431554 std::string header = ConstructDataHeader(kLen1);
Ryan Hamilton7505eb92019-06-08 00:22:171555 mock_quic_data_.AddRead(
1556 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
Renjie Tangaadb84b2019-08-31 01:00:231557 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341558 ConstructAckPacket(packet_number++, 2, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551559 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1560
Victor Vasiliev076657c2019-03-12 02:46:431561 std::string header2 = ConstructDataHeader(kLen3);
1562 mock_quic_data_.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:171563 ASYNC, ConstructServerDataPacket(3, header2 + std::string(kMsg3, kLen3)));
Yixin Wang0d2c6b7e12017-08-16 21:12:551564 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1565
1566 mock_quic_data_.AddWrite(ASYNC, ERR_IO_PENDING); // Pause
1567
Victor Vasiliev076657c2019-03-12 02:46:431568 std::string header3 = ConstructDataHeader(kLen2);
Nick Harperc6cb7a612020-02-24 20:03:321569 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:411570 mock_quic_data_.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231571 ASYNC, ConstructDataPacket(packet_number++, std::string(kMsg2, kLen2)));
1572 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341573 SYNCHRONOUS, ConstructAckAndDataPacket(packet_number++, 3, 3,
Renjie Tangaadb84b2019-08-31 01:00:231574 std::string(kMsg2, kLen2)));
Renjief49758b2019-01-11 23:32:411575 } else {
1576 mock_quic_data_.AddWrite(
Renjie Tangd5133972019-12-06 00:20:281577 ASYNC, ConstructDataPacket(packet_number++,
1578 {header3 + std::string(kMsg2, kLen2)}));
Renjie Tangaadb84b2019-08-31 01:00:231579 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341580 ASYNC, ConstructAckAndDataPacket(packet_number++, 3, 3,
Victor Vasiliev076657c2019-03-12 02:46:431581 header3 + std::string(kMsg2, kLen2)));
Renjief49758b2019-01-11 23:32:411582 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551583
Renjie Tangaadb84b2019-08-31 01:00:231584 mock_quic_data_.AddWrite(
1585 SYNCHRONOUS,
1586 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
Yixin Wang0d2c6b7e12017-08-16 21:12:551587
1588 Initialize();
1589
1590 AssertConnectSucceeds();
1591
1592 ResumeAndRun();
1593 AssertSyncReadEquals(kMsg1, kLen1);
1594
1595 // Write should block until the next read completes.
1596 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1597 // asynchronous starting with the second time it's called while the UDP socket
1598 // is write-blocked. Therefore, at least two writes need to be called on
1599 // |sock_| to get an asynchronous one.
Renjied172e812019-01-16 05:12:351600 AssertWriteReturns(kMsg2, kLen2, kLen2);
Yixin Wang0d2c6b7e12017-08-16 21:12:551601 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
1602
1603 AssertAsyncReadEquals(kMsg3, kLen3);
1604
1605 ASSERT_FALSE(write_callback_.have_result());
1606
1607 // Now the write will complete
1608 ResumeAndRun();
Yixin Wangdbbd8752018-01-17 21:50:021609 EXPECT_EQ(kLen2, write_callback_.WaitForResult());
Yixin Wang0d2c6b7e12017-08-16 21:12:551610}
1611
1612// ----------- Reading/Writing on Closed socket
1613
1614// Reading from an already closed socket should return 0
1615TEST_P(QuicProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
Renjie Tangaadb84b2019-08-31 01:00:231616 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251617 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231618 mock_quic_data_.AddWrite(SYNCHRONOUS,
1619 ConstructSettingsPacket(packet_number++));
1620 }
1621 mock_quic_data_.AddWrite(SYNCHRONOUS,
1622 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431623 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551624 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211625 mock_quic_data_.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang0d2c6b7e12017-08-16 21:12:551626
1627 Initialize();
1628
1629 AssertConnectSucceeds();
1630
1631 ResumeAndRun();
1632
1633 ASSERT_FALSE(sock_->IsConnected());
Raul Tambre94493c652019-03-11 17:18:351634 ASSERT_EQ(0, sock_->Read(nullptr, 1, CompletionOnceCallback()));
1635 ASSERT_EQ(0, sock_->Read(nullptr, 1, CompletionOnceCallback()));
1636 ASSERT_EQ(0, sock_->Read(nullptr, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551637 ASSERT_FALSE(sock_->IsConnectedAndIdle());
1638}
1639
1640// Read pending when socket is closed should return 0
1641TEST_P(QuicProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
Renjie Tangaadb84b2019-08-31 01:00:231642 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251643 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231644 mock_quic_data_.AddWrite(SYNCHRONOUS,
1645 ConstructSettingsPacket(packet_number++));
1646 }
1647 mock_quic_data_.AddWrite(SYNCHRONOUS,
1648 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431649 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551650 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211651 mock_quic_data_.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang0d2c6b7e12017-08-16 21:12:551652
1653 Initialize();
1654
1655 AssertConnectSucceeds();
1656
1657 AssertReadStarts(kMsg1, kLen1);
1658
1659 ResumeAndRun();
1660
1661 ASSERT_EQ(0, read_callback_.WaitForResult());
1662}
1663
1664// Reading from a disconnected socket is an error
1665TEST_P(QuicProxyClientSocketTest, ReadOnDisconnectSocketReturnsNotConnected) {
Renjie Tangaadb84b2019-08-31 01:00:231666 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251667 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231668 mock_quic_data_.AddWrite(SYNCHRONOUS,
1669 ConstructSettingsPacket(packet_number++));
1670 }
1671 mock_quic_data_.AddWrite(SYNCHRONOUS,
1672 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431673 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551674 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1675 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341676 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1677 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551678
1679 Initialize();
1680
1681 AssertConnectSucceeds();
1682
1683 sock_->Disconnect();
1684
1685 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
Bence Békyd8a21fc32018-06-27 18:29:581686 sock_->Read(nullptr, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551687}
1688
1689// Reading data after receiving FIN should return buffered data received before
1690// FIN, then 0.
1691TEST_P(QuicProxyClientSocketTest, ReadAfterFinReceivedReturnsBufferedData) {
Renjie Tangaadb84b2019-08-31 01:00:231692 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251693 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231694 mock_quic_data_.AddWrite(SYNCHRONOUS,
1695 ConstructSettingsPacket(packet_number++));
1696 }
1697 mock_quic_data_.AddWrite(SYNCHRONOUS,
1698 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431699 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551700 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1701
Victor Vasiliev076657c2019-03-12 02:46:431702 std::string header = ConstructDataHeader(kLen1);
1703 mock_quic_data_.AddRead(ASYNC, ConstructServerDataFinPacket(
Ryan Hamilton7505eb92019-06-08 00:22:171704 2, header + std::string(kMsg1, kLen1)));
Ryan Hamiltonb5d4c5a2019-06-21 22:08:411705 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341706 ConstructAckPacket(packet_number++, 2, 1));
Renjie Tangaadb84b2019-08-31 01:00:231707 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1708 mock_quic_data_.AddWrite(
1709 SYNCHRONOUS,
1710 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
Yixin Wang0d2c6b7e12017-08-16 21:12:551711
1712 Initialize();
1713
1714 AssertConnectSucceeds();
1715
1716 ResumeAndRun();
1717
1718 AssertSyncReadEquals(kMsg1, kLen1);
Raul Tambre94493c652019-03-11 17:18:351719 ASSERT_EQ(0, sock_->Read(nullptr, 1, CompletionOnceCallback()));
1720 ASSERT_EQ(0, sock_->Read(nullptr, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551721
1722 sock_->Disconnect();
1723 ASSERT_EQ(ERR_SOCKET_NOT_CONNECTED,
Bence Békyd8a21fc32018-06-27 18:29:581724 sock_->Read(nullptr, 1, CompletionOnceCallback()));
Yixin Wang0d2c6b7e12017-08-16 21:12:551725}
1726
1727// Calling Write() on a closed socket is an error.
1728TEST_P(QuicProxyClientSocketTest, WriteOnClosedStream) {
Renjie Tangaadb84b2019-08-31 01:00:231729 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251730 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231731 mock_quic_data_.AddWrite(SYNCHRONOUS,
1732 ConstructSettingsPacket(packet_number++));
1733 }
1734 mock_quic_data_.AddWrite(SYNCHRONOUS,
1735 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431736 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551737 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211738 mock_quic_data_.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang0d2c6b7e12017-08-16 21:12:551739
1740 Initialize();
1741
1742 AssertConnectSucceeds();
1743
1744 ResumeAndRun();
1745
1746 AssertWriteReturns(kMsg1, kLen1, ERR_QUIC_PROTOCOL_ERROR);
1747}
1748
1749// Calling Write() on a disconnected socket is an error.
1750TEST_P(QuicProxyClientSocketTest, WriteOnDisconnectedSocket) {
Renjie Tangaadb84b2019-08-31 01:00:231751 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251752 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231753 mock_quic_data_.AddWrite(SYNCHRONOUS,
1754 ConstructSettingsPacket(packet_number++));
1755 }
1756 mock_quic_data_.AddWrite(SYNCHRONOUS,
1757 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431758 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551759 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1760 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341761 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1762 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551763
1764 Initialize();
1765
1766 AssertConnectSucceeds();
1767
1768 sock_->Disconnect();
1769
1770 AssertWriteReturns(kMsg1, kLen1, ERR_SOCKET_NOT_CONNECTED);
1771}
1772
1773// If the socket is closed with a pending Write(), the callback should be called
1774// with the same error the session was closed with.
1775TEST_P(QuicProxyClientSocketTest, WritePendingOnClose) {
Renjie Tangaadb84b2019-08-31 01:00:231776 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251777 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231778 mock_quic_data_.AddWrite(SYNCHRONOUS,
1779 ConstructSettingsPacket(packet_number++));
1780 }
1781 mock_quic_data_.AddWrite(SYNCHRONOUS,
1782 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431783 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551784 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1785 mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
1786
1787 Initialize();
1788
1789 AssertConnectSucceeds();
1790
1791 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1792 // asynchronous starting with the second time it's called while the UDP socket
1793 // is write-blocked. Therefore, at least two writes need to be called on
1794 // |sock_| to get an asynchronous one.
Renjied172e812019-01-16 05:12:351795 AssertWriteReturns(kMsg1, kLen1, kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:551796
1797 // This second write will be async. This is the pending write that's being
1798 // tested.
1799 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1800
1801 // Make sure the write actually starts.
1802 base::RunLoop().RunUntilIdle();
1803
Ryan Hamilton8d9ee76e2018-05-29 23:52:521804 session_->CloseSessionOnError(ERR_CONNECTION_CLOSED,
Renjieba55fae2018-09-20 03:05:161805 quic::QUIC_INTERNAL_ERROR,
1806 quic::ConnectionCloseBehavior::SILENT_CLOSE);
Yixin Wang0d2c6b7e12017-08-16 21:12:551807
1808 EXPECT_THAT(write_callback_.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
1809}
1810
1811TEST_P(QuicProxyClientSocketTest, DisconnectWithWritePending) {
Renjie Tangaadb84b2019-08-31 01:00:231812 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251813 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231814 mock_quic_data_.AddWrite(SYNCHRONOUS,
1815 ConstructSettingsPacket(packet_number++));
1816 }
1817 mock_quic_data_.AddWrite(SYNCHRONOUS,
1818 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431819 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551820 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1821 mock_quic_data_.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
1822
1823 Initialize();
1824
1825 AssertConnectSucceeds();
1826
1827 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1828 // asynchronous starting with the second time it's called while the UDP socket
1829 // is write-blocked. Therefore, at least two writes need to be called on
1830 // |sock_| to get an asynchronous one.
Renjied172e812019-01-16 05:12:351831 AssertWriteReturns(kMsg1, kLen1, kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:551832
1833 // This second write will be async. This is the pending write that's being
1834 // tested.
1835 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
1836
1837 // Make sure the write actually starts.
1838 base::RunLoop().RunUntilIdle();
1839
1840 sock_->Disconnect();
1841 EXPECT_FALSE(sock_->IsConnected());
1842
1843 base::RunLoop().RunUntilIdle();
1844
1845 EXPECT_FALSE(sock_->IsConnected());
1846 EXPECT_FALSE(write_callback_.have_result());
1847}
1848
1849// If the socket is Disconnected with a pending Read(), the callback
1850// should not be called.
1851TEST_P(QuicProxyClientSocketTest, DisconnectWithReadPending) {
Renjie Tangaadb84b2019-08-31 01:00:231852 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251853 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231854 mock_quic_data_.AddWrite(SYNCHRONOUS,
1855 ConstructSettingsPacket(packet_number++));
1856 }
1857 mock_quic_data_.AddWrite(SYNCHRONOUS,
1858 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431859 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551860 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1861 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341862 SYNCHRONOUS, ConstructAckAndRstPacket(packet_number++,
1863 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang0d2c6b7e12017-08-16 21:12:551864
1865 Initialize();
1866
1867 AssertConnectSucceeds();
1868
1869 EXPECT_TRUE(sock_->IsConnected());
1870
1871 AssertReadStarts(kMsg1, kLen1);
1872
1873 sock_->Disconnect();
1874 EXPECT_FALSE(sock_->IsConnected());
1875
1876 base::RunLoop().RunUntilIdle();
1877
1878 EXPECT_FALSE(sock_->IsConnected());
1879 EXPECT_FALSE(read_callback_.have_result());
1880}
1881
1882// If the socket is Reset when both a read and write are pending,
1883// both should be called back.
1884TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePending) {
Renjie Tangaadb84b2019-08-31 01:00:231885 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251886 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231887 mock_quic_data_.AddWrite(SYNCHRONOUS,
1888 ConstructSettingsPacket(packet_number++));
1889 }
1890 mock_quic_data_.AddWrite(SYNCHRONOUS,
1891 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431892 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551893 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1894
1895 mock_quic_data_.AddRead(
Ryan Hamiltonb5d4c5a2019-06-21 22:08:411896 ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED));
Yixin Wang2bea3cf2017-11-09 18:11:031897 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Victor Vasiliev076657c2019-03-12 02:46:431898 std::string header = ConstructDataHeader(kLen2);
Nick Harperc6cb7a612020-02-24 20:03:321899 if (!version_.HasIetfQuicFrames()) {
Renjie Tangaadb84b2019-08-31 01:00:231900 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341901 ASYNC, ConstructAckAndDataPacket(packet_number++, 1, 1,
Renjie Tangaadb84b2019-08-31 01:00:231902 std::string(kMsg2, kLen2)));
Renjief49758b2019-01-11 23:32:411903 mock_quic_data_.AddWrite(
Ryan Hamiltonb5d4c5a2019-06-21 22:08:411904 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:231905 ConstructAckAndRstPacket(packet_number++,
Renjie Tangcd594f32020-07-11 20:18:341906 quic::QUIC_RST_ACKNOWLEDGEMENT, 2, 2));
Renjief49758b2019-01-11 23:32:411907 } else {
Renjie Tangd5133972019-12-06 00:20:281908 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341909 ASYNC, ConstructAckAndDataPacket(packet_number++, 1, 1,
Renjie Tangd5133972019-12-06 00:20:281910 {header + std::string(kMsg2, kLen2)}));
Ryan Hamiltonb5d4c5a2019-06-21 22:08:411911 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341912 SYNCHRONOUS, ConstructAckAndRstOnlyPacket(
1913 packet_number++, quic::QUIC_STREAM_CANCELLED, 2, 2));
Renjief49758b2019-01-11 23:32:411914 }
Yixin Wang0d2c6b7e12017-08-16 21:12:551915
1916 Initialize();
1917
1918 AssertConnectSucceeds();
1919
1920 EXPECT_TRUE(sock_->IsConnected());
1921
1922 AssertReadStarts(kMsg1, kLen1);
1923
1924 // Write should block until the next read completes.
1925 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
1926 // asynchronous starting with the second time it's called while the UDP socket
1927 // is write-blocked. Therefore, at least two writes need to be called on
1928 // |sock_| to get an asynchronous one.
Renjied172e812019-01-16 05:12:351929 AssertWriteReturns(kMsg2, kLen2, kLen2);
Renjief49758b2019-01-11 23:32:411930
Yixin Wang0d2c6b7e12017-08-16 21:12:551931 AssertWriteReturns(kMsg2, kLen2, ERR_IO_PENDING);
1932
1933 ResumeAndRun();
1934
1935 EXPECT_TRUE(read_callback_.have_result());
1936 EXPECT_TRUE(write_callback_.have_result());
1937}
1938
1939// Makes sure the proxy client socket's source gets the expected NetLog events
1940// and only the expected NetLog events (No SpdySession events).
1941TEST_P(QuicProxyClientSocketTest, NetLog) {
Renjie Tangaadb84b2019-08-31 01:00:231942 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:251943 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231944 mock_quic_data_.AddWrite(SYNCHRONOUS,
1945 ConstructSettingsPacket(packet_number++));
1946 }
1947 mock_quic_data_.AddWrite(SYNCHRONOUS,
1948 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:431949 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:551950 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1951
Victor Vasiliev076657c2019-03-12 02:46:431952 std::string header = ConstructDataHeader(kLen1);
Ryan Hamilton7505eb92019-06-08 00:22:171953 mock_quic_data_.AddRead(
1954 ASYNC, ConstructServerDataPacket(2, header + std::string(kMsg1, kLen1)));
Ryan Hamiltonb5d4c5a2019-06-21 22:08:411955 mock_quic_data_.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341956 ConstructAckPacket(packet_number++, 2, 1));
Renjie Tangaadb84b2019-08-31 01:00:231957 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1958 mock_quic_data_.AddWrite(
1959 SYNCHRONOUS,
1960 ConstructRstPacket(packet_number++, quic::QUIC_STREAM_CANCELLED));
Yixin Wang0d2c6b7e12017-08-16 21:12:551961
1962 Initialize();
1963
1964 AssertConnectSucceeds();
1965
1966 ResumeAndRun();
1967 AssertSyncReadEquals(kMsg1, kLen1);
1968
1969 NetLogSource sock_source = sock_->NetLog().source();
1970 sock_.reset();
1971
Matt Reichhoff0049a0b72021-10-20 20:44:261972 auto entry_list = net_log_observer_.GetEntriesForSource(sock_source);
Yixin Wang0d2c6b7e12017-08-16 21:12:551973
1974 ASSERT_EQ(entry_list.size(), 10u);
1975 EXPECT_TRUE(
1976 LogContainsBeginEvent(entry_list, 0, NetLogEventType::SOCKET_ALIVE));
1977 EXPECT_TRUE(LogContainsEvent(entry_list, 1,
1978 NetLogEventType::HTTP2_PROXY_CLIENT_SESSION,
1979 NetLogEventPhase::NONE));
1980 EXPECT_TRUE(LogContainsBeginEvent(
1981 entry_list, 2, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1982 EXPECT_TRUE(LogContainsEvent(
1983 entry_list, 3, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
1984 NetLogEventPhase::NONE));
1985 EXPECT_TRUE(LogContainsEndEvent(
1986 entry_list, 4, NetLogEventType::HTTP_TRANSACTION_TUNNEL_SEND_REQUEST));
1987 EXPECT_TRUE(LogContainsBeginEvent(
1988 entry_list, 5, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1989 EXPECT_TRUE(LogContainsEvent(
1990 entry_list, 6,
1991 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
1992 NetLogEventPhase::NONE));
1993 EXPECT_TRUE(LogContainsEndEvent(
1994 entry_list, 7, NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS));
1995 EXPECT_TRUE(LogContainsEvent(entry_list, 8,
1996 NetLogEventType::SOCKET_BYTES_RECEIVED,
1997 NetLogEventPhase::NONE));
1998 EXPECT_TRUE(
1999 LogContainsEndEvent(entry_list, 9, NetLogEventType::SOCKET_ALIVE));
2000}
2001
Bence Béky8ddc2492018-06-13 01:02:042002// A helper class that will delete |sock| when the callback is invoked.
Yixin Wang0d2c6b7e12017-08-16 21:12:552003class DeleteSockCallback : public TestCompletionCallbackBase {
2004 public:
2005 explicit DeleteSockCallback(std::unique_ptr<QuicProxyClientSocket>* sock)
Bence Béky8ddc2492018-06-13 01:02:042006 : sock_(sock) {}
Yixin Wang0d2c6b7e12017-08-16 21:12:552007
Peter Boström293b1342021-09-22 17:31:432008 DeleteSockCallback(const DeleteSockCallback&) = delete;
2009 DeleteSockCallback& operator=(const DeleteSockCallback&) = delete;
2010
Tsuyoshi Horo07c3f0e2022-06-16 07:30:472011 ~DeleteSockCallback() override = default;
Yixin Wang0d2c6b7e12017-08-16 21:12:552012
Bence Béky8ddc2492018-06-13 01:02:042013 CompletionOnceCallback callback() {
2014 return base::BindOnce(&DeleteSockCallback::OnComplete,
2015 base::Unretained(this));
2016 }
Yixin Wang0d2c6b7e12017-08-16 21:12:552017
2018 private:
2019 void OnComplete(int result) {
Raul Tambre94493c652019-03-11 17:18:352020 sock_->reset(nullptr);
Yixin Wang0d2c6b7e12017-08-16 21:12:552021 SetResult(result);
2022 }
2023
Keishi Hattori0e45c022021-11-27 09:25:522024 raw_ptr<std::unique_ptr<QuicProxyClientSocket>> sock_;
Yixin Wang0d2c6b7e12017-08-16 21:12:552025};
2026
2027// If the socket is reset when both a read and write are pending, and the
2028// read callback causes the socket to be deleted, the write callback should
2029// not be called.
2030TEST_P(QuicProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
Renjie Tangaadb84b2019-08-31 01:00:232031 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:252032 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232033 mock_quic_data_.AddWrite(SYNCHRONOUS,
2034 ConstructSettingsPacket(packet_number++));
2035 }
2036 mock_quic_data_.AddWrite(SYNCHRONOUS,
2037 ConstructConnectRequestPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:432038 mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
Yixin Wang0d2c6b7e12017-08-16 21:12:552039 mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2040
2041 mock_quic_data_.AddRead(
Ryan Hamiltonb5d4c5a2019-06-21 22:08:412042 ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED));
Yixin Wang0d2c6b7e12017-08-16 21:12:552043 mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Nick Harperc6cb7a612020-02-24 20:03:322044 if (!version_.HasIetfQuicFrames()) {
Renjie Tangaadb84b2019-08-31 01:00:232045 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:342046 ASYNC, ConstructAckAndDataPacket(packet_number++, 1, 1,
Renjie Tangaadb84b2019-08-31 01:00:232047 std::string(kMsg1, kLen1)));
Renjief49758b2019-01-11 23:32:412048 mock_quic_data_.AddWrite(
Ryan Hamiltonb5d4c5a2019-06-21 22:08:412049 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:232050 ConstructAckAndRstPacket(packet_number++,
Renjie Tangcd594f32020-07-11 20:18:342051 quic::QUIC_RST_ACKNOWLEDGEMENT, 2, 2));
Renjief49758b2019-01-11 23:32:412052 } else {
Victor Vasiliev076657c2019-03-12 02:46:432053 std::string header = ConstructDataHeader(kLen1);
Renjie Tangd5133972019-12-06 00:20:282054 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:342055 ASYNC, ConstructAckAndDataPacket(packet_number++, 1, 1,
Renjie Tangd5133972019-12-06 00:20:282056 {header + std::string(kMsg1, kLen1)}));
Ryan Hamiltonb5d4c5a2019-06-21 22:08:412057 mock_quic_data_.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:342058 SYNCHRONOUS, ConstructAckAndRstOnlyPacket(
2059 packet_number++, quic::QUIC_STREAM_CANCELLED, 2, 2));
Renjief49758b2019-01-11 23:32:412060 }
Yixin Wang0d2c6b7e12017-08-16 21:12:552061
2062 Initialize();
2063
2064 AssertConnectSucceeds();
2065
2066 EXPECT_TRUE(sock_->IsConnected());
2067
2068 DeleteSockCallback read_callback(&sock_);
Victor Costan9c7302b2018-08-27 16:39:442069 scoped_refptr<IOBuffer> read_buf = base::MakeRefCounted<IOBuffer>(kLen1);
Yixin Wang0d2c6b7e12017-08-16 21:12:552070 ASSERT_EQ(ERR_IO_PENDING,
2071 sock_->Read(read_buf.get(), kLen1, read_callback.callback()));
2072
2073 // QuicChromiumClientStream::Handle::WriteStreamData() will only be
2074 // asynchronous starting with the second time it's called while the UDP socket
2075 // is write-blocked. Therefore, at least two writes need to be called on
2076 // |sock_| to get an asynchronous one.
Renjied172e812019-01-16 05:12:352077 AssertWriteReturns(kMsg1, kLen1, kLen1);
Renjief49758b2019-01-11 23:32:412078
Yixin Wang0d2c6b7e12017-08-16 21:12:552079 AssertWriteReturns(kMsg1, kLen1, ERR_IO_PENDING);
2080
2081 ResumeAndRun();
2082
2083 EXPECT_FALSE(sock_.get());
2084
2085 EXPECT_EQ(0, read_callback.WaitForResult());
2086 EXPECT_FALSE(write_callback_.have_result());
2087}
2088
David Schinazi09e9a6012019-10-03 17:37:572089INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
2090 QuicProxyClientSocketTest,
2091 ::testing::ValuesIn(GetTestParams()),
2092 ::testing::PrintToStringParamName());
Yixin Wang0d2c6b7e12017-08-16 21:12:552093
Tsuyoshi Horo4f516be2022-06-14 11:53:132094} // namespace net::test