blob: 8020bd06ce1a519e80da1b6d59f6753c9ce1bd2c [file] [log] [blame]
[email protected]61a527782013-02-21 03:58:001// Copyright (c) 2012 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
rchbd089ab2017-05-26 23:05:045#include <algorithm>
bnc359ed2a2016-04-29 20:43:456#include <ostream>
bnc912a04b2016-04-20 14:19:507#include <string>
8#include <utility>
[email protected]1e960032013-12-20 19:00:209#include <vector>
10
Sebastien Marchand6d0558fd2019-01-25 16:49:3711#include "base/bind.h"
[email protected]61a527782013-02-21 03:58:0012#include "base/compiler_specific.h"
Keishi Hattori0e45c022021-11-27 09:25:5213#include "base/memory/raw_ptr.h"
mmenke651bae7f2015-12-18 21:26:4514#include "base/run_loop.h"
Bence Béky319388a882020-09-23 18:42:5215#include "base/strings/strcat.h"
zhongyie537a002017-06-27 16:48:2116#include "base/strings/string_number_conversions.h"
Bence Békyd74f4382018-02-20 18:26:1917#include "base/strings/string_piece.h"
bnc8be55ebb2015-10-30 14:12:0718#include "base/strings/stringprintf.h"
Devlin Cronine4bcb40e2018-06-05 18:02:4719#include "base/test/metrics/histogram_tester.h"
Matt Menke26e41542019-06-05 01:09:5120#include "base/test/scoped_feature_list.h"
rtenneti56977812016-01-15 19:26:5621#include "net/base/chunked_upload_data_stream.h"
Bence Békyd8a21fc32018-06-27 18:29:5822#include "net/base/completion_once_callback.h"
Matt Menke26e41542019-06-05 01:09:5123#include "net/base/features.h"
Tsuyoshi Horo01faed62019-02-20 22:11:3724#include "net/base/ip_endpoint.h"
mgershaf9a9232017-04-13 20:19:0325#include "net/base/mock_network_change_notifier.h"
Matt Menke9aa86262019-08-21 15:52:0726#include "net/base/network_isolation_key.h"
Matt Menke4807a9a2020-11-21 00:14:4127#include "net/base/schemeful_site.h"
[email protected]61a527782013-02-21 03:58:0028#include "net/base/test_completion_callback.h"
tbansalc3308d72016-08-27 10:25:0429#include "net/base/test_proxy_delegate.h"
rsleevid6de8302016-06-21 01:33:2030#include "net/cert/ct_policy_enforcer.h"
[email protected]6e7845ae2013-03-29 21:48:1131#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5332#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0033#include "net/http/http_auth_handler_factory.h"
34#include "net/http/http_network_session.h"
35#include "net/http/http_network_transaction.h"
Matt Menke6e879bd2019-03-18 17:26:0436#include "net/http/http_proxy_connect_job.h"
Matt Menke609160742019-08-02 18:47:2637#include "net/http/http_server_properties.h"
[email protected]61a527782013-02-21 03:58:0038#include "net/http/http_stream.h"
39#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1940#include "net/http/http_transaction_test_util.h"
Yoichi Osato4c75c0c2020-06-24 08:03:5741#include "net/http/test_upload_data_stream_not_allow_http1.h"
[email protected]b1c988b2013-06-13 06:48:1142#include "net/http/transport_security_state.h"
Matt Reichhoff0049a0b72021-10-20 20:44:2643#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0044#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5145#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4646#include "net/log/test_net_log_util.h"
Nicolas Arciniegad2013f92020-02-07 23:00:5647#include "net/proxy_resolution/configured_proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4048#include "net/proxy_resolution/proxy_config_service_fixed.h"
49#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0850#include "net/quic/crypto/proof_verifier_chromium.h"
51#include "net/quic/mock_crypto_client_stream_factory.h"
Victor Vasiliev7752898d2019-11-14 21:30:2252#include "net/quic/mock_quic_context.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0853#include "net/quic/mock_quic_data.h"
54#include "net/quic/quic_chromium_alarm_factory.h"
55#include "net/quic/quic_http_stream.h"
56#include "net/quic/quic_http_utils.h"
57#include "net/quic/quic_stream_factory_peer.h"
58#include "net/quic/quic_test_packet_maker.h"
59#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0060#include "net/socket/client_socket_factory.h"
61#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2162#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2863#include "net/socket/socket_performance_watcher.h"
64#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0065#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5866#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5767#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2968#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0169#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4370#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4071#include "net/test/test_with_task_environment.h"
Ryan Hamiltonea4fa192022-04-12 18:30:4972#include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_decrypter.h"
73#include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_encrypter.h"
74#include "net/third_party/quiche/src/quiche/quic/core/quic_framer.h"
75#include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
76#include "net/third_party/quiche/src/quiche/quic/platform/api/quic_test.h"
77#include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
78#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_clock.h"
79#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
80#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_session_peer.h"
81#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
82#include "net/third_party/quiche/src/quiche/spdy/core/spdy_frame_builder.h"
83#include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2984#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0085#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4886#include "net/url_request/url_request.h"
Matt Menkea9606a0eb2020-09-11 20:36:3887#include "net/url_request/url_request_job_factory.h"
allada71b2efb2016-09-09 04:57:4888#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0189#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0090#include "testing/gtest/include/gtest/gtest.h"
91#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4692#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0093
Reilly Grant89a7e512018-01-20 01:57:1694using ::testing::ElementsAre;
95using ::testing::Key;
96
bnc508835902015-05-12 20:10:2997namespace net {
98namespace test {
[email protected]61a527782013-02-21 03:58:0099
100namespace {
101
bnc359ed2a2016-04-29 20:43:45102enum DestinationType {
103 // In pooling tests with two requests for different origins to the same
104 // destination, the destination should be
105 SAME_AS_FIRST, // the same as the first origin,
106 SAME_AS_SECOND, // the same as the second origin, or
107 DIFFERENT, // different from both.
108};
109
rch9ae5b3b2016-02-11 00:36:29110const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45111const char kDifferentHostname[] = "different.example.com";
112
David Schinazi09e9a6012019-10-03 17:37:57113struct TestParams {
114 quic::ParsedQuicVersion version;
115 bool client_headers_include_h2_stream_dependency;
116};
117
118// Used by ::testing::PrintToStringParamName().
119std::string PrintToString(const TestParams& p) {
Victor Vasiliev62c09dc2020-11-06 18:18:29120 return base::StrCat(
121 {ParsedQuicVersionToString(p.version), "_",
122 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
123 "Dependency"});
David Schinazi09e9a6012019-10-03 17:37:57124}
125
bnc359ed2a2016-04-29 20:43:45126// Run QuicNetworkTransactionWithDestinationTest instances with all value
127// combinations of version and destination_type.
128struct PoolingTestParams {
Nick Harper23290b82019-05-02 00:02:56129 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45130 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05131 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45132};
133
David Schinazi09e9a6012019-10-03 17:37:57134// Used by ::testing::PrintToStringParamName().
135std::string PrintToString(const PoolingTestParams& p) {
136 const char* destination_string = "";
137 switch (p.destination_type) {
138 case SAME_AS_FIRST:
139 destination_string = "SAME_AS_FIRST";
140 break;
141 case SAME_AS_SECOND:
142 destination_string = "SAME_AS_SECOND";
143 break;
144 case DIFFERENT:
145 destination_string = "DIFFERENT";
146 break;
147 }
Victor Vasiliev62c09dc2020-11-06 18:18:29148 return base::StrCat(
149 {ParsedQuicVersionToString(p.version), "_", destination_string, "_",
150 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
151 "Dependency"});
David Schinazi09e9a6012019-10-03 17:37:57152}
153
Ryan Hamiltona2dcbae2022-02-09 19:02:45154std::string GenerateQuicAltSvcHeaderValue(
155 const quic::ParsedQuicVersionVector& versions,
156 std::string host,
157 uint16_t port) {
158 std::string value;
Bence Békyb89104962020-01-24 00:05:17159 std::string version_string;
David Schinazifbd4c432020-04-07 19:23:55160 bool first_version = true;
161 for (const auto& version : versions) {
162 if (first_version) {
163 first_version = false;
Bence Békyb89104962020-01-24 00:05:17164 } else {
Ryan Hamiltona2dcbae2022-02-09 19:02:45165 value.append(", ");
David Schinazifbd4c432020-04-07 19:23:55166 }
Ryan Hamiltona2dcbae2022-02-09 19:02:45167 value.append(base::StrCat({quic::AlpnForVersion(version), "=\"", host, ":",
168 base::NumberToString(port), "\""}));
zhongyie537a002017-06-27 16:48:21169 }
Ryan Hamiltona2dcbae2022-02-09 19:02:45170 return value;
171}
Bence Békyb89104962020-01-24 00:05:17172
Ryan Hamiltona2dcbae2022-02-09 19:02:45173std::string GenerateQuicAltSvcHeaderValue(
174 const quic::ParsedQuicVersionVector& versions,
175 uint16_t port) {
176 return GenerateQuicAltSvcHeaderValue(versions, "", port);
177}
178
179std::string GenerateQuicAltSvcHeader(
180 const quic::ParsedQuicVersionVector& versions) {
181 std::string altsvc_header = "Alt-Svc: ";
182 altsvc_header.append(GenerateQuicAltSvcHeaderValue(versions, 443));
183 altsvc_header.append("\r\n");
Bence Békyb89104962020-01-24 00:05:17184 return altsvc_header;
zhongyie537a002017-06-27 16:48:21185}
186
David Schinazi09e9a6012019-10-03 17:37:57187std::vector<TestParams> GetTestParams() {
188 std::vector<TestParams> params;
189 quic::ParsedQuicVersionVector all_supported_versions =
190 quic::AllSupportedVersions();
Nico Weber6dcde5b2020-02-22 20:49:20191 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
Renjie Tang3d8a6ddd2019-11-20 00:18:43192 params.push_back(TestParams{version, false});
193 params.push_back(TestParams{version, true});
David Schinazi09e9a6012019-10-03 17:37:57194 }
195 return params;
196}
197
bnc359ed2a2016-04-29 20:43:45198std::vector<PoolingTestParams> GetPoolingTestParams() {
199 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56200 quic::ParsedQuicVersionVector all_supported_versions =
Ryan Hamilton93424eb82019-08-23 04:28:40201 quic::AllSupportedVersions();
Nico Weber6dcde5b2020-02-22 20:49:20202 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
Renjie Tang3d8a6ddd2019-11-20 00:18:43203 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
204 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
205 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
206 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
207 params.push_back(PoolingTestParams{version, DIFFERENT, false});
208 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45209 }
210 return params;
211}
bncb07c05532015-05-14 19:07:20212
Bence Béky319388a882020-09-23 18:42:52213std::string ConstructDataFrameForVersion(base::StringPiece body,
214 quic::ParsedQuicVersion version) {
215 if (!version.HasIetfQuicFrames()) {
Jan Wilken Dörrie14a065b2021-02-12 14:28:32216 return std::string(body);
Bence Béky319388a882020-09-23 18:42:52217 }
Victor Vasilievc617d452022-03-07 15:54:25218 quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
219 body.size(), quiche::SimpleBufferAllocator::Get());
Ian Swett17d4d1c02021-06-08 19:52:41220 return base::StrCat({base::StringPiece(buffer.data(), buffer.size()), body});
Bence Béky319388a882020-09-23 18:42:52221}
222
[email protected]61a527782013-02-21 03:58:00223} // namespace
224
tbansal0f56a39a2016-04-07 22:03:38225class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40226 public:
tbansal180587c2017-02-16 15:13:23227 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
228 bool* rtt_notification_received)
229 : should_notify_updated_rtt_(should_notify_updated_rtt),
230 rtt_notification_received_(rtt_notification_received) {}
Peter Boström293b1342021-09-22 17:31:43231
232 TestSocketPerformanceWatcher(const TestSocketPerformanceWatcher&) = delete;
233 TestSocketPerformanceWatcher& operator=(const TestSocketPerformanceWatcher&) =
234 delete;
235
tbansal0f56a39a2016-04-07 22:03:38236 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40237
tbansal180587c2017-02-16 15:13:23238 bool ShouldNotifyUpdatedRTT() const override {
239 return *should_notify_updated_rtt_;
240 }
tbansalfdf5665b2015-09-21 22:46:40241
tbansal0f56a39a2016-04-07 22:03:38242 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
243 *rtt_notification_received_ = true;
244 }
245
246 void OnConnectionChanged() override {}
247
248 private:
Keishi Hattori0e45c022021-11-27 09:25:52249 raw_ptr<bool> should_notify_updated_rtt_;
250 raw_ptr<bool> rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38251};
252
253class TestSocketPerformanceWatcherFactory
254 : public SocketPerformanceWatcherFactory {
255 public:
256 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23257 : watcher_count_(0u),
258 should_notify_updated_rtt_(true),
259 rtt_notification_received_(false) {}
Peter Boström293b1342021-09-22 17:31:43260
261 TestSocketPerformanceWatcherFactory(
262 const TestSocketPerformanceWatcherFactory&) = delete;
263 TestSocketPerformanceWatcherFactory& operator=(
264 const TestSocketPerformanceWatcherFactory&) = delete;
265
tbansal0f56a39a2016-04-07 22:03:38266 ~TestSocketPerformanceWatcherFactory() override {}
267
268 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42269 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41270 const Protocol protocol,
271 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51272 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38273 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51274 }
275 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42276 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23277 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
278 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40279 }
280
tbansalc8a94ea2015-11-02 23:58:51281 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40282
tbansalc8a94ea2015-11-02 23:58:51283 bool rtt_notification_received() const { return rtt_notification_received_; }
284
tbansal180587c2017-02-16 15:13:23285 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
286 should_notify_updated_rtt_ = should_notify_updated_rtt;
287 }
288
tbansalc8a94ea2015-11-02 23:58:51289 private:
tbansal0f56a39a2016-04-07 22:03:38290 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23291 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51292 bool rtt_notification_received_;
293};
294
Ryan Hamilton8d9ee76e2018-05-29 23:52:52295class QuicNetworkTransactionTest
296 : public PlatformTest,
David Schinazi09e9a6012019-10-03 17:37:57297 public ::testing::WithParamInterface<TestParams>,
Gabriel Charette694c3c332019-08-19 14:53:05298 public WithTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00299 protected:
[email protected]1c04f9522013-02-21 20:32:43300 QuicNetworkTransactionTest()
David Schinazi09e9a6012019-10-03 17:37:57301 : version_(GetParam().version),
302 client_headers_include_h2_stream_dependency_(
303 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:56304 supported_versions_(quic::test::SupportedVersions(version_)),
Zhongyi Shi1c022d22020-03-20 19:00:16305 client_maker_(new QuicTestPacketMaker(
306 version_,
307 quic::QuicUtils::CreateRandomConnectionId(
308 context_.random_generator()),
309 context_.clock(),
310 kDefaultServerHostName,
311 quic::Perspective::IS_CLIENT,
312 client_headers_include_h2_stream_dependency_)),
Victor Vasiliev7752898d2019-11-14 21:30:22313 server_maker_(version_,
314 quic::QuicUtils::CreateRandomConnectionId(
315 context_.random_generator()),
316 context_.clock(),
317 kDefaultServerHostName,
318 quic::Perspective::IS_SERVER,
319 false),
320 quic_task_runner_(new TestTaskRunner(context_.mock_clock())),
[email protected]1c04f9522013-02-21 20:32:43321 ssl_config_service_(new SSLConfigServiceDefaults),
Nicolas Arciniegad2013f92020-02-07 23:00:56322 proxy_resolution_service_(
323 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11324 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke3233d8f22019-08-20 21:01:49325 http_server_properties_(std::make_unique<HttpServerProperties>()),
rchf114d982015-10-21 01:34:56326 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:19327 FLAGS_quic_enable_http3_grease_randomness = false;
David Schinazif492e4318a2021-09-09 16:41:19328 FLAGS_quic_enable_chaos_protection = false;
[email protected]aa9b14d2013-05-10 23:45:19329 request_.method = "GET";
rchf114d982015-10-21 01:34:56330 std::string url("https://");
bncb07c05532015-05-14 19:07:20331 url.append(kDefaultServerHostName);
332 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19333 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10334 request_.traffic_annotation =
335 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Victor Vasiliev7752898d2019-11-14 21:30:22336 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56337
338 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29339 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56340 verify_details_.cert_verify_result.verified_cert = cert;
341 verify_details_.cert_verify_result.is_issued_by_known_root = true;
342 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43343 }
[email protected]61a527782013-02-21 03:58:00344
dcheng67be2b1f2014-10-27 21:47:29345 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00346 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55347 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00348 }
349
dcheng67be2b1f2014-10-27 21:47:29350 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00351 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
352 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55353 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00354 PlatformTest::TearDown();
355 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55356 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40357 session_.reset();
[email protected]61a527782013-02-21 03:58:00358 }
359
Ryan Hamilton8d9ee76e2018-05-29 23:52:52360 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23361 ConstructClientConnectionClosePacket(uint64_t num) {
Zhongyi Shi1c022d22020-03-20 19:00:16362 return client_maker_->MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52363 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30364 }
365
Ryan Hamilton8d9ee76e2018-05-29 23:52:52366 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23367 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03368 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52369 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58370 }
371
Ryan Hamilton8d9ee76e2018-05-29 23:52:52372 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23373 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52374 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20375 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58376 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20377 }
378
Ryan Hamilton8d9ee76e2018-05-29 23:52:52379 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23380 uint64_t packet_number,
381 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34382 uint64_t smallest_received) {
Zhongyi Shi1c022d22020-03-20 19:00:16383 return client_maker_->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34384 smallest_received);
fayang3bcb8b502016-12-07 21:44:37385 }
386
Ryan Hamilton8d9ee76e2018-05-29 23:52:52387 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23388 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52389 quic::QuicStreamId stream_id,
390 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23391 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34392 uint64_t smallest_received) {
393 return client_maker_->MakeAckAndRstPacket(
394 num, false, stream_id, error_code, largest_received, smallest_received);
zhongyi6b5a3892016-03-12 04:46:20395 }
396
Ryan Hamilton8d9ee76e2018-05-29 23:52:52397 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23398 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52399 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41400 quic::QuicRstStreamErrorCode error_code) {
Zhongyi Shi1c022d22020-03-20 19:00:16401 return client_maker_->MakeRstPacket(num, false, stream_id, error_code,
402 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56403 }
404
Ryan Hamilton8d9ee76e2018-05-29 23:52:52405 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58406 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23407 uint64_t num,
Fan Yangac867502019-01-28 21:10:23408 uint64_t largest_received,
409 uint64_t smallest_received,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52410 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29411 const std::string& quic_error_details,
412 uint64_t frame_type) {
Zhongyi Shi1c022d22020-03-20 19:00:16413 return client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:34414 num, false, largest_received, smallest_received, quic_error,
415 quic_error_details, frame_type);
zhongyica364fbb2015-12-12 03:39:12416 }
417
Ryan Hamilton8d9ee76e2018-05-29 23:52:52418 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23419 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12420 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52421 quic::QuicStreamId stream_id,
422 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58423 return server_maker_.MakeRstPacket(num, include_version, stream_id,
424 error_code);
zhongyica364fbb2015-12-12 03:39:12425 }
426
Ryan Hamilton8d9ee76e2018-05-29 23:52:52427 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02428 uint64_t packet_number) {
Zhongyi Shi1c022d22020-03-20 19:00:16429 return client_maker_->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37430 }
431
Ryan Hamilton8d9ee76e2018-05-29 23:52:52432 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23433 uint64_t packet_number,
434 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34435 uint64_t smallest_received) {
fayang3bcb8b502016-12-07 21:44:37436 return server_maker_.MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34437 smallest_received);
fayang3bcb8b502016-12-07 21:44:37438 }
439
Ryan Hamilton8d9ee76e2018-05-29 23:52:52440 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23441 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57442 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52443 quic::QuicStreamId id,
444 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02445 RequestPriority request_priority) {
Zhongyi Shi1c022d22020-03-20 19:00:16446 return client_maker_->MakePriorityPacket(
Yixin Wangb470bc882018-02-15 18:43:57447 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02448 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wang385652a2018-02-16 02:37:23449 }
450
Ryan Hamilton8d9ee76e2018-05-29 23:52:52451 std::unique_ptr<quic::QuicEncryptedPacket>
Haoyue Wang9d70d65c2020-05-29 22:45:34452 ConstructClientPriorityFramesPacket(
453 uint64_t packet_number,
454 bool should_include_version,
455 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
456 priority_frames) {
457 return client_maker_->MakeMultiplePriorityFramesPacket(
458 packet_number, should_include_version, priority_frames);
459 }
460
461 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25462 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23463 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23464 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23465 uint64_t largest_received,
466 uint64_t smallest_received,
Yixin Wange7ecc472018-03-06 19:00:25467 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
Ryan Hamilton0d65a8c2019-06-07 00:46:02468 priority_frames) {
Zhongyi Shi1c022d22020-03-20 19:00:16469 return client_maker_->MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23470 packet_number, should_include_version, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34471 smallest_received, priority_frames);
Yixin Wangb470bc882018-02-15 18:43:57472 }
473
Haoyue Wang9d70d65c2020-05-29 22:45:34474 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckAndPriorityPacket(
475 uint64_t packet_number,
476 bool should_include_version,
477 uint64_t largest_received,
478 uint64_t smallest_received,
479 quic::QuicStreamId id,
480 quic::QuicStreamId parent_stream_id,
481 RequestPriority request_priority) {
482 return client_maker_->MakeAckAndPriorityPacket(
483 packet_number, should_include_version, largest_received,
484 smallest_received, id, parent_stream_id,
485 ConvertRequestPriorityToQuicPriority(request_priority));
486 }
487
zhongyi32569c62016-01-08 02:54:30488 // Uses default QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01489 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
490 const std::string& scheme,
491 const std::string& path) {
Zhongyi Shi1c022d22020-03-20 19:00:16492 return GetRequestHeaders(method, scheme, path, client_maker_.get());
zhongyi32569c62016-01-08 02:54:30493 }
494
495 // Uses customized QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01496 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
497 const std::string& scheme,
498 const std::string& path,
499 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50500 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00501 }
502
Bence Béky4c325e52020-10-22 20:48:01503 spdy::Http2HeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Zhongyi Shi1c022d22020-03-20 19:00:16504 return client_maker_->ConnectRequestHeaders(host_port);
Yixin Wang46a273ec302018-01-23 17:59:56505 }
506
Bence Béky4c325e52020-10-22 20:48:01507 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58508 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00509 }
510
zhongyi32569c62016-01-08 02:54:30511 // Appends alt_svc headers in the response headers.
Bence Béky4c325e52020-10-22 20:48:01512 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status,
513 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58514 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30515 }
516
Ryan Hamilton8d9ee76e2018-05-29 23:52:52517 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23518 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52519 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05520 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00521 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10522 absl::string_view data) {
Ryan Hamilton7505eb92019-06-08 00:22:17523 return server_maker_.MakeDataPacket(packet_number, stream_id,
524 should_include_version, fin, data);
[email protected]61a527782013-02-21 03:58:00525 }
526
Ryan Hamilton8d9ee76e2018-05-29 23:52:52527 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23528 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52529 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36530 bool should_include_version,
531 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10532 absl::string_view data) {
Zhongyi Shi1c022d22020-03-20 19:00:16533 return client_maker_->MakeDataPacket(packet_number, stream_id,
534 should_include_version, fin, data);
ckrasicda193a82016-07-09 00:39:36535 }
536
Ryan Hamilton8d9ee76e2018-05-29 23:52:52537 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23538 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56539 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52540 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23541 uint64_t largest_received,
542 uint64_t smallest_received,
Yixin Wang46a273ec302018-01-23 17:59:56543 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10544 absl::string_view data) {
Renjie Tangcd594f32020-07-11 20:18:34545 return client_maker_->MakeAckAndDataPacket(packet_number, include_version,
546 stream_id, largest_received,
547 smallest_received, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56548 }
549
Kenichi Ishibashi10111e82021-03-23 02:19:06550 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckDataAndRst(
551 uint64_t packet_number,
552 bool include_version,
553 quic::QuicStreamId stream_id,
554 quic::QuicRstStreamErrorCode error_code,
555 uint64_t largest_received,
556 uint64_t smallest_received,
557 quic::QuicStreamId data_id,
558 bool fin,
559 absl::string_view data) {
560 return client_maker_->MakeAckDataAndRst(
561 packet_number, include_version, stream_id, error_code, largest_received,
562 smallest_received, data_id, fin, data);
563 }
564
Ryan Hamilton8d9ee76e2018-05-29 23:52:52565 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23566 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52567 quic::QuicStreamId stream_id,
568 bool should_include_version,
569 bool fin,
Bence Béky4c325e52020-10-22 20:48:01570 spdy::Http2HeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56571 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
572 should_include_version, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02573 std::move(headers), 0);
Yixin Wang46a273ec302018-01-23 17:59:56574 }
575
Ryan Hamilton8d9ee76e2018-05-29 23:52:52576 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23577 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52578 quic::QuicStreamId stream_id,
579 bool should_include_version,
580 bool fin,
Bence Béky4c325e52020-10-22 20:48:01581 spdy::Http2HeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02582 quic::QuicStreamId parent_stream_id) {
Yixin Wang46a273ec302018-01-23 17:59:56583 return ConstructClientRequestHeadersPacket(
584 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:02585 std::move(headers), parent_stream_id);
zhongyi32569c62016-01-08 02:54:30586 }
587
Ryan Hamilton8d9ee76e2018-05-29 23:52:52588 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23589 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52590 quic::QuicStreamId stream_id,
591 bool should_include_version,
592 bool fin,
593 RequestPriority request_priority,
Bence Béky4c325e52020-10-22 20:48:01594 spdy::Http2HeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02595 quic::QuicStreamId parent_stream_id) {
Ryan Hamilton0239aac2018-05-19 00:03:13596 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56597 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16598 return client_maker_->MakeRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56599 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02600 std::move(headers), parent_stream_id, nullptr);
[email protected]61a527782013-02-21 03:58:00601 }
602
Ryan Hamilton8d9ee76e2018-05-29 23:52:52603 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25604 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23605 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52606 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25607 bool should_include_version,
608 bool fin,
609 RequestPriority request_priority,
Bence Béky4c325e52020-10-22 20:48:01610 spdy::Http2HeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52611 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25612 size_t* spdy_headers_frame_length,
613 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13614 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25615 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16616 return client_maker_->MakeRequestHeadersAndMultipleDataFramesPacket(
Yixin Wange7ecc472018-03-06 19:00:25617 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02618 std::move(headers), parent_stream_id, spdy_headers_frame_length,
Yixin Wange7ecc472018-03-06 19:00:25619 data_writes);
620 }
621
Ryan Hamilton8d9ee76e2018-05-29 23:52:52622 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23623 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52624 quic::QuicStreamId stream_id,
625 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13626 bool should_include_version,
Bence Béky4c325e52020-10-22 20:48:01627 spdy::Http2HeaderBlock headers) {
Renjie Tangb7afea82020-07-15 23:35:47628 return server_maker_.MakePushPromisePacket(
ckrasic769733c2016-06-30 00:42:13629 packet_number, stream_id, promised_stream_id, should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02630 false, std::move(headers), nullptr);
ckrasic769733c2016-06-30 00:42:13631 }
632
Ryan Hamilton8d9ee76e2018-05-29 23:52:52633 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23634 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52635 quic::QuicStreamId stream_id,
636 bool should_include_version,
637 bool fin,
Bence Béky4c325e52020-10-22 20:48:01638 spdy::Http2HeaderBlock headers) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02639 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
640 should_include_version, fin,
641 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30642 }
643
Bence Béky319388a882020-09-23 18:42:52644 std::string ConstructDataFrame(base::StringPiece body) {
645 return ConstructDataFrameForVersion(body, version_);
Renjief49758b2019-01-11 23:32:41646 }
647
Nick Harper23290b82019-05-02 00:02:56648 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41649 session_params_.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:38650 context_.params()->supported_versions = supported_versions;
Victor Vasilieva1e66d72019-12-05 17:55:38651 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:05652 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00653
Victor Vasiliev7752898d2019-11-14 21:30:22654 session_context_.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:41655 session_context_.client_socket_factory = &socket_factory_;
656 session_context_.quic_crypto_client_stream_factory =
657 &crypto_client_stream_factory_;
658 session_context_.host_resolver = &host_resolver_;
659 session_context_.cert_verifier = &cert_verifier_;
660 session_context_.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:41661 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
662 session_context_.socket_performance_watcher_factory =
663 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59664 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41665 session_context_.ssl_config_service = ssl_config_service_.get();
666 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49667 session_context_.http_server_properties = http_server_properties_.get();
Matt Reichhoff0049a0b72021-10-20 20:44:26668 session_context_.net_log = NetLog::Get();
mmenke6ddfbea2017-05-31 21:48:41669
Renjie Tang6ff9a9b2021-02-03 22:11:09670 session_ =
671 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
Matt Menkeb566c392019-09-11 23:22:43672 session_->quic_stream_factory()
673 ->set_is_quic_known_to_work_on_current_network(true);
Yixin Wang46a273ec302018-01-23 17:59:56674 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
675 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00676 }
677
zhongyi86838d52017-06-30 01:19:44678 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21679
David Schinazif832cb82019-11-08 22:25:27680 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
Zhongyi Shi1c022d22020-03-20 19:00:16681 const std::string& status_line,
682 const quic::ParsedQuicVersion& version) {
[email protected]aa9b14d2013-05-10 23:45:19683 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42684 ASSERT_TRUE(response != nullptr);
685 ASSERT_TRUE(response->headers.get() != nullptr);
David Schinazif832cb82019-11-08 22:25:27686 EXPECT_EQ(status_line, response->headers->GetStatusLine());
[email protected]aa9b14d2013-05-10 23:45:19687 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52688 EXPECT_TRUE(response->was_alpn_negotiated);
Victor Vasiliev22dd3f212022-02-11 21:57:29689 auto connection_info =
690 QuicHttpStream::ConnectionInfoFromQuicVersion(version);
691 if (connection_info == response->connection_info) {
692 return;
693 }
694 // QUIC v1 and QUIC v2 are considered a match, because they have the same
695 // ALPN token.
696 if ((connection_info == HttpResponseInfo::CONNECTION_INFO_QUIC_RFC_V1 ||
697 connection_info == HttpResponseInfo::CONNECTION_INFO_QUIC_2_DRAFT_1) &&
698 (response->connection_info ==
699 HttpResponseInfo::CONNECTION_INFO_QUIC_RFC_V1 ||
700 response->connection_info ==
701 HttpResponseInfo::CONNECTION_INFO_QUIC_2_DRAFT_1)) {
702 return;
703 }
704
705 // They do not match. This EXPECT_EQ will fail and print useful
706 // information.
707 EXPECT_EQ(connection_info, response->connection_info);
[email protected]aa9b14d2013-05-10 23:45:19708 }
709
Zhongyi Shi1c022d22020-03-20 19:00:16710 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
711 const std::string& status_line) {
712 CheckWasQuicResponse(trans, status_line, version_);
713 }
714
David Schinazif832cb82019-11-08 22:25:27715 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
Kenichi Ishibashif8634ab2021-03-16 23:41:28716 CheckWasQuicResponse(trans, "HTTP/1.1 200", version_);
David Schinazif832cb82019-11-08 22:25:27717 }
718
bnc691fda62016-08-12 00:43:16719 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41720 const HttpResponseInfo* response = trans->GetResponseInfo();
721 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37722 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41723 }
724
bnc691fda62016-08-12 00:43:16725 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19726 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42727 ASSERT_TRUE(response != nullptr);
728 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19729 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
730 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52731 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52732 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19733 response->connection_info);
734 }
735
Yixin Wang46a273ec302018-01-23 17:59:56736 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
737 const HttpResponseInfo* response = trans->GetResponseInfo();
738 ASSERT_TRUE(response != nullptr);
739 ASSERT_TRUE(response->headers.get() != nullptr);
740 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
741 EXPECT_TRUE(response->was_fetched_via_spdy);
742 EXPECT_TRUE(response->was_alpn_negotiated);
743 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
744 response->connection_info);
745 }
746
bnc691fda62016-08-12 00:43:16747 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19748 const std::string& expected) {
749 std::string response_data;
bnc691fda62016-08-12 00:43:16750 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19751 EXPECT_EQ(expected, response_data);
752 }
753
bnc691fda62016-08-12 00:43:16754 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19755 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:26756 int rv = trans->Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:01757 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
758 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19759 }
760
761 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16762 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
763 RunTransaction(&trans);
764 CheckWasHttpResponse(&trans);
765 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19766 }
767
tbansalc3308d72016-08-27 10:25:04768 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
769 bool used_proxy,
770 uint16_t port) {
771 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalc3308d72016-08-27 10:25:04772 RunTransaction(&trans);
773 CheckWasHttpResponse(&trans);
774 CheckResponsePort(&trans, port);
775 CheckResponseData(&trans, expected);
tbansal2ecbbc72016-10-06 17:15:47776 if (used_proxy) {
777 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
778 } else {
779 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
780 }
tbansalc3308d72016-08-27 10:25:04781 }
David Schinazif832cb82019-11-08 22:25:27782 void SendRequestAndExpectQuicResponse(const std::string& expected,
783 const std::string& status_line) {
784 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443,
785 status_line);
786 }
tbansalc3308d72016-08-27 10:25:04787
[email protected]aa9b14d2013-05-10 23:45:19788 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56789 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12790 }
791
bnc62a44f022015-04-02 15:59:41792 void SendRequestAndExpectQuicResponseFromProxyOnPort(
793 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46794 uint16_t port) {
bnc62a44f022015-04-02 15:59:41795 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19796 }
797
798 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05799 MockCryptoClientStream::HandshakeMode handshake_mode,
800 const NetworkIsolationKey& network_isolation_key =
801 NetworkIsolationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19802 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46803 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21804 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
Peter Kastinge5a38ed2021-10-02 03:06:35805 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:49806 http_server_properties_->SetQuicAlternativeService(
Matt Menkeb32ba5122019-09-10 19:17:05807 server, network_isolation_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07808 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19809 }
810
rchbe69cb902016-02-11 01:10:48811 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27812 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48813 const HostPortPair& alternative) {
814 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46815 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21816 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48817 alternative.port());
Peter Kastinge5a38ed2021-10-02 03:06:35818 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:49819 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07820 server, NetworkIsolationKey(), alternative_service, expiration,
821 supported_versions_);
rchbe69cb902016-02-11 01:10:48822 }
823
Matt Menkeb32ba5122019-09-10 19:17:05824 void ExpectBrokenAlternateProtocolMapping(
825 const NetworkIsolationKey& network_isolation_key =
826 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46827 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34828 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49829 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05830 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34831 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49832 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05833 alternative_service_info_vector[0].alternative_service(),
834 network_isolation_key));
[email protected]aa9b14d2013-05-10 23:45:19835 }
836
Matt Menkeb32ba5122019-09-10 19:17:05837 void ExpectQuicAlternateProtocolMapping(
838 const NetworkIsolationKey& network_isolation_key =
839 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46840 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34841 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49842 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05843 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34844 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54845 EXPECT_EQ(
846 kProtoQUIC,
847 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49848 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05849 alternative_service_info_vector[0].alternative_service(),
850 network_isolation_key));
[email protected]4d590c9c2014-05-02 05:14:33851 }
852
[email protected]aa9b14d2013-05-10 23:45:19853 void AddHangingNonAlternateProtocolSocketData() {
Lei Zhange00db752021-04-17 00:48:46854 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
[email protected]dda75ab2013-06-22 22:43:30855 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30856 hanging_data->set_connect_data(hanging_connect);
857 hanging_data_.push_back(std::move(hanging_data));
858 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
[email protected]aa9b14d2013-05-10 23:45:19859 }
860
Zhongyi Shia6b68d112018-09-24 07:49:03861 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Victor Vasilieva1e66d72019-12-05 17:55:38862 context_.params()->migrate_sessions_on_network_change_v2 = true;
863 context_.params()->migrate_sessions_early_v2 = true;
864 context_.params()->retry_on_alternate_network_before_handshake = true;
Renjie Tang6ff9a9b2021-02-03 22:11:09865 scoped_mock_change_notifier_ =
866 std::make_unique<ScopedMockNetworkChangeNotifier>();
Zhongyi Shia6b68d112018-09-24 07:49:03867 MockNetworkChangeNotifier* mock_ncn =
868 scoped_mock_change_notifier_->mock_network_change_notifier();
869 mock_ncn->ForceNetworkHandlesSupported();
870 mock_ncn->SetConnectedNetworksList(
871 {kDefaultNetworkForTests, kNewNetworkForTests});
872 }
873
Matt Menkeb32ba5122019-09-10 19:17:05874 // Adds a new socket data provider for an HTTP request, and runs a request,
875 // expecting it to be used.
876 void AddHttpDataAndRunRequest() {
877 MockWrite http_writes[] = {
878 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
879 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
880 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
881
Ryan Hamiltona2dcbae2022-02-09 19:02:45882 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
883 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
884 MockRead(SYNCHRONOUS, 5, "http used"),
885 // Connection closed.
886 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:05887 SequencedSocketData http_data(http_reads, http_writes);
888 socket_factory_.AddSocketDataProvider(&http_data);
889 SSLSocketDataProvider ssl_data(ASYNC, OK);
890 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
891 SendRequestAndExpectHttpResponse("http used");
892 EXPECT_TRUE(http_data.AllWriteDataConsumed());
893 EXPECT_TRUE(http_data.AllReadDataConsumed());
894 }
895
896 // Adds a new socket data provider for a QUIC request, and runs a request,
897 // expecting it to be used. The new QUIC session is not closed.
898 void AddQuicDataAndRunRequest() {
899 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22900 version_,
901 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
902 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menkeb32ba5122019-09-10 19:17:05903 client_headers_include_h2_stream_dependency_);
904 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22905 version_,
906 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
907 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
908 false);
Matt Menkeb32ba5122019-09-10 19:17:05909 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56910 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05911 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:25912 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:56913 quic_data.AddWrite(
914 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_number++));
915 }
Matt Menkeb32ba5122019-09-10 19:17:05916 quic_data.AddWrite(
917 SYNCHRONOUS,
918 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56919 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
920 true, true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Matt Menkeb32ba5122019-09-10 19:17:05921 GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
922 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Fan Yang1ef6dfef2021-07-24 16:20:16923 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Matt Menkeb32ba5122019-09-10 19:17:05924 quic_data.AddRead(
925 ASYNC, server_maker.MakeResponseHeadersPacket(
926 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:28927 false, server_maker.GetResponseHeaders("200"), nullptr));
Matt Menkeb32ba5122019-09-10 19:17:05928 quic_data.AddRead(
929 ASYNC, server_maker.MakeDataPacket(
930 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:52931 true, ConstructDataFrame("quic used")));
Matt Menkeb32ba5122019-09-10 19:17:05932 // Don't care about the final ack.
933 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
934 // No more data to read.
935 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
936 quic_data.AddSocketDataToFactory(&socket_factory_);
Fan Yang1ef6dfef2021-07-24 16:20:16937
938 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
939 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:26940 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Fan Yang1ef6dfef2021-07-24 16:20:16941 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
942
943 // Pump the message loop to get the request started.
944 base::RunLoop().RunUntilIdle();
945 // Explicitly confirm the handshake.
946 crypto_client_stream_factory_.last_stream()
947 ->NotifySessionOneRttKeyAvailable();
948
949 ASSERT_FALSE(quic_data.AllReadDataConsumed());
950 quic_data.Resume();
951
952 // Run the QUIC session to completion.
953 base::RunLoop().RunUntilIdle();
Matt Menkeb32ba5122019-09-10 19:17:05954
955 EXPECT_TRUE(quic_data.AllReadDataConsumed());
956 }
957
Bence Béky6e243aa2019-12-13 19:01:07958 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56959 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
960 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36961 }
962
Bence Béky6e243aa2019-12-13 19:01:07963 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56964 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
965 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36966 }
967
Bence Béky6e243aa2019-12-13 19:01:07968 quic::QuicStreamId GetQpackDecoderStreamId() const {
969 return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
970 version_.transport_version, 1);
971 }
972
973 std::string StreamCancellationQpackDecoderInstruction(int n) const {
Ian Swettb70d9f8f2020-04-10 23:38:43974 return StreamCancellationQpackDecoderInstruction(n, true);
975 }
976
977 std::string StreamCancellationQpackDecoderInstruction(
978 int n,
979 bool create_stream) const {
Bence Béky6e243aa2019-12-13 19:01:07980 const quic::QuicStreamId cancelled_stream_id =
981 GetNthClientInitiatedBidirectionalStreamId(n);
982 EXPECT_LT(cancelled_stream_id, 63u);
983
Peter Kasting241e6d22021-06-09 17:24:58984 const char opcode = 0x40;
Ian Swettb70d9f8f2020-04-10 23:38:43985 if (create_stream) {
Peter Kasting241e6d22021-06-09 17:24:58986 return {0x03, static_cast<char>(opcode | cancelled_stream_id)};
Ian Swettb70d9f8f2020-04-10 23:38:43987 } else {
Peter Kasting241e6d22021-06-09 17:24:58988 return {static_cast<char>(opcode | cancelled_stream_id)};
Ian Swettb70d9f8f2020-04-10 23:38:43989 }
Bence Béky6e243aa2019-12-13 19:01:07990 }
991
Bence Béky230ac612017-08-30 19:17:08992 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49993 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08994 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49995 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08996 }
997
Zhongyi Shi1c022d22020-03-20 19:00:16998 void SendRequestAndExpectQuicResponseMaybeFromProxy(
999 const std::string& expected,
1000 bool used_proxy,
1001 uint16_t port,
1002 const std::string& status_line,
1003 const quic::ParsedQuicVersion& version) {
1004 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Zhongyi Shi1c022d22020-03-20 19:00:161005 RunTransaction(&trans);
1006 CheckWasQuicResponse(&trans, status_line, version);
1007 CheckResponsePort(&trans, port);
1008 CheckResponseData(&trans, expected);
Zhongyi Shi1c022d22020-03-20 19:00:161009 if (used_proxy) {
1010 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
Cammie Smith Barnesbf91e2a2020-12-23 20:49:041011
1012 // DNS aliases should be empty when using a proxy.
1013 EXPECT_TRUE(trans.GetResponseInfo()->dns_aliases.empty());
Zhongyi Shi1c022d22020-03-20 19:00:161014 } else {
1015 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1016 }
1017 }
1018
Victor Vasiliev22dd3f212022-02-11 21:57:291019 // Verify that the set of QUIC protocols in `alt_svc_info_vector` and
1020 // `supported_versions` is the same. Since QUICv1 and QUICv2 have the same
1021 // ALPN token "h3", they cannot be distinguished when parsing ALPN, so
1022 // consider them equal. This is accomplished by comparing the set of ALPN
1023 // strings (instead of comparing the set of ParsedQuicVersion entities).
1024 static void VerifyQuicVersionsInAlternativeServices(
1025 const AlternativeServiceInfoVector& alt_svc_info_vector,
1026 const quic::ParsedQuicVersionVector& supported_versions) {
1027 // Process supported versions.
1028 std::set<std::string> supported_alpn;
1029 for (const auto& version : supported_versions) {
1030 if (version.AlpnDeferToRFCv1()) {
1031 // These versions currently do not support Alt-Svc.
1032 return;
1033 }
1034 supported_alpn.insert(quic::ParsedQuicVersionToString(version));
1035 }
1036
1037 // Versions that support the legacy Google-specific Alt-Svc format are sent
1038 // in a single Alt-Svc entry, therefore they are accumulated in a single
1039 // AlternativeServiceInfo, whereas more recent versions all have their own
1040 // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
1041 std::set<std::string> alt_svc_negotiated_alpn;
1042 for (const auto& alt_svc_info : alt_svc_info_vector) {
1043 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
1044 for (const auto& version : alt_svc_info.advertised_versions()) {
1045 alt_svc_negotiated_alpn.insert(
1046 quic::ParsedQuicVersionToString(version));
1047 }
1048 }
1049
1050 // Compare.
1051 EXPECT_EQ(alt_svc_negotiated_alpn, supported_alpn);
1052 }
1053
Nick Harper23290b82019-05-02 00:02:561054 const quic::ParsedQuicVersion version_;
Ryan Hamiltona2dcbae2022-02-09 19:02:451055 const std::string alt_svc_header_ =
1056 GenerateQuicAltSvcHeader({version_}) + "\r\n";
Yixin Wang079ad542018-01-11 04:06:051057 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:561058 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:011059 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Victor Vasiliev7752898d2019-11-14 21:30:221060 MockQuicContext context_;
Zhongyi Shi1c022d22020-03-20 19:00:161061 std::unique_ptr<QuicTestPacketMaker> client_maker_;
alyssar2adf3ac2016-05-03 17:12:581062 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:091063 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:421064 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:001065 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:561066 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:051067 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Eric Orthbe86fee2021-10-28 22:31:111068 MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
1069 RuleResolver::GetLocalhostResult()};
[email protected]1c04f9522013-02-21 20:32:431070 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:111071 TransportSecurityState transport_security_state_;
Ryan Sleevi8a9c9c12018-05-09 02:36:231072 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:381073 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:071074 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:261075 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:421076 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:491077 std::unique_ptr<HttpServerProperties> http_server_properties_;
Matt Menke30a878c2021-07-20 22:25:091078 HttpNetworkSessionParams session_params_;
1079 HttpNetworkSessionContext session_context_;
[email protected]aa9b14d2013-05-10 23:45:191080 HttpRequestInfo request_;
Matt Reichhoff0049a0b72021-10-20 20:44:261081 NetLogWithSource net_log_with_source_{
1082 NetLogWithSource::Make(NetLogSourceType::NONE)};
1083 RecordingNetLogObserver net_log_observer_;
danakjad1777e2016-04-16 00:56:421084 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:561085 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:031086 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:121087
1088 private:
1089 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1090 const std::string& expected,
bnc62a44f022015-04-02 15:59:411091 bool used_proxy,
David Schinazif832cb82019-11-08 22:25:271092 uint16_t port,
1093 const std::string& status_line) {
Zhongyi Shi1c022d22020-03-20 19:00:161094 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
1095 status_line, version_);
tbansal7cec3812015-02-05 21:25:121096 }
David Schinazif832cb82019-11-08 22:25:271097
1098 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1099 const std::string& expected,
1100 bool used_proxy,
1101 uint16_t port) {
1102 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
Kenichi Ishibashif8634ab2021-03-16 23:41:281103 "HTTP/1.1 200", version_);
David Schinazif832cb82019-11-08 22:25:271104 }
[email protected]61a527782013-02-21 03:58:001105};
1106
David Schinazi09e9a6012019-10-03 17:37:571107INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1108 QuicNetworkTransactionTest,
1109 ::testing::ValuesIn(GetTestParams()),
1110 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201111
Ryan Hamiltona64a5bcf2017-11-30 07:35:281112TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:381113 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281114 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381115 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281116 HostPortPair::FromString("mail.example.org:443"));
1117 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271118 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281119
Ryan Hamiltonabad59e2019-06-06 04:02:591120 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251121 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231122 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281123 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1124 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211125 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281126
1127 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1128
1129 CreateSession();
1130
1131 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1132 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261133 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1135 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1136
1137 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1138 -ERR_INTERNET_DISCONNECTED, 1);
1139 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1140 -ERR_INTERNET_DISCONNECTED, 1);
1141}
1142
1143TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Victor Vasilieva1e66d72019-12-05 17:55:381144 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281145 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381146 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281147 HostPortPair::FromString("mail.example.org:443"));
1148 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271149 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281150
Ryan Hamiltonabad59e2019-06-06 04:02:591151 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251152 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231153 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281154 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1155 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211156 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281157
1158 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1159
1160 CreateSession();
1161
1162 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1163 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261164 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281165 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1166 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1167
1168 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1169 -ERR_INTERNET_DISCONNECTED, 1);
1170 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1171 -ERR_INTERNET_DISCONNECTED, 1);
1172}
1173
tbansal180587c2017-02-16 15:13:231174TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381175 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231176 HostPortPair::FromString("mail.example.org:443"));
1177
Ryan Hamiltonabad59e2019-06-06 04:02:591178 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231179 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251180 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231181 mock_quic_data.AddWrite(SYNCHRONOUS,
1182 ConstructInitialSettingsPacket(packet_num++));
1183 }
rch5cb522462017-04-25 20:18:361184 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231185 SYNCHRONOUS,
1186 ConstructClientRequestHeadersPacket(
1187 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1188 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431189 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331190 ASYNC, ConstructServerResponseHeadersPacket(
1191 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281192 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331193 mock_quic_data.AddRead(
1194 ASYNC, ConstructServerDataPacket(
1195 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521196 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231197 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341198 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231199 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1200
1201 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1202
1203 CreateSession();
1204 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1205
1206 EXPECT_FALSE(
1207 test_socket_performance_watcher_factory_.rtt_notification_received());
1208 SendRequestAndExpectQuicResponse("hello!");
1209 EXPECT_TRUE(
1210 test_socket_performance_watcher_factory_.rtt_notification_received());
1211}
1212
1213TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381214 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231215 HostPortPair::FromString("mail.example.org:443"));
1216
Ryan Hamiltonabad59e2019-06-06 04:02:591217 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231218 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251219 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231220 mock_quic_data.AddWrite(SYNCHRONOUS,
1221 ConstructInitialSettingsPacket(packet_num++));
1222 }
rch5cb522462017-04-25 20:18:361223 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231224 SYNCHRONOUS,
1225 ConstructClientRequestHeadersPacket(
1226 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1227 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431228 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331229 ASYNC, ConstructServerResponseHeadersPacket(
1230 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281231 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331232 mock_quic_data.AddRead(
1233 ASYNC, ConstructServerDataPacket(
1234 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521235 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231236 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341237 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231238 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1239
1240 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1241
1242 CreateSession();
1243 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1244
1245 EXPECT_FALSE(
1246 test_socket_performance_watcher_factory_.rtt_notification_received());
1247 SendRequestAndExpectQuicResponse("hello!");
1248 EXPECT_FALSE(
1249 test_socket_performance_watcher_factory_.rtt_notification_received());
1250}
1251
[email protected]1e960032013-12-20 19:00:201252TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:381253 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571254 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471255
Ryan Hamiltonabad59e2019-06-06 04:02:591256 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231257 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251258 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231259 mock_quic_data.AddWrite(SYNCHRONOUS,
1260 ConstructInitialSettingsPacket(packet_num++));
1261 }
rch5cb522462017-04-25 20:18:361262 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231263 SYNCHRONOUS,
1264 ConstructClientRequestHeadersPacket(
1265 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1266 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431267 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331268 ASYNC, ConstructServerResponseHeadersPacket(
1269 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281270 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331271 mock_quic_data.AddRead(
1272 ASYNC, ConstructServerDataPacket(
1273 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521274 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231275 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341276 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:591277 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471278
rcha5399e02015-04-21 19:32:041279 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471280
[email protected]4dca587c2013-03-07 16:54:471281 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471282
[email protected]aa9b14d2013-05-10 23:45:191283 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471284
[email protected]98b20ce2013-05-10 05:55:261285 // Check that the NetLog was filled reasonably.
Matt Reichhoff0049a0b72021-10-20 20:44:261286 auto entries = net_log_observer_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261287 EXPECT_LT(0u, entries.size());
1288
1289 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291290 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001291 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1292 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261293 EXPECT_LT(0, pos);
1294
David Schinazi24bfaa02020-10-22 19:54:381295 // ... and also a TYPE_QUIC_SESSION_PACKET_SENT.
1296 pos = ExpectLogContainsSomewhere(entries, 0,
1297 NetLogEventType::QUIC_SESSION_PACKET_SENT,
1298 NetLogEventPhase::NONE);
1299 EXPECT_LT(0, pos);
1300
rchfd527212015-08-25 00:41:261301 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291302 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261303 entries, 0,
mikecirone8b85c432016-09-08 19:11:001304 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1305 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261306 EXPECT_LT(0, pos);
1307
Eric Roman79cc7552019-07-19 02:17:541308 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261309
rchfd527212015-08-25 00:41:261310 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1311 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001312 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1313 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261314 EXPECT_LT(0, pos);
1315
[email protected]98b20ce2013-05-10 05:55:261316 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291317 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001318 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1319 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261320 EXPECT_LT(0, pos);
1321
Eric Roman79cc7552019-07-19 02:17:541322 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Victor Vasiliev7da08172019-10-14 06:04:251323 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451324 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1325 static_cast<quic::QuicStreamId>(log_stream_id));
1326 } else {
1327 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1328 static_cast<quic::QuicStreamId>(log_stream_id));
1329 }
[email protected]4dca587c2013-03-07 16:54:471330}
1331
Bence Békyb6300042020-01-28 21:18:201332// Regression test for https://crbug.com/1043531.
1333TEST_P(QuicNetworkTransactionTest, ResetOnEmptyResponseHeaders) {
1334 if (!quic::VersionUsesHttp3(version_.transport_version)) {
1335 return;
1336 }
1337
Kenichi Ishibashi10111e82021-03-23 02:19:061338 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Bence Békyb6300042020-01-28 21:18:201339 context_.params()->origins_to_force_quic_on.insert(
1340 HostPortPair::FromString("mail.example.org:443"));
1341
1342 MockQuicData mock_quic_data(version_);
1343 int write_packet_num = 1;
1344 mock_quic_data.AddWrite(SYNCHRONOUS,
1345 ConstructInitialSettingsPacket(write_packet_num++));
1346 mock_quic_data.AddWrite(
1347 SYNCHRONOUS,
1348 ConstructClientRequestHeadersPacket(
1349 write_packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1350 true, true, GetRequestHeaders("GET", "https", "/")));
1351
1352 const quic::QuicStreamId request_stream_id =
1353 GetNthClientInitiatedBidirectionalStreamId(0);
Bence Béky4c325e52020-10-22 20:48:011354 spdy::Http2HeaderBlock empty_response_headers;
Bence Békyb6300042020-01-28 21:18:201355 const std::string response_data = server_maker_.QpackEncodeHeaders(
1356 request_stream_id, std::move(empty_response_headers), nullptr);
1357 uint64_t read_packet_num = 1;
1358 mock_quic_data.AddRead(
1359 ASYNC, ConstructServerDataPacket(read_packet_num++, request_stream_id,
1360 false, false, response_data));
1361 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1362
1363 mock_quic_data.AddWrite(
Kenichi Ishibashi10111e82021-03-23 02:19:061364 ASYNC, ConstructClientAckDataAndRst(
1365 write_packet_num++, true, request_stream_id,
1366 quic::QUIC_STREAM_GENERAL_PROTOCOL_ERROR, 1, 1,
1367 GetQpackDecoderStreamId(), false,
1368 StreamCancellationQpackDecoderInstruction(request_stream_id)));
Bence Békyb6300042020-01-28 21:18:201369
1370 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1371
1372 CreateSession();
1373
1374 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1375 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261376 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Bence Békyb6300042020-01-28 21:18:201377 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Kenichi Ishibashi10111e82021-03-23 02:19:061378 EXPECT_THAT(callback.WaitForResult(), IsError(net::ERR_QUIC_PROTOCOL_ERROR));
1379 base::RunLoop().RunUntilIdle();
1380 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1381 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
Bence Békyb6300042020-01-28 21:18:201382}
1383
rchbd089ab2017-05-26 23:05:041384TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381385 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041386 HostPortPair::FromString("mail.example.org:443"));
1387
Ryan Hamiltonabad59e2019-06-06 04:02:591388 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231389 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251390 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231391 mock_quic_data.AddWrite(SYNCHRONOUS,
1392 ConstructInitialSettingsPacket(packet_num++));
1393 }
rchbd089ab2017-05-26 23:05:041394 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231395 SYNCHRONOUS,
1396 ConstructClientRequestHeadersPacket(
1397 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1398 true, GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashif8634ab2021-03-16 23:41:281399 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200");
rchbd089ab2017-05-26 23:05:041400 response_headers["key1"] = std::string(30000, 'A');
1401 response_headers["key2"] = std::string(30000, 'A');
1402 response_headers["key3"] = std::string(30000, 'A');
1403 response_headers["key4"] = std::string(30000, 'A');
1404 response_headers["key5"] = std::string(30000, 'A');
1405 response_headers["key6"] = std::string(30000, 'A');
1406 response_headers["key7"] = std::string(30000, 'A');
1407 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451408 quic::QuicStreamId stream_id;
1409 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251410 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451411 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281412 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451413 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451414 } else {
1415 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1416 spdy::SpdyHeadersIR headers_frame(
1417 GetNthClientInitiatedBidirectionalStreamId(0),
1418 std::move(response_headers));
1419 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1420 spdy::SpdySerializedFrame spdy_frame =
1421 response_framer.SerializeFrame(headers_frame);
1422 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1423 }
rchbd089ab2017-05-26 23:05:041424
Fan Yangac867502019-01-28 21:10:231425 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041426 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451427 for (size_t offset = 0; offset < response_data.length();
1428 offset += chunk_size) {
1429 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431430 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451431 ASYNC, ConstructServerDataPacket(
1432 packet_number++, stream_id, false, false,
Victor Vasiliev502ba582020-09-15 23:16:151433 absl::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041434 }
1435
1436 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331437 ASYNC, ConstructServerDataPacket(
1438 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Bence Béky319388a882020-09-23 18:42:521439 false, true, ConstructDataFrame("hello!")));
rchbd089ab2017-05-26 23:05:041440 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341441 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Renjie Tangaadb84b2019-08-31 01:00:231442 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341443 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3));
rchbd089ab2017-05-26 23:05:041444
1445 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1446
1447 CreateSession();
1448
1449 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421450 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1451 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041452}
1453
1454TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381455 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1456 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041457 HostPortPair::FromString("mail.example.org:443"));
1458
Ryan Hamiltonabad59e2019-06-06 04:02:591459 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231460 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251461 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231462 mock_quic_data.AddWrite(SYNCHRONOUS,
1463 ConstructInitialSettingsPacket(packet_num++));
1464 }
rchbd089ab2017-05-26 23:05:041465 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231466 SYNCHRONOUS,
1467 ConstructClientRequestHeadersPacket(
1468 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1469 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451470
Kenichi Ishibashif8634ab2021-03-16 23:41:281471 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200");
rchbd089ab2017-05-26 23:05:041472 response_headers["key1"] = std::string(30000, 'A');
1473 response_headers["key2"] = std::string(30000, 'A');
1474 response_headers["key3"] = std::string(30000, 'A');
1475 response_headers["key4"] = std::string(30000, 'A');
1476 response_headers["key5"] = std::string(30000, 'A');
1477 response_headers["key6"] = std::string(30000, 'A');
1478 response_headers["key7"] = std::string(30000, 'A');
1479 response_headers["key8"] = std::string(30000, 'A');
1480 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451481
1482 quic::QuicStreamId stream_id;
1483 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251484 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451485 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281486 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451487 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451488 } else {
1489 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1490 spdy::SpdyHeadersIR headers_frame(
1491 GetNthClientInitiatedBidirectionalStreamId(0),
1492 std::move(response_headers));
1493 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1494 spdy::SpdySerializedFrame spdy_frame =
1495 response_framer.SerializeFrame(headers_frame);
1496 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1497 }
rchbd089ab2017-05-26 23:05:041498
Fan Yangac867502019-01-28 21:10:231499 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041500 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451501 for (size_t offset = 0; offset < response_data.length();
1502 offset += chunk_size) {
1503 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431504 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451505 ASYNC, ConstructServerDataPacket(
1506 packet_number++, stream_id, false, false,
Victor Vasiliev502ba582020-09-15 23:16:151507 absl::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041508 }
1509
1510 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331511 ASYNC, ConstructServerDataPacket(
1512 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Bence Béky319388a882020-09-23 18:42:521513 false, true, ConstructDataFrame("hello!")));
rchbd089ab2017-05-26 23:05:041514 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341515 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431516 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331517 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231518 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:341519 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3));
rchbd089ab2017-05-26 23:05:041520
1521 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1522
1523 CreateSession();
1524
1525 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1526 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261527 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rchbd089ab2017-05-26 23:05:041528 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1529 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1530}
1531
Kenichi Ishibashifd2d3e62022-03-01 22:54:051532TEST_P(QuicNetworkTransactionTest, RedirectMultipleLocations) {
1533 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1534 context_.params()->origins_to_force_quic_on.insert(
1535 HostPortPair::FromString("mail.example.org:443"));
1536
1537 MockQuicData mock_quic_data(version_);
1538 int packet_num = 1;
1539 if (VersionUsesHttp3(version_.transport_version)) {
1540 mock_quic_data.AddWrite(SYNCHRONOUS,
1541 ConstructInitialSettingsPacket(packet_num++));
1542 }
1543 mock_quic_data.AddWrite(
1544 SYNCHRONOUS,
1545 ConstructClientRequestHeadersPacket(
1546 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1547 true, GetRequestHeaders("GET", "https", "/")));
1548
1549 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("301");
1550 response_headers.AppendValueOrAddHeader("location", "https://example1.test");
1551 response_headers.AppendValueOrAddHeader("location", "https://example2.test");
1552
1553 if (quic::VersionUsesHttp3(version_.transport_version)) {
1554 const quic::QuicStreamId stream_id =
1555 GetNthClientInitiatedBidirectionalStreamId(0);
1556 const std::string response_data = server_maker_.QpackEncodeHeaders(
1557 stream_id, std::move(response_headers), nullptr);
1558 ASSERT_LT(response_data.size(), 1200u);
1559 mock_quic_data.AddRead(
1560 ASYNC, ConstructServerDataPacket(/*packet_number=*/1, stream_id,
1561 /*should_include_version=*/false,
1562 /*fin=*/true, response_data));
1563 } else {
1564 const quic::QuicStreamId stream_id =
1565 quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1566 spdy::SpdyHeadersIR headers_frame(
1567 GetNthClientInitiatedBidirectionalStreamId(0),
1568 std::move(response_headers));
1569 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1570 spdy::SpdySerializedFrame spdy_frame =
1571 response_framer.SerializeFrame(headers_frame);
1572 const std::string response_data =
1573 std::string(spdy_frame.data(), spdy_frame.size());
1574 ASSERT_LT(response_data.size(), 1200u);
1575 mock_quic_data.AddRead(
1576 ASYNC, ConstructServerDataPacket(/*packet_number=*/1, stream_id,
1577 /*should_include_version=*/false,
1578 /*fin=*/false, response_data));
1579 }
1580 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1581
1582 mock_quic_data.AddWrite(
1583 ASYNC, ConstructClientAckAndRstPacket(
1584 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1585 quic::QUIC_STREAM_CANCELLED,
1586 /*largest_received=*/1, /*smallest_received=*/1));
1587
1588 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1589
1590 CreateSession();
1591
1592 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1593 TestCompletionCallback callback;
1594 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
1595 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1596 ASSERT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1597}
1598
rcha2bd44b2016-07-02 00:42:551599TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Victor Vasilieva1e66d72019-12-05 17:55:381600 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551601
Ryan Hamilton9835e662018-08-02 05:36:271602 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551603
Ryan Hamiltonabad59e2019-06-06 04:02:591604 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231605 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251606 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231607 mock_quic_data.AddWrite(SYNCHRONOUS,
1608 ConstructInitialSettingsPacket(packet_num++));
1609 }
rch5cb522462017-04-25 20:18:361610 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231611 SYNCHRONOUS,
1612 ConstructClientRequestHeadersPacket(
1613 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1614 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431615 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331616 ASYNC, ConstructServerResponseHeadersPacket(
1617 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281618 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331619 mock_quic_data.AddRead(
1620 ASYNC, ConstructServerDataPacket(
1621 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521622 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231623 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341624 ConstructClientAckPacket(packet_num++, 2, 1));
rcha2bd44b2016-07-02 00:42:551625 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1626
1627 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1628
1629 CreateSession();
1630
1631 SendRequestAndExpectQuicResponse("hello!");
1632 EXPECT_TRUE(
1633 test_socket_performance_watcher_factory_.rtt_notification_received());
1634}
1635
David Schinazif832cb82019-11-08 22:25:271636// Regression test for https://crbug.com/695225
1637TEST_P(QuicNetworkTransactionTest, 408Response) {
Victor Vasilieva1e66d72019-12-05 17:55:381638 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
David Schinazif832cb82019-11-08 22:25:271639
1640 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1641
1642 MockQuicData mock_quic_data(version_);
1643 int packet_num = 1;
1644 if (VersionUsesHttp3(version_.transport_version)) {
1645 mock_quic_data.AddWrite(SYNCHRONOUS,
1646 ConstructInitialSettingsPacket(packet_num++));
1647 }
1648 mock_quic_data.AddWrite(
1649 SYNCHRONOUS,
1650 ConstructClientRequestHeadersPacket(
1651 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1652 true, GetRequestHeaders("GET", "https", "/")));
1653 mock_quic_data.AddRead(
1654 ASYNC, ConstructServerResponseHeadersPacket(
1655 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281656 GetResponseHeaders("408")));
David Schinazif832cb82019-11-08 22:25:271657 mock_quic_data.AddRead(
1658 ASYNC, ConstructServerDataPacket(
1659 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521660 ConstructDataFrame("hello!")));
David Schinazif832cb82019-11-08 22:25:271661 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341662 ConstructClientAckPacket(packet_num++, 2, 1));
David Schinazif832cb82019-11-08 22:25:271663 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1664
1665 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1666
1667 CreateSession();
1668
Kenichi Ishibashif8634ab2021-03-16 23:41:281669 SendRequestAndExpectQuicResponse("hello!", "HTTP/1.1 408");
David Schinazif832cb82019-11-08 22:25:271670}
1671
[email protected]cf3e3cd62014-02-05 16:16:161672TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411673 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561674 proxy_resolution_service_ =
1675 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
1676 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161677
Ryan Hamiltonabad59e2019-06-06 04:02:591678 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231679 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251680 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231681 mock_quic_data.AddWrite(SYNCHRONOUS,
1682 ConstructInitialSettingsPacket(packet_num++));
1683 }
rch5cb522462017-04-25 20:18:361684 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231685 SYNCHRONOUS,
1686 ConstructClientRequestHeadersPacket(
1687 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1688 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431689 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331690 ASYNC, ConstructServerResponseHeadersPacket(
1691 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281692 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331693 mock_quic_data.AddRead(
1694 ASYNC, ConstructServerDataPacket(
1695 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521696 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231697 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341698 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:501699 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211700 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
[email protected]cf3e3cd62014-02-05 16:16:161701
rcha5399e02015-04-21 19:32:041702 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161703
tbansal0f56a39a2016-04-07 22:03:381704 EXPECT_FALSE(
1705 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161706 // There is no need to set up an alternate protocol job, because
1707 // no attempt will be made to speak to the proxy over TCP.
1708
rch9ae5b3b2016-02-11 00:36:291709 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161710 CreateSession();
1711
bnc62a44f022015-04-02 15:59:411712 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381713 EXPECT_TRUE(
1714 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161715}
1716
bnc313ba9c2015-06-11 15:42:311717// Regression test for https://crbug.com/492458. Test that for an HTTP
1718// connection through a QUIC proxy, the certificate exhibited by the proxy is
1719// checked against the proxy hostname, not the origin hostname.
1720TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291721 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311722 const std::string proxy_host = "www.example.org";
1723
mmenke6ddfbea2017-05-31 21:48:411724 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561725 proxy_resolution_service_ =
1726 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
1727 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311728
Zhongyi Shi1c022d22020-03-20 19:00:161729 client_maker_->set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591730 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231731 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251732 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231733 mock_quic_data.AddWrite(SYNCHRONOUS,
1734 ConstructInitialSettingsPacket(packet_num++));
1735 }
rch5cb522462017-04-25 20:18:361736 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231737 SYNCHRONOUS,
1738 ConstructClientRequestHeadersPacket(
1739 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1740 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431741 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331742 ASYNC, ConstructServerResponseHeadersPacket(
1743 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281744 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331745 mock_quic_data.AddRead(
1746 ASYNC, ConstructServerDataPacket(
1747 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521748 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231749 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341750 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:501751 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211752 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc313ba9c2015-06-11 15:42:311753 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1754
1755 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291756 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311757 ASSERT_TRUE(cert.get());
1758 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241759 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1760 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311761 ProofVerifyDetailsChromium verify_details;
1762 verify_details.cert_verify_result.verified_cert = cert;
1763 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561764 ProofVerifyDetailsChromium verify_details2;
1765 verify_details2.cert_verify_result.verified_cert = cert;
1766 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311767
1768 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091769 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321770 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271771 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311772 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1773}
1774
rchbe69cb902016-02-11 01:10:481775TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Victor Vasilieva1e66d72019-12-05 17:55:381776 context_.params()->allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481777 HostPortPair origin("www.example.org", 443);
1778 HostPortPair alternative("mail.example.org", 443);
1779
1780 base::FilePath certs_dir = GetTestCertsDirectory();
1781 scoped_refptr<X509Certificate> cert(
1782 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1783 ASSERT_TRUE(cert.get());
1784 // TODO(rch): the connection should be "to" the origin, so if the cert is
1785 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241786 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1787 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481788 ProofVerifyDetailsChromium verify_details;
1789 verify_details.cert_verify_result.verified_cert = cert;
1790 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1791
Zhongyi Shi1c022d22020-03-20 19:00:161792 client_maker_->set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591793 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021794
Renjie Tangaadb84b2019-08-31 01:00:231795 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251796 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231797 mock_quic_data.AddWrite(SYNCHRONOUS,
1798 ConstructInitialSettingsPacket(packet_num++));
1799 }
rch5cb522462017-04-25 20:18:361800 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231801 SYNCHRONOUS,
1802 ConstructClientRequestHeadersPacket(
1803 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1804 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431805 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331806 ASYNC, ConstructServerResponseHeadersPacket(
1807 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281808 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331809 mock_quic_data.AddRead(
1810 ASYNC, ConstructServerDataPacket(
1811 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521812 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231813 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341814 ConstructClientAckPacket(packet_num++, 2, 1));
rchbe69cb902016-02-11 01:10:481815 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211816 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rchbe69cb902016-02-11 01:10:481817 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1818
1819 request_.url = GURL("https://" + origin.host());
1820 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271821 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091822 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321823 CreateSession();
rchbe69cb902016-02-11 01:10:481824
1825 SendRequestAndExpectQuicResponse("hello!");
1826}
1827
zhongyief3f4ce52017-07-05 23:53:281828TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
David Schinazi84c58bb2020-06-04 20:14:331829 quic::ParsedQuicVersion unsupported_version =
1830 quic::ParsedQuicVersion::Unsupported();
Bence Békyb89104962020-01-24 00:05:171831 // Add support for another QUIC version besides |version_|. Also find an
zhongyief3f4ce52017-07-05 23:53:281832 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561833 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281834 if (version == version_)
1835 continue;
1836 if (supported_versions_.size() != 2) {
1837 supported_versions_.push_back(version);
1838 continue;
1839 }
1840 unsupported_version = version;
1841 break;
1842 }
Bence Békyb89104962020-01-24 00:05:171843 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:331844 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), unsupported_version);
zhongyief3f4ce52017-07-05 23:53:281845
1846 // Set up alternative service to use QUIC with a version that is not
1847 // supported.
1848 url::SchemeHostPort server(request_.url);
1849 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1850 443);
Peter Kastinge5a38ed2021-10-02 03:06:351851 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:491852 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071853 server, NetworkIsolationKey(), alternative_service, expiration,
1854 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281855
1856 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491857 http_server_properties_->GetAlternativeServiceInfos(
1858 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281859 EXPECT_EQ(1u, alt_svc_info_vector.size());
1860 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1861 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1862 EXPECT_EQ(unsupported_version,
1863 alt_svc_info_vector[0].advertised_versions()[0]);
1864
1865 // First request should still be sent via TCP as the QUIC version advertised
1866 // in the stored AlternativeService is not supported by the client. However,
1867 // the response from the server will advertise new Alt-Svc with supported
1868 // versions.
David Schinazifbd4c432020-04-07 19:23:551869 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyief3f4ce52017-07-05 23:53:281870 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:171871 MockRead("HTTP/1.1 200 OK\r\n"),
1872 MockRead(altsvc_header.c_str()),
1873 MockRead("\r\n"),
zhongyief3f4ce52017-07-05 23:53:281874 MockRead("hello world"),
1875 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1876 MockRead(ASYNC, OK)};
1877
Ryan Sleevib8d7ea02018-05-07 20:01:011878 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281879 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081880 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281881 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1882
1883 // Second request should be sent via QUIC as a new list of verions supported
1884 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591885 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231886 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251887 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231888 mock_quic_data.AddWrite(SYNCHRONOUS,
1889 ConstructInitialSettingsPacket(packet_num++));
1890 }
zhongyief3f4ce52017-07-05 23:53:281891 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231892 SYNCHRONOUS,
1893 ConstructClientRequestHeadersPacket(
1894 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1895 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431896 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331897 ASYNC, ConstructServerResponseHeadersPacket(
1898 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281899 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331900 mock_quic_data.AddRead(
1901 ASYNC, ConstructServerDataPacket(
1902 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521903 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231904 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341905 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyief3f4ce52017-07-05 23:53:281906 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211907 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyief3f4ce52017-07-05 23:53:281908
1909 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1910
1911 AddHangingNonAlternateProtocolSocketData();
1912
1913 CreateSession(supported_versions_);
1914
1915 SendRequestAndExpectHttpResponse("hello world");
1916 SendRequestAndExpectQuicResponse("hello!");
1917
1918 // Check alternative service list is updated with new versions.
1919 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491920 session_->http_server_properties()->GetAlternativeServiceInfos(
1921 server, NetworkIsolationKey());
Victor Vasiliev22dd3f212022-02-11 21:57:291922 VerifyQuicVersionsInAlternativeServices(alt_svc_info_vector,
1923 supported_versions_);
zhongyief3f4ce52017-07-05 23:53:281924}
1925
bncaccd4962017-04-06 21:00:261926// Regression test for https://crbug.com/546991.
1927// The server might not be able to serve a request on an alternative connection,
1928// and might send a 421 Misdirected Request response status to indicate this.
1929// HttpNetworkTransaction should reset the request and retry without using
1930// alternative services.
1931TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1932 // Set up alternative service to use QUIC.
1933 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1934 // that overrides |enable_alternative_services|.
1935 url::SchemeHostPort server(request_.url);
1936 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1937 443);
Peter Kastinge5a38ed2021-10-02 03:06:351938 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:491939 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071940 server, NetworkIsolationKey(), alternative_service, expiration,
1941 supported_versions_);
bncaccd4962017-04-06 21:00:261942
davidbena4449722017-05-05 23:30:531943 // First try: The alternative job uses QUIC and reports an HTTP 421
1944 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1945 // paused at Connect(), so it will never exit the socket pool. This ensures
1946 // that the alternate job always wins the race and keeps whether the
1947 // |http_data| exits the socket pool before the main job is aborted
1948 // deterministic. The first main job gets aborted without the socket pool ever
1949 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591950 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231951 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251952 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231953 mock_quic_data.AddWrite(SYNCHRONOUS,
1954 ConstructInitialSettingsPacket(packet_num++));
1955 }
rch5cb522462017-04-25 20:18:361956 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231957 SYNCHRONOUS,
1958 ConstructClientRequestHeadersPacket(
1959 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1960 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331961 mock_quic_data.AddRead(
1962 ASYNC, ConstructServerResponseHeadersPacket(
1963 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021964 GetResponseHeaders("421")));
David Schinazi395918c2021-02-05 18:56:211965 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncaccd4962017-04-06 21:00:261966 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1967
davidbena4449722017-05-05 23:30:531968 // Second try: The main job uses TCP, and there is no alternate job. Once the
1969 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1970 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261971 // Note that if there was an alternative QUIC Job created for the second try,
1972 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1973 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531974 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1975 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1976 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1977 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1978 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1979 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011980 reads, writes);
bncaccd4962017-04-06 21:00:261981 socket_factory_.AddSocketDataProvider(&http_data);
1982 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1983
bncaccd4962017-04-06 21:00:261984 CreateSession();
1985 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531986
1987 // Run until |mock_quic_data| has failed and |http_data| has paused.
1988 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261989 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
davidbena4449722017-05-05 23:30:531990 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1991 base::RunLoop().RunUntilIdle();
1992
1993 // |mock_quic_data| must have run to completion.
1994 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1995 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1996
1997 // Now that the QUIC data has been consumed, unblock |http_data|.
1998 http_data.socket()->OnConnectComplete(MockConnect());
1999
2000 // The retry logic must hide the 421 status. The transaction succeeds on
2001 // |http_data|.
2002 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:262003 CheckWasHttpResponse(&trans);
2004 CheckResponsePort(&trans, 443);
2005 CheckResponseData(&trans, "hello!");
2006}
2007
[email protected]1e960032013-12-20 19:00:202008TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Victor Vasilieva1e66d72019-12-05 17:55:382009 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:572010 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:302011
Ryan Hamiltonabad59e2019-06-06 04:02:592012 MockQuicData mock_quic_data1(version_);
Victor Vasiliev7da08172019-10-14 06:04:252013 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232014 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:402015 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Zhongyi Shi1c022d22020-03-20 19:00:162016 client_maker_->Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:592017 MockQuicData mock_quic_data2(version_);
Victor Vasiliev7da08172019-10-14 06:04:252018 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232019 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:302020 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:402021 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:432022 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:402023
2024 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
2025 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:302026
2027 CreateSession();
2028
tbansal0f56a39a2016-04-07 22:03:382029 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:402030 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:162031 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:402032 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262033 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:012034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2035 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:382036 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:532037
2038 NetErrorDetails details;
2039 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522040 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:402041 }
[email protected]cebe3282013-05-22 23:49:302042}
2043
tbansalc8a94ea2015-11-02 23:58:512044TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
2045 // Attempt to "force" quic on 443, which will not be honored.
Victor Vasilieva1e66d72019-12-05 17:55:382046 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:572047 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:512048
2049 MockRead http_reads[] = {
2050 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
2051 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2052 MockRead(ASYNC, OK)};
2053
Ryan Sleevib8d7ea02018-05-07 20:01:012054 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:512055 socket_factory_.AddSocketDataProvider(&data);
2056 SSLSocketDataProvider ssl(ASYNC, OK);
2057 socket_factory_.AddSSLSocketDataProvider(&ssl);
2058
2059 CreateSession();
2060
2061 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:382062 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:512063}
2064
bncc958faa2015-07-31 18:14:522065TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:352066 if (version_.AlpnDeferToRFCv1()) {
2067 // These versions currently do not support Alt-Svc.
2068 return;
2069 }
bncc958faa2015-07-31 18:14:522070 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452071 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:562072 MockRead("hello world"),
bncc958faa2015-07-31 18:14:522073 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2074 MockRead(ASYNC, OK)};
2075
Ryan Sleevib8d7ea02018-05-07 20:01:012076 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:522077 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082078 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:562079 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:522080
Ryan Hamiltonabad59e2019-06-06 04:02:592081 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232082 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252083 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232084 mock_quic_data.AddWrite(SYNCHRONOUS,
2085 ConstructInitialSettingsPacket(packet_num++));
2086 }
rch5cb522462017-04-25 20:18:362087 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232088 SYNCHRONOUS,
2089 ConstructClientRequestHeadersPacket(
2090 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2091 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432092 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332093 ASYNC, ConstructServerResponseHeadersPacket(
2094 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282095 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332096 mock_quic_data.AddRead(
2097 ASYNC, ConstructServerDataPacket(
2098 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522099 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232100 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342101 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:522102 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212103 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:522104
2105 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2106
rtennetib8e80fb2016-05-16 00:12:092107 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322108 CreateSession();
bncc958faa2015-07-31 18:14:522109
2110 SendRequestAndExpectHttpResponse("hello world");
2111 SendRequestAndExpectQuicResponse("hello!");
2112}
2113
Ryan Hamilton64f21d52019-08-31 07:10:512114TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:352115 if (version_.AlpnDeferToRFCv1()) {
2116 // These versions currently do not support Alt-Svc.
2117 return;
2118 }
Ryan Hamilton64f21d52019-08-31 07:10:512119 std::string alt_svc_header =
2120 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
2121 MockRead http_reads[] = {
2122 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
2123 MockRead("hello world"),
2124 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2125 MockRead(ASYNC, OK)};
2126
2127 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2128 socket_factory_.AddSocketDataProvider(&http_data);
2129 AddCertificate(&ssl_data_);
2130 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2131
2132 MockQuicData mock_quic_data(version_);
2133 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252134 if (VersionUsesHttp3(version_.transport_version)) {
Ryan Hamilton64f21d52019-08-31 07:10:512135 mock_quic_data.AddWrite(SYNCHRONOUS,
2136 ConstructInitialSettingsPacket(packet_num++));
2137 }
2138 mock_quic_data.AddWrite(
2139 SYNCHRONOUS,
2140 ConstructClientRequestHeadersPacket(
2141 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2142 true, GetRequestHeaders("GET", "https", "/")));
2143 mock_quic_data.AddRead(
2144 ASYNC, ConstructServerResponseHeadersPacket(
2145 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282146 GetResponseHeaders("200")));
Ryan Hamilton64f21d52019-08-31 07:10:512147 mock_quic_data.AddRead(
2148 ASYNC, ConstructServerDataPacket(
2149 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522150 ConstructDataFrame("hello!")));
Ryan Hamilton64f21d52019-08-31 07:10:512151 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342152 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton64f21d52019-08-31 07:10:512153 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212154 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamilton64f21d52019-08-31 07:10:512155
2156 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2157
2158 AddHangingNonAlternateProtocolSocketData();
2159 CreateSession();
2160
2161 SendRequestAndExpectHttpResponse("hello world");
2162 SendRequestAndExpectQuicResponse("hello!");
2163}
2164
Matt Menke3233d8f22019-08-20 21:01:492165// Much like above, but makes sure NetworkIsolationKey is respected.
2166TEST_P(QuicNetworkTransactionTest,
2167 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:352168 if (version_.AlpnDeferToRFCv1()) {
2169 // These versions currently do not support Alt-Svc.
2170 return;
2171 }
Matt Menke3233d8f22019-08-20 21:01:492172 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:052173 feature_list.InitWithFeatures(
2174 // enabled_features
2175 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2176 features::kPartitionConnectionsByNetworkIsolationKey},
2177 // disabled_features
2178 {});
Matt Menke3233d8f22019-08-20 21:01:492179 // Since HttpServerProperties caches the feature value, have to create a new
2180 // one.
2181 http_server_properties_ = std::make_unique<HttpServerProperties>();
2182
Matt Menke4807a9a2020-11-21 00:14:412183 const SchemefulSite kSite1(GURL("https://foo.test/"));
2184 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
2185 const SchemefulSite kSite2(GURL("https://bar.test/"));
2186 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menke3233d8f22019-08-20 21:01:492187
2188 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452189 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Matt Menke3233d8f22019-08-20 21:01:492190 MockRead("hello world"),
2191 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2192 MockRead(ASYNC, OK)};
2193
2194 AddCertificate(&ssl_data_);
2195
2196 // Request with empty NetworkIsolationKey.
2197 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2198 socket_factory_.AddSocketDataProvider(&http_data1);
2199 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2200
2201 // First request with kNetworkIsolationKey1.
2202 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2203 socket_factory_.AddSocketDataProvider(&http_data2);
2204 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2205
2206 // Request with kNetworkIsolationKey2.
2207 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2208 socket_factory_.AddSocketDataProvider(&http_data3);
2209 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2210
2211 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2212 // alternative service infrmation has been received in this context before.
2213 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232214 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252215 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232216 mock_quic_data.AddWrite(SYNCHRONOUS,
2217 ConstructInitialSettingsPacket(packet_num++));
2218 }
Matt Menke3233d8f22019-08-20 21:01:492219 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232220 SYNCHRONOUS,
2221 ConstructClientRequestHeadersPacket(
2222 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2223 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492224 mock_quic_data.AddRead(
2225 ASYNC, ConstructServerResponseHeadersPacket(
2226 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282227 GetResponseHeaders("200")));
Matt Menke3233d8f22019-08-20 21:01:492228 mock_quic_data.AddRead(
2229 ASYNC, ConstructServerDataPacket(
2230 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522231 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232232 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342233 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menke3233d8f22019-08-20 21:01:492234 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212235 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Matt Menke3233d8f22019-08-20 21:01:492236
2237 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2238
2239 AddHangingNonAlternateProtocolSocketData();
2240 CreateSession();
2241
2242 // This is first so that the test fails if alternative service info is
2243 // written with the right NetworkIsolationKey, but always queried with an
2244 // empty one.
2245 request_.network_isolation_key = NetworkIsolationKey();
2246 SendRequestAndExpectHttpResponse("hello world");
2247 request_.network_isolation_key = kNetworkIsolationKey1;
2248 SendRequestAndExpectHttpResponse("hello world");
2249 request_.network_isolation_key = kNetworkIsolationKey2;
2250 SendRequestAndExpectHttpResponse("hello world");
2251
2252 // Only use QUIC when using a NetworkIsolationKey which has been used when
2253 // alternative service information was received.
2254 request_.network_isolation_key = kNetworkIsolationKey1;
2255 SendRequestAndExpectQuicResponse("hello!");
2256}
2257
zhongyia00ca012017-07-06 23:36:392258TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
Ryan Hamiltona51800a2022-02-12 19:34:352259 if (version_.AlpnDeferToRFCv1()) {
2260 // These versions currently do not support Alt-Svc.
2261 return;
2262 }
Victor Vasiliev22dd3f212022-02-11 21:57:292263 // Both client and server supports two QUIC versions:
2264 // Client supports |supported_versions_[0]| and |supported_versions_[1]|,
2265 // server supports |version_| and |advertised_version_2|.
2266 // Only |version_| (same as |supported_versions_[0]|) is supported by both.
zhongyia00ca012017-07-06 23:36:392267 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2268 // PacketMakers are using |version_|.
2269
Victor Vasiliev22dd3f212022-02-11 21:57:292270 // Compare ALPN strings instead of ParsedQuicVersions because QUIC v1 and v2
2271 // have the same ALPN string.
2272 ASSERT_EQ(1u, supported_versions_.size());
2273 ASSERT_EQ(supported_versions_[0], version_);
David Schinazi84c58bb2020-06-04 20:14:332274 quic::ParsedQuicVersion advertised_version_2 =
2275 quic::ParsedQuicVersion::Unsupported();
Nick Harper23290b82019-05-02 00:02:562276 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Victor Vasiliev22dd3f212022-02-11 21:57:292277 if (quic::AlpnForVersion(version) == quic::AlpnForVersion(version_)) {
zhongyia00ca012017-07-06 23:36:392278 continue;
Victor Vasiliev22dd3f212022-02-11 21:57:292279 }
zhongyia00ca012017-07-06 23:36:392280 if (supported_versions_.size() != 2) {
2281 supported_versions_.push_back(version);
2282 continue;
2283 }
Victor Vasiliev22dd3f212022-02-11 21:57:292284 if (supported_versions_.size() == 2 &&
2285 quic::AlpnForVersion(supported_versions_[1]) ==
2286 quic::AlpnForVersion(version)) {
2287 continue;
2288 }
zhongyia00ca012017-07-06 23:36:392289 advertised_version_2 = version;
2290 break;
2291 }
Bence Békyb89104962020-01-24 00:05:172292 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:332293 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), advertised_version_2);
zhongyia00ca012017-07-06 23:36:392294
Bence Békyb89104962020-01-24 00:05:172295 std::string QuicAltSvcWithVersionHeader =
2296 base::StringPrintf("Alt-Svc: %s=\":443\", %s=\":443\"\r\n\r\n",
2297 quic::AlpnForVersion(advertised_version_2).c_str(),
2298 quic::AlpnForVersion(version_).c_str());
zhongyia00ca012017-07-06 23:36:392299
2300 MockRead http_reads[] = {
2301 MockRead("HTTP/1.1 200 OK\r\n"),
2302 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2303 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2304 MockRead(ASYNC, OK)};
2305
Ryan Sleevib8d7ea02018-05-07 20:01:012306 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392307 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082308 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392309 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2310
Ryan Hamiltonabad59e2019-06-06 04:02:592311 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232312 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252313 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232314 mock_quic_data.AddWrite(SYNCHRONOUS,
2315 ConstructInitialSettingsPacket(packet_num++));
2316 }
zhongyia00ca012017-07-06 23:36:392317 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232318 SYNCHRONOUS,
2319 ConstructClientRequestHeadersPacket(
2320 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2321 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432322 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332323 ASYNC, ConstructServerResponseHeadersPacket(
2324 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282325 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332326 mock_quic_data.AddRead(
2327 ASYNC, ConstructServerDataPacket(
2328 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522329 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232330 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342331 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392332 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212333 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyia00ca012017-07-06 23:36:392334
2335 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2336
2337 AddHangingNonAlternateProtocolSocketData();
2338 CreateSession(supported_versions_);
2339
2340 SendRequestAndExpectHttpResponse("hello world");
2341 SendRequestAndExpectQuicResponse("hello!");
2342}
2343
Zhongyi Shi1c022d22020-03-20 19:00:162344TEST_P(QuicNetworkTransactionTest,
2345 PickQuicVersionWhenMultipleVersionsAreSupported) {
2346 // Client and server both support more than one QUIC_VERSION.
2347 // Client prefers |version_|, and then common_version_2.
2348 // Server prefers common_version_2, and then |version_|.
David Schinazifbd4c432020-04-07 19:23:552349 // We should honor the server's preference.
Zhongyi Shi1c022d22020-03-20 19:00:162350 // The picked version is verified via checking the version used by the
2351 // TestPacketMakers and the response.
Bence Békyb89104962020-01-24 00:05:172352
Zhongyi Shi1c022d22020-03-20 19:00:162353 // Find an alternative commonly supported version other than |version_|.
David Schinazi84c58bb2020-06-04 20:14:332354 quic::ParsedQuicVersion common_version_2 =
2355 quic::ParsedQuicVersion::Unsupported();
2356 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Ryan Hamiltona51800a2022-02-12 19:34:352357 if (version != version_ && !version.AlpnDeferToRFCv1()) {
Zhongyi Shi1c022d22020-03-20 19:00:162358 common_version_2 = version;
2359 break;
2360 }
zhongyia00ca012017-07-06 23:36:392361 }
David Schinazi84c58bb2020-06-04 20:14:332362 ASSERT_NE(common_version_2, quic::ParsedQuicVersion::Unsupported());
zhongyia00ca012017-07-06 23:36:392363
Zhongyi Shi1c022d22020-03-20 19:00:162364 // Setting up client's preference list: {|version_|, |common_version_2|}.
2365 supported_versions_.clear();
2366 supported_versions_.push_back(version_);
2367 supported_versions_.push_back(common_version_2);
zhongyia00ca012017-07-06 23:36:392368
Zhongyi Shi1c022d22020-03-20 19:00:162369 // Setting up server's Alt-Svc header in the following preference order:
2370 // |common_version_2|, |version_|.
2371 std::string QuicAltSvcWithVersionHeader;
David Schinazi84c58bb2020-06-04 20:14:332372 quic::ParsedQuicVersion picked_version =
2373 quic::ParsedQuicVersion::Unsupported();
2374 QuicAltSvcWithVersionHeader =
2375 "Alt-Svc: " + quic::AlpnForVersion(common_version_2) +
2376 "=\":443\"; ma=3600, " + quic::AlpnForVersion(version_) +
2377 "=\":443\"; ma=3600\r\n\r\n";
2378 picked_version = common_version_2; // Use server's preference.
zhongyia00ca012017-07-06 23:36:392379
2380 MockRead http_reads[] = {
2381 MockRead("HTTP/1.1 200 OK\r\n"),
2382 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2383 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2384 MockRead(ASYNC, OK)};
2385
Ryan Sleevib8d7ea02018-05-07 20:01:012386 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392387 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082388 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392389 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2390
Zhongyi Shi1c022d22020-03-20 19:00:162391 MockQuicData mock_quic_data(picked_version);
2392
2393 // Reset QuicTestPacket makers as the version picked may not be |version_|.
Renjie Tang6ff9a9b2021-02-03 22:11:092394 client_maker_ = std::make_unique<QuicTestPacketMaker>(
Zhongyi Shi1c022d22020-03-20 19:00:162395 picked_version,
2396 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2397 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Renjie Tang6ff9a9b2021-02-03 22:11:092398 client_headers_include_h2_stream_dependency_);
Zhongyi Shi1c022d22020-03-20 19:00:162399 QuicTestPacketMaker server_maker(
2400 picked_version,
2401 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2402 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
2403 false);
2404
Renjie Tangaadb84b2019-08-31 01:00:232405 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:162406 if (VersionUsesHttp3(picked_version.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232407 mock_quic_data.AddWrite(SYNCHRONOUS,
2408 ConstructInitialSettingsPacket(packet_num++));
2409 }
Zhongyi Shi1c022d22020-03-20 19:00:162410
2411 quic::QuicStreamId client_stream_0 =
2412 quic::test::GetNthClientInitiatedBidirectionalStreamId(
2413 picked_version.transport_version, 0);
2414 mock_quic_data.AddWrite(SYNCHRONOUS,
2415 ConstructClientRequestHeadersPacket(
2416 packet_num++, client_stream_0, true, true,
2417 GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashif8634ab2021-03-16 23:41:282418 mock_quic_data.AddRead(ASYNC,
2419 server_maker.MakeResponseHeadersPacket(
2420 1, client_stream_0, false, false,
2421 server_maker.GetResponseHeaders("200"), nullptr));
Fan Yang32c5a112018-12-10 20:06:332422 mock_quic_data.AddRead(
Bence Béky319388a882020-09-23 18:42:522423 ASYNC, server_maker.MakeDataPacket(
2424 2, client_stream_0, false, true,
2425 ConstructDataFrameForVersion("hello!", picked_version)));
Renjie Tangaadb84b2019-08-31 01:00:232426 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342427 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392428 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212429 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyia00ca012017-07-06 23:36:392430
2431 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2432
2433 AddHangingNonAlternateProtocolSocketData();
2434 CreateSession(supported_versions_);
2435
2436 SendRequestAndExpectHttpResponse("hello world");
Zhongyi Shi1c022d22020-03-20 19:00:162437 SendRequestAndExpectQuicResponseMaybeFromProxy(
Kenichi Ishibashif8634ab2021-03-16 23:41:282438 "hello!", false, 443, "HTTP/1.1 200", picked_version);
zhongyia00ca012017-07-06 23:36:392439}
2440
zhongyi3d4a55e72016-04-22 20:36:462441TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
Ryan Hamiltona51800a2022-02-12 19:34:352442 if (version_.AlpnDeferToRFCv1()) {
2443 // These versions currently do not support Alt-Svc.
2444 return;
2445 }
Ryan Hamiltona2dcbae2022-02-09 19:02:452446 std::string alt_svc_header = base::StrCat(
2447 {"Alt-Svc: ",
2448 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.com", 443), ",",
2449 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
zhongyi3d4a55e72016-04-22 20:36:462450 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452451 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
zhongyi3d4a55e72016-04-22 20:36:462452 MockRead("hello world"),
2453 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2454 MockRead(ASYNC, OK)};
2455
Ryan Sleevib8d7ea02018-05-07 20:01:012456 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462457 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082458 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462459 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2460
2461 CreateSession();
bncb26024382016-06-29 02:39:452462 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462463 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452464 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462465 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402466 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462467 session_->http_server_properties();
2468 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2469 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2470 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462471 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492472 2u, http_server_properties
2473 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2474 .size());
bncb26024382016-06-29 02:39:452475 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492476 http_server_properties
2477 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2478 .empty());
zhongyi3d4a55e72016-04-22 20:36:462479}
2480
2481TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
Ryan Hamiltona51800a2022-02-12 19:34:352482 if (version_.AlpnDeferToRFCv1()) {
2483 // These versions currently do not support Alt-Svc.
2484 return;
2485 }
Ryan Hamiltona2dcbae2022-02-09 19:02:452486 std::string alt_svc_header = base::StrCat(
2487 {"Alt-Svc: ",
2488 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.com", 443), ",",
2489 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
zhongyi3d4a55e72016-04-22 20:36:462490 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452491 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
zhongyi3d4a55e72016-04-22 20:36:462492 MockRead("hello world"),
2493 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2494 MockRead(ASYNC, OK)};
2495
Ryan Sleevib8d7ea02018-05-07 20:01:012496 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082497 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462498
2499 socket_factory_.AddSocketDataProvider(&http_data);
2500 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2501 socket_factory_.AddSocketDataProvider(&http_data);
2502 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2503
2504 CreateSession();
2505
2506 // Send https request and set alternative services if response header
2507 // advertises alternative service for mail.example.org.
2508 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402509 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462510 session_->http_server_properties();
2511
2512 const url::SchemeHostPort https_server(request_.url);
2513 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342514 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492515 2u, http_server_properties
2516 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2517 .size());
zhongyi3d4a55e72016-04-22 20:36:462518
2519 // Send http request to the same origin but with diffrent scheme, should not
2520 // use QUIC.
2521 request_.url = GURL("http://mail.example.org:443");
2522 SendRequestAndExpectHttpResponse("hello world");
2523}
2524
zhongyie537a002017-06-27 16:48:212525TEST_P(QuicNetworkTransactionTest,
2526 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442527 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562528 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Bence Békyb89104962020-01-24 00:05:172529 if (version != version_) {
2530 supported_versions_.push_back(version);
2531 break;
2532 }
zhongyi86838d52017-06-30 01:19:442533 }
2534
David Schinazifbd4c432020-04-07 19:23:552535 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyie537a002017-06-27 16:48:212536 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:172537 MockRead("HTTP/1.1 200 OK\r\n"),
2538 MockRead(altsvc_header.c_str()),
2539 MockRead("\r\n"),
zhongyie537a002017-06-27 16:48:212540 MockRead("hello world"),
2541 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2542 MockRead(ASYNC, OK)};
2543
Ryan Sleevib8d7ea02018-05-07 20:01:012544 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212545 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082546 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212547 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2548
Ryan Hamiltonabad59e2019-06-06 04:02:592549 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232550 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252551 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232552 mock_quic_data.AddWrite(SYNCHRONOUS,
2553 ConstructInitialSettingsPacket(packet_num++));
2554 }
zhongyie537a002017-06-27 16:48:212555 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232556 SYNCHRONOUS,
2557 ConstructClientRequestHeadersPacket(
2558 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2559 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432560 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332561 ASYNC, ConstructServerResponseHeadersPacket(
2562 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282563 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332564 mock_quic_data.AddRead(
2565 ASYNC, ConstructServerDataPacket(
2566 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522567 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232568 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342569 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyie537a002017-06-27 16:48:212570 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212571 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyie537a002017-06-27 16:48:212572
2573 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2574
2575 AddHangingNonAlternateProtocolSocketData();
2576
zhongyi86838d52017-06-30 01:19:442577 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212578
2579 SendRequestAndExpectHttpResponse("hello world");
2580 SendRequestAndExpectQuicResponse("hello!");
2581
Bence Békyb89104962020-01-24 00:05:172582 // Alt-Svc header contains all possible versions, so alternative services
2583 // should contain all of |supported_versions_|.
zhongyie537a002017-06-27 16:48:212584 const url::SchemeHostPort https_server(request_.url);
2585 const AlternativeServiceInfoVector alt_svc_info_vector =
2586 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492587 https_server, NetworkIsolationKey());
Victor Vasiliev22dd3f212022-02-11 21:57:292588 VerifyQuicVersionsInAlternativeServices(alt_svc_info_vector,
2589 supported_versions_);
zhongyie537a002017-06-27 16:48:212590}
2591
danzh3134c2562016-08-12 14:07:522592TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Ryan Hamiltona51800a2022-02-12 19:34:352593 if (version_.AlpnDeferToRFCv1()) {
2594 // These versions currently do not support Alt-Svc.
2595 return;
2596 }
Nick Harper23290b82019-05-02 00:02:562597 std::string altsvc_header = base::StringPrintf(
Bence Békyb89104962020-01-24 00:05:172598 "Alt-Svc: %s=\":443\"\r\n\r\n", quic::AlpnForVersion(version_).c_str());
bnc8be55ebb2015-10-30 14:12:072599 MockRead http_reads[] = {
2600 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2601 MockRead("hello world"),
2602 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2603 MockRead(ASYNC, OK)};
2604
Ryan Sleevib8d7ea02018-05-07 20:01:012605 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072606 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082607 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072608 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2609
Ryan Hamiltonabad59e2019-06-06 04:02:592610 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232611 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252612 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232613 mock_quic_data.AddWrite(SYNCHRONOUS,
2614 ConstructInitialSettingsPacket(packet_num++));
2615 }
rch5cb522462017-04-25 20:18:362616 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232617 SYNCHRONOUS,
2618 ConstructClientRequestHeadersPacket(
2619 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2620 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432621 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332622 ASYNC, ConstructServerResponseHeadersPacket(
2623 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282624 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332625 mock_quic_data.AddRead(
2626 ASYNC, ConstructServerDataPacket(
2627 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522628 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232629 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342630 ConstructClientAckPacket(packet_num++, 2, 1));
bnc8be55ebb2015-10-30 14:12:072631 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212632 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc8be55ebb2015-10-30 14:12:072633
2634 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2635
rtennetib8e80fb2016-05-16 00:12:092636 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322637 CreateSession();
bnc8be55ebb2015-10-30 14:12:072638
2639 SendRequestAndExpectHttpResponse("hello world");
2640 SendRequestAndExpectQuicResponse("hello!");
2641}
2642
zhongyi6b5a3892016-03-12 04:46:202643TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harperc6cb7a612020-02-24 20:03:322644 if (version_.HasIetfQuicFrames()) {
Renjie Tangba21e032019-09-27 21:52:282645 // GoAway is not available under version 99
Frank Kastenholz6e4c5382018-06-21 23:00:092646 return;
2647 }
Ryan Hamiltonabad59e2019-06-06 04:02:592648 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232649 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252650 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232651 mock_quic_data.AddWrite(SYNCHRONOUS,
2652 ConstructInitialSettingsPacket(packet_num++));
2653 }
rch5cb522462017-04-25 20:18:362654 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232655 SYNCHRONOUS,
2656 ConstructClientRequestHeadersPacket(
2657 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2658 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332659 mock_quic_data.AddRead(
2660 ASYNC, ConstructServerResponseHeadersPacket(
2661 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282662 GetResponseHeaders("200")));
zhongyi6b5a3892016-03-12 04:46:202663 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522664 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432665 mock_quic_data.AddRead(SYNCHRONOUS,
2666 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522667 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432668 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232669 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342670 ConstructClientAckPacket(packet_num++, 2, 1));
Fan Yang32c5a112018-12-10 20:06:332671 mock_quic_data.AddRead(
2672 SYNCHRONOUS, ConstructServerDataPacket(
2673 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:522674 true, ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232675 mock_quic_data.AddWrite(
2676 SYNCHRONOUS,
2677 ConstructClientAckAndRstPacket(
2678 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:342679 quic::QUIC_STREAM_CANCELLED, 3, 3));
zhongyi6b5a3892016-03-12 04:46:202680 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212681 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi6b5a3892016-03-12 04:46:202682
2683 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2684
2685 // The non-alternate protocol job needs to hang in order to guarantee that
2686 // the alternate-protocol job will "win".
2687 AddHangingNonAlternateProtocolSocketData();
2688
2689 // In order for a new QUIC session to be established via alternate-protocol
2690 // without racing an HTTP connection, we need the host resolution to happen
2691 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2692 // connection to the the server, in this test we require confirmation
2693 // before encrypting so the HTTP job will still start.
2694 host_resolver_.set_synchronous_mode(true);
2695 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2696 "");
zhongyi6b5a3892016-03-12 04:46:202697
2698 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432699 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2700 false);
Ryan Hamilton9835e662018-08-02 05:36:272701 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202702
bnc691fda62016-08-12 00:43:162703 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202704 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262705 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:012706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202707
Fan Yang3673cc72020-02-07 14:49:282708 crypto_client_stream_factory_.last_stream()
2709 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:012710 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202711
2712 // Check whether this transaction is correctly marked as received a go-away
2713 // because of migrating port.
2714 NetErrorDetails details;
2715 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162716 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202717 EXPECT_TRUE(details.quic_port_migration_detected);
2718}
2719
Zhongyi Shia6b68d112018-09-24 07:49:032720// This test verifies that a new QUIC connection will be attempted on the
2721// alternate network if the original QUIC connection fails with idle timeout
2722// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2723// alternate network as well, QUIC is marked as broken and the brokenness will
2724// not expire when default network changes.
Renjie Tangb6fc5e02020-06-30 00:48:342725// TODO(fayang): Add time driven idle network detection test.
2726TEST_P(QuicNetworkTransactionTest,
2727 DISABLED_QuicFailsOnBothNetworksWhileTCPSucceeds) {
Ryan Hamiltona51800a2022-02-12 19:34:352728 if (version_.AlpnDeferToRFCv1()) {
2729 // These versions currently do not support Alt-Svc.
2730 return;
2731 }
Renjie Tangb6fc5e02020-06-30 00:48:342732 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432733 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2734 return;
2735 }
Zhongyi Shia6b68d112018-09-24 07:49:032736 SetUpTestForRetryConnectionOnAlternateNetwork();
2737
Zhongyi Shi1c022d22020-03-20 19:00:162738 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032739
2740 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592741 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032742 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2743 int packet_num = 1;
2744 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162745 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:592746 // Retransmit the handshake messages.
Zhongyi Shia6b68d112018-09-24 07:49:032747 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162748 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032749 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162750 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032751 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162752 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032753 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162754 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032755 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2756 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162757 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:032758 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522759 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:032760 quic_data.AddSocketDataToFactory(&socket_factory_);
2761
2762 // Add successful TCP data so that TCP job will succeed.
2763 MockWrite http_writes[] = {
2764 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2765 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2766 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2767
Ryan Hamiltona2dcbae2022-02-09 19:02:452768 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2769 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
2770 MockRead(SYNCHRONOUS, 5, "TCP succeeds"),
2771 MockRead(SYNCHRONOUS, OK, 6)};
Zhongyi Shia6b68d112018-09-24 07:49:032772 SequencedSocketData http_data(http_reads, http_writes);
2773 socket_factory_.AddSocketDataProvider(&http_data);
2774 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2775
2776 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592777 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032778 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2779 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2780 quic_data2.AddSocketDataToFactory(&socket_factory_);
2781
2782 // Resolve the host resolution synchronously.
2783 host_resolver_.set_synchronous_mode(true);
2784 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2785 "");
Zhongyi Shia6b68d112018-09-24 07:49:032786
2787 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432788 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2789 false);
Zhongyi Shia6b68d112018-09-24 07:49:032790 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032791 QuicStreamFactoryPeer::SetAlarmFactory(
2792 session_->quic_stream_factory(),
2793 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222794 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032795 // Add alternate protocol mapping to race QUIC and TCP.
2796 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2797 // peer.
2798 AddQuicAlternateProtocolMapping(
2799 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2800
2801 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2802 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262803 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Zhongyi Shia6b68d112018-09-24 07:49:032804 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2805
2806 // Pump the message loop to get the request started.
2807 // Request will be served with TCP job.
2808 base::RunLoop().RunUntilIdle();
2809 EXPECT_THAT(callback.WaitForResult(), IsOk());
2810 CheckResponseData(&trans, "TCP succeeds");
2811
Zhongyi Shia6b68d112018-09-24 07:49:032812 // Fast forward to idle timeout the original connection. A new connection will
2813 // be kicked off on the alternate network.
2814 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2815 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2816 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2817
2818 // Run the message loop to execute posted tasks, which will report job status.
2819 base::RunLoop().RunUntilIdle();
2820
2821 // Verify that QUIC is marked as broken.
2822 ExpectBrokenAlternateProtocolMapping();
2823
2824 // Deliver a message to notify the new network becomes default, the brokenness
2825 // will not expire as QUIC is broken on both networks.
2826 scoped_mock_change_notifier_->mock_network_change_notifier()
2827 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2828 ExpectBrokenAlternateProtocolMapping();
2829
2830 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2831 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2832}
2833
2834// This test verifies that a new QUIC connection will be attempted on the
2835// alternate network if the original QUIC connection fails with idle timeout
2836// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2837// alternate network, QUIC is marked as broken. The brokenness will expire when
2838// the default network changes.
Renjie Tangb6fc5e02020-06-30 00:48:342839// TODO(fayang): Add time driven idle network detection test.
2840TEST_P(QuicNetworkTransactionTest,
2841 DISABLED_RetryOnAlternateNetworkWhileTCPSucceeds) {
Ryan Hamiltona51800a2022-02-12 19:34:352842 if (version_.AlpnDeferToRFCv1()) {
2843 // These versions currently do not support Alt-Svc.
2844 return;
2845 }
Renjie Tangb6fc5e02020-06-30 00:48:342846 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432847 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2848 return;
2849 }
2850
Zhongyi Shia6b68d112018-09-24 07:49:032851 SetUpTestForRetryConnectionOnAlternateNetwork();
2852
Zhongyi Shi1c022d22020-03-20 19:00:162853 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032854
2855 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592856 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032857 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2858 int packet_num = 1;
2859 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162860 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:592861 // Retransmit the handshake messages.
Zhongyi Shia6b68d112018-09-24 07:49:032862 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162863 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032864 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162865 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032866 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162867 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032868 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162869 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032870 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2871 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162872 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:032873 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522874 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:032875 quic_data.AddSocketDataToFactory(&socket_factory_);
2876
2877 // Add successful TCP data so that TCP job will succeed.
2878 MockWrite http_writes[] = {
2879 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2880 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2881 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2882
Ryan Hamiltona2dcbae2022-02-09 19:02:452883 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2884 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
2885 MockRead(SYNCHRONOUS, 5, "TCP succeeds"),
2886 MockRead(SYNCHRONOUS, OK, 6)};
Zhongyi Shia6b68d112018-09-24 07:49:032887 SequencedSocketData http_data(http_reads, http_writes);
2888 socket_factory_.AddSocketDataProvider(&http_data);
2889 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2890
2891 // Quic connection will be retried on the alternate network after the initial
2892 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592893 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032894 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2895 quic_data2.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162896 client_maker_->MakeDummyCHLOPacket(1)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:032897
Zhongyi Shi1c022d22020-03-20 19:00:162898 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252899 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232900 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032901 quic_data2.AddSocketDataToFactory(&socket_factory_);
2902
2903 // Resolve the host resolution synchronously.
2904 host_resolver_.set_synchronous_mode(true);
2905 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2906 "");
Zhongyi Shia6b68d112018-09-24 07:49:032907
2908 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432909 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2910 false);
Zhongyi Shia6b68d112018-09-24 07:49:032911 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032912 QuicStreamFactoryPeer::SetAlarmFactory(
2913 session_->quic_stream_factory(),
2914 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222915 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032916 // Add alternate protocol mapping to race QUIC and TCP.
2917 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2918 // peer.
2919 AddQuicAlternateProtocolMapping(
2920 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2921
2922 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2923 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262924 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Zhongyi Shia6b68d112018-09-24 07:49:032925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2926
2927 // Pump the message loop to get the request started.
2928 // Request will be served with TCP job.
2929 base::RunLoop().RunUntilIdle();
2930 EXPECT_THAT(callback.WaitForResult(), IsOk());
2931 CheckResponseData(&trans, "TCP succeeds");
2932
Zhongyi Shia6b68d112018-09-24 07:49:032933 // Fast forward to idle timeout the original connection. A new connection will
2934 // be kicked off on the alternate network.
2935 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2936 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2937 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2938
2939 // The second connection hasn't finish handshake, verify that QUIC is not
2940 // marked as broken.
2941 ExpectQuicAlternateProtocolMapping();
2942 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:282943 crypto_client_stream_factory_.last_stream()
2944 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia6b68d112018-09-24 07:49:032945 // Run message loop to execute posted tasks, which will notify JoController
2946 // about the orphaned job status.
2947 base::RunLoop().RunUntilIdle();
2948
2949 // Verify that QUIC is marked as broken.
2950 ExpectBrokenAlternateProtocolMapping();
2951
2952 // Deliver a message to notify the new network becomes default, the previous
2953 // brokenness will be clear as the brokenness is bond with old default
2954 // network.
2955 scoped_mock_change_notifier_->mock_network_change_notifier()
2956 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2957 ExpectQuicAlternateProtocolMapping();
2958
2959 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2960 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2961}
2962
Matt Menkeb32ba5122019-09-10 19:17:052963// Much like above test, but verifies NetworkIsolationKeys are respected.
Renjie Tangb6fc5e02020-06-30 00:48:342964// TODO(fayang): Add time driven idle network detection test.
2965TEST_P(
2966 QuicNetworkTransactionTest,
2967 DISABLED_RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:352968 if (version_.AlpnDeferToRFCv1()) {
2969 // These versions currently do not support Alt-Svc.
2970 return;
2971 }
Renjie Tangb6fc5e02020-06-30 00:48:342972 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432973 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2974 return;
2975 }
2976
Matt Menke4807a9a2020-11-21 00:14:412977 const SchemefulSite kSite1(GURL("https://foo.test/"));
2978 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
2979 const SchemefulSite kSite2(GURL("https://bar.test/"));
2980 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:052981
2982 base::test::ScopedFeatureList feature_list;
2983 feature_list.InitWithFeatures(
2984 // enabled_features
2985 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2986 // Need to partition connections by NetworkIsolationKey for
2987 // QuicSessionAliasKey to include NetworkIsolationKeys.
2988 features::kPartitionConnectionsByNetworkIsolationKey},
2989 // disabled_features
2990 {});
2991 // Since HttpServerProperties caches the feature value, have to create a new
2992 // one.
2993 http_server_properties_ = std::make_unique<HttpServerProperties>();
2994
2995 SetUpTestForRetryConnectionOnAlternateNetwork();
2996
Zhongyi Shi1c022d22020-03-20 19:00:162997 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Matt Menkeb32ba5122019-09-10 19:17:052998
2999 // The request will initially go out over QUIC.
3000 MockQuicData quic_data(version_);
3001 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
3002 int packet_num = 1;
3003 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163004 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:593005 // Retransmit the handshake messages.
Matt Menkeb32ba5122019-09-10 19:17:053006 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163007 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:053008 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163009 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:053010 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163011 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:053012 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163013 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:053014 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
3015 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163016 client_maker_->MakeConnectionClosePacket(
Matt Menkeb32ba5122019-09-10 19:17:053017 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523018 "No recent network activity after 4s. Timeout:4s"));
Matt Menkeb32ba5122019-09-10 19:17:053019 quic_data.AddSocketDataToFactory(&socket_factory_);
3020
3021 // Add successful TCP data so that TCP job will succeed.
3022 MockWrite http_writes[] = {
3023 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3024 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3025 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3026
Ryan Hamiltona2dcbae2022-02-09 19:02:453027 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3028 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3029 MockRead(SYNCHRONOUS, 5, "TCP succeeds"),
3030 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:053031 SequencedSocketData http_data(http_reads, http_writes);
3032 socket_factory_.AddSocketDataProvider(&http_data);
3033 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3034
3035 // Quic connection will be retried on the alternate network after the initial
3036 // one fails on the default network.
3037 MockQuicData quic_data2(version_);
3038 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
3039 quic_data2.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163040 client_maker_->MakeDummyCHLOPacket(1)); // CHLO
Matt Menkeb32ba5122019-09-10 19:17:053041
Zhongyi Shi1c022d22020-03-20 19:00:163042 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253043 if (VersionUsesHttp3(version_.transport_version))
Matt Menkeb32ba5122019-09-10 19:17:053044 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
3045 quic_data2.AddSocketDataToFactory(&socket_factory_);
3046
3047 // Resolve the host resolution synchronously.
3048 host_resolver_.set_synchronous_mode(true);
3049 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3050 "");
3051
3052 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433053 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3054 false);
Matt Menkeb32ba5122019-09-10 19:17:053055 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
3056 QuicStreamFactoryPeer::SetAlarmFactory(
3057 session_->quic_stream_factory(),
3058 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223059 context_.clock()));
Matt Menkeb32ba5122019-09-10 19:17:053060 // Add alternate protocol mapping to race QUIC and TCP.
3061 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3062 // peer.
3063 AddQuicAlternateProtocolMapping(
3064 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
3065 AddQuicAlternateProtocolMapping(
3066 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
3067
3068 request_.network_isolation_key = kNetworkIsolationKey1;
3069 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3070 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263071 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeb32ba5122019-09-10 19:17:053072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3073
3074 // Pump the message loop to get the request started.
3075 // Request will be served with TCP job.
3076 base::RunLoop().RunUntilIdle();
3077 EXPECT_THAT(callback.WaitForResult(), IsOk());
3078 CheckResponseData(&trans, "TCP succeeds");
3079
3080 // Fast forward to idle timeout the original connection. A new connection will
3081 // be kicked off on the alternate network.
3082 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3083 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3084 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3085
3086 // The second connection hasn't finish handshake, verify that QUIC is not
3087 // marked as broken.
3088 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
3089 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3090 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:283091 crypto_client_stream_factory_.last_stream()
3092 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:053093 // Run message loop to execute posted tasks, which will notify JoController
3094 // about the orphaned job status.
3095 base::RunLoop().RunUntilIdle();
3096
3097 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
3098 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3099 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3100
3101 // Deliver a message to notify the new network becomes default, the previous
3102 // brokenness will be clear as the brokenness is bond with old default
3103 // network.
3104 scoped_mock_change_notifier_->mock_network_change_notifier()
3105 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3106 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
3107 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3108
3109 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3110 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3111}
3112
Zhongyi Shia6b68d112018-09-24 07:49:033113// This test verifies that a new QUIC connection will be attempted on the
3114// alternate network if the original QUIC connection fails with idle timeout
3115// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
3116// alternative network succeeds, QUIC is not marked as broken.
Renjie Tangb6fc5e02020-06-30 00:48:343117// TODO(fayang): Add time driven idle network detection test.
3118TEST_P(QuicNetworkTransactionTest,
3119 DISABLED_RetryOnAlternateNetworkWhileTCPHanging) {
3120 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433121 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3122 return;
3123 }
3124
Zhongyi Shia6b68d112018-09-24 07:49:033125 SetUpTestForRetryConnectionOnAlternateNetwork();
3126
Zhongyi Shi1c022d22020-03-20 19:00:163127 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:033128
3129 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593130 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:033131 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
3132 int packet_num = 1;
3133 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163134 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:593135 // Retransmit the handshake messages.
Zhongyi Shia6b68d112018-09-24 07:49:033136 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163137 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033138 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163139 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033140 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163141 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033142 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163143 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033144 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
3145 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163146 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:033147 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523148 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:033149 quic_data.AddSocketDataToFactory(&socket_factory_);
3150
3151 // Add hanging TCP data so that TCP job will never succeeded.
3152 AddHangingNonAlternateProtocolSocketData();
3153
3154 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:593155 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:233156 packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:163157 quic_data2.AddWrite(
3158 SYNCHRONOUS,
3159 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:033160
Victor Vasiliev076657c2019-03-12 02:46:433161 const std::string body = "hello!";
Renjief49758b2019-01-11 23:32:413162
Zhongyi Shi1c022d22020-03-20 19:00:163163 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253164 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233165 quic_data2.AddWrite(SYNCHRONOUS,
3166 ConstructInitialSettingsPacket(packet_num++));
3167 }
Zhongyi Shia6b68d112018-09-24 07:49:033168 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233169 SYNCHRONOUS,
3170 ConstructClientRequestHeadersPacket(
3171 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3172 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:033173 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333174 ASYNC, ConstructServerResponseHeadersPacket(
3175 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283176 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:333177 quic_data2.AddRead(
3178 ASYNC, ConstructServerDataPacket(
3179 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523180 ConstructDataFrame(body)));
Renjie Tangaadb84b2019-08-31 01:00:233181 quic_data2.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343182 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shia6b68d112018-09-24 07:49:033183 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
3184 quic_data2.AddSocketDataToFactory(&socket_factory_);
3185
3186 // Resolve the host resolution synchronously.
3187 host_resolver_.set_synchronous_mode(true);
3188 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3189 "");
Zhongyi Shia6b68d112018-09-24 07:49:033190
3191 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433192 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3193 false);
Zhongyi Shia6b68d112018-09-24 07:49:033194 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:033195 QuicStreamFactoryPeer::SetAlarmFactory(
3196 session_->quic_stream_factory(),
3197 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223198 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:033199 // Add alternate protocol mapping to race QUIC and TCP.
3200 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3201 // peer.
3202 AddQuicAlternateProtocolMapping(
3203 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3204
3205 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3206 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263207 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Zhongyi Shia6b68d112018-09-24 07:49:033208 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3209
3210 // Pump the message loop to get the request started.
3211 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:033212
3213 // Fast forward to idle timeout the original connection. A new connection will
3214 // be kicked off on the alternate network.
3215 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3216 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3217 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3218
3219 // Verify that QUIC is not marked as broken.
3220 ExpectQuicAlternateProtocolMapping();
3221 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:283222 crypto_client_stream_factory_.last_stream()
3223 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia6b68d112018-09-24 07:49:033224
3225 // Read the response.
3226 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:413227 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:033228 // Verify that QUIC is not marked as broken.
3229 ExpectQuicAlternateProtocolMapping();
3230
3231 // Deliver a message to notify the new network becomes default.
3232 scoped_mock_change_notifier_->mock_network_change_notifier()
3233 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3234 ExpectQuicAlternateProtocolMapping();
3235 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3236 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3237}
3238
rch9ecde09b2017-04-08 00:18:233239// Verify that if a QUIC connection times out, the QuicHttpStream will
3240// return QUIC_PROTOCOL_ERROR.
3241TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:383242 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Peter Kastinge5a38ed2021-10-02 03:06:353243 context_.params()->idle_connection_timeout = base::Seconds(5);
rch9ecde09b2017-04-08 00:18:233244
3245 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593246 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133247 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233248 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3249
Zhongyi Shi1c022d22020-03-20 19:00:163250 client_maker_->set_save_packet_frames(true);
3251 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493252 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253253 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493254 quic_data.AddWrite(SYNCHRONOUS,
3255 ConstructInitialSettingsPacket(packet_num++));
3256 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023257 quic_data.AddWrite(
3258 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163259 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493260 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3261 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453262
Zhongyi Shi1c022d22020-03-20 19:00:163263 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233264
Victor Vasiliev7da08172019-10-14 06:04:253265 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper0b214c132020-10-26 20:10:233266 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3267 // sending PTO packets.
3268 packet_num++;
3269 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163270 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493271 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233272 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3273 // sending PTO packets.
3274 packet_num++;
3275 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163276 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493277 2, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233278 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3279 // sending PTO packets.
3280 packet_num++;
3281 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163282 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493283 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233284
3285 quic_data.AddWrite(SYNCHRONOUS,
3286 client_maker_->MakeConnectionClosePacket(
3287 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3288 "No recent network activity after 4s. Timeout:4s"));
Victor Vasilievce06e5d2022-03-04 04:34:333289 } else if (version_.UsesTls() || GetQuicRestartFlag(quic_default_on_pto2)) {
Nick Harper0b214c132020-10-26 20:10:233290 // Settings were sent in the request packet so there is only 1 packet to
3291 // retransmit.
3292 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3293 // sending PTO packets.
3294 packet_num++;
3295 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163296 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493297 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233298 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3299 // sending PTO packets.
3300 packet_num++;
3301 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163302 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493303 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233304 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3305 // sending PTO packets.
3306 packet_num++;
3307 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163308 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper0b214c132020-10-26 20:10:233309 1, packet_num++, true));
Ryan Hamilton3cc2c152019-07-09 19:36:013310
Findit2403b85d2019-11-19 05:06:373311 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163312 client_maker_->MakeConnectionClosePacket(
Findit2403b85d2019-11-19 05:06:373313 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523314 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493315 } else {
3316 // Settings were sent in the request packet so there is only 1 packet to
3317 // retransmit.
3318 // TLP 1
Zhongyi Shi1c022d22020-03-20 19:00:163319 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493320 1, packet_num++, true));
3321 // TLP 2
Zhongyi Shi1c022d22020-03-20 19:00:163322 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493323 1, packet_num++, true));
3324 // RTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163325 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493326 1, packet_num++, true));
3327 // RTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163328 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493329 1, packet_num++, true));
3330 // RTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163331 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493332 1, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373333
Nick Harper057264a82019-09-12 23:33:493334 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163335 client_maker_->MakeConnectionClosePacket(
Nick Harper057264a82019-09-12 23:33:493336 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523337 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493338 }
Fan Yang928f1632017-12-14 18:55:223339
rch9ecde09b2017-04-08 00:18:233340 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3341 quic_data.AddRead(ASYNC, OK);
3342 quic_data.AddSocketDataToFactory(&socket_factory_);
3343
3344 // In order for a new QUIC session to be established via alternate-protocol
3345 // without racing an HTTP connection, we need the host resolution to happen
3346 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3347 // connection to the the server, in this test we require confirmation
3348 // before encrypting so the HTTP job will still start.
3349 host_resolver_.set_synchronous_mode(true);
3350 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3351 "");
rch9ecde09b2017-04-08 00:18:233352
3353 CreateSession();
3354 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233355 QuicStreamFactoryPeer::SetAlarmFactory(
3356 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193357 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223358 context_.clock()));
rch9ecde09b2017-04-08 00:18:233359
Ryan Hamilton9835e662018-08-02 05:36:273360 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233361
3362 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3363 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263364 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch9ecde09b2017-04-08 00:18:233365 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3366
3367 // Pump the message loop to get the request started.
3368 base::RunLoop().RunUntilIdle();
3369 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283370 crypto_client_stream_factory_.last_stream()
3371 ->NotifySessionOneRttKeyAvailable();
rch9ecde09b2017-04-08 00:18:233372
3373 // Run the QUIC session to completion.
3374 quic_task_runner_->RunUntilIdle();
3375
3376 ExpectQuicAlternateProtocolMapping();
3377 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3378 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3379}
3380
David Schinazi7e980ab2020-05-13 20:26:553381// TODO(fayang): Add time driven TOO_MANY_RTOS test.
rch9ecde09b2017-04-08 00:18:233382
rch2f2991c2017-04-13 19:28:173383// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3384// the request fails with QUIC_PROTOCOL_ERROR.
3385TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:383386 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173387 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593388 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:163389 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493390 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253391 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493392 quic_data.AddWrite(SYNCHRONOUS,
3393 ConstructInitialSettingsPacket(packet_num++));
3394 }
3395 quic_data.AddWrite(
3396 SYNCHRONOUS,
3397 ConstructClientRequestHeadersPacket(
3398 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3399 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163400 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553401 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173402 // Peer sending data from an non-existing stream causes this end to raise
3403 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333404 quic_data.AddRead(
3405 ASYNC, ConstructServerRstPacket(
3406 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3407 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173408 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:343409 quic_data.AddWrite(
3410 SYNCHRONOUS,
3411 ConstructClientAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:343412 packet_num++, 1, 1,
Renjie Tang248e36ea2020-06-26 00:12:343413 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
3414 : quic::QUIC_INVALID_STREAM_ID,
Renjie Tanga35322a2020-12-02 20:12:273415 quic_error_details,
3416 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
3417 : quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173418 quic_data.AddSocketDataToFactory(&socket_factory_);
3419
3420 // In order for a new QUIC session to be established via alternate-protocol
3421 // without racing an HTTP connection, we need the host resolution to happen
3422 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3423 // connection to the the server, in this test we require confirmation
3424 // before encrypting so the HTTP job will still start.
3425 host_resolver_.set_synchronous_mode(true);
3426 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3427 "");
rch2f2991c2017-04-13 19:28:173428
3429 CreateSession();
3430
Ryan Hamilton9835e662018-08-02 05:36:273431 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173432
3433 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3434 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263435 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:173436 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3437
3438 // Pump the message loop to get the request started.
3439 base::RunLoop().RunUntilIdle();
3440 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283441 crypto_client_stream_factory_.last_stream()
3442 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:173443
3444 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553445 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173446
3447 // Run the QUIC session to completion.
3448 base::RunLoop().RunUntilIdle();
3449 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3450 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3451
3452 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3453 ExpectQuicAlternateProtocolMapping();
3454 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3455}
3456
rch2f2991c2017-04-13 19:28:173457// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3458// connection times out, then QUIC will be marked as broken and the request
3459// retried over TCP.
3460TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Ryan Hamiltona51800a2022-02-12 19:34:353461 if (version_.AlpnDeferToRFCv1()) {
3462 // These versions currently do not support Alt-Svc.
3463 return;
3464 }
Peter Kastinge5a38ed2021-10-02 03:06:353465 context_.params()->idle_connection_timeout = base::Seconds(5);
rch2f2991c2017-04-13 19:28:173466
3467 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593468 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133469 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173470 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3471
Zhongyi Shi1c022d22020-03-20 19:00:163472 client_maker_->set_save_packet_frames(true);
3473 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493474 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253475 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493476 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163477 client_maker_->MakeInitialSettingsPacket(packet_num++));
Nick Harper057264a82019-09-12 23:33:493478 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023479 quic_data.AddWrite(
3480 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163481 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493482 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3483 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453484
Zhongyi Shi1c022d22020-03-20 19:00:163485 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253486 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper0b214c132020-10-26 20:10:233487 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3488 // sending PTO packets.
3489 packet_num++;
3490 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163491 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493492 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233493
3494 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3495 // sending PTO packets.
3496 packet_num++;
3497 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163498 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493499 2, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233500
3501 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3502 // sending PTO packets.
3503 packet_num++;
3504 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163505 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493506 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233507
3508 quic_data.AddWrite(SYNCHRONOUS,
3509 client_maker_->MakeConnectionClosePacket(
3510 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3511 "No recent network activity after 4s. Timeout:4s"));
Victor Vasilievce06e5d2022-03-04 04:34:333512 } else if (version_.UsesTls() || GetQuicRestartFlag(quic_default_on_pto2)) {
Nick Harper0b214c132020-10-26 20:10:233513 // Settings were sent in the request packet so there is only 1 packet to
3514 // retransmit.
3515 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3516 // sending PTO packets.
3517 packet_num++;
3518 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163519 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493520 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233521 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3522 // sending PTO packets.
3523 packet_num++;
3524 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163525 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493526 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233527 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3528 // sending PTO packets.
3529 packet_num++;
3530 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163531 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper0b214c132020-10-26 20:10:233532 1, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373533
3534 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163535 client_maker_->MakeConnectionClosePacket(
Findit2403b85d2019-11-19 05:06:373536 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523537 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493538 } else {
3539 // TLP 1
Zhongyi Shi1c022d22020-03-20 19:00:163540 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493541 1, packet_num++, true));
3542 // TLP 2
Zhongyi Shi1c022d22020-03-20 19:00:163543 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493544 1, packet_num++, true));
3545 // RTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163546 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493547 1, packet_num++, true));
3548 // RTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163549 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493550 1, packet_num++, true));
3551 // RTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163552 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493553 1, packet_num++, true));
3554
3555 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163556 client_maker_->MakeConnectionClosePacket(
Nick Harper057264a82019-09-12 23:33:493557 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523558 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493559 }
Fan Yang928f1632017-12-14 18:55:223560
rch2f2991c2017-04-13 19:28:173561 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3562 quic_data.AddRead(ASYNC, OK);
3563 quic_data.AddSocketDataToFactory(&socket_factory_);
3564
3565 // After that fails, it will be resent via TCP.
3566 MockWrite http_writes[] = {
3567 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3568 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3569 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3570
Ryan Hamiltona2dcbae2022-02-09 19:02:453571 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3572 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3573 MockRead(SYNCHRONOUS, 5, "hello world"),
3574 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013575 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173576 socket_factory_.AddSocketDataProvider(&http_data);
3577 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3578
3579 // In order for a new QUIC session to be established via alternate-protocol
3580 // without racing an HTTP connection, we need the host resolution to happen
3581 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3582 // connection to the the server, in this test we require confirmation
3583 // before encrypting so the HTTP job will still start.
3584 host_resolver_.set_synchronous_mode(true);
3585 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3586 "");
rch2f2991c2017-04-13 19:28:173587
3588 CreateSession();
3589 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173590 QuicStreamFactoryPeer::SetAlarmFactory(
3591 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193592 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223593 context_.clock()));
rch2f2991c2017-04-13 19:28:173594
Ryan Hamilton9835e662018-08-02 05:36:273595 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173596
3597 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3598 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263599 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:173600 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3601
3602 // Pump the message loop to get the request started.
3603 base::RunLoop().RunUntilIdle();
3604 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283605 crypto_client_stream_factory_.last_stream()
3606 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:173607
3608 // Run the QUIC session to completion.
3609 quic_task_runner_->RunUntilIdle();
3610 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3611
3612 ExpectQuicAlternateProtocolMapping();
3613
3614 // Let the transaction proceed which will result in QUIC being marked
3615 // as broken and the request falling back to TCP.
3616 EXPECT_THAT(callback.WaitForResult(), IsOk());
3617
3618 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3619 ASSERT_FALSE(http_data.AllReadDataConsumed());
3620
3621 // Read the response body over TCP.
3622 CheckResponseData(&trans, "hello world");
3623 ExpectBrokenAlternateProtocolMapping();
3624 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3625 ASSERT_TRUE(http_data.AllReadDataConsumed());
3626}
3627
rch2f2991c2017-04-13 19:28:173628// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3629// protocol error occurs after the handshake is confirmed, the request
3630// retried over TCP and the QUIC will be marked as broken.
3631TEST_P(QuicNetworkTransactionTest,
3632 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:353633 if (version_.AlpnDeferToRFCv1()) {
3634 // These versions currently do not support Alt-Svc.
3635 return;
3636 }
Peter Kastinge5a38ed2021-10-02 03:06:353637 context_.params()->idle_connection_timeout = base::Seconds(5);
rch2f2991c2017-04-13 19:28:173638
3639 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593640 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:163641 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493642 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253643 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493644 quic_data.AddWrite(SYNCHRONOUS,
3645 ConstructInitialSettingsPacket(packet_num++));
3646 }
3647 quic_data.AddWrite(
3648 SYNCHRONOUS,
3649 ConstructClientRequestHeadersPacket(
3650 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3651 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163652 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553653 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3654
rch2f2991c2017-04-13 19:28:173655 // Peer sending data from an non-existing stream causes this end to raise
3656 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333657 quic_data.AddRead(
3658 ASYNC, ConstructServerRstPacket(
3659 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3660 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173661 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:343662 quic_data.AddWrite(
3663 SYNCHRONOUS,
3664 ConstructClientAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:343665 packet_num++, 1, 1,
Renjie Tang248e36ea2020-06-26 00:12:343666 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
3667 : quic::QUIC_INVALID_STREAM_ID,
Renjie Tanga35322a2020-12-02 20:12:273668 quic_error_details,
3669 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
3670 : quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173671 quic_data.AddSocketDataToFactory(&socket_factory_);
3672
3673 // After that fails, it will be resent via TCP.
3674 MockWrite http_writes[] = {
3675 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3676 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3677 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3678
Ryan Hamiltona2dcbae2022-02-09 19:02:453679 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3680 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3681 MockRead(SYNCHRONOUS, 5, "hello world"),
3682 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013683 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173684 socket_factory_.AddSocketDataProvider(&http_data);
3685 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3686
3687 // In order for a new QUIC session to be established via alternate-protocol
3688 // without racing an HTTP connection, we need the host resolution to happen
3689 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3690 // connection to the the server, in this test we require confirmation
3691 // before encrypting so the HTTP job will still start.
3692 host_resolver_.set_synchronous_mode(true);
3693 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3694 "");
rch2f2991c2017-04-13 19:28:173695
3696 CreateSession();
3697
Ryan Hamilton9835e662018-08-02 05:36:273698 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173699
3700 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3701 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263702 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:173703 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3704
3705 // Pump the message loop to get the request started.
3706 base::RunLoop().RunUntilIdle();
3707 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283708 crypto_client_stream_factory_.last_stream()
3709 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553710 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173711
3712 // Run the QUIC session to completion.
3713 base::RunLoop().RunUntilIdle();
3714 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3715
3716 ExpectQuicAlternateProtocolMapping();
3717
3718 // Let the transaction proceed which will result in QUIC being marked
3719 // as broken and the request falling back to TCP.
3720 EXPECT_THAT(callback.WaitForResult(), IsOk());
3721
3722 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3723 ASSERT_FALSE(http_data.AllReadDataConsumed());
3724
3725 // Read the response body over TCP.
3726 CheckResponseData(&trans, "hello world");
3727 ExpectBrokenAlternateProtocolMapping();
3728 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3729 ASSERT_TRUE(http_data.AllReadDataConsumed());
3730}
3731
Matt Menkeb32ba5122019-09-10 19:17:053732// Much like above test, but verifies that NetworkIsolationKey is respected.
3733TEST_P(QuicNetworkTransactionTest,
3734 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:353735 if (version_.AlpnDeferToRFCv1()) {
3736 // These versions currently do not support Alt-Svc.
3737 return;
3738 }
Matt Menke4807a9a2020-11-21 00:14:413739 const SchemefulSite kSite1(GURL("https://foo.test/"));
3740 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
3741 const SchemefulSite kSite2(GURL("https://bar.test/"));
3742 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:053743
3744 base::test::ScopedFeatureList feature_list;
3745 feature_list.InitWithFeatures(
3746 // enabled_features
3747 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3748 features::kPartitionConnectionsByNetworkIsolationKey},
3749 // disabled_features
3750 {});
3751 // Since HttpServerProperties caches the feature value, have to create a new
3752 // one.
3753 http_server_properties_ = std::make_unique<HttpServerProperties>();
3754
Peter Kastinge5a38ed2021-10-02 03:06:353755 context_.params()->idle_connection_timeout = base::Seconds(5);
Matt Menkeb32ba5122019-09-10 19:17:053756
3757 // The request will initially go out over QUIC.
3758 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:563759 uint64_t packet_number = 1;
Zhongyi Shi1c022d22020-03-20 19:00:163760 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:253761 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:563762 quic_data.AddWrite(SYNCHRONOUS,
3763 ConstructInitialSettingsPacket(packet_number++));
3764 }
3765 quic_data.AddWrite(
3766 SYNCHRONOUS,
3767 ConstructClientRequestHeadersPacket(
3768 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3769 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163770 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:053771 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3772
3773 // Peer sending data from an non-existing stream causes this end to raise
3774 // error and close connection.
3775 quic_data.AddRead(
3776 ASYNC, ConstructServerRstPacket(
3777 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3778 quic::QUIC_STREAM_LAST_ERROR));
3779 std::string quic_error_details = "Data for nonexistent stream";
Nick Harper1ccb0ce2020-10-07 00:28:583780 quic::QuicErrorCode quic_error_code = quic::QUIC_INVALID_STREAM_ID;
3781 if (version_.HasIetfQuicFrames()) {
3782 quic_error_code = quic::QUIC_HTTP_STREAM_WRONG_DIRECTION;
3783 }
Renjie Tanga35322a2020-12-02 20:12:273784 quic_data.AddWrite(
3785 SYNCHRONOUS,
3786 ConstructClientAckAndConnectionClosePacket(
3787 packet_number++, 1, 1, quic_error_code, quic_error_details,
3788 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
3789 : quic::IETF_RST_STREAM));
Matt Menkeb32ba5122019-09-10 19:17:053790 quic_data.AddSocketDataToFactory(&socket_factory_);
3791
3792 // After that fails, it will be resent via TCP.
3793 MockWrite http_writes[] = {
3794 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3795 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3796 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3797
Ryan Hamiltona2dcbae2022-02-09 19:02:453798 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3799 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3800 MockRead(SYNCHRONOUS, 5, "hello world"),
3801 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:053802 SequencedSocketData http_data(http_reads, http_writes);
3803 socket_factory_.AddSocketDataProvider(&http_data);
3804 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3805
3806 // In order for a new QUIC session to be established via alternate-protocol
3807 // without racing an HTTP connection, we need the host resolution to happen
3808 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3809 // connection to the the server, in this test we require confirmation
3810 // before encrypting so the HTTP job will still start.
3811 host_resolver_.set_synchronous_mode(true);
3812 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3813 "");
3814
3815 CreateSession();
3816
3817 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3818 kNetworkIsolationKey1);
3819 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3820 kNetworkIsolationKey2);
3821
3822 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3823 TestCompletionCallback callback;
3824 request_.network_isolation_key = kNetworkIsolationKey1;
Matt Reichhoff0049a0b72021-10-20 20:44:263825 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeb32ba5122019-09-10 19:17:053826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3827
3828 // Pump the message loop to get the request started.
3829 base::RunLoop().RunUntilIdle();
3830 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283831 crypto_client_stream_factory_.last_stream()
3832 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:053833 quic_data.Resume();
3834
3835 // Run the QUIC session to completion.
3836 base::RunLoop().RunUntilIdle();
3837 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3838
3839 // Let the transaction proceed which will result in QUIC being marked
3840 // as broken and the request falling back to TCP.
3841 EXPECT_THAT(callback.WaitForResult(), IsOk());
3842 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3843 ASSERT_FALSE(http_data.AllReadDataConsumed());
3844
3845 // Read the response body over TCP.
3846 CheckResponseData(&trans, "hello world");
3847 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3848 ASSERT_TRUE(http_data.AllReadDataConsumed());
3849
3850 // The alternative service shouldhave been marked as broken under
3851 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3852 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3853 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3854
3855 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3856 AddHttpDataAndRunRequest();
3857 // Requests using other NetworkIsolationKeys can still use QUIC.
3858 request_.network_isolation_key = kNetworkIsolationKey2;
3859 AddQuicDataAndRunRequest();
3860
3861 // The last two requests should not have changed the alternative service
3862 // mappings.
3863 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3864 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3865}
3866
rch30943ee2017-06-12 21:28:443867// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3868// request is reset from, then QUIC will be marked as broken and the request
3869// retried over TCP.
3870TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:353871 if (version_.AlpnDeferToRFCv1()) {
3872 // These versions currently do not support Alt-Svc.
3873 return;
3874 }
rch30943ee2017-06-12 21:28:443875 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593876 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133877 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443878 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3879
Zhongyi Shi1c022d22020-03-20 19:00:163880 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493881 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253882 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493883 quic_data.AddWrite(SYNCHRONOUS,
3884 ConstructInitialSettingsPacket(packet_num++));
3885 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023886 quic_data.AddWrite(
3887 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163888 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493889 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3890 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453891
Zhongyi Shi1c022d22020-03-20 19:00:163892 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553893 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443894
Fan Yang32c5a112018-12-10 20:06:333895 quic_data.AddRead(ASYNC,
3896 ConstructServerRstPacket(
3897 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3898 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443899
Bence Béky6e243aa2019-12-13 19:01:073900 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang248e36ea2020-06-26 00:12:343901 quic_data.AddWrite(
Renjie Tanga35322a2020-12-02 20:12:273902 SYNCHRONOUS,
Fan Yang8d4177792021-07-16 17:48:533903 client_maker_->MakeAckRstAndDataPacket(
Renjie Tanga35322a2020-12-02 20:12:273904 packet_num++, true, GetNthClientInitiatedBidirectionalStreamId(0),
3905 quic::QUIC_HEADERS_TOO_LARGE, 1, 1, GetQpackDecoderStreamId(),
3906 false, StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:073907 }
3908
rch30943ee2017-06-12 21:28:443909 quic_data.AddRead(ASYNC, OK);
3910 quic_data.AddSocketDataToFactory(&socket_factory_);
3911
3912 // After that fails, it will be resent via TCP.
3913 MockWrite http_writes[] = {
3914 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3915 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3916 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3917
Ryan Hamiltona2dcbae2022-02-09 19:02:453918 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3919 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3920 MockRead(SYNCHRONOUS, 5, "hello world"),
3921 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013922 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443923 socket_factory_.AddSocketDataProvider(&http_data);
3924 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3925
3926 // In order for a new QUIC session to be established via alternate-protocol
3927 // without racing an HTTP connection, we need the host resolution to happen
3928 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3929 // connection to the the server, in this test we require confirmation
3930 // before encrypting so the HTTP job will still start.
3931 host_resolver_.set_synchronous_mode(true);
3932 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3933 "");
rch30943ee2017-06-12 21:28:443934
3935 CreateSession();
3936
Ryan Hamilton9835e662018-08-02 05:36:273937 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443938
3939 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3940 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263941 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch30943ee2017-06-12 21:28:443942 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3943
3944 // Pump the message loop to get the request started.
3945 base::RunLoop().RunUntilIdle();
3946 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283947 crypto_client_stream_factory_.last_stream()
3948 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553949 quic_data.Resume();
rch30943ee2017-06-12 21:28:443950
3951 // Run the QUIC session to completion.
3952 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3953
3954 ExpectQuicAlternateProtocolMapping();
3955
3956 // Let the transaction proceed which will result in QUIC being marked
3957 // as broken and the request falling back to TCP.
3958 EXPECT_THAT(callback.WaitForResult(), IsOk());
3959
3960 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3961 ASSERT_FALSE(http_data.AllReadDataConsumed());
3962
3963 // Read the response body over TCP.
3964 CheckResponseData(&trans, "hello world");
3965 ExpectBrokenAlternateProtocolMapping();
3966 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3967 ASSERT_TRUE(http_data.AllReadDataConsumed());
3968}
3969
Ryan Hamilton6c2a2a82017-12-15 02:06:283970// Verify that when an origin has two alt-svc advertisements, one local and one
3971// remote, that when the local is broken the request will go over QUIC via
3972// the remote Alt-Svc.
3973// This is a regression test for crbug/825646.
3974TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:383975 context_.params()->allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:283976
3977 GURL origin1 = request_.url; // mail.example.org
3978 GURL origin2("https://www.example.org/");
3979 ASSERT_NE(origin1.host(), origin2.host());
3980
3981 scoped_refptr<X509Certificate> cert(
3982 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243983 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3984 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283985
3986 ProofVerifyDetailsChromium verify_details;
3987 verify_details.cert_verify_result.verified_cert = cert;
3988 verify_details.cert_verify_result.is_issued_by_known_root = true;
3989 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3990
Ryan Hamiltonabad59e2019-06-06 04:02:593991 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233992 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253993 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233994 mock_quic_data.AddWrite(SYNCHRONOUS,
3995 ConstructInitialSettingsPacket(packet_num++));
3996 }
Ryan Hamilton6c2a2a82017-12-15 02:06:283997 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233998 SYNCHRONOUS,
3999 ConstructClientRequestHeadersPacket(
4000 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4001 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434002 mock_quic_data.AddRead(
4003 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334004 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284005 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434006 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334007 ASYNC, ConstructServerDataPacket(
4008 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524009 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234010 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344011 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284012 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214013 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamilton6c2a2a82017-12-15 02:06:284014
4015 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:594016 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:284017 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4018 AddHangingNonAlternateProtocolSocketData();
4019
4020 CreateSession();
4021
4022 // Set up alternative service for |origin1|.
4023 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4024 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
Peter Kastinge5a38ed2021-10-02 03:06:354025 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamilton6c2a2a82017-12-15 02:06:284026 AlternativeServiceInfoVector alternative_services;
4027 alternative_services.push_back(
4028 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4029 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384030 context_.params()->supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:284031 alternative_services.push_back(
4032 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4033 remote_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384034 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494035 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4036 NetworkIsolationKey(),
4037 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:284038
Matt Menkeb32ba5122019-09-10 19:17:054039 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4040 NetworkIsolationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:284041
4042 SendRequestAndExpectQuicResponse("hello!");
4043}
4044
Ryan Hamilton899c2e082019-11-14 01:22:024045// Verify that when multiple alternatives are broken,
4046// ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
4047// This is a regression test for crbug/1024613.
4048TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
Ryan Hamiltona51800a2022-02-12 19:34:354049 if (version_.AlpnDeferToRFCv1()) {
4050 // These versions currently do not support Alt-Svc.
4051 return;
4052 }
Ryan Hamilton899c2e082019-11-14 01:22:024053 base::HistogramTester histogram_tester;
4054
4055 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454056 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Ryan Hamilton899c2e082019-11-14 01:22:024057 MockRead("hello world"),
4058 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4059 MockRead(ASYNC, OK)};
4060
4061 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4062 socket_factory_.AddSocketDataProvider(&http_data);
4063 AddCertificate(&ssl_data_);
4064 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4065
4066 GURL origin1 = request_.url; // mail.example.org
4067
4068 scoped_refptr<X509Certificate> cert(
4069 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
4070 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
4071
4072 ProofVerifyDetailsChromium verify_details;
4073 verify_details.cert_verify_result.verified_cert = cert;
4074 verify_details.cert_verify_result.is_issued_by_known_root = true;
4075 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4076
4077 CreateSession();
4078
4079 // Set up alternative service for |origin1|.
4080 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
Peter Kastinge5a38ed2021-10-02 03:06:354081 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamilton899c2e082019-11-14 01:22:024082 AlternativeServiceInfoVector alternative_services;
4083 alternative_services.push_back(
4084 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4085 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384086 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024087 alternative_services.push_back(
4088 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4089 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384090 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024091 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4092 NetworkIsolationKey(),
4093 alternative_services);
4094
4095 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4096 NetworkIsolationKey());
4097
4098 SendRequestAndExpectHttpResponse("hello world");
4099
4100 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
4101 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
4102}
4103
rch30943ee2017-06-12 21:28:444104// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4105// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:054106// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:444107// connection instead of going back to the broken QUIC connection.
4108// This is a regression tests for crbug/731303.
4109TEST_P(QuicNetworkTransactionTest,
4110 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:354111 if (version_.AlpnDeferToRFCv1()) {
4112 // These versions currently do not support Alt-Svc.
4113 return;
4114 }
Victor Vasilieva1e66d72019-12-05 17:55:384115 context_.params()->allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444116
4117 GURL origin1 = request_.url;
4118 GURL origin2("https://www.example.org/");
4119 ASSERT_NE(origin1.host(), origin2.host());
4120
Ryan Hamiltonabad59e2019-06-06 04:02:594121 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:444122
4123 scoped_refptr<X509Certificate> cert(
4124 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244125 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4126 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444127
4128 ProofVerifyDetailsChromium verify_details;
4129 verify_details.cert_verify_result.verified_cert = cert;
4130 verify_details.cert_verify_result.is_issued_by_known_root = true;
4131 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4132
Renjie Tangaadb84b2019-08-31 01:00:234133 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254134 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234135 mock_quic_data.AddWrite(SYNCHRONOUS,
4136 ConstructInitialSettingsPacket(packet_num++));
4137 }
rch30943ee2017-06-12 21:28:444138 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434139 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234140 SYNCHRONOUS,
4141 ConstructClientRequestHeadersPacket(
4142 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4143 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434144 mock_quic_data.AddRead(
4145 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334146 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284147 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434148 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334149 ASYNC, ConstructServerDataPacket(
4150 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524151 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234152 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344153 ConstructClientAckPacket(packet_num++, 2, 1));
rch30943ee2017-06-12 21:28:444154
4155 // Second request will go over the pooled QUIC connection, but will be
4156 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054157 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224158 version_,
4159 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4160 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054161 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174162 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224163 version_,
4164 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4165 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434166 mock_quic_data.AddWrite(
4167 SYNCHRONOUS,
4168 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234169 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4170 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024171 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334172 mock_quic_data.AddRead(
4173 ASYNC, ConstructServerRstPacket(
4174 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4175 quic::QUIC_HEADERS_TOO_LARGE));
Bence Béky6e243aa2019-12-13 19:01:074176
4177 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangcd594f32020-07-11 20:18:344178 mock_quic_data.AddWrite(
4179 SYNCHRONOUS,
Fan Yang8d4177792021-07-16 17:48:534180 client_maker_->MakeAckRstAndDataPacket(
Renjie Tanga35322a2020-12-02 20:12:274181 packet_num++, /*include_version=*/true,
4182 GetNthClientInitiatedBidirectionalStreamId(1),
4183 quic::QUIC_HEADERS_TOO_LARGE, 3, 2, GetQpackDecoderStreamId(),
Renjie Tangcd594f32020-07-11 20:18:344184 /*fin=*/false, StreamCancellationQpackDecoderInstruction(1)));
Bence Béky6e243aa2019-12-13 19:01:074185 }
4186
rch30943ee2017-06-12 21:28:444187 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214188 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rch30943ee2017-06-12 21:28:444189
4190 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4191
4192 // After that fails, it will be resent via TCP.
4193 MockWrite http_writes[] = {
4194 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4195 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4196 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4197
Ryan Hamiltona2dcbae2022-02-09 19:02:454198 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4199 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
4200 MockRead(SYNCHRONOUS, 5, "hello world"),
4201 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014202 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444203 socket_factory_.AddSocketDataProvider(&http_data);
4204 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4205
Ryan Hamilton6c2a2a82017-12-15 02:06:284206 // Then the next request to the second origin will be sent over TCP.
4207 socket_factory_.AddSocketDataProvider(&http_data);
4208 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444209
4210 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564211 QuicStreamFactoryPeer::SetAlarmFactory(
4212 session_->quic_stream_factory(),
4213 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224214 context_.clock()));
rch30943ee2017-06-12 21:28:444215
4216 // Set up alternative service for |origin1|.
Peter Kastinge5a38ed2021-10-02 03:06:354217 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244218 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494219 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074220 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4221 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:444222
4223 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244224 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494225 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074226 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4227 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344228
rch30943ee2017-06-12 21:28:444229 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524230 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444231 SendRequestAndExpectQuicResponse("hello!");
4232
4233 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524234 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:054235 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:444236 request_.url = origin2;
4237 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:054238 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
4239 alternative1, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244240 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:054241 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
4242 alternative2, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244243 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444244
Matt Menkeb32ba5122019-09-10 19:17:054245 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:444246 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284247 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444248}
4249
bnc8be55ebb2015-10-30 14:12:074250TEST_P(QuicNetworkTransactionTest,
4251 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Ryan Hamiltona51800a2022-02-12 19:34:354252 if (version_.AlpnDeferToRFCv1()) {
4253 // These versions currently do not support Alt-Svc.
4254 return;
4255 }
Nick Harper23290b82019-05-02 00:02:564256 std::string altsvc_header =
4257 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4258 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074259 MockRead http_reads[] = {
4260 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4261 MockRead("hello world"),
4262 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4263 MockRead(ASYNC, OK)};
4264
Ryan Sleevib8d7ea02018-05-07 20:01:014265 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074266 socket_factory_.AddSocketDataProvider(&http_data);
4267 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4268 socket_factory_.AddSocketDataProvider(&http_data);
4269 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4270
rch3f4b8452016-02-23 16:59:324271 CreateSession();
bnc8be55ebb2015-10-30 14:12:074272
4273 SendRequestAndExpectHttpResponse("hello world");
4274 SendRequestAndExpectHttpResponse("hello world");
4275}
4276
Xida Chen9bfe0b62018-04-24 19:52:214277// When multiple alternative services are advertised, HttpStreamFactory should
4278// select the alternative service which uses existing QUIC session if available.
4279// If no existing QUIC session can be used, use the first alternative service
4280// from the list.
zhongyi32569c62016-01-08 02:54:304281TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:354282 if (version_.AlpnDeferToRFCv1()) {
4283 // These versions currently do not support Alt-Svc.
4284 return;
4285 }
Victor Vasilieva1e66d72019-12-05 17:55:384286 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltona2dcbae2022-02-09 19:02:454287 std::string alt_svc_header = base::StrCat(
4288 {"Alt-Svc: ",
4289 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.org", 443), ",",
4290 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
bncc958faa2015-07-31 18:14:524291 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454292 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
bncc958faa2015-07-31 18:14:524293 MockRead("hello world"),
4294 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4295 MockRead(ASYNC, OK)};
4296
Ryan Sleevib8d7ea02018-05-07 20:01:014297 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524298 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084299 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564300 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524301
zhongyi32569c62016-01-08 02:54:304302 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294303 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304304 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594305 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234306 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254307 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234308 mock_quic_data.AddWrite(SYNCHRONOUS,
4309 ConstructInitialSettingsPacket(packet_num++));
4310 }
rch5cb522462017-04-25 20:18:364311 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234312 SYNCHRONOUS,
4313 ConstructClientRequestHeadersPacket(
4314 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4315 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304316
Ryan Hamiltona2dcbae2022-02-09 19:02:454317 std::string alt_svc_list = base::StrCat(
4318 {GenerateQuicAltSvcHeaderValue({version_}, "mail.example.org", 444), ",",
4319 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.org", 443), ",",
4320 GenerateQuicAltSvcHeaderValue({version_}, "bar.example.org", 445)});
Zhongyi Shi32f2fd02018-04-16 18:23:434321 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024322 ASYNC, ConstructServerResponseHeadersPacket(
4323 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284324 GetResponseHeaders("200", alt_svc_list)));
Zhongyi Shi32f2fd02018-04-16 18:23:434325 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334326 ASYNC, ConstructServerDataPacket(
4327 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524328 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234329 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344330 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:304331
4332 // Second QUIC request data.
4333 // Connection pooling, using existing session, no need to include version
4334 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584335 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234336 SYNCHRONOUS,
4337 ConstructClientRequestHeadersPacket(
4338 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4339 true, GetRequestHeaders("GET", "https", "/"),
4340 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434341 mock_quic_data.AddRead(
4342 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334343 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284344 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434345 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334346 ASYNC, ConstructServerDataPacket(
4347 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524348 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474349 mock_quic_data.AddWrite(SYNCHRONOUS,
4350 ConstructClientAckPacket(packet_num++, 4, 3));
bncc958faa2015-07-31 18:14:524351 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214352 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:524353
4354 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4355
rtennetib8e80fb2016-05-16 00:12:094356 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324357 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564358 QuicStreamFactoryPeer::SetAlarmFactory(
4359 session_->quic_stream_factory(),
4360 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224361 context_.clock()));
bncc958faa2015-07-31 18:14:524362
4363 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304364
bnc359ed2a2016-04-29 20:43:454365 SendRequestAndExpectQuicResponse("hello!");
4366 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304367}
4368
Ryan Hamilton8d9ee76e2018-05-29 23:52:524369// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454370// even if alternative service destination is different.
4371TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Victor Vasilieva1e66d72019-12-05 17:55:384372 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594373 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454374
Renjie Tangaadb84b2019-08-31 01:00:234375 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254376 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234377 mock_quic_data.AddWrite(SYNCHRONOUS,
4378 ConstructInitialSettingsPacket(packet_num++));
4379 }
bnc359ed2a2016-04-29 20:43:454380 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434381 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234382 SYNCHRONOUS,
4383 ConstructClientRequestHeadersPacket(
4384 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4385 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434386 mock_quic_data.AddRead(
4387 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334388 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284389 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434390 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334391 ASYNC, ConstructServerDataPacket(
4392 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524393 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234394 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344395 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:304396
bnc359ed2a2016-04-29 20:43:454397 // Second request.
alyssar2adf3ac2016-05-03 17:12:584398 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234399 SYNCHRONOUS,
4400 ConstructClientRequestHeadersPacket(
4401 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4402 true, GetRequestHeaders("GET", "https", "/"),
4403 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434404 mock_quic_data.AddRead(
4405 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334406 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284407 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434408 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334409 ASYNC, ConstructServerDataPacket(
4410 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524411 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474412 mock_quic_data.AddWrite(SYNCHRONOUS,
4413 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:304414 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214415 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi32569c62016-01-08 02:54:304416
4417 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454418
4419 AddHangingNonAlternateProtocolSocketData();
4420 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304421
rch3f4b8452016-02-23 16:59:324422 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564423 QuicStreamFactoryPeer::SetAlarmFactory(
4424 session_->quic_stream_factory(),
4425 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224426 context_.clock()));
zhongyi32569c62016-01-08 02:54:304427
bnc359ed2a2016-04-29 20:43:454428 const char destination1[] = "first.example.com";
4429 const char destination2[] = "second.example.com";
4430
4431 // Set up alternative service entry to destination1.
4432 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214433 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
Peter Kastinge5a38ed2021-10-02 03:06:354434 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:494435 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074436 server, NetworkIsolationKey(), alternative_service, expiration,
4437 supported_versions_);
bnc359ed2a2016-04-29 20:43:454438 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524439 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454440 SendRequestAndExpectQuicResponse("hello!");
4441
4442 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214443 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494444 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074445 server, NetworkIsolationKey(), alternative_service, expiration,
4446 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524447 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454448 // even though alternative service destination is different.
4449 SendRequestAndExpectQuicResponse("hello!");
4450}
4451
4452// Pool to existing session with matching destination and matching certificate
4453// even if origin is different, and even if the alternative service with
4454// matching destination is not the first one on the list.
4455TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Victor Vasilieva1e66d72019-12-05 17:55:384456 context_.params()->allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454457 GURL origin1 = request_.url;
4458 GURL origin2("https://www.example.org/");
4459 ASSERT_NE(origin1.host(), origin2.host());
4460
Ryan Hamiltonabad59e2019-06-06 04:02:594461 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454462
Renjie Tangaadb84b2019-08-31 01:00:234463 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254464 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234465 mock_quic_data.AddWrite(SYNCHRONOUS,
4466 ConstructInitialSettingsPacket(packet_num++));
4467 }
bnc359ed2a2016-04-29 20:43:454468 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434469 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234470 SYNCHRONOUS,
4471 ConstructClientRequestHeadersPacket(
4472 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4473 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434474 mock_quic_data.AddRead(
4475 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334476 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284477 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434478 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334479 ASYNC, ConstructServerDataPacket(
4480 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524481 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234482 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344483 ConstructClientAckPacket(packet_num++, 2, 1));
bnc359ed2a2016-04-29 20:43:454484
4485 // Second request.
Yixin Wang079ad542018-01-11 04:06:054486 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224487 version_,
4488 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4489 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054490 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174491 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224492 version_,
4493 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4494 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584495 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434496 SYNCHRONOUS,
4497 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234498 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4499 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024500 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434501 mock_quic_data.AddRead(
4502 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334503 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284504 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434505 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334506 ASYNC, ConstructServerDataPacket(
4507 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524508 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474509 mock_quic_data.AddWrite(SYNCHRONOUS,
4510 ConstructClientAckPacket(packet_num++, 4, 3));
bnc359ed2a2016-04-29 20:43:454511 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214512 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:454513
4514 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4515
4516 AddHangingNonAlternateProtocolSocketData();
4517 AddHangingNonAlternateProtocolSocketData();
4518
4519 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564520 QuicStreamFactoryPeer::SetAlarmFactory(
4521 session_->quic_stream_factory(),
4522 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224523 context_.clock()));
bnc359ed2a2016-04-29 20:43:454524
4525 const char destination1[] = "first.example.com";
4526 const char destination2[] = "second.example.com";
4527
4528 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214529 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
Peter Kastinge5a38ed2021-10-02 03:06:354530 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:494531 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074532 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4533 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454534
4535 // Set up multiple alternative service entries for |origin2|,
4536 // the first one with a different destination as for |origin1|,
4537 // the second one with the same. The second one should be used,
4538 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214539 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454540 AlternativeServiceInfoVector alternative_services;
4541 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214542 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4543 alternative_service2, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384544 context_.params()->supported_versions));
bnc359ed2a2016-04-29 20:43:454545 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214546 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4547 alternative_service1, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384548 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494549 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4550 NetworkIsolationKey(),
4551 alternative_services);
bnc359ed2a2016-04-29 20:43:454552 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524553 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454554 SendRequestAndExpectQuicResponse("hello!");
4555
4556 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524557 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454558 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584559
bnc359ed2a2016-04-29 20:43:454560 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304561}
4562
4563// Multiple origins have listed the same alternative services. When there's a
4564// existing QUIC session opened by a request to other origin,
4565// if the cert is valid, should select this QUIC session to make the request
4566// if this is also the first existing QUIC session.
4567TEST_P(QuicNetworkTransactionTest,
4568 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltona51800a2022-02-12 19:34:354569 if (version_.AlpnDeferToRFCv1()) {
4570 // These versions currently do not support Alt-Svc.
4571 return;
4572 }
Victor Vasilieva1e66d72019-12-05 17:55:384573 context_.params()->allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294574 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304575
rch9ae5b3b2016-02-11 00:36:294576 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304577 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454578 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rch9ae5b3b2016-02-11 00:36:294579 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304580 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4581 MockRead(ASYNC, OK)};
4582
Ryan Sleevib8d7ea02018-05-07 20:01:014583 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304584 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084585 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304586 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4587
4588 // HTTP data for request to mail.example.org.
Ryan Hamiltona2dcbae2022-02-09 19:02:454589 std::string alt_svc_header2 = base::StrCat(
4590 {"Alt-Svc: ", GenerateQuicAltSvcHeaderValue({version_}, 444), ",",
4591 GenerateQuicAltSvcHeaderValue({version_}, "www.example.org", 443),
4592 "\r\n\r\n"});
zhongyi32569c62016-01-08 02:54:304593 MockRead http_reads2[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454594 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header2.data()),
zhongyi32569c62016-01-08 02:54:304595 MockRead("hello world from mail.example.org"),
4596 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4597 MockRead(ASYNC, OK)};
4598
Ryan Sleevib8d7ea02018-05-07 20:01:014599 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304600 socket_factory_.AddSocketDataProvider(&http_data2);
4601 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4602
Yixin Wang079ad542018-01-11 04:06:054603 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:224604 version_,
4605 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4606 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054607 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584608 server_maker_.set_hostname("www.example.org");
Zhongyi Shi1c022d22020-03-20 19:00:164609 client_maker_->set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594610 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234611 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254612 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234613 mock_quic_data.AddWrite(SYNCHRONOUS,
4614 ConstructInitialSettingsPacket(packet_num++));
4615 }
zhongyi32569c62016-01-08 02:54:304616 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584617 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234618 SYNCHRONOUS,
4619 ConstructClientRequestHeadersPacket(
4620 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4621 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434622
4623 mock_quic_data.AddRead(
4624 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334625 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284626 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334627 mock_quic_data.AddRead(
4628 ASYNC, ConstructServerDataPacket(
4629 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524630 ConstructDataFrame("hello from mail QUIC!")));
Renjie Tangaadb84b2019-08-31 01:00:234631 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344632 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434633 // Second QUIC request data.
4634 mock_quic_data.AddWrite(
4635 SYNCHRONOUS,
4636 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234637 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4638 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024639 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434640 mock_quic_data.AddRead(
4641 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334642 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284643 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334644 mock_quic_data.AddRead(
4645 ASYNC, ConstructServerDataPacket(
4646 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524647 ConstructDataFrame("hello from mail QUIC!")));
Renjie Tangb7afea82020-07-15 23:35:474648 mock_quic_data.AddWrite(SYNCHRONOUS,
4649 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:304650 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214651 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi32569c62016-01-08 02:54:304652
4653 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304654
rtennetib8e80fb2016-05-16 00:12:094655 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324656 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564657 QuicStreamFactoryPeer::SetAlarmFactory(
4658 session_->quic_stream_factory(),
4659 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224660 context_.clock()));
zhongyi32569c62016-01-08 02:54:304661
4662 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294663 request_.url = GURL("https://www.example.org/");
4664 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304665 request_.url = GURL("https://mail.example.org/");
4666 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4667
rch9ae5b3b2016-02-11 00:36:294668 // Open a QUIC session to mail.example.org:443 when making request
4669 // to mail.example.org.
4670 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454671 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304672
rch9ae5b3b2016-02-11 00:36:294673 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304674 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454675 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524676}
4677
4678TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
Ryan Hamiltona51800a2022-02-12 19:34:354679 if (version_.AlpnDeferToRFCv1()) {
4680 // These versions currently do not support Alt-Svc.
4681 return;
4682 }
Ryan Hamiltona2dcbae2022-02-09 19:02:454683 std::string alt_svc_header =
4684 base::StrCat({"Alt-Svc: ", GenerateQuicAltSvcHeaderValue({version_}, 137),
4685 "\r\n\r\n"});
bncc958faa2015-07-31 18:14:524686 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454687 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
bncc958faa2015-07-31 18:14:524688 MockRead("hello world"),
4689 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4690 MockRead(ASYNC, OK)};
4691
Ryan Sleevib8d7ea02018-05-07 20:01:014692 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524693 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084694 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564695 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524696
rtennetib8e80fb2016-05-16 00:12:094697 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324698 CreateSession();
bncc958faa2015-07-31 18:14:524699
4700 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454701
4702 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344703 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494704 http_server_properties_->GetAlternativeServiceInfos(
4705 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344706 ASSERT_EQ(1u, alternative_service_info_vector.size());
4707 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544708 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344709 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4710 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4711 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524712}
4713
4714TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
Ryan Hamiltona51800a2022-02-12 19:34:354715 if (version_.AlpnDeferToRFCv1()) {
4716 // These versions currently do not support Alt-Svc.
4717 return;
4718 }
bncc958faa2015-07-31 18:14:524719 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454720 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:564721 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524722 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4723 MockRead(ASYNC, OK)};
4724
Ryan Sleevib8d7ea02018-05-07 20:01:014725 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524726 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084727 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564728 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524729
Ryan Hamiltonabad59e2019-06-06 04:02:594730 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234731 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254732 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234733 mock_quic_data.AddWrite(SYNCHRONOUS,
4734 ConstructInitialSettingsPacket(packet_num++));
4735 }
rch5cb522462017-04-25 20:18:364736 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234737 SYNCHRONOUS,
4738 ConstructClientRequestHeadersPacket(
4739 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4740 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434741 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334742 ASYNC, ConstructServerResponseHeadersPacket(
4743 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284744 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334745 mock_quic_data.AddRead(
4746 ASYNC, ConstructServerDataPacket(
4747 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524748 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234749 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344750 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:524751 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214752 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:524753
4754 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4755
rtennetib8e80fb2016-05-16 00:12:094756 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324757 CreateSession();
bncc958faa2015-07-31 18:14:524758
bnc3472afd2016-11-17 15:27:214759 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524760 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494761 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054762 alternative_service, NetworkIsolationKey());
Matt Menke3233d8f22019-08-20 21:01:494763 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054764 alternative_service, NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524765
4766 SendRequestAndExpectHttpResponse("hello world");
4767 SendRequestAndExpectQuicResponse("hello!");
4768
mmenkee24011922015-12-17 22:12:594769 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524770
Matt Menke3233d8f22019-08-20 21:01:494771 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054772 alternative_service, NetworkIsolationKey()));
Matt Menke19475f72019-08-21 18:57:444773 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4774 url::SchemeHostPort("https", request_.url.host(), 443),
4775 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524776}
4777
Matt Menkeb32ba5122019-09-10 19:17:054778TEST_P(QuicNetworkTransactionTest,
4779 ConfirmAlternativeServiceWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:354780 if (version_.AlpnDeferToRFCv1()) {
4781 // These versions currently do not support Alt-Svc.
4782 return;
4783 }
Matt Menke4807a9a2020-11-21 00:14:414784 const SchemefulSite kSite1(GURL("https://foo.test/"));
4785 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
4786 const SchemefulSite kSite2(GURL("https://bar.test/"));
4787 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:054788
4789 base::test::ScopedFeatureList feature_list;
4790 feature_list.InitWithFeatures(
4791 // enabled_features
4792 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4793 features::kPartitionConnectionsByNetworkIsolationKey},
4794 // disabled_features
4795 {});
4796 // Since HttpServerProperties caches the feature value, have to create a new
4797 // one.
4798 http_server_properties_ = std::make_unique<HttpServerProperties>();
4799
4800 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454801 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Matt Menkeb32ba5122019-09-10 19:17:054802 MockRead("hello world"),
4803 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4804 MockRead(ASYNC, OK)};
4805
4806 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4807 socket_factory_.AddSocketDataProvider(&http_data);
4808 AddCertificate(&ssl_data_);
4809 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4810
4811 MockQuicData mock_quic_data(version_);
4812 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254813 if (VersionUsesHttp3(version_.transport_version)) {
Matt Menkeb32ba5122019-09-10 19:17:054814 mock_quic_data.AddWrite(SYNCHRONOUS,
4815 ConstructInitialSettingsPacket(packet_num++));
4816 }
4817 mock_quic_data.AddWrite(
4818 SYNCHRONOUS,
4819 ConstructClientRequestHeadersPacket(
4820 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4821 true, GetRequestHeaders("GET", "https", "/")));
4822 mock_quic_data.AddRead(
4823 ASYNC, ConstructServerResponseHeadersPacket(
4824 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284825 GetResponseHeaders("200")));
Matt Menkeb32ba5122019-09-10 19:17:054826 mock_quic_data.AddRead(
4827 ASYNC, ConstructServerDataPacket(
4828 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524829 ConstructDataFrame("hello!")));
Matt Menkeb32ba5122019-09-10 19:17:054830 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344831 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menkeb32ba5122019-09-10 19:17:054832 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214833 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Matt Menkeb32ba5122019-09-10 19:17:054834
4835 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4836
4837 CreateSession();
4838
4839 AlternativeService alternative_service(kProtoQUIC,
4840 HostPortPair::FromURL(request_.url));
4841 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4842 alternative_service, kNetworkIsolationKey1);
4843 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4844 alternative_service, kNetworkIsolationKey2);
4845 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4846 alternative_service, kNetworkIsolationKey1));
4847 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4848 alternative_service, kNetworkIsolationKey2));
4849
4850 request_.network_isolation_key = kNetworkIsolationKey1;
4851 SendRequestAndExpectHttpResponse("hello world");
4852 SendRequestAndExpectQuicResponse("hello!");
4853
4854 mock_quic_data.Resume();
4855
4856 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4857 alternative_service, kNetworkIsolationKey1));
4858 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4859 url::SchemeHostPort("https", request_.url.host(), 443),
4860 kNetworkIsolationKey1));
4861 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4862 alternative_service, kNetworkIsolationKey2));
4863 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4864 url::SchemeHostPort("https", request_.url.host(), 443),
4865 kNetworkIsolationKey2));
4866}
4867
bncc958faa2015-07-31 18:14:524868TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
Ryan Hamiltona51800a2022-02-12 19:34:354869 if (version_.AlpnDeferToRFCv1()) {
4870 // These versions currently do not support Alt-Svc.
4871 return;
4872 }
bncc958faa2015-07-31 18:14:524873 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454874 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:564875 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524876 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4877 MockRead(ASYNC, OK)};
4878
Ryan Sleevib8d7ea02018-05-07 20:01:014879 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524880 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564881 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524882
Ryan Hamiltonabad59e2019-06-06 04:02:594883 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234884 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254885 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234886 mock_quic_data.AddWrite(SYNCHRONOUS,
4887 ConstructInitialSettingsPacket(packet_num++));
4888 }
rch5cb522462017-04-25 20:18:364889 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234890 SYNCHRONOUS,
4891 ConstructClientRequestHeadersPacket(
4892 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4893 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434894 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334895 ASYNC, ConstructServerResponseHeadersPacket(
4896 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284897 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334898 mock_quic_data.AddRead(
4899 ASYNC, ConstructServerDataPacket(
4900 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524901 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234902 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344903 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:524904 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4905
4906 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4907
4908 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324909 CreateSession();
bncc958faa2015-07-31 18:14:524910
4911 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4912 SendRequestAndExpectHttpResponse("hello world");
4913}
4914
bnc1c196c6e2016-05-28 13:51:484915TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
Ryan Hamiltona51800a2022-02-12 19:34:354916 if (version_.AlpnDeferToRFCv1()) {
4917 // These versions currently do not support Alt-Svc.
4918 return;
4919 }
[email protected]dda75ab2013-06-22 22:43:304920 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274921 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304922
4923 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564924 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294925 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564926 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304927
Ryan Hamiltona2dcbae2022-02-09 19:02:454928 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4929 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
4930 MockRead(SYNCHRONOUS, 5, "hello world"),
4931 MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304932
Ryan Sleevib8d7ea02018-05-07 20:01:014933 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504934 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084935 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504936 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304937
4938 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454939 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304940 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454941 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304942 };
Ryan Sleevib8d7ea02018-05-07 20:01:014943 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504944 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304945
4946 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014947 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504948 socket_factory_.AddSocketDataProvider(&http_data2);
4949 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304950
bnc912a04b2016-04-20 14:19:504951 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304952
4953 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304954 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174955 ASSERT_TRUE(http_data.AllReadDataConsumed());
4956 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304957
4958 // Now run the second request in which the QUIC socket hangs,
4959 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304960 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454961 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304962
rch37de576c2015-05-17 20:28:174963 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4964 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454965 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304966}
4967
[email protected]1e960032013-12-20 19:00:204968TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594969 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164970 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494971 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254972 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:494973 mock_quic_data.AddWrite(SYNCHRONOUS,
4974 ConstructInitialSettingsPacket(packet_num++));
4975 }
Zhongyi Shi32f2fd02018-04-16 18:23:434976 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494977 SYNCHRONOUS,
4978 ConstructClientRequestHeadersPacket(
4979 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4980 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:164981 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4982 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Zhongyi Shi32f2fd02018-04-16 18:23:434983 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334984 ASYNC, ConstructServerResponseHeadersPacket(
4985 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284986 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334987 mock_quic_data.AddRead(
4988 ASYNC, ConstructServerDataPacket(
4989 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524990 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:494991 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344992 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:504993 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214994 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
[email protected]8ba81212013-05-03 13:11:484995
rcha5399e02015-04-21 19:32:044996 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484997
rtennetib8e80fb2016-05-16 00:12:094998 // The non-alternate protocol job needs to hang in order to guarantee that
4999 // the alternate-protocol job will "win".
5000 AddHangingNonAlternateProtocolSocketData();
5001
rch3f4b8452016-02-23 16:59:325002 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275003 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yang1ef6dfef2021-07-24 16:20:165004 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5005 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265006 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Fan Yang1ef6dfef2021-07-24 16:20:165007 IsError(ERR_IO_PENDING));
5008 // Complete host resolution in next message loop so that QUIC job could
5009 // proceed.
5010 base::RunLoop().RunUntilIdle();
5011 // Explicitly confirm the handshake.
5012 crypto_client_stream_factory_.last_stream()
5013 ->NotifySessionOneRttKeyAvailable();
5014
5015 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
5016 mock_quic_data.Resume();
5017
5018 // Run the QUIC session to completion.
5019 base::RunLoop().RunUntilIdle();
5020
5021 EXPECT_THAT(callback.WaitForResult(), IsOk());
5022
5023 CheckWasQuicResponse(&trans);
5024 CheckResponseData(&trans, "hello!");
rchac7f35e2017-03-15 20:42:305025
Matt Menke19475f72019-08-21 18:57:445026 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5027 url::SchemeHostPort("https", request_.url.host(), 443),
5028 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:485029}
5030
[email protected]1e960032013-12-20 19:00:205031TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:595032 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165033 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495034 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255035 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495036 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:165037 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:495038 }
Fan Yang32c5a112018-12-10 20:06:335039 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495040 SYNCHRONOUS,
5041 ConstructClientRequestHeadersPacket(
5042 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5043 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:165044 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5045 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Zhongyi Shi32f2fd02018-04-16 18:23:435046 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335047 ASYNC, ConstructServerResponseHeadersPacket(
5048 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285049 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335050 mock_quic_data.AddRead(
5051 ASYNC, ConstructServerDataPacket(
5052 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525053 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:495054 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345055 ConstructClientAckPacket(packet_number++, 2, 1));
rchb27683c2015-07-29 23:53:505056 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215057 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rcha5399e02015-04-21 19:32:045058 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275059
5060 // In order for a new QUIC session to be established via alternate-protocol
5061 // without racing an HTTP connection, we need the host resolution to happen
5062 // synchronously.
5063 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295064 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565065 "");
[email protected]3a120a6b2013-06-25 01:08:275066
rtennetib8e80fb2016-05-16 00:12:095067 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325068 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275069 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yang1ef6dfef2021-07-24 16:20:165070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5071 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265072 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Fan Yang1ef6dfef2021-07-24 16:20:165073 IsError(ERR_IO_PENDING));
5074 // Complete host resolution in next message loop so that QUIC job could
5075 // proceed.
5076 base::RunLoop().RunUntilIdle();
5077 // Explicitly confirm the handshake.
5078 crypto_client_stream_factory_.last_stream()
5079 ->NotifySessionOneRttKeyAvailable();
5080
5081 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
5082 mock_quic_data.Resume();
5083
5084 // Run the QUIC session to completion.
5085 base::RunLoop().RunUntilIdle();
5086
5087 EXPECT_THAT(callback.WaitForResult(), IsOk());
5088
5089 CheckWasQuicResponse(&trans);
5090 CheckResponseData(&trans, "hello!");
[email protected]3a120a6b2013-06-25 01:08:275091}
5092
[email protected]0fc924b2014-03-31 04:34:155093TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ryan Hamiltona51800a2022-02-12 19:34:355094 if (version_.AlpnDeferToRFCv1()) {
5095 // These versions currently do not support Alt-Svc.
5096 return;
5097 }
Nicolas Arciniegad2013f92020-02-07 23:00:565098 proxy_resolution_service_ =
5099 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
5100 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155101
5102 // Since we are using a proxy, the QUIC job will not succeed.
5103 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295104 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5105 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565106 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155107
Ryan Hamiltona2dcbae2022-02-09 19:02:455108 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
5109 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
5110 MockRead(SYNCHRONOUS, 5, "hello world"),
5111 MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155112
Ryan Sleevib8d7ea02018-05-07 20:01:015113 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155114 socket_factory_.AddSocketDataProvider(&http_data);
5115
5116 // In order for a new QUIC session to be established via alternate-protocol
5117 // without racing an HTTP connection, we need the host resolution to happen
5118 // synchronously.
5119 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295120 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565121 "");
[email protected]0fc924b2014-03-31 04:34:155122
rch9ae5b3b2016-02-11 00:36:295123 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325124 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275125 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155126 SendRequestAndExpectHttpResponse("hello world");
5127}
5128
[email protected]1e960032013-12-20 19:00:205129TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:595130 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235131 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165132 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255133 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235134 mock_quic_data.AddWrite(SYNCHRONOUS,
5135 ConstructInitialSettingsPacket(packet_num++));
5136 }
Zhongyi Shi1c022d22020-03-20 19:00:165137 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365138 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235139 SYNCHRONOUS,
5140 ConstructClientRequestHeadersPacket(
5141 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5142 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435143 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335144 ASYNC, ConstructServerResponseHeadersPacket(
5145 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285146 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335147 mock_quic_data.AddRead(
5148 ASYNC, ConstructServerDataPacket(
5149 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525150 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235151 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345152 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:595153 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045154 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125155
rtennetib8e80fb2016-05-16 00:12:095156 // The non-alternate protocol job needs to hang in order to guarantee that
5157 // the alternate-protocol job will "win".
5158 AddHangingNonAlternateProtocolSocketData();
5159
[email protected]11c05872013-08-20 02:04:125160 // In order for a new QUIC session to be established via alternate-protocol
5161 // without racing an HTTP connection, we need the host resolution to happen
5162 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5163 // connection to the the server, in this test we require confirmation
5164 // before encrypting so the HTTP job will still start.
5165 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295166 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565167 "");
[email protected]11c05872013-08-20 02:04:125168
rch3f4b8452016-02-23 16:59:325169 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435170 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5171 false);
Ryan Hamilton9835e662018-08-02 05:36:275172 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125173
bnc691fda62016-08-12 00:43:165174 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125175 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265176 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015177 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125178
Fan Yang3673cc72020-02-07 14:49:285179 crypto_client_stream_factory_.last_stream()
5180 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015181 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505182
bnc691fda62016-08-12 00:43:165183 CheckWasQuicResponse(&trans);
5184 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125185}
5186
Steven Valdez58097ec32018-07-16 18:29:045187TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015188 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595189 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165190 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255191 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495192 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:165193 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:495194 }
Steven Valdez58097ec32018-07-16 18:29:045195 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015196 SYNCHRONOUS,
5197 ConstructClientRequestHeadersPacket(
5198 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5199 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335200 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025201 ASYNC, ConstructServerResponseHeadersPacket(
5202 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285203 GetResponseHeaders("425")));
Bence Béky6e243aa2019-12-13 19:01:075204 if (VersionUsesHttp3(version_.transport_version)) {
5205 mock_quic_data.AddWrite(
5206 SYNCHRONOUS,
5207 ConstructClientAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:345208 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, false,
Bence Béky6e243aa2019-12-13 19:01:075209 StreamCancellationQpackDecoderInstruction(0)));
5210 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165211 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075212 packet_number++, false,
5213 GetNthClientInitiatedBidirectionalStreamId(0),
5214 quic::QUIC_STREAM_CANCELLED));
5215 } else {
5216 mock_quic_data.AddWrite(
5217 SYNCHRONOUS,
5218 ConstructClientAckAndRstPacket(
5219 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:345220 quic::QUIC_STREAM_CANCELLED, 1, 1));
Bence Béky6e243aa2019-12-13 19:01:075221 }
Steven Valdez58097ec32018-07-16 18:29:045222
Zhongyi Shi1c022d22020-03-20 19:00:165223 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:045224
Steven Valdez58097ec32018-07-16 18:29:045225 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015226 SYNCHRONOUS,
5227 ConstructClientRequestHeadersPacket(
5228 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5229 true, GetRequestHeaders("GET", "https", "/"),
5230 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045231 mock_quic_data.AddRead(
5232 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335233 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285234 GetResponseHeaders("200")));
Steven Valdez58097ec32018-07-16 18:29:045235 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335236 ASYNC, ConstructServerDataPacket(
5237 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:525238 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:475239 mock_quic_data.AddWrite(SYNCHRONOUS,
5240 ConstructClientAckPacket(packet_number++, 3, 1));
Steven Valdez58097ec32018-07-16 18:29:045241 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215242 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Steven Valdez58097ec32018-07-16 18:29:045243
5244 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5245
5246 // In order for a new QUIC session to be established via alternate-protocol
5247 // without racing an HTTP connection, we need the host resolution to happen
5248 // synchronously.
5249 host_resolver_.set_synchronous_mode(true);
5250 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5251 "");
Steven Valdez58097ec32018-07-16 18:29:045252
5253 AddHangingNonAlternateProtocolSocketData();
5254 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275255 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565256 QuicStreamFactoryPeer::SetAlarmFactory(
5257 session_->quic_stream_factory(),
5258 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225259 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045260
5261 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5262 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265263 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Steven Valdez58097ec32018-07-16 18:29:045264 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5265
5266 // Confirm the handshake after the 425 Too Early.
5267 base::RunLoop().RunUntilIdle();
5268
5269 // The handshake hasn't been confirmed yet, so the retry should not have
5270 // succeeded.
5271 EXPECT_FALSE(callback.have_result());
5272
Fan Yang3673cc72020-02-07 14:49:285273 crypto_client_stream_factory_.last_stream()
5274 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:045275
5276 EXPECT_THAT(callback.WaitForResult(), IsOk());
5277 CheckWasQuicResponse(&trans);
5278 CheckResponseData(&trans, "hello!");
5279}
5280
5281TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015282 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595283 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165284 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255285 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495286 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:165287 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:495288 }
Steven Valdez58097ec32018-07-16 18:29:045289 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015290 SYNCHRONOUS,
5291 ConstructClientRequestHeadersPacket(
5292 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5293 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335294 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025295 ASYNC, ConstructServerResponseHeadersPacket(
5296 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285297 GetResponseHeaders("425")));
Bence Béky6e243aa2019-12-13 19:01:075298 if (VersionUsesHttp3(version_.transport_version)) {
5299 mock_quic_data.AddWrite(
5300 SYNCHRONOUS,
5301 ConstructClientAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:345302 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, false,
Bence Béky6e243aa2019-12-13 19:01:075303 StreamCancellationQpackDecoderInstruction(0)));
5304 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165305 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075306 packet_number++, false,
5307 GetNthClientInitiatedBidirectionalStreamId(0),
5308 quic::QUIC_STREAM_CANCELLED));
5309 } else {
5310 mock_quic_data.AddWrite(
5311 SYNCHRONOUS,
5312 ConstructClientAckAndRstPacket(
5313 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:345314 quic::QUIC_STREAM_CANCELLED, 1, 1));
Bence Béky6e243aa2019-12-13 19:01:075315 }
Steven Valdez58097ec32018-07-16 18:29:045316
Zhongyi Shi1c022d22020-03-20 19:00:165317 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:045318
Steven Valdez58097ec32018-07-16 18:29:045319 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015320 SYNCHRONOUS,
5321 ConstructClientRequestHeadersPacket(
5322 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5323 true, GetRequestHeaders("GET", "https", "/"),
5324 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335325 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025326 ASYNC, ConstructServerResponseHeadersPacket(
5327 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285328 GetResponseHeaders("425")));
Bence Béky6e243aa2019-12-13 19:01:075329 if (VersionUsesHttp3(version_.transport_version)) {
5330 mock_quic_data.AddWrite(
5331 SYNCHRONOUS,
5332 ConstructClientAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:345333 packet_number++, false, GetQpackDecoderStreamId(), 2, 1, false,
Renjie Tang248e36ea2020-06-26 00:12:345334 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:075335 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165336 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075337 packet_number++, false,
5338 GetNthClientInitiatedBidirectionalStreamId(1),
5339 quic::QUIC_STREAM_CANCELLED));
5340 } else {
5341 mock_quic_data.AddWrite(
5342 SYNCHRONOUS,
5343 ConstructClientAckAndRstPacket(
5344 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
Renjie Tangcd594f32020-07-11 20:18:345345 quic::QUIC_STREAM_CANCELLED, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:075346 }
Steven Valdez58097ec32018-07-16 18:29:045347 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215348 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Steven Valdez58097ec32018-07-16 18:29:045349
5350 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5351
5352 // In order for a new QUIC session to be established via alternate-protocol
5353 // without racing an HTTP connection, we need the host resolution to happen
5354 // synchronously.
5355 host_resolver_.set_synchronous_mode(true);
5356 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5357 "");
Steven Valdez58097ec32018-07-16 18:29:045358
5359 AddHangingNonAlternateProtocolSocketData();
5360 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275361 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565362 QuicStreamFactoryPeer::SetAlarmFactory(
5363 session_->quic_stream_factory(),
5364 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225365 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045366
5367 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5368 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265369 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Steven Valdez58097ec32018-07-16 18:29:045370 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5371
5372 // Confirm the handshake after the 425 Too Early.
5373 base::RunLoop().RunUntilIdle();
5374
5375 // The handshake hasn't been confirmed yet, so the retry should not have
5376 // succeeded.
5377 EXPECT_FALSE(callback.have_result());
5378
Fan Yang3673cc72020-02-07 14:49:285379 crypto_client_stream_factory_.last_stream()
5380 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:045381
5382 EXPECT_THAT(callback.WaitForResult(), IsOk());
5383 const HttpResponseInfo* response = trans.GetResponseInfo();
5384 ASSERT_TRUE(response != nullptr);
5385 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:285386 EXPECT_EQ("HTTP/1.1 425", response->headers->GetStatusLine());
Steven Valdez58097ec32018-07-16 18:29:045387 EXPECT_TRUE(response->was_fetched_via_spdy);
5388 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085389 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5390 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045391}
5392
zhongyica364fbb2015-12-12 03:39:125393TEST_P(QuicNetworkTransactionTest,
5394 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Victor Vasilieva1e66d72019-12-05 17:55:385395 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595396 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235397 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165398 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255399 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235400 mock_quic_data.AddWrite(SYNCHRONOUS,
5401 ConstructInitialSettingsPacket(packet_num++));
5402 }
Zhongyi Shi1c022d22020-03-20 19:00:165403 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365404 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235405 SYNCHRONOUS,
5406 ConstructClientRequestHeadersPacket(
5407 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5408 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125409 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525410 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435411 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125412 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5413
5414 // The non-alternate protocol job needs to hang in order to guarantee that
5415 // the alternate-protocol job will "win".
5416 AddHangingNonAlternateProtocolSocketData();
5417
5418 // In order for a new QUIC session to be established via alternate-protocol
5419 // without racing an HTTP connection, we need the host resolution to happen
5420 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5421 // connection to the the server, in this test we require confirmation
5422 // before encrypting so the HTTP job will still start.
5423 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295424 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125425 "");
zhongyica364fbb2015-12-12 03:39:125426
rch3f4b8452016-02-23 16:59:325427 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435428 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5429 false);
Ryan Hamilton9835e662018-08-02 05:36:275430 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125431
bnc691fda62016-08-12 00:43:165432 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125433 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265434 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015435 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125436
Fan Yang3673cc72020-02-07 14:49:285437 crypto_client_stream_factory_.last_stream()
5438 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015439 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125440
5441 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525442 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125443
bnc691fda62016-08-12 00:43:165444 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125445 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525446 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5447 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125448}
5449
5450TEST_P(QuicNetworkTransactionTest,
5451 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Victor Vasilieva1e66d72019-12-05 17:55:385452 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595453 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235454 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165455 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255456 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235457 mock_quic_data.AddWrite(SYNCHRONOUS,
5458 ConstructInitialSettingsPacket(packet_num++));
5459 }
Zhongyi Shi1c022d22020-03-20 19:00:165460 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365461 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235462 SYNCHRONOUS,
5463 ConstructClientRequestHeadersPacket(
5464 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5465 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215466 // Peer sending data from an non-existing stream causes this end to raise
5467 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335468 mock_quic_data.AddRead(
5469 ASYNC, ConstructServerRstPacket(
5470 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5471 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215472 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:375473 mock_quic_data.AddWrite(
Renjie Tang248e36ea2020-06-26 00:12:345474 SYNCHRONOUS,
5475 ConstructClientAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:345476 packet_num++, 1, 1,
Renjie Tang248e36ea2020-06-26 00:12:345477 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
5478 : quic::QUIC_INVALID_STREAM_ID,
Renjie Tanga35322a2020-12-02 20:12:275479 quic_error_details,
5480 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
5481 : quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125482 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5483
5484 // The non-alternate protocol job needs to hang in order to guarantee that
5485 // the alternate-protocol job will "win".
5486 AddHangingNonAlternateProtocolSocketData();
5487
5488 // In order for a new QUIC session to be established via alternate-protocol
5489 // without racing an HTTP connection, we need the host resolution to happen
5490 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5491 // connection to the the server, in this test we require confirmation
5492 // before encrypting so the HTTP job will still start.
5493 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295494 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125495 "");
zhongyica364fbb2015-12-12 03:39:125496
rch3f4b8452016-02-23 16:59:325497 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435498 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5499 false);
Ryan Hamilton9835e662018-08-02 05:36:275500 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125501
bnc691fda62016-08-12 00:43:165502 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125503 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265504 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015505 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125506
Fan Yang3673cc72020-02-07 14:49:285507 crypto_client_stream_factory_.last_stream()
5508 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015509 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125510 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525511 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125512
bnc691fda62016-08-12 00:43:165513 trans.PopulateNetErrorDetails(&details);
Renjie Tang248e36ea2020-06-26 00:12:345514 EXPECT_EQ(version_.HasIetfQuicFrames()
5515 ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
5516 : quic::QUIC_INVALID_STREAM_ID,
5517 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125518}
5519
Nick Harper057264a82019-09-12 23:33:495520TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:595521 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235522 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165523 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255524 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235525 mock_quic_data.AddWrite(SYNCHRONOUS,
5526 ConstructInitialSettingsPacket(packet_num++));
5527 }
Zhongyi Shi1c022d22020-03-20 19:00:165528 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365529 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235530 SYNCHRONOUS,
5531 ConstructClientRequestHeadersPacket(
5532 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5533 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485534 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335535 mock_quic_data.AddRead(
5536 ASYNC, ConstructServerResponseHeadersPacket(
5537 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285538 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335539 mock_quic_data.AddRead(
5540 ASYNC, ConstructServerRstPacket(
5541 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5542 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075543
5544 if (VersionUsesHttp3(version_.transport_version)) {
5545 mock_quic_data.AddWrite(
Renjie Tanga35322a2020-12-02 20:12:275546 SYNCHRONOUS,
5547 client_maker_->MakeAckRstAndDataPacket(
5548 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5549 quic::QUIC_STREAM_CANCELLED, 2, 1, GetQpackDecoderStreamId(), false,
5550 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:075551 } else {
5552 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345553 ConstructClientAckPacket(packet_num++, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:075554 }
rchcd5f1c62016-06-23 02:43:485555 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5556 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5557
5558 // The non-alternate protocol job needs to hang in order to guarantee that
5559 // the alternate-protocol job will "win".
5560 AddHangingNonAlternateProtocolSocketData();
5561
5562 // In order for a new QUIC session to be established via alternate-protocol
5563 // without racing an HTTP connection, we need the host resolution to happen
5564 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5565 // connection to the the server, in this test we require confirmation
5566 // before encrypting so the HTTP job will still start.
5567 host_resolver_.set_synchronous_mode(true);
5568 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5569 "");
rchcd5f1c62016-06-23 02:43:485570
5571 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435572 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5573 false);
Ryan Hamilton9835e662018-08-02 05:36:275574 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485575
bnc691fda62016-08-12 00:43:165576 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485577 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265578 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015579 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485580
Fan Yang3673cc72020-02-07 14:49:285581 crypto_client_stream_factory_.last_stream()
5582 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:485583 // Read the headers.
robpercival214763f2016-07-01 23:27:015584 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485585
bnc691fda62016-08-12 00:43:165586 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485587 ASSERT_TRUE(response != nullptr);
5588 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:285589 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
rchcd5f1c62016-06-23 02:43:485590 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525591 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085592 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5593 response->connection_info);
rchcd5f1c62016-06-23 02:43:485594
5595 std::string response_data;
bnc691fda62016-08-12 00:43:165596 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485597}
5598
Nick Harper057264a82019-09-12 23:33:495599TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:385600 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595601 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235602 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165603 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255604 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235605 mock_quic_data.AddWrite(SYNCHRONOUS,
5606 ConstructInitialSettingsPacket(packet_num++));
5607 }
Zhongyi Shi1c022d22020-03-20 19:00:165608 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365609 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235610 SYNCHRONOUS,
5611 ConstructClientRequestHeadersPacket(
5612 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5613 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335614 mock_quic_data.AddRead(
5615 ASYNC, ConstructServerRstPacket(
5616 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5617 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075618
5619 if (VersionUsesHttp3(version_.transport_version)) {
5620 mock_quic_data.AddWrite(
Renjie Tanga35322a2020-12-02 20:12:275621 SYNCHRONOUS,
Fan Yang8d4177792021-07-16 17:48:535622 client_maker_->MakeAckRstAndDataPacket(
Renjie Tanga35322a2020-12-02 20:12:275623 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5624 quic::QUIC_STREAM_CANCELLED, 1, 1, GetQpackDecoderStreamId(), false,
5625 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:075626 }
5627
rchcd5f1c62016-06-23 02:43:485628 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5629 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5630
5631 // The non-alternate protocol job needs to hang in order to guarantee that
5632 // the alternate-protocol job will "win".
5633 AddHangingNonAlternateProtocolSocketData();
5634
5635 // In order for a new QUIC session to be established via alternate-protocol
5636 // without racing an HTTP connection, we need the host resolution to happen
5637 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5638 // connection to the the server, in this test we require confirmation
5639 // before encrypting so the HTTP job will still start.
5640 host_resolver_.set_synchronous_mode(true);
5641 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5642 "");
rchcd5f1c62016-06-23 02:43:485643
5644 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435645 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5646 false);
Ryan Hamilton9835e662018-08-02 05:36:275647 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485648
bnc691fda62016-08-12 00:43:165649 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485650 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265651 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485653
Fan Yang3673cc72020-02-07 14:49:285654 crypto_client_stream_factory_.last_stream()
5655 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:485656 // Read the headers.
robpercival214763f2016-07-01 23:27:015657 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485658}
5659
[email protected]1e960032013-12-20 19:00:205660TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305661 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525662 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585663 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305664 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505665 MockRead(ASYNC, close->data(), close->length()),
5666 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5667 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305668 };
Ryan Sleevib8d7ea02018-05-07 20:01:015669 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305670 socket_factory_.AddSocketDataProvider(&quic_data);
5671
5672 // Main job which will succeed even though the alternate job fails.
5673 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025674 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5675 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5676 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305677
Ryan Sleevib8d7ea02018-05-07 20:01:015678 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305679 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565680 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305681
rch3f4b8452016-02-23 16:59:325682 CreateSession();
David Schinazic8281052019-01-24 06:14:175683 AddQuicAlternateProtocolMapping(
5684 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195685 SendRequestAndExpectHttpResponse("hello from http");
5686 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305687}
5688
Matt Menkeb32ba5122019-09-10 19:17:055689TEST_P(QuicNetworkTransactionTest,
5690 BrokenAlternateProtocolWithNetworkIsolationKey) {
Matt Menke4807a9a2020-11-21 00:14:415691 const SchemefulSite kSite1(GURL("https://foo.test/"));
5692 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
5693 const SchemefulSite kSite2(GURL("https://bar.test/"));
5694 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:055695
5696 base::test::ScopedFeatureList feature_list;
5697 feature_list.InitWithFeatures(
5698 // enabled_features
5699 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5700 features::kPartitionConnectionsByNetworkIsolationKey},
5701 // disabled_features
5702 {});
5703 // Since HttpServerProperties caches the feature value, have to create a new
5704 // one.
5705 http_server_properties_ = std::make_unique<HttpServerProperties>();
5706
5707 // Alternate-protocol job
5708 std::unique_ptr<quic::QuicEncryptedPacket> close(
5709 ConstructServerConnectionClosePacket(1));
5710 MockRead quic_reads[] = {
5711 MockRead(ASYNC, close->data(), close->length()),
5712 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5713 MockRead(ASYNC, OK), // EOF
5714 };
5715 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5716 socket_factory_.AddSocketDataProvider(&quic_data);
5717
5718 // Main job which will succeed even though the alternate job fails.
5719 MockRead http_reads[] = {
5720 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5721 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5722 MockRead(ASYNC, OK)};
5723
5724 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5725 socket_factory_.AddSocketDataProvider(&http_data);
5726 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5727
5728 CreateSession();
5729 AddQuicAlternateProtocolMapping(
5730 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5731 AddQuicAlternateProtocolMapping(
5732 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5733 request_.network_isolation_key = kNetworkIsolationKey1;
5734 SendRequestAndExpectHttpResponse("hello from http");
5735
5736 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5737 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5738}
5739
[email protected]1e960032013-12-20 19:00:205740TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595741 // Alternate-protocol job
5742 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025743 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595744 };
Ryan Sleevib8d7ea02018-05-07 20:01:015745 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595746 socket_factory_.AddSocketDataProvider(&quic_data);
5747
5748 // Main job which will succeed even though the alternate job fails.
5749 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025750 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5751 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5752 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595753
Ryan Sleevib8d7ea02018-05-07 20:01:015754 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595755 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565756 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595757
rch3f4b8452016-02-23 16:59:325758 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595759
Ryan Hamilton9835e662018-08-02 05:36:275760 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195761 SendRequestAndExpectHttpResponse("hello from http");
5762 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595763}
5764
[email protected]00c159f2014-05-21 22:38:165765TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535766 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165767 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025768 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165769 };
Ryan Sleevib8d7ea02018-05-07 20:01:015770 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165771 socket_factory_.AddSocketDataProvider(&quic_data);
5772
[email protected]eb71ab62014-05-23 07:57:535773 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165774 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025775 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165776 };
5777
Ryan Sleevib8d7ea02018-05-07 20:01:015778 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165779 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5780 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565781 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165782
rtennetib8e80fb2016-05-16 00:12:095783 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325784 CreateSession();
[email protected]00c159f2014-05-21 22:38:165785
Ryan Hamilton9835e662018-08-02 05:36:275786 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165787 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165788 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265789 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015790 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5791 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165792 ExpectQuicAlternateProtocolMapping();
5793}
5794
Zhongyi Shia0cef1082017-08-25 01:49:505795TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5796 // Tests that TCP job is delayed and QUIC job does not require confirmation
5797 // if QUIC was recently supported on the same IP on start.
5798
5799 // Set QUIC support on the last IP address, which is same with the local IP
5800 // address. Require confirmation mode will be turned off immediately when
5801 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435802 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5803 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:505804
Ryan Hamiltonabad59e2019-06-06 04:02:595805 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165806 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495807 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255808 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495809 mock_quic_data.AddWrite(SYNCHRONOUS,
5810 ConstructInitialSettingsPacket(packet_number++));
5811 }
Zhongyi Shi32f2fd02018-04-16 18:23:435812 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495813 SYNCHRONOUS,
5814 ConstructClientRequestHeadersPacket(
5815 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5816 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:165817 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5818 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
Zhongyi Shi32f2fd02018-04-16 18:23:435819 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335820 ASYNC, ConstructServerResponseHeadersPacket(
5821 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285822 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335823 mock_quic_data.AddRead(
5824 ASYNC, ConstructServerDataPacket(
5825 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525826 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:495827 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345828 ConstructClientAckPacket(packet_number++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505829 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215830 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Zhongyi Shia0cef1082017-08-25 01:49:505831
5832 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5833 // No HTTP data is mocked as TCP job never starts in this case.
5834
5835 CreateSession();
5836 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:435837 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5838 false);
Zhongyi Shia0cef1082017-08-25 01:49:505839
Ryan Hamilton9835e662018-08-02 05:36:275840 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505841
5842 // Stall host resolution so that QUIC job will not succeed synchronously.
5843 // Socket will not be configured immediately and QUIC support is not sorted
5844 // out, TCP job will still be delayed as server properties indicates QUIC
5845 // support on last IP address.
5846 host_resolver_.set_synchronous_mode(false);
5847
5848 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5849 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265850 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Zhongyi Shia0cef1082017-08-25 01:49:505851 IsError(ERR_IO_PENDING));
5852 // Complete host resolution in next message loop so that QUIC job could
5853 // proceed.
5854 base::RunLoop().RunUntilIdle();
Fan Yang1ef6dfef2021-07-24 16:20:165855 // Explicitly confirm the handshake.
5856 crypto_client_stream_factory_.last_stream()
5857 ->NotifySessionOneRttKeyAvailable();
5858
5859 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
5860 mock_quic_data.Resume();
5861
5862 // Run the QUIC session to completion.
5863 base::RunLoop().RunUntilIdle();
Zhongyi Shia0cef1082017-08-25 01:49:505864 EXPECT_THAT(callback.WaitForResult(), IsOk());
5865
5866 CheckWasQuicResponse(&trans);
5867 CheckResponseData(&trans, "hello!");
5868}
5869
5870TEST_P(QuicNetworkTransactionTest,
5871 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5872 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5873 // was recently supported on a different IP address on start.
5874
5875 // Set QUIC support on the last IP address, which is different with the local
5876 // IP address. Require confirmation mode will remain when local IP address is
5877 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435878 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5879 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:505880
Ryan Hamiltonabad59e2019-06-06 04:02:595881 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235882 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165883 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255884 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235885 mock_quic_data.AddWrite(SYNCHRONOUS,
5886 ConstructInitialSettingsPacket(packet_num++));
5887 }
Zhongyi Shi1c022d22020-03-20 19:00:165888 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:505889 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235890 SYNCHRONOUS,
5891 ConstructClientRequestHeadersPacket(
5892 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5893 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435894 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335895 ASYNC, ConstructServerResponseHeadersPacket(
5896 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285897 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335898 mock_quic_data.AddRead(
5899 ASYNC, ConstructServerDataPacket(
5900 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525901 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235902 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345903 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505904 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5905 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5906 // No HTTP data is mocked as TCP job will be delayed and never starts.
5907
5908 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435909 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5910 false);
Ryan Hamilton9835e662018-08-02 05:36:275911 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505912
5913 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5914 // Socket will not be configured immediately and QUIC support is not sorted
5915 // out, TCP job will still be delayed as server properties indicates QUIC
5916 // support on last IP address.
5917 host_resolver_.set_synchronous_mode(false);
5918
5919 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5920 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265921 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Zhongyi Shia0cef1082017-08-25 01:49:505922 IsError(ERR_IO_PENDING));
5923
5924 // Complete host resolution in next message loop so that QUIC job could
5925 // proceed.
5926 base::RunLoop().RunUntilIdle();
5927 // Explicitly confirm the handshake so that QUIC job could succeed.
Fan Yang3673cc72020-02-07 14:49:285928 crypto_client_stream_factory_.last_stream()
5929 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia0cef1082017-08-25 01:49:505930 EXPECT_THAT(callback.WaitForResult(), IsOk());
5931
5932 CheckWasQuicResponse(&trans);
5933 CheckResponseData(&trans, "hello!");
5934}
5935
Ryan Hamilton75f197262017-08-17 14:00:075936TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5937 // Test that NetErrorDetails is correctly populated, even if the
5938 // handshake has not yet been confirmed and no stream has been created.
5939
5940 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595941 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075942 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5943 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5944 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5945
5946 // Main job will also fail.
5947 MockRead http_reads[] = {
5948 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5949 };
5950
Ryan Sleevib8d7ea02018-05-07 20:01:015951 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075952 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5953 socket_factory_.AddSocketDataProvider(&http_data);
5954 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5955
5956 AddHangingNonAlternateProtocolSocketData();
5957 CreateSession();
5958 // Require handshake confirmation to ensure that no QUIC streams are
5959 // created, and to ensure that the TCP job does not wait for the QUIC
5960 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:435961 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5962 false);
Ryan Hamilton75f197262017-08-17 14:00:075963
Ryan Hamilton9835e662018-08-02 05:36:275964 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075965 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5966 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265967 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton75f197262017-08-17 14:00:075968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5969 // Allow the TCP job to fail.
5970 base::RunLoop().RunUntilIdle();
5971 // Now let the QUIC job fail.
5972 mock_quic_data.Resume();
5973 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5974 ExpectQuicAlternateProtocolMapping();
5975 NetErrorDetails details;
5976 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525977 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075978}
5979
[email protected]1e960032013-12-20 19:00:205980TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455981 // Alternate-protocol job
5982 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025983 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455984 };
Ryan Sleevib8d7ea02018-05-07 20:01:015985 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455986 socket_factory_.AddSocketDataProvider(&quic_data);
5987
[email protected]c92c1b52014-05-31 04:16:065988 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015989 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065990 socket_factory_.AddSocketDataProvider(&quic_data2);
5991
[email protected]4d283b32013-10-17 12:57:275992 // Final job that will proceed when the QUIC job fails.
5993 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025994 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5995 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5996 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275997
Ryan Sleevib8d7ea02018-05-07 20:01:015998 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275999 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566000 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:276001
rch3f4b8452016-02-23 16:59:326002 CreateSession();
[email protected]77c6c162013-08-17 02:57:456003
Ryan Hamilton9835e662018-08-02 05:36:276004 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:456005
[email protected]4d283b32013-10-17 12:57:276006 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:456007
6008 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:276009
rch37de576c2015-05-17 20:28:176010 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6011 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:456012}
6013
Matt Menkeb32ba5122019-09-10 19:17:056014TEST_P(QuicNetworkTransactionTest,
6015 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
6016 base::test::ScopedFeatureList feature_list;
6017 feature_list.InitWithFeatures(
6018 // enabled_features
6019 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
6020 features::kPartitionConnectionsByNetworkIsolationKey},
6021 // disabled_features
6022 {});
6023 // Since HttpServerProperties caches the feature value, have to create a new
6024 // one.
6025 http_server_properties_ = std::make_unique<HttpServerProperties>();
6026
Matt Menke4807a9a2020-11-21 00:14:416027 const SchemefulSite kSite1(GURL("https://foo.test/"));
6028 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
6029 const SchemefulSite kSite2(GURL("https://bar.test/"));
6030 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:056031
6032 // Alternate-protocol job
6033 MockRead quic_reads[] = {
6034 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
6035 };
6036 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
6037 socket_factory_.AddSocketDataProvider(&quic_data);
6038
6039 // Second Alternate-protocol job which will race with the TCP job.
6040 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
6041 socket_factory_.AddSocketDataProvider(&quic_data2);
6042
6043 // Final job that will proceed when the QUIC job fails.
6044 MockRead http_reads[] = {
6045 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6046 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6047 MockRead(ASYNC, OK)};
6048
6049 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
6050 socket_factory_.AddSocketDataProvider(&http_data);
6051 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6052
6053 CreateSession();
6054
6055 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6056 kNetworkIsolationKey1);
6057 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6058 kNetworkIsolationKey2);
6059
6060 request_.network_isolation_key = kNetworkIsolationKey1;
6061 SendRequestAndExpectHttpResponse("hello from http");
6062 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6063 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
6064
6065 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6066 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6067
6068 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
6069 AddHttpDataAndRunRequest();
6070 // Requests using other NetworkIsolationKeys can still use QUIC.
6071 request_.network_isolation_key = kNetworkIsolationKey2;
6072 AddQuicDataAndRunRequest();
6073
6074 // The last two requests should not have changed the alternative service
6075 // mappings.
6076 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6077 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6078}
6079
[email protected]eb71ab62014-05-23 07:57:536080TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:336081 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:016082 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:496083 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:336084 socket_factory_.AddSocketDataProvider(&quic_data);
6085
6086 // Main job which will succeed even though the alternate job fails.
6087 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026088 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6089 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6090 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:336091
Ryan Sleevib8d7ea02018-05-07 20:01:016092 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:336093 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566094 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:336095
rch3f4b8452016-02-23 16:59:326096 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276097 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:336098 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:536099
6100 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:336101}
6102
[email protected]4fee9672014-01-08 14:47:156103TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltona51800a2022-02-12 19:34:356104 if (version_.AlpnDeferToRFCv1()) {
6105 // These versions currently do not support Alt-Svc.
6106 return;
6107 }
Ryan Hamiltonabad59e2019-06-06 04:02:596108 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:166109 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:176110 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:046111 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:156112
6113 // When the QUIC connection fails, we will try the request again over HTTP.
6114 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:456115 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:566116 MockRead("hello world"),
6117 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6118 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:156119
Ryan Sleevib8d7ea02018-05-07 20:01:016120 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:156121 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566122 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:156123
6124 // In order for a new QUIC session to be established via alternate-protocol
6125 // without racing an HTTP connection, we need the host resolution to happen
6126 // synchronously.
6127 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:296128 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:566129 "");
[email protected]4fee9672014-01-08 14:47:156130
rch3f4b8452016-02-23 16:59:326131 CreateSession();
David Schinazic8281052019-01-24 06:14:176132 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
6133 AddQuicAlternateProtocolMapping(
6134 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:156135 SendRequestAndExpectHttpResponse("hello world");
6136}
6137
tbansalc3308d72016-08-27 10:25:046138TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltona51800a2022-02-12 19:34:356139 if (version_.AlpnDeferToRFCv1()) {
6140 // These versions currently do not support Alt-Svc.
6141 return;
6142 }
Ryan Hamiltonabad59e2019-06-06 04:02:596143 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:166144 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:176145 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:336146 mock_quic_data.AddWrite(
6147 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6148 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
6149 true, GetRequestHeaders("GET", "https", "/")));
Renjie Tangcd594f32020-07-11 20:18:346150 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1));
tbansalc3308d72016-08-27 10:25:046151 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6152
6153 // When the QUIC connection fails, we will try the request again over HTTP.
6154 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:456155 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
tbansalc3308d72016-08-27 10:25:046156 MockRead("hello world"),
6157 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6158 MockRead(ASYNC, OK)};
6159
Ryan Sleevib8d7ea02018-05-07 20:01:016160 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:046161 socket_factory_.AddSocketDataProvider(&http_data);
6162 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6163
6164 TestProxyDelegate test_proxy_delegate;
6165 const HostPortPair host_port_pair("myproxy.org", 443);
tbansalc3308d72016-08-27 10:25:046166
Nicolas Arciniegad2013f92020-02-07 23:00:566167 proxy_resolution_service_ =
6168 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Matt Menke7bc4def2020-07-29 20:54:516169 "QUIC myproxy.org:443; HTTPS myproxy.org:443",
6170 TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526171 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046172 request_.url = GURL("http://mail.example.org/");
6173
6174 // In order for a new QUIC session to be established via alternate-protocol
6175 // without racing an HTTP connection, we need the host resolution to happen
6176 // synchronously.
6177 host_resolver_.set_synchronous_mode(true);
6178 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:046179
6180 CreateSession();
David Schinazic8281052019-01-24 06:14:176181 crypto_client_stream_factory_.set_handshake_mode(
6182 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:046183 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596184 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166185 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046186}
6187
bnc508835902015-05-12 20:10:296188TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
Zhongyi Shi1c022d22020-03-20 19:00:166189 client_maker_->set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386190 EXPECT_FALSE(
6191 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:596192 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236193 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256194 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236195 mock_quic_data.AddWrite(SYNCHRONOUS,
6196 ConstructInitialSettingsPacket(packet_num++));
6197 }
rch5cb522462017-04-25 20:18:366198 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236199 SYNCHRONOUS,
6200 ConstructClientRequestHeadersPacket(
6201 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6202 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436203 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336204 ASYNC, ConstructServerResponseHeadersPacket(
6205 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286206 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336207 mock_quic_data.AddRead(
6208 ASYNC, ConstructServerDataPacket(
6209 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526210 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:236211 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346212 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:506213 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296214 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6215
bncb07c05532015-05-14 19:07:206216 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096217 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326218 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276219 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296220 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386221 EXPECT_TRUE(
6222 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296223}
6224
rtenneti56977812016-01-15 19:26:566225TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Victor Vasilieva1e66d72019-12-05 17:55:386226 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576227 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566228
Renjie Tangaadb84b2019-08-31 01:00:236229 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:256230 if (!VersionUsesHttp3(version_.transport_version))
David Schinazi395918c2021-02-05 18:56:216231 mock_quic_data.AddRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED);
Renjie Tangaadb84b2019-08-31 01:00:236232 else
6233 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6234 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6235 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6236
6237 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6238 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
6239 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:016240 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:236241 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:566242
rtennetib8e80fb2016-05-16 00:12:096243 // The non-alternate protocol job needs to hang in order to guarantee that
6244 // the alternate-protocol job will "win".
6245 AddHangingNonAlternateProtocolSocketData();
6246
rtenneti56977812016-01-15 19:26:566247 CreateSession();
6248 request_.method = "POST";
6249 ChunkedUploadDataStream upload_data(0);
6250 upload_data.AppendData("1", 1, true);
6251
6252 request_.upload_data_stream = &upload_data;
6253
bnc691fda62016-08-12 00:43:166254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566255 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266256 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:016257 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566258 EXPECT_NE(OK, callback.WaitForResult());
6259}
6260
rche11300ef2016-09-02 01:44:286261TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Victor Vasilieva1e66d72019-12-05 17:55:386262 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286263 ScopedMockNetworkChangeNotifier network_change_notifier;
6264 MockNetworkChangeNotifier* mock_ncn =
6265 network_change_notifier.mock_network_change_notifier();
6266 mock_ncn->ForceNetworkHandlesSupported();
6267 mock_ncn->SetConnectedNetworksList(
6268 {kDefaultNetworkForTests, kNewNetworkForTests});
6269
Victor Vasilieva1e66d72019-12-05 17:55:386270 context_.params()->origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286271 HostPortPair::FromString("mail.example.org:443"));
Victor Vasilieva1e66d72019-12-05 17:55:386272 context_.params()->migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286273
Ryan Hamiltonabad59e2019-06-06 04:02:596274 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286275 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236276 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256277 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236278 socket_data.AddWrite(SYNCHRONOUS,
6279 ConstructInitialSettingsPacket(packet_num++));
6280 }
Fan Yang32c5a112018-12-10 20:06:336281 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236282 SYNCHRONOUS,
6283 ConstructClientRequestHeadersPacket(
6284 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6285 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:286286 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6287 socket_data.AddSocketDataToFactory(&socket_factory_);
6288
Ryan Hamiltonabad59e2019-06-06 04:02:596289 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286290 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6291 socket_data2.AddSocketDataToFactory(&socket_factory_);
6292
6293 // The non-alternate protocol job needs to hang in order to guarantee that
6294 // the alternate-protocol job will "win".
6295 AddHangingNonAlternateProtocolSocketData();
6296
6297 CreateSession();
6298 request_.method = "POST";
6299 ChunkedUploadDataStream upload_data(0);
6300
6301 request_.upload_data_stream = &upload_data;
6302
rdsmith1d343be52016-10-21 20:37:506303 std::unique_ptr<HttpNetworkTransaction> trans(
6304 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286305 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266306 int rv = trans->Start(&request_, callback.callback(), net_log_with_source_);
rche11300ef2016-09-02 01:44:286307 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6308
6309 base::RunLoop().RunUntilIdle();
6310 upload_data.AppendData("1", 1, true);
6311 base::RunLoop().RunUntilIdle();
6312
6313 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506314 trans.reset();
rche11300ef2016-09-02 01:44:286315 session_.reset();
6316}
6317
Ryan Hamilton4b3574532017-10-30 20:17:256318TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386319 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256320 HostPortPair::FromString("mail.example.org:443"));
6321
Ryan Hamiltonabad59e2019-06-06 04:02:596322 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236323 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256324 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236325 socket_data.AddWrite(SYNCHRONOUS,
6326 ConstructInitialSettingsPacket(packet_num++));
6327 }
Ryan Hamilton4b3574532017-10-30 20:17:256328 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336329 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236330 SYNCHRONOUS,
6331 ConstructClientRequestHeadersPacket(
6332 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6333 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436334 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336335 ASYNC, ConstructServerResponseHeadersPacket(
6336 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286337 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336338 socket_data.AddRead(
6339 ASYNC, ConstructServerDataPacket(
6340 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526341 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:236342 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346343 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256344 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi1c022d22020-03-20 19:00:166345 socket_data.AddWrite(SYNCHRONOUS,
6346 client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:346347 packet_num++, false, 2, 1,
Zhongyi Shi1c022d22020-03-20 19:00:166348 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256349
6350 socket_data.AddSocketDataToFactory(&socket_factory_);
6351
6352 CreateSession();
6353
6354 SendRequestAndExpectQuicResponse("hello!");
6355 session_.reset();
6356}
6357
6358TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386359 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256360 HostPortPair::FromString("mail.example.org:443"));
6361
Ryan Hamiltonabad59e2019-06-06 04:02:596362 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236363 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256364 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236365 socket_data.AddWrite(SYNCHRONOUS,
6366 ConstructInitialSettingsPacket(packet_num++));
6367 }
Ryan Hamilton4b3574532017-10-30 20:17:256368 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336369 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236370 SYNCHRONOUS,
6371 ConstructClientRequestHeadersPacket(
6372 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6373 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436374 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336375 ASYNC, ConstructServerResponseHeadersPacket(
6376 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286377 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336378 socket_data.AddRead(
6379 ASYNC, ConstructServerDataPacket(
6380 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526381 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:236382 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346383 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256384 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi1c022d22020-03-20 19:00:166385 socket_data.AddWrite(SYNCHRONOUS,
6386 client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:346387 packet_num++, false, 2, 1,
Zhongyi Shi1c022d22020-03-20 19:00:166388 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256389
6390 socket_data.AddSocketDataToFactory(&socket_factory_);
6391
6392 CreateSession();
6393
6394 SendRequestAndExpectQuicResponse("hello!");
6395 session_.reset();
6396}
6397
Ryan Hamilton9edcf1a2017-11-22 05:55:176398TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386399 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6400 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256401 HostPortPair::FromString("mail.example.org:443"));
6402
Ryan Hamiltonabad59e2019-06-06 04:02:596403 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256404 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256405 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236406 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176407 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256408 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6409 }
6410 socket_data.AddSocketDataToFactory(&socket_factory_);
6411
6412 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176413 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176414 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6415 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256416
Victor Vasiliev7752898d2019-11-14 21:30:226417 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256418 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6419 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266420 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton4b3574532017-10-30 20:17:256421 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176422 while (!callback.have_result()) {
6423 base::RunLoop().RunUntilIdle();
6424 quic_task_runner_->RunUntilIdle();
6425 }
6426 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256427 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176428 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6429 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6430 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226431 EXPECT_TRUE(context_.clock()->Now() - start >
6432 quic::QuicTime::Delta::FromSeconds(4));
6433 EXPECT_TRUE(context_.clock()->Now() - start <
6434 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256435}
6436
Ryan Hamilton9edcf1a2017-11-22 05:55:176437TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386438 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6439 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256440 HostPortPair::FromString("mail.example.org:443"));
6441
Ryan Hamiltonabad59e2019-06-06 04:02:596442 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256443 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256444 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236445 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176446 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256447 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6448 }
6449 socket_data.AddSocketDataToFactory(&socket_factory_);
6450
6451 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176452 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176453 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6454 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256455
Victor Vasiliev7752898d2019-11-14 21:30:226456 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256457 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6458 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266459 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton4b3574532017-10-30 20:17:256460 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176461 while (!callback.have_result()) {
6462 base::RunLoop().RunUntilIdle();
6463 quic_task_runner_->RunUntilIdle();
6464 }
6465 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256466 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176467 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6468 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6469 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226470 EXPECT_TRUE(context_.clock()->Now() - start >
6471 quic::QuicTime::Delta::FromSeconds(4));
6472 EXPECT_TRUE(context_.clock()->Now() - start <
6473 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256474}
6475
Cherie Shi7596de632018-02-22 07:28:186476TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Victor Vasilieva1e66d72019-12-05 17:55:386477 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6478 context_.params()->origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186479 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev62c09dc2020-11-06 18:18:296480 const std::string error_details = base::StrCat(
6481 {"Write failed with error: ", base::NumberToString(ERR_MSG_TOO_BIG), " (",
6482 strerror(ERR_MSG_TOO_BIG), ")"});
Cherie Shi7596de632018-02-22 07:28:186483
Ryan Hamiltonabad59e2019-06-06 04:02:596484 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186485 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236486 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256487 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236488 socket_data.AddWrite(SYNCHRONOUS,
6489 ConstructInitialSettingsPacket(packet_num++));
6490 }
Cherie Shi7596de632018-02-22 07:28:186491 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6492 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526493 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236494 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:166495 client_maker_->MakeConnectionClosePacket(
Renjie Tangaadb84b2019-08-31 01:00:236496 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186497 socket_data.AddSocketDataToFactory(&socket_factory_);
6498
6499 CreateSession();
6500
6501 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6502 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266503 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Cherie Shi7596de632018-02-22 07:28:186504 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6505 base::RunLoop().RunUntilIdle();
6506 ASSERT_TRUE(callback.have_result());
6507 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6508 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6509 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6510}
6511
ckrasic769733c2016-06-30 00:42:136512// Adds coverage to catch regression such as https://crbug.com/622043
6513TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Victor Vasiliev638956df2021-04-05 16:41:406514 if (VersionUsesHttp3(version_.transport_version)) {
6515 return;
6516 }
Victor Vasilieva1e66d72019-12-05 17:55:386517 context_.params()->origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136518 HostPortPair::FromString("mail.example.org:443"));
6519
Ryan Hamiltonabad59e2019-06-06 04:02:596520 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236521 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436522 mock_quic_data.AddWrite(
6523 SYNCHRONOUS,
6524 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336525 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026526 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436527 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:476528 ASYNC, ConstructServerPushPromisePacket(
6529 1, GetNthClientInitiatedBidirectionalStreamId(0),
6530 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6531 GetRequestHeaders("GET", "https", "/pushed.jpg")));
Haoyue Wang9d70d65c2020-05-29 22:45:346532 const bool should_send_priority_packet =
6533 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:346534 !VersionUsesHttp3(version_.transport_version);
6535 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346536 mock_quic_data.AddWrite(
6537 SYNCHRONOUS,
6538 ConstructClientAckAndPriorityPacket(
6539 client_packet_number++, false,
6540 /*largest_received=*/1, /*smallest_received=*/1,
6541 GetNthServerInitiatedUnidirectionalStreamId(0),
6542 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576543 }
Zhongyi Shi32f2fd02018-04-16 18:23:436544 mock_quic_data.AddRead(
6545 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336546 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286547 GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:006548 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346549 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346550 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346551 }
Zhongyi Shi32f2fd02018-04-16 18:23:436552 mock_quic_data.AddRead(
6553 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336554 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286555 false, GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:006556 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346557 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346558 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346559 }
Zhongyi Shi32f2fd02018-04-16 18:23:436560 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336561 ASYNC, ConstructServerDataPacket(
6562 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526563 ConstructDataFrame("hello!")));
Fan Yang32d79502020-06-24 22:36:006564 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346565 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346566 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:346567 }
Zhongyi Shi32f2fd02018-04-16 18:23:436568 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336569 ASYNC, ConstructServerDataPacket(
6570 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526571 ConstructDataFrame("and hello!")));
Fan Yang32d79502020-06-24 22:36:006572 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346573 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346574 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:346575 }
Renjie Tangee921d12020-02-06 00:41:496576 if (!VersionUsesHttp3(version_.transport_version)) {
6577 mock_quic_data.AddWrite(SYNCHRONOUS,
6578 ConstructClientAckAndRstPacket(
6579 client_packet_number++,
6580 GetNthServerInitiatedUnidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:346581 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
Renjie Tangee921d12020-02-06 00:41:496582 } else {
6583 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:166584 SYNCHRONOUS, client_maker_->MakeAckAndPriorityUpdatePacket(
Renjie Tangcd594f32020-07-11 20:18:346585 client_packet_number++, true, 5, 5, 3,
Renjie Tangee921d12020-02-06 00:41:496586 GetNthServerInitiatedUnidirectionalStreamId(0)));
6587 }
ckrasic769733c2016-06-30 00:42:136588 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216589 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
ckrasic769733c2016-06-30 00:42:136590 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6591
6592 // The non-alternate protocol job needs to hang in order to guarantee that
6593 // the alternate-protocol job will "win".
6594 AddHangingNonAlternateProtocolSocketData();
6595
6596 CreateSession();
6597
6598 // PUSH_PROMISE handling in the http layer gets exercised here.
6599 SendRequestAndExpectQuicResponse("hello!");
6600
6601 request_.url = GURL("https://mail.example.org/pushed.jpg");
6602 SendRequestAndExpectQuicResponse("and hello!");
6603
6604 // Check that the NetLog was filled reasonably.
Matt Reichhoff0049a0b72021-10-20 20:44:266605 auto entries = net_log_observer_.GetEntries();
ckrasic769733c2016-06-30 00:42:136606 EXPECT_LT(0u, entries.size());
6607
6608 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6609 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006610 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6611 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136612 EXPECT_LT(0, pos);
6613}
6614
Matt Menked804aaf2020-07-21 21:25:486615// Checks that if the same resource is pushed using two different
6616// NetworkIsolationKeys, both pushed resources are tracked independently, and
6617// NetworkIsolationKeys are respected.
6618TEST_P(QuicNetworkTransactionTest, QuicServerPushRespectsNetworkIsolationKey) {
Victor Vasiliev638956df2021-04-05 16:41:406619 if (VersionUsesHttp3(version_.transport_version)) {
6620 return;
6621 }
Matt Menked804aaf2020-07-21 21:25:486622 base::test::ScopedFeatureList feature_list;
6623 feature_list.InitAndEnableFeature(
6624 features::kPartitionConnectionsByNetworkIsolationKey);
Matt Menked804aaf2020-07-21 21:25:486625 context_.params()->origins_to_force_quic_on.insert(
6626 HostPortPair::FromString("mail.example.org:443"));
6627
6628 MockQuicData mock_quic_data1(version_);
6629 uint64_t client_packet_number1 = 1;
Matt Menked804aaf2020-07-21 21:25:486630 mock_quic_data1.AddWrite(
6631 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6632 client_packet_number1++,
6633 GetNthClientInitiatedBidirectionalStreamId(0), true,
6634 true, GetRequestHeaders("GET", "https", "/")));
6635 mock_quic_data1.AddRead(
6636 ASYNC, ConstructServerPushPromisePacket(
6637 1, GetNthClientInitiatedBidirectionalStreamId(0),
6638 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6639 GetRequestHeaders("GET", "https", "/pushed.jpg")));
6640 const bool should_send_priority_packet =
6641 client_headers_include_h2_stream_dependency_ &&
6642 !VersionUsesHttp3(version_.transport_version);
6643 if (should_send_priority_packet) {
6644 mock_quic_data1.AddWrite(
6645 SYNCHRONOUS,
6646 ConstructClientAckAndPriorityPacket(
6647 client_packet_number1++, false,
6648 /*largest_received=*/1, /*smallest_received=*/1,
6649 GetNthServerInitiatedUnidirectionalStreamId(0),
6650 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
6651 }
6652 mock_quic_data1.AddRead(
6653 ASYNC, ConstructServerResponseHeadersPacket(
6654 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286655 GetResponseHeaders("200")));
Matt Menked804aaf2020-07-21 21:25:486656 if (!should_send_priority_packet) {
6657 mock_quic_data1.AddWrite(
6658 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 2, 1));
6659 }
6660 mock_quic_data1.AddRead(
6661 ASYNC, ConstructServerResponseHeadersPacket(
6662 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286663 false, GetResponseHeaders("200")));
Matt Menked804aaf2020-07-21 21:25:486664 if (should_send_priority_packet) {
6665 mock_quic_data1.AddWrite(
6666 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 3, 1));
6667 }
Matt Menked804aaf2020-07-21 21:25:486668 mock_quic_data1.AddRead(
6669 ASYNC, ConstructServerDataPacket(
6670 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526671 ConstructDataFrame("hello1")));
Matt Menked804aaf2020-07-21 21:25:486672 if (!should_send_priority_packet) {
6673 mock_quic_data1.AddWrite(
6674 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 4, 3));
6675 }
Matt Menked804aaf2020-07-21 21:25:486676 mock_quic_data1.AddRead(
6677 ASYNC, ConstructServerDataPacket(
6678 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526679 ConstructDataFrame("and hello1")));
Matt Menked804aaf2020-07-21 21:25:486680 if (should_send_priority_packet) {
6681 mock_quic_data1.AddWrite(
6682 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 5, 3));
6683 }
6684 if (!VersionUsesHttp3(version_.transport_version)) {
6685 mock_quic_data1.AddWrite(SYNCHRONOUS,
6686 ConstructClientAckAndRstPacket(
6687 client_packet_number1++,
6688 GetNthServerInitiatedUnidirectionalStreamId(0),
6689 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
6690 } else {
6691 mock_quic_data1.AddWrite(
6692 SYNCHRONOUS, client_maker_->MakeAckAndPriorityUpdatePacket(
6693 client_packet_number1++, true, 5, 5, 3,
6694 GetNthServerInitiatedUnidirectionalStreamId(0)));
6695 }
6696 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6697 mock_quic_data1.AddRead(ASYNC, 0); // EOF
6698 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
6699
6700 QuicTestPacketMaker client_maker2(
6701 version_,
6702 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
6703 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
6704 client_headers_include_h2_stream_dependency_);
Matt Menked804aaf2020-07-21 21:25:486705 QuicTestPacketMaker server_maker2(
6706 version_,
6707 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
6708 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
6709 false);
6710 MockQuicData mock_quic_data2(version_);
6711 uint64_t client_packet_number2 = 1;
6712 if (VersionUsesHttp3(version_.transport_version)) {
6713 mock_quic_data2.AddWrite(
6714 SYNCHRONOUS,
6715 client_maker2.MakeInitialSettingsPacket(client_packet_number2++));
6716 }
6717 mock_quic_data2.AddWrite(
6718 SYNCHRONOUS,
6719 client_maker2.MakeRequestHeadersPacket(
6720 client_packet_number2++,
6721 GetNthClientInitiatedBidirectionalStreamId(0), true, true,
6722 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
6723 GetRequestHeaders("GET", "https", "/"), 0, nullptr));
6724 mock_quic_data2.AddRead(
6725 ASYNC, server_maker2.MakePushPromisePacket(
6726 1, GetNthClientInitiatedBidirectionalStreamId(0),
6727 GetNthServerInitiatedUnidirectionalStreamId(0), false, false,
6728 GetRequestHeaders("GET", "https", "/pushed.jpg"), nullptr));
6729 if (should_send_priority_packet) {
6730 mock_quic_data2.AddWrite(
6731 SYNCHRONOUS,
6732 client_maker2.MakeAckAndPriorityPacket(
6733 client_packet_number2++, false,
6734 /*largest_received=*/1, /*smallest_received=*/1,
6735 GetNthServerInitiatedUnidirectionalStreamId(0),
6736 GetNthClientInitiatedBidirectionalStreamId(0),
6737 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)));
6738 }
6739 mock_quic_data2.AddRead(
6740 ASYNC, server_maker2.MakeResponseHeadersPacket(
6741 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286742 GetResponseHeaders("200"), nullptr));
Matt Menked804aaf2020-07-21 21:25:486743 if (!should_send_priority_packet) {
6744 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6745 client_packet_number2++, 2, 1));
6746 }
6747 mock_quic_data2.AddRead(
6748 ASYNC, server_maker2.MakeResponseHeadersPacket(
6749 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286750 false, GetResponseHeaders("200"), nullptr));
Matt Menked804aaf2020-07-21 21:25:486751 if (should_send_priority_packet) {
6752 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6753 client_packet_number2++, 3, 1));
6754 }
Matt Menked804aaf2020-07-21 21:25:486755 mock_quic_data2.AddRead(
6756 ASYNC, server_maker2.MakeDataPacket(
6757 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526758 ConstructDataFrame("hello2")));
Matt Menked804aaf2020-07-21 21:25:486759 if (!should_send_priority_packet) {
6760 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6761 client_packet_number2++, 4, 3));
6762 }
Matt Menked804aaf2020-07-21 21:25:486763 mock_quic_data2.AddRead(
6764 ASYNC, server_maker2.MakeDataPacket(
6765 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526766 ConstructDataFrame("and hello2")));
Matt Menked804aaf2020-07-21 21:25:486767 if (should_send_priority_packet) {
6768 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6769 client_packet_number2++, 5, 3));
6770 }
6771 if (!VersionUsesHttp3(version_.transport_version)) {
6772 mock_quic_data2.AddWrite(SYNCHRONOUS,
6773 client_maker2.MakeAckAndRstPacket(
6774 client_packet_number2++, false,
6775 GetNthServerInitiatedUnidirectionalStreamId(0),
6776 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
6777 } else {
6778 mock_quic_data2.AddWrite(
6779 SYNCHRONOUS, client_maker2.MakeAckAndPriorityUpdatePacket(
6780 client_packet_number2++, true, 5, 5, 3,
6781 GetNthServerInitiatedUnidirectionalStreamId(0)));
6782 }
6783 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6784 mock_quic_data2.AddRead(ASYNC, 0); // EOF
6785 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
6786
6787 scoped_refptr<X509Certificate> cert(
6788 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
6789 verify_details_.cert_verify_result.verified_cert = cert;
6790 verify_details_.cert_verify_result.is_issued_by_known_root = true;
6791 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
6792
6793 // The non-alternate protocol jobs need to hang in order to guarantee that
6794 // the alternate-protocol job will "win". Use "AddTcpSocketDataProvider()", as
6795 // the connection requests may or may not actually make it to the socket
6796 // factory, there may or may not be a TCP connection made in between the two
6797 // QUIC connection attempts.
6798 StaticSocketDataProvider hanging_data1;
6799 hanging_data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
6800 socket_factory_.AddTcpSocketDataProvider(&hanging_data1);
6801 StaticSocketDataProvider hanging_data2;
6802 hanging_data2.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
6803 socket_factory_.AddTcpSocketDataProvider(&hanging_data2);
6804
6805 CreateSession();
6806
6807 NetworkIsolationKey network_isolation_key1 =
6808 NetworkIsolationKey::CreateTransient();
6809 NetworkIsolationKey network_isolation_key2 =
6810 NetworkIsolationKey::CreateTransient();
6811
6812 // Creates the first QUIC session, and triggers the first push.
6813 request_.network_isolation_key = network_isolation_key1;
6814 SendRequestAndExpectQuicResponse("hello1");
6815
6816 // Use a different NIK, which creates another QUIC session, triggering a
6817 // second push,
6818 request_.network_isolation_key = network_isolation_key2;
6819 SendRequestAndExpectQuicResponse("hello2");
6820
6821 // Use the second NIK again, should receive the push body from the second
6822 // session.
6823 request_.url = GURL("https://mail.example.org/pushed.jpg");
6824 SendRequestAndExpectQuicResponse("and hello2");
6825
6826 // Use the first NIK again, should receive the push body from the first
6827 // session.
6828 request_.network_isolation_key = network_isolation_key1;
6829 SendRequestAndExpectQuicResponse("and hello1");
6830}
6831
rch56ec40a2017-06-23 14:48:446832// Regression test for http://crbug.com/719461 in which a promised stream
6833// is closed before the pushed headers arrive, but after the connection
6834// is closed and before the callbacks are executed.
6835TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Victor Vasiliev638956df2021-04-05 16:41:406836 if (VersionUsesHttp3(version_.transport_version)) {
6837 return;
6838 }
Victor Vasilieva1e66d72019-12-05 17:55:386839 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6840 context_.params()->origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446841 HostPortPair::FromString("mail.example.org:443"));
6842
Ryan Hamiltonabad59e2019-06-06 04:02:596843 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236844 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446845 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436846 mock_quic_data.AddWrite(
6847 SYNCHRONOUS,
6848 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336849 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026850 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446851 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436852 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:476853 ASYNC, ConstructServerPushPromisePacket(
6854 1, GetNthClientInitiatedBidirectionalStreamId(0),
6855 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6856 GetRequestHeaders("GET", "https", "/pushed.jpg")));
Haoyue Wang9d70d65c2020-05-29 22:45:346857 const bool should_send_priority_packet =
6858 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:346859 !VersionUsesHttp3(version_.transport_version);
6860 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346861 mock_quic_data.AddWrite(
6862 SYNCHRONOUS,
6863 ConstructClientAckAndPriorityPacket(
6864 client_packet_number++, false,
6865 /*largest_received=*/1, /*smallest_received=*/1,
6866 GetNthServerInitiatedUnidirectionalStreamId(0),
6867 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576868 }
rch56ec40a2017-06-23 14:48:446869 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436870 mock_quic_data.AddRead(
6871 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336872 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286873 GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:006874 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346875 // Client ACKs the response headers.
6876 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346877 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346878 }
rch56ec40a2017-06-23 14:48:446879 // Response body for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436880 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336881 ASYNC, ConstructServerDataPacket(
6882 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526883 ConstructDataFrame("hello!")));
Fan Yang32d79502020-06-24 22:36:006884 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346885 // Client ACKs the response headers.
6886 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346887 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346888 }
rch56ec40a2017-06-23 14:48:446889 // Write error for the third request.
6890 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6891 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216892 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rch56ec40a2017-06-23 14:48:446893 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6894
6895 CreateSession();
6896
6897 // Send a request which triggers a push promise from the server.
6898 SendRequestAndExpectQuicResponse("hello!");
6899
6900 // Start a push transaction that will be cancelled after the connection
6901 // is closed, but before the callback is executed.
6902 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196903 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446904 session_.get());
6905 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:266906 int rv = trans2->Start(&request_, callback2.callback(), net_log_with_source_);
rch56ec40a2017-06-23 14:48:446907 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6908 base::RunLoop().RunUntilIdle();
6909
6910 // Cause the connection to close on a write error.
6911 HttpRequestInfo request3;
6912 request3.method = "GET";
6913 request3.url = GURL("https://mail.example.org/");
6914 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106915 request3.traffic_annotation =
6916 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446917 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6918 TestCompletionCallback callback3;
Matt Reichhoff0049a0b72021-10-20 20:44:266919 EXPECT_THAT(
6920 trans3.Start(&request3, callback3.callback(), net_log_with_source_),
6921 IsError(ERR_IO_PENDING));
rch56ec40a2017-06-23 14:48:446922
6923 base::RunLoop().RunUntilIdle();
6924
6925 // When |trans2| is destroyed, the underlying stream will be closed.
6926 EXPECT_FALSE(callback2.have_result());
6927 trans2 = nullptr;
6928
6929 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6930}
6931
ckrasicda193a82016-07-09 00:39:366932TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Victor Vasilieva1e66d72019-12-05 17:55:386933 context_.params()->origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366934 HostPortPair::FromString("mail.example.org:443"));
6935
Ryan Hamiltonabad59e2019-06-06 04:02:596936 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:366937
Renjief49758b2019-01-11 23:32:416938 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:256939 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236940 mock_quic_data.AddWrite(
6941 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
6942 }
ckrasicda193a82016-07-09 00:39:366943
Bence Béky319388a882020-09-23 18:42:526944 mock_quic_data.AddWrite(
6945 SYNCHRONOUS,
6946 ConstructClientRequestHeadersAndDataFramesPacket(
6947 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6948 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
6949 0, nullptr, {ConstructDataFrame("1")}));
ckrasicda193a82016-07-09 00:39:366950
Zhongyi Shi32f2fd02018-04-16 18:23:436951 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336952 ASYNC, ConstructServerResponseHeadersPacket(
6953 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286954 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336955
6956 mock_quic_data.AddRead(
6957 ASYNC, ConstructServerDataPacket(
6958 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526959 ConstructDataFrame("hello!")));
ckrasicda193a82016-07-09 00:39:366960
Renjie Tangcd594f32020-07-11 20:18:346961 mock_quic_data.AddWrite(SYNCHRONOUS,
6962 ConstructClientAckPacket(write_packet_index++, 2, 1));
ckrasicda193a82016-07-09 00:39:366963
6964 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216965 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
ckrasicda193a82016-07-09 00:39:366966 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6967
6968 // The non-alternate protocol job needs to hang in order to guarantee that
6969 // the alternate-protocol job will "win".
6970 AddHangingNonAlternateProtocolSocketData();
6971
6972 CreateSession();
6973 request_.method = "POST";
6974 ChunkedUploadDataStream upload_data(0);
6975 upload_data.AppendData("1", 1, true);
6976
6977 request_.upload_data_stream = &upload_data;
6978
6979 SendRequestAndExpectQuicResponse("hello!");
6980}
6981
Ryan Sleevia9d6aa62019-07-26 13:32:186982TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
Ryan Hamiltona51800a2022-02-12 19:34:356983 if (version_.AlpnDeferToRFCv1()) {
6984 // These versions currently do not support Alt-Svc.
6985 return;
6986 }
Ryan Sleevia9d6aa62019-07-26 13:32:186987 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:206988
6989 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:456990 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yixin Wang10f477ed2017-11-21 04:20:206991 MockRead("hello world"),
6992 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6993 MockRead(ASYNC, OK)};
6994
Ryan Sleevib8d7ea02018-05-07 20:01:016995 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206996 socket_factory_.AddSocketDataProvider(&http_data);
6997 AddCertificate(&ssl_data_);
6998 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6999
Ryan Hamiltonabad59e2019-06-06 04:02:597000 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237001 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257002 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237003 mock_quic_data.AddWrite(SYNCHRONOUS,
7004 ConstructInitialSettingsPacket(packet_num++));
7005 }
Yixin Wang10f477ed2017-11-21 04:20:207006 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237007 SYNCHRONOUS,
7008 ConstructClientRequestHeadersPacket(
7009 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7010 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437011 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337012 ASYNC, ConstructServerResponseHeadersPacket(
7013 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287014 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:337015 mock_quic_data.AddRead(
7016 ASYNC, ConstructServerDataPacket(
7017 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527018 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:237019 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347020 ConstructClientAckPacket(packet_num++, 2, 1));
Yixin Wang10f477ed2017-11-21 04:20:207021 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:217022 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang10f477ed2017-11-21 04:20:207023
7024 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7025
7026 AddHangingNonAlternateProtocolSocketData();
7027 CreateSession();
7028
7029 SendRequestAndExpectHttpResponse("hello world");
7030 SendRequestAndExpectQuicResponse("hello!");
7031}
7032
Ryan Sleevia9d6aa62019-07-26 13:32:187033TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
Ryan Hamiltona51800a2022-02-12 19:34:357034 if (version_.AlpnDeferToRFCv1()) {
7035 // These versions currently do not support Alt-Svc.
7036 return;
7037 }
Ryan Sleevia9d6aa62019-07-26 13:32:187038 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:207039
7040 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:457041 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yixin Wang10f477ed2017-11-21 04:20:207042 MockRead("hello world"),
7043 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7044 MockRead(ASYNC, OK)};
7045
Ryan Sleevib8d7ea02018-05-07 20:01:017046 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207047 socket_factory_.AddSocketDataProvider(&http_data);
7048 AddCertificate(&ssl_data_);
7049 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7050 socket_factory_.AddSocketDataProvider(&http_data);
7051 AddCertificate(&ssl_data_);
7052 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7053
7054 AddHangingNonAlternateProtocolSocketData();
7055 CreateSession();
7056
7057 SendRequestAndExpectHttpResponse("hello world");
7058 SendRequestAndExpectHttpResponse("hello world");
7059}
7060
bnc359ed2a2016-04-29 20:43:457061class QuicNetworkTransactionWithDestinationTest
7062 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:017063 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:057064 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:457065 protected:
7066 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:557067 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:057068 client_headers_include_h2_stream_dependency_(
7069 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:567070 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:457071 destination_type_(GetParam().destination_type),
bnc359ed2a2016-04-29 20:43:457072 ssl_config_service_(new SSLConfigServiceDefaults),
Nicolas Arciniegad2013f92020-02-07 23:00:567073 proxy_resolution_service_(
7074 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:117075 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Ryan Hamiltonf9a421f2020-01-31 21:09:527076 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:197077 FLAGS_quic_enable_http3_grease_randomness = false;
Ryan Hamiltonf9a421f2020-01-31 21:09:527078 }
bnc359ed2a2016-04-29 20:43:457079
7080 void SetUp() override {
7081 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557082 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457083
Matt Menke30a878c2021-07-20 22:25:097084 HttpNetworkSessionParams session_params;
mmenke6ddfbea2017-05-31 21:48:417085 session_params.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:387086 context_.params()->allow_remote_alt_svc = true;
7087 context_.params()->supported_versions = supported_versions_;
7088 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:057089 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:417090
Matt Menke30a878c2021-07-20 22:25:097091 HttpNetworkSessionContext session_context;
bnc359ed2a2016-04-29 20:43:457092
Victor Vasiliev7752898d2019-11-14 21:30:227093 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
bnc359ed2a2016-04-29 20:43:457094
7095 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277096 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:417097 session_context.quic_crypto_client_stream_factory =
7098 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:457099
Victor Vasiliev7752898d2019-11-14 21:30:227100 session_context.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:417101 session_context.client_socket_factory = &socket_factory_;
7102 session_context.host_resolver = &host_resolver_;
7103 session_context.cert_verifier = &cert_verifier_;
7104 session_context.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:417105 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
7106 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:457107 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:417108 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:597109 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:417110 session_context.http_auth_handler_factory = auth_handler_factory_.get();
7111 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:457112
Renjie Tang6ff9a9b2021-02-03 22:11:097113 session_ =
7114 std::make_unique<HttpNetworkSession>(session_params, session_context);
Matt Menkeb566c392019-09-11 23:22:437115 session_->quic_stream_factory()
7116 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:457117 }
7118
7119 void TearDown() override {
7120 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7121 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557122 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457123 PlatformTest::TearDown();
7124 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557125 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:407126 session_.reset();
bnc359ed2a2016-04-29 20:43:457127 }
7128
zhongyie537a002017-06-27 16:48:217129 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:457130 HostPortPair destination;
7131 switch (destination_type_) {
7132 case SAME_AS_FIRST:
7133 destination = HostPortPair(origin1_, 443);
7134 break;
7135 case SAME_AS_SECOND:
7136 destination = HostPortPair(origin2_, 443);
7137 break;
7138 case DIFFERENT:
7139 destination = HostPortPair(kDifferentHostname, 443);
7140 break;
7141 }
bnc3472afd2016-11-17 15:27:217142 AlternativeService alternative_service(kProtoQUIC, destination);
Peter Kastinge5a38ed2021-10-02 03:06:357143 base::Time expiration = base::Time::Now() + base::Days(1);
zhongyie537a002017-06-27 16:48:217144 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:077145 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
7146 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:457147 }
7148
Ryan Hamilton8d9ee76e2018-05-29 23:52:527149 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237150 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527151 quic::QuicStreamId stream_id,
7152 bool should_include_version,
7153 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527154 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137155 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457156 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Bence Béky4c325e52020-10-22 20:48:017157 spdy::Http2HeaderBlock headers(
Ryan Hamilton0239aac2018-05-19 00:03:137158 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027159 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457160 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027161 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:457162 }
7163
Ryan Hamilton8d9ee76e2018-05-29 23:52:527164 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237165 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527166 quic::QuicStreamId stream_id,
7167 bool should_include_version,
7168 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587169 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:027170 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:457171 }
7172
Ryan Hamilton8d9ee76e2018-05-29 23:52:527173 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237174 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527175 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527176 QuicTestPacketMaker* maker) {
Kenichi Ishibashif8634ab2021-03-16 23:41:287177 spdy::Http2HeaderBlock headers(maker->GetResponseHeaders("200"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027178 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
7179 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:457180 }
7181
Ryan Hamilton8d9ee76e2018-05-29 23:52:527182 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237183 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527184 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457185 QuicTestPacketMaker* maker) {
Bence Béky319388a882020-09-23 18:42:527186 return maker->MakeDataPacket(
7187 packet_number, stream_id, false, true,
7188 ConstructDataFrameForVersion("hello", version_));
bnc359ed2a2016-04-29 20:43:457189 }
7190
Ryan Hamilton8d9ee76e2018-05-29 23:52:527191 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237192 uint64_t packet_number,
7193 uint64_t largest_received,
7194 uint64_t smallest_received,
bnc359ed2a2016-04-29 20:43:457195 QuicTestPacketMaker* maker) {
7196 return maker->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:347197 smallest_received);
bnc359ed2a2016-04-29 20:43:457198 }
7199
Ryan Hamilton8d9ee76e2018-05-29 23:52:527200 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237201 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:377202 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027203 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:377204 }
7205
bnc359ed2a2016-04-29 20:43:457206 void AddRefusedSocketData() {
7207 std::unique_ptr<StaticSocketDataProvider> refused_data(
7208 new StaticSocketDataProvider());
7209 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7210 refused_data->set_connect_data(refused_connect);
7211 socket_factory_.AddSocketDataProvider(refused_data.get());
7212 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7213 }
7214
7215 void AddHangingSocketData() {
7216 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7217 new StaticSocketDataProvider());
7218 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7219 hanging_data->set_connect_data(hanging_connect);
7220 socket_factory_.AddSocketDataProvider(hanging_data.get());
7221 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7222 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7223 }
7224
7225 bool AllDataConsumed() {
7226 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7227 if (!socket_data_ptr->AllReadDataConsumed() ||
7228 !socket_data_ptr->AllWriteDataConsumed()) {
7229 return false;
7230 }
7231 }
7232 return true;
7233 }
7234
7235 void SendRequestAndExpectQuicResponse(const std::string& host) {
7236 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7237 HttpRequestInfo request;
7238 std::string url("https://");
7239 url.append(host);
7240 request.url = GURL(url);
7241 request.load_flags = 0;
7242 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107243 request.traffic_annotation =
7244 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457245 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267246 int rv = trans.Start(&request, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:017247 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457248
7249 std::string response_data;
robpercival214763f2016-07-01 23:27:017250 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457251 EXPECT_EQ("hello", response_data);
7252
7253 const HttpResponseInfo* response = trans.GetResponseInfo();
7254 ASSERT_TRUE(response != nullptr);
7255 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:287256 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
bnc359ed2a2016-04-29 20:43:457257 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527258 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:087259 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457260 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377261 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457262 }
7263
Fan Yang32c5a112018-12-10 20:06:337264 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567265 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7266 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367267 }
7268
Ryan Hamiltonf9a421f2020-01-31 21:09:527269 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Nick Harper23290b82019-05-02 00:02:567270 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057271 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567272 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457273 DestinationType destination_type_;
7274 std::string origin1_;
7275 std::string origin2_;
Victor Vasiliev7752898d2019-11-14 21:30:227276 MockQuicContext context_;
bnc359ed2a2016-04-29 20:43:457277 std::unique_ptr<HttpNetworkSession> session_;
7278 MockClientSocketFactory socket_factory_;
Eric Orthbe86fee2021-10-28 22:31:117279 MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
7280 RuleResolver::GetLocalhostResult()};
bnc359ed2a2016-04-29 20:43:457281 MockCertVerifier cert_verifier_;
7282 TransportSecurityState transport_security_state_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237283 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457284 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077285 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:267286 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457287 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:267288 HttpServerProperties http_server_properties_;
Matt Reichhoff0049a0b72021-10-20 20:44:267289 NetLogWithSource net_log_with_source_{
7290 NetLogWithSource::Make(NetLogSourceType::NONE)};
bnc359ed2a2016-04-29 20:43:457291 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7292 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7293 static_socket_data_provider_vector_;
7294 SSLSocketDataProvider ssl_data_;
7295};
7296
Victor Costane635086f2019-01-27 05:20:307297INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7298 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:577299 ::testing::ValuesIn(GetPoolingTestParams()),
7300 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:457301
7302// A single QUIC request fails because the certificate does not match the origin
7303// hostname, regardless of whether it matches the alternative service hostname.
7304TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7305 if (destination_type_ == DIFFERENT)
7306 return;
7307
7308 GURL url("https://mail.example.com/");
7309 origin1_ = url.host();
7310
7311 // Not used for requests, but this provides a test case where the certificate
7312 // is valid for the hostname of the alternative service.
7313 origin2_ = "mail.example.org";
7314
zhongyie537a002017-06-27 16:48:217315 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457316
7317 scoped_refptr<X509Certificate> cert(
7318 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247319 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7320 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457321
7322 ProofVerifyDetailsChromium verify_details;
7323 verify_details.cert_verify_result.verified_cert = cert;
7324 verify_details.cert_verify_result.is_issued_by_known_root = true;
7325 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7326
Ryan Hamiltonabad59e2019-06-06 04:02:597327 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457328 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
David Schinazi395918c2021-02-05 18:56:217329 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:457330
7331 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7332
7333 AddRefusedSocketData();
7334
7335 HttpRequestInfo request;
7336 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107337 request.traffic_annotation =
7338 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457339
7340 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7341 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267342 int rv = trans.Start(&request, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:017343 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457344
7345 EXPECT_TRUE(AllDataConsumed());
7346}
7347
7348// First request opens QUIC session to alternative service. Second request
7349// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527350// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457351TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7352 origin1_ = "mail.example.org";
7353 origin2_ = "news.example.org";
7354
zhongyie537a002017-06-27 16:48:217355 SetQuicAlternativeService(origin1_);
7356 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457357
7358 scoped_refptr<X509Certificate> cert(
7359 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247360 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7361 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7362 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457363
7364 ProofVerifyDetailsChromium verify_details;
7365 verify_details.cert_verify_result.verified_cert = cert;
7366 verify_details.cert_verify_result.is_issued_by_known_root = true;
7367 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7368
Yixin Wang079ad542018-01-11 04:06:057369 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227370 version_,
7371 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7372 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057373 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177374 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227375 version_,
7376 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7377 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457378
Ryan Hamiltonabad59e2019-06-06 04:02:597379 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237380 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257381 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237382 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7383 packet_num++, &client_maker));
7384 }
Fan Yang32c5a112018-12-10 20:06:337385 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237386 SYNCHRONOUS,
7387 ConstructClientRequestHeadersPacket(
7388 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7389 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:027390 mock_quic_data.AddRead(
7391 ASYNC,
7392 ConstructServerResponseHeadersPacket(
7393 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437394 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337395 ASYNC,
7396 ConstructServerDataPacket(
7397 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237398 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347399 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457400
Yixin Wang079ad542018-01-11 04:06:057401 client_maker.set_hostname(origin2_);
7402 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457403
Zhongyi Shi32f2fd02018-04-16 18:23:437404 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027405 SYNCHRONOUS,
7406 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237407 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027408 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7409 mock_quic_data.AddRead(
7410 ASYNC,
7411 ConstructServerResponseHeadersPacket(
7412 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437413 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337414 ASYNC,
7415 ConstructServerDataPacket(
7416 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237417 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347418 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3, &client_maker));
bnc359ed2a2016-04-29 20:43:457419 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:217420 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:457421
7422 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7423
7424 AddHangingSocketData();
7425 AddHangingSocketData();
7426
Victor Vasiliev7752898d2019-11-14 21:30:227427 scoped_refptr<TestTaskRunner> quic_task_runner(
7428 new TestTaskRunner(context_.mock_clock()));
Fan Yangc9e00dc2018-10-09 14:17:567429 QuicStreamFactoryPeer::SetAlarmFactory(
7430 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097431 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Victor Vasiliev7752898d2019-11-14 21:30:227432 context_.clock()));
Fan Yangc9e00dc2018-10-09 14:17:567433
bnc359ed2a2016-04-29 20:43:457434 SendRequestAndExpectQuicResponse(origin1_);
7435 SendRequestAndExpectQuicResponse(origin2_);
7436
7437 EXPECT_TRUE(AllDataConsumed());
7438}
7439
7440// First request opens QUIC session to alternative service. Second request does
7441// not pool to it, even though destination matches, because certificate is not
7442// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527443// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457444TEST_P(QuicNetworkTransactionWithDestinationTest,
7445 DoNotPoolIfCertificateInvalid) {
7446 origin1_ = "news.example.org";
7447 origin2_ = "mail.example.com";
7448
zhongyie537a002017-06-27 16:48:217449 SetQuicAlternativeService(origin1_);
7450 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457451
7452 scoped_refptr<X509Certificate> cert1(
7453 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247454 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7455 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7456 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457457
7458 scoped_refptr<X509Certificate> cert2(
7459 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247460 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7461 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457462
7463 ProofVerifyDetailsChromium verify_details1;
7464 verify_details1.cert_verify_result.verified_cert = cert1;
7465 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7466 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7467
7468 ProofVerifyDetailsChromium verify_details2;
7469 verify_details2.cert_verify_result.verified_cert = cert2;
7470 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7471 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7472
Yixin Wang079ad542018-01-11 04:06:057473 QuicTestPacketMaker client_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227474 version_,
7475 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7476 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057477 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177478 QuicTestPacketMaker server_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227479 version_,
7480 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7481 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457482
Ryan Hamiltonabad59e2019-06-06 04:02:597483 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:237484 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257485 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237486 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7487 packet_num++, &client_maker1));
7488 }
Fan Yang32c5a112018-12-10 20:06:337489 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237490 SYNCHRONOUS,
7491 ConstructClientRequestHeadersPacket(
7492 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7493 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437494 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337495 ASYNC,
7496 ConstructServerResponseHeadersPacket(
7497 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437498 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337499 ASYNC,
7500 ConstructServerDataPacket(
7501 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437502 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237503 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347504 ConstructClientAckPacket(packet_num++, 2, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457505 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7506 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7507
7508 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7509
Yixin Wang079ad542018-01-11 04:06:057510 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227511 version_,
7512 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7513 context_.clock(), origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057514 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177515 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227516 version_,
7517 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7518 context_.clock(), origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457519
Ryan Hamiltonabad59e2019-06-06 04:02:597520 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:237521 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:257522 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237523 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7524 packet_num2++, &client_maker2));
7525 }
Fan Yang32c5a112018-12-10 20:06:337526 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237527 SYNCHRONOUS,
7528 ConstructClientRequestHeadersPacket(
7529 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7530 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437531 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337532 ASYNC,
7533 ConstructServerResponseHeadersPacket(
7534 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437535 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337536 ASYNC,
7537 ConstructServerDataPacket(
7538 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437539 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237540 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347541 ConstructClientAckPacket(packet_num2++, 2, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457542 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7543 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7544
7545 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7546
bnc359ed2a2016-04-29 20:43:457547 SendRequestAndExpectQuicResponse(origin1_);
7548 SendRequestAndExpectQuicResponse(origin2_);
7549
7550 EXPECT_TRUE(AllDataConsumed());
7551}
7552
ckrasicdee37572017-04-06 22:42:277553// crbug.com/705109 - this confirms that matching request with a body
7554// triggers a crash (pre-fix).
7555TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Victor Vasiliev638956df2021-04-05 16:41:407556 if (VersionUsesHttp3(version_.transport_version)) {
7557 return;
7558 }
Victor Vasilieva1e66d72019-12-05 17:55:387559 context_.params()->origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277560 HostPortPair::FromString("mail.example.org:443"));
7561
Ryan Hamiltonabad59e2019-06-06 04:02:597562 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237563 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437564 mock_quic_data.AddWrite(
7565 SYNCHRONOUS,
7566 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337567 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027568 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437569 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:477570 ASYNC, ConstructServerPushPromisePacket(
7571 1, GetNthClientInitiatedBidirectionalStreamId(0),
7572 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7573 GetRequestHeaders("GET", "https", "/pushed.jpg")));
Renjie Tang703fea92019-07-23 21:08:317574
Haoyue Wang9d70d65c2020-05-29 22:45:347575 const bool should_send_priority_packet =
7576 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:347577 !VersionUsesHttp3(version_.transport_version);
7578 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347579 mock_quic_data.AddWrite(
7580 SYNCHRONOUS,
7581 ConstructClientAckAndPriorityPacket(
7582 client_packet_number++, false,
7583 /*largest_received=*/1, /*smallest_received=*/1,
7584 GetNthServerInitiatedUnidirectionalStreamId(0),
7585 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577586 }
Zhongyi Shi32f2fd02018-04-16 18:23:437587 mock_quic_data.AddRead(
7588 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337589 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287590 GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:007591 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347592 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347593 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:347594 }
Zhongyi Shi32f2fd02018-04-16 18:23:437595 mock_quic_data.AddRead(
7596 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337597 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287598 false, GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:007599 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347600 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347601 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:347602 }
Zhongyi Shi32f2fd02018-04-16 18:23:437603 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337604 ASYNC, ConstructServerDataPacket(
7605 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527606 ConstructDataFrame("hello!")));
Fan Yang32d79502020-06-24 22:36:007607 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347608 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347609 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:347610 }
Renjief49758b2019-01-11 23:32:417611
Zhongyi Shi32f2fd02018-04-16 18:23:437612 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337613 ASYNC, ConstructServerDataPacket(
7614 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527615 ConstructDataFrame("and hello!")));
Fan Yang32d79502020-06-24 22:36:007616 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347617 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347618 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:347619 }
ckrasicdee37572017-04-06 22:42:277620
7621 // Because the matching request has a body, we will see the push
7622 // stream get cancelled, and the matching request go out on the
7623 // wire.
Fan Yang32d79502020-06-24 22:36:007624 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347625 mock_quic_data.AddWrite(
7626 SYNCHRONOUS,
7627 ConstructClientRstPacket(client_packet_number++,
7628 GetNthServerInitiatedUnidirectionalStreamId(0),
7629 quic::QUIC_STREAM_CANCELLED));
7630 } else {
7631 mock_quic_data.AddWrite(SYNCHRONOUS,
7632 ConstructClientAckAndRstPacket(
7633 client_packet_number++,
7634 GetNthServerInitiatedUnidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:347635 quic::QUIC_STREAM_CANCELLED, 5, 5));
Haoyue Wang9d70d65c2020-05-29 22:45:347636 }
Bence Béky319388a882020-09-23 18:42:527637 mock_quic_data.AddWrite(
7638 SYNCHRONOUS,
7639 ConstructClientRequestHeadersAndDataFramesPacket(
7640 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
7641 false, true, DEFAULT_PRIORITY,
7642 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7643 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7644 {ConstructDataFrame("1")}));
ckrasicdee37572017-04-06 22:42:277645
7646 // We see the same response as for the earlier pushed and cancelled
7647 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437648 mock_quic_data.AddRead(
7649 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337650 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287651 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:437652 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337653 ASYNC, ConstructServerDataPacket(
7654 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:527655 ConstructDataFrame("and hello!")));
ckrasicdee37572017-04-06 22:42:277656
Yixin Wangb470bc882018-02-15 18:43:577657 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347658 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6));
ckrasicdee37572017-04-06 22:42:277659 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:217660 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
ckrasicdee37572017-04-06 22:42:277661 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7662
7663 // The non-alternate protocol job needs to hang in order to guarantee that
7664 // the alternate-protocol job will "win".
7665 AddHangingNonAlternateProtocolSocketData();
7666
7667 CreateSession();
7668
7669 // PUSH_PROMISE handling in the http layer gets exercised here.
7670 SendRequestAndExpectQuicResponse("hello!");
7671
7672 request_.url = GURL("https://mail.example.org/pushed.jpg");
7673 ChunkedUploadDataStream upload_data(0);
7674 upload_data.AppendData("1", 1, true);
7675 request_.upload_data_stream = &upload_data;
7676 SendRequestAndExpectQuicResponse("and hello!");
7677}
7678
Bence Béky7538a952018-02-01 16:59:527679// Regression test for https://crbug.com/797825: If pushed headers describe a
7680// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7681// not be called (otherwise a DCHECK fails).
7682TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Victor Vasiliev638956df2021-04-05 16:41:407683 if (VersionUsesHttp3(version_.transport_version)) {
7684 return;
7685 }
Bence Béky4c325e52020-10-22 20:48:017686 spdy::Http2HeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527687 pushed_request_headers[":authority"] = "";
7688 pushed_request_headers[":method"] = "GET";
7689 pushed_request_headers[":path"] = "/";
7690 pushed_request_headers[":scheme"] = "nosuchscheme";
7691
Victor Vasilieva1e66d72019-12-05 17:55:387692 context_.params()->origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:527693 HostPortPair::FromString("mail.example.org:443"));
7694
Ryan Hamiltonabad59e2019-06-06 04:02:597695 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:527696
Renjie Tangaadb84b2019-08-31 01:00:237697 int packet_num = 1;
Bence Béky7538a952018-02-01 16:59:527698 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237699 SYNCHRONOUS,
7700 ConstructClientRequestHeadersPacket(
7701 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7702 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:527703
Fan Yang32c5a112018-12-10 20:06:337704 mock_quic_data.AddRead(
7705 ASYNC, ConstructServerPushPromisePacket(
7706 1, GetNthClientInitiatedBidirectionalStreamId(0),
7707 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Renjie Tangb7afea82020-07-15 23:35:477708 std::move(pushed_request_headers)));
Renjie Tangcd594f32020-07-11 20:18:347709 mock_quic_data.AddWrite(
7710 SYNCHRONOUS,
7711 ConstructClientAckAndRstPacket(
7712 packet_num++, GetNthServerInitiatedUnidirectionalStreamId(0),
7713 quic::QUIC_INVALID_PROMISE_URL, 1, 1));
Bence Béky7538a952018-02-01 16:59:527714
Zhongyi Shi32f2fd02018-04-16 18:23:437715 mock_quic_data.AddRead(
7716 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337717 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287718 GetResponseHeaders("200")));
Bence Béky7538a952018-02-01 16:59:527719
Zhongyi Shi32f2fd02018-04-16 18:23:437720 mock_quic_data.AddRead(
7721 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337722 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287723 false, GetResponseHeaders("200")));
Renjie Tangcd594f32020-07-11 20:18:347724 mock_quic_data.AddWrite(SYNCHRONOUS,
7725 ConstructClientAckPacket(packet_num++, 3, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:437726 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337727 ASYNC, ConstructServerDataPacket(
7728 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527729 ConstructDataFrame("hello!")));
Bence Béky7538a952018-02-01 16:59:527730
David Schinazi395918c2021-02-05 18:56:217731 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Bence Béky7538a952018-02-01 16:59:527732 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7733
7734 // The non-alternate protocol job needs to hang in order to guarantee that
7735 // the alternate-protocol job will "win".
7736 AddHangingNonAlternateProtocolSocketData();
7737
7738 CreateSession();
7739
7740 // PUSH_PROMISE handling in the http layer gets exercised here.
7741 SendRequestAndExpectQuicResponse("hello!");
7742
7743 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7744 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7745}
7746
Yixin Wang46a273ec302018-01-23 17:59:567747// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147748TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567749 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147750 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567751 proxy_resolution_service_ =
7752 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
7753 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567754
Ryan Hamiltonabad59e2019-06-06 04:02:597755 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237756 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257757 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237758 mock_quic_data.AddWrite(SYNCHRONOUS,
7759 ConstructInitialSettingsPacket(packet_num++));
7760 }
Fan Yang32c5a112018-12-10 20:06:337761 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237762 SYNCHRONOUS,
7763 ConstructClientRequestHeadersPacket(
7764 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:497765 false,
7766 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:577767 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:497768 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:237769 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337770 mock_quic_data.AddRead(
7771 ASYNC, ConstructServerResponseHeadersPacket(
7772 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287773 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:567774
7775 const char get_request[] =
7776 "GET / HTTP/1.1\r\n"
7777 "Host: mail.example.org\r\n"
7778 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:527779 mock_quic_data.AddWrite(
7780 SYNCHRONOUS,
7781 ConstructClientAckAndDataPacket(
7782 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
7783 1, false, ConstructDataFrame(get_request)));
Renjief49758b2019-01-11 23:32:417784
Yixin Wang46a273ec302018-01-23 17:59:567785 const char get_response[] =
7786 "HTTP/1.1 200 OK\r\n"
7787 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437788 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337789 ASYNC, ConstructServerDataPacket(
7790 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527791 ConstructDataFrame(get_response)));
Fan Yang32c5a112018-12-10 20:06:337792 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417793 SYNCHRONOUS, ConstructServerDataPacket(
7794 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527795 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:237796 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347797 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:567798 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7799
Bence Béky6e243aa2019-12-13 19:01:077800 if (VersionUsesHttp3(version_.transport_version)) {
7801 mock_quic_data.AddWrite(
7802 SYNCHRONOUS, ConstructClientDataPacket(
7803 packet_num++, GetQpackDecoderStreamId(), true, false,
7804 StreamCancellationQpackDecoderInstruction(0)));
7805 }
7806
Yixin Wang46a273ec302018-01-23 17:59:567807 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417808 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237809 ConstructClientRstPacket(packet_num++,
7810 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417811 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567812
7813 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7814
7815 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7816
7817 CreateSession();
7818
7819 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097820 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567821 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567822 RunTransaction(&trans);
7823 CheckWasHttpResponse(&trans);
7824 CheckResponsePort(&trans, 70);
7825 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:567826 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7827
Cammie Smith Barnesbf91e2a2020-12-23 20:49:047828 // DNS aliases should be empty when using a proxy.
7829 EXPECT_TRUE(trans.GetResponseInfo()->dns_aliases.empty());
7830
Yixin Wang46a273ec302018-01-23 17:59:567831 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7832 // proxy socket to disconnect.
7833 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7834
7835 base::RunLoop().RunUntilIdle();
7836 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7837 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7838}
7839
7840// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147841TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567842 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147843 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567844 proxy_resolution_service_ =
7845 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
7846 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567847
Ryan Hamiltonabad59e2019-06-06 04:02:597848 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237849 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257850 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237851 mock_quic_data.AddWrite(SYNCHRONOUS,
7852 ConstructInitialSettingsPacket(packet_num++));
7853 }
Fan Yang32c5a112018-12-10 20:06:337854 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237855 SYNCHRONOUS,
7856 ConstructClientRequestHeadersPacket(
7857 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:497858 false,
7859 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:577860 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:497861 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:237862 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337863 mock_quic_data.AddRead(
7864 ASYNC, ConstructServerResponseHeadersPacket(
7865 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287866 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:567867
7868 SpdyTestUtil spdy_util;
7869
Ryan Hamilton0239aac2018-05-19 00:03:137870 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567871 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:527872 mock_quic_data.AddWrite(
7873 SYNCHRONOUS,
7874 ConstructClientAckAndDataPacket(
7875 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
7876 1, false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Ryan Hamilton0239aac2018-05-19 00:03:137877 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567878 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:437879 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177880 ASYNC, ConstructServerDataPacket(
7881 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527882 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:567883
Ryan Hamilton0239aac2018-05-19 00:03:137884 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197885 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Zhongyi Shi32f2fd02018-04-16 18:23:437886 mock_quic_data.AddRead(
7887 SYNCHRONOUS,
7888 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337889 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527890 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Renjie Tangaadb84b2019-08-31 01:00:237891 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347892 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:567893 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7894
Bence Béky6e243aa2019-12-13 19:01:077895 if (VersionUsesHttp3(version_.transport_version)) {
7896 mock_quic_data.AddWrite(
7897 SYNCHRONOUS, ConstructClientDataPacket(
7898 packet_num++, GetQpackDecoderStreamId(), true, false,
7899 StreamCancellationQpackDecoderInstruction(0)));
7900 }
7901
Yixin Wang46a273ec302018-01-23 17:59:567902 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437903 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237904 ConstructClientRstPacket(packet_num++,
7905 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417906 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567907
7908 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7909
7910 SSLSocketDataProvider ssl_data(ASYNC, OK);
7911 ssl_data.next_proto = kProtoHTTP2;
7912 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7913
7914 CreateSession();
7915
7916 request_.url = GURL("https://mail.example.org/");
7917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567918 RunTransaction(&trans);
7919 CheckWasSpdyResponse(&trans);
7920 CheckResponsePort(&trans, 70);
7921 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:567922 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7923
Wez0e717112018-06-18 23:09:227924 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7925 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567926 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7927
7928 base::RunLoop().RunUntilIdle();
7929 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7930 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7931}
7932
7933// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7934// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147935TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567936 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147937 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567938 proxy_resolution_service_ =
7939 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
7940 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567941
Ryan Hamiltonabad59e2019-06-06 04:02:597942 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:417943 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:257944 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237945 mock_quic_data.AddWrite(
7946 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7947 }
Fan Yang32c5a112018-12-10 20:06:337948 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417949 SYNCHRONOUS,
7950 ConstructClientRequestHeadersPacket(
7951 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangee921d12020-02-06 00:41:497952 true, false,
7953 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:577954 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:497955 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027956 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337957 mock_quic_data.AddRead(
7958 ASYNC, ConstructServerResponseHeadersPacket(
7959 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287960 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:567961
Yixin Wang46a273ec302018-01-23 17:59:567962 const char get_request_1[] =
7963 "GET / HTTP/1.1\r\n"
7964 "Host: mail.example.org\r\n"
7965 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:527966 mock_quic_data.AddWrite(
7967 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7968 write_packet_index++, false,
7969 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
7970 false, ConstructDataFrame(get_request_1)));
Renjief49758b2019-01-11 23:32:417971
Yixin Wang46a273ec302018-01-23 17:59:567972 const char get_response_1[] =
7973 "HTTP/1.1 200 OK\r\n"
7974 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437975 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437976 ASYNC, ConstructServerDataPacket(
7977 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527978 ConstructDataFrame(get_response_1)));
Yixin Wang46a273ec302018-01-23 17:59:567979
Fan Yang32c5a112018-12-10 20:06:337980 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177981 SYNCHRONOUS, ConstructServerDataPacket(
7982 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527983 false, ConstructDataFrame("0123456789")));
Yixin Wang46a273ec302018-01-23 17:59:567984
Renjie Tangcd594f32020-07-11 20:18:347985 mock_quic_data.AddWrite(SYNCHRONOUS,
7986 ConstructClientAckPacket(write_packet_index++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:567987
7988 const char get_request_2[] =
7989 "GET /2 HTTP/1.1\r\n"
7990 "Host: mail.example.org\r\n"
7991 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:527992 mock_quic_data.AddWrite(
7993 SYNCHRONOUS,
7994 ConstructClientDataPacket(
7995 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7996 false, false, ConstructDataFrame(get_request_2)));
Yixin Wang46a273ec302018-01-23 17:59:567997
7998 const char get_response_2[] =
7999 "HTTP/1.1 200 OK\r\n"
8000 "Content-Length: 7\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:438001 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438002 ASYNC, ConstructServerDataPacket(
8003 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:528004 ConstructDataFrame(get_response_2)));
Yixin Wang46a273ec302018-01-23 17:59:568005
Ryan Hamilton8d9ee76e2018-05-29 23:52:528006 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178007 SYNCHRONOUS, ConstructServerDataPacket(
8008 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:528009 false, ConstructDataFrame("0123456")));
Yixin Wang46a273ec302018-01-23 17:59:568010
Renjie Tangcd594f32020-07-11 20:18:348011 mock_quic_data.AddWrite(SYNCHRONOUS,
8012 ConstructClientAckPacket(write_packet_index++, 5, 4));
Yixin Wang46a273ec302018-01-23 17:59:568013 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8014
Bence Béky6e243aa2019-12-13 19:01:078015 if (VersionUsesHttp3(version_.transport_version)) {
8016 mock_quic_data.AddWrite(
8017 SYNCHRONOUS, ConstructClientDataPacket(
8018 write_packet_index++, GetQpackDecoderStreamId(), true,
8019 false, StreamCancellationQpackDecoderInstruction(0)));
8020 }
8021
Renjief49758b2019-01-11 23:32:418022 mock_quic_data.AddWrite(
8023 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418024 ConstructClientRstPacket(write_packet_index++,
8025 GetNthClientInitiatedBidirectionalStreamId(0),
8026 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568027
8028 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8029
8030 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8031
8032 CreateSession();
8033
8034 request_.url = GURL("https://mail.example.org/");
8035 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568036 RunTransaction(&trans_1);
8037 CheckWasHttpResponse(&trans_1);
8038 CheckResponsePort(&trans_1, 70);
8039 CheckResponseData(&trans_1, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568040 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8041
8042 request_.url = GURL("https://mail.example.org/2");
8043 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568044 RunTransaction(&trans_2);
8045 CheckWasHttpResponse(&trans_2);
8046 CheckResponsePort(&trans_2, 70);
8047 CheckResponseData(&trans_2, "0123456");
Yixin Wang46a273ec302018-01-23 17:59:568048 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8049
8050 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8051 // proxy socket to disconnect.
8052 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8053
8054 base::RunLoop().RunUntilIdle();
8055 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8056 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8057}
8058
8059// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
8060// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
8061// server is reused for the second request.
Bence Békyf6bb6b22020-04-17 20:22:118062TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:568063 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148064 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568065 proxy_resolution_service_ =
8066 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8067 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568068
Ryan Hamiltonabad59e2019-06-06 04:02:598069 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238070 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258071 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238072 mock_quic_data.AddWrite(SYNCHRONOUS,
8073 ConstructInitialSettingsPacket(packet_num++));
8074 }
Yixin Wang46a273ec302018-01-23 17:59:568075
8076 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:338077 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238078 SYNCHRONOUS,
8079 ConstructClientRequestHeadersPacket(
8080 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498081 false,
8082 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578083 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498084 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238085 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438086 mock_quic_data.AddRead(
8087 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338088 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288089 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:568090
8091 // GET request, response, and data over QUIC tunnel for first request
8092 const char get_request[] =
8093 "GET / HTTP/1.1\r\n"
8094 "Host: mail.example.org\r\n"
8095 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:528096 mock_quic_data.AddWrite(
8097 SYNCHRONOUS,
8098 ConstructClientAckAndDataPacket(
8099 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
8100 1, false, ConstructDataFrame(get_request)));
Renjief49758b2019-01-11 23:32:418101
Yixin Wang46a273ec302018-01-23 17:59:568102 const char get_response[] =
8103 "HTTP/1.1 200 OK\r\n"
8104 "Content-Length: 10\r\n\r\n";
8105 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338106 ASYNC, ConstructServerDataPacket(
8107 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:528108 ConstructDataFrame(get_response)));
Fan Yang32c5a112018-12-10 20:06:338109 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418110 SYNCHRONOUS, ConstructServerDataPacket(
8111 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:528112 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238113 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348114 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:568115
8116 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438117 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238118 SYNCHRONOUS,
8119 ConstructClientRequestHeadersPacket(
8120 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Renjie Tangee921d12020-02-06 00:41:498121 false,
8122 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578123 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498124 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238125 ConnectRequestHeaders("different.example.org:443"),
8126 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438127 mock_quic_data.AddRead(
8128 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338129 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288130 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:568131
8132 // GET request, response, and data over QUIC tunnel for second request
8133 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138134 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568135 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:528136 mock_quic_data.AddWrite(
8137 SYNCHRONOUS,
8138 ConstructClientAckAndDataPacket(
8139 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 4,
8140 4, false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:568141
Ryan Hamilton0239aac2018-05-19 00:03:138142 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568143 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:438144 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178145 ASYNC, ConstructServerDataPacket(
8146 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:528147 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:568148
Ryan Hamilton0239aac2018-05-19 00:03:138149 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198150 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Zhongyi Shi32f2fd02018-04-16 18:23:438151 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438152 ASYNC, ConstructServerDataPacket(
8153 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:528154 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:568155
Renjie Tangaadb84b2019-08-31 01:00:238156 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348157 ConstructClientAckPacket(packet_num++, 6, 5));
Yixin Wang46a273ec302018-01-23 17:59:568158 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8159
Bence Béky6e243aa2019-12-13 19:01:078160 if (VersionUsesHttp3(version_.transport_version)) {
8161 mock_quic_data.AddWrite(
8162 SYNCHRONOUS, ConstructClientDataPacket(
8163 packet_num++, GetQpackDecoderStreamId(), true, false,
8164 StreamCancellationQpackDecoderInstruction(0)));
8165 }
8166
Yixin Wang46a273ec302018-01-23 17:59:568167 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418168 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238169 ConstructClientRstPacket(packet_num++,
8170 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418171 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:078172
8173 if (VersionUsesHttp3(version_.transport_version)) {
8174 mock_quic_data.AddWrite(
8175 SYNCHRONOUS, ConstructClientDataPacket(
8176 packet_num++, GetQpackDecoderStreamId(), true, false,
Bence Békyf6bb6b22020-04-17 20:22:118177 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078178 }
8179
Yixin Wang46a273ec302018-01-23 17:59:568180 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438181 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238182 ConstructClientRstPacket(packet_num++,
8183 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418184 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568185
8186 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8187
8188 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8189
8190 SSLSocketDataProvider ssl_data(ASYNC, OK);
8191 ssl_data.next_proto = kProtoHTTP2;
8192 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8193
8194 CreateSession();
8195
8196 request_.url = GURL("https://mail.example.org/");
8197 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568198 RunTransaction(&trans_1);
8199 CheckWasHttpResponse(&trans_1);
8200 CheckResponsePort(&trans_1, 70);
8201 CheckResponseData(&trans_1, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568202 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8203
8204 request_.url = GURL("https://different.example.org/");
8205 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568206 RunTransaction(&trans_2);
8207 CheckWasSpdyResponse(&trans_2);
8208 CheckResponsePort(&trans_2, 70);
8209 CheckResponseData(&trans_2, "0123456");
Yixin Wang46a273ec302018-01-23 17:59:568210 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8211
8212 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8213 // proxy socket to disconnect.
8214 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8215
8216 base::RunLoop().RunUntilIdle();
8217 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8218 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8219}
8220
8221// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148222TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568223 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148224 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568225 proxy_resolution_service_ =
8226 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8227 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568228
Ryan Hamiltonabad59e2019-06-06 04:02:598229 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238230 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258231 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238232 mock_quic_data.AddWrite(SYNCHRONOUS,
8233 ConstructInitialSettingsPacket(packet_num++));
8234 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:528235 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238236 SYNCHRONOUS,
8237 ConstructClientRequestHeadersPacket(
8238 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498239 false,
8240 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578241 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498242 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238243 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338244 mock_quic_data.AddRead(
8245 ASYNC, ConstructServerResponseHeadersPacket(
8246 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8247 GetResponseHeaders("500")));
8248 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:238249 mock_quic_data.AddWrite(
8250 SYNCHRONOUS,
8251 ConstructClientAckAndRstPacket(
8252 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:348253 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568254
8255 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8256
8257 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8258
8259 CreateSession();
8260
8261 request_.url = GURL("https://mail.example.org/");
8262 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568263 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268264 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:568265 EXPECT_EQ(ERR_IO_PENDING, rv);
8266 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
Yixin Wang46a273ec302018-01-23 17:59:568267
8268 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8269 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8270}
8271
8272// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148273TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568274 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148275 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568276 proxy_resolution_service_ =
8277 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8278 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568279
Ryan Hamiltonabad59e2019-06-06 04:02:598280 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238281 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258282 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238283 mock_quic_data.AddWrite(SYNCHRONOUS,
8284 ConstructInitialSettingsPacket(packet_num++));
8285 }
Fan Yang32c5a112018-12-10 20:06:338286 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238287 SYNCHRONOUS,
8288 ConstructClientRequestHeadersPacket(
8289 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498290 false,
8291 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578292 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498293 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238294 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:568295 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8296
8297 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8298
8299 CreateSession();
8300
8301 request_.url = GURL("https://mail.example.org/");
8302 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568303 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268304 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:568305 EXPECT_EQ(ERR_IO_PENDING, rv);
8306 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8307
8308 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8309 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8310}
8311
8312// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8313// host. Retries request and succeeds.
Bence Békyf6bb6b22020-04-17 20:22:118314TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568315 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148316 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568317 proxy_resolution_service_ =
8318 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8319 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568320
Ryan Hamiltonabad59e2019-06-06 04:02:598321 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238322 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258323 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238324 mock_quic_data.AddWrite(SYNCHRONOUS,
8325 ConstructInitialSettingsPacket(packet_num++));
8326 }
Fan Yang32c5a112018-12-10 20:06:338327 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238328 SYNCHRONOUS,
8329 ConstructClientRequestHeadersPacket(
8330 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498331 false,
8332 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578333 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498334 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238335 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438336 mock_quic_data.AddRead(
8337 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338338 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288339 GetResponseHeaders("200")));
Bence Béky6e243aa2019-12-13 19:01:078340 if (VersionUsesHttp3(version_.transport_version)) {
8341 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:348342 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8343 packet_num++, false, GetQpackDecoderStreamId(), 1, 1,
8344 false, StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:078345 mock_quic_data.AddWrite(
8346 SYNCHRONOUS,
8347 ConstructClientRstPacket(packet_num++,
8348 GetNthClientInitiatedBidirectionalStreamId(0),
8349 quic::QUIC_STREAM_CANCELLED));
8350 } else {
8351 mock_quic_data.AddWrite(
8352 SYNCHRONOUS,
8353 ConstructClientAckAndRstPacket(
8354 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:348355 quic::QUIC_STREAM_CANCELLED, 1, 1));
Bence Béky6e243aa2019-12-13 19:01:078356 }
Yixin Wang46a273ec302018-01-23 17:59:568357
Zhongyi Shi32f2fd02018-04-16 18:23:438358 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238359 SYNCHRONOUS,
8360 ConstructClientRequestHeadersPacket(
8361 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Renjie Tangee921d12020-02-06 00:41:498362 false,
8363 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578364 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498365 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238366 ConnectRequestHeaders("mail.example.org:443"),
8367 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438368 mock_quic_data.AddRead(
8369 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338370 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288371 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:568372
8373 const char get_request[] =
8374 "GET / HTTP/1.1\r\n"
8375 "Host: mail.example.org\r\n"
8376 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:528377 mock_quic_data.AddWrite(
8378 SYNCHRONOUS,
8379 ConstructClientAckAndDataPacket(
8380 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 2,
8381 2, false, ConstructDataFrame(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:568382 const char get_response[] =
8383 "HTTP/1.1 200 OK\r\n"
8384 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:438385 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338386 ASYNC, ConstructServerDataPacket(
8387 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:528388 ConstructDataFrame(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528389
Fan Yang32c5a112018-12-10 20:06:338390 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418391 SYNCHRONOUS, ConstructServerDataPacket(
8392 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:528393 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238394 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348395 ConstructClientAckPacket(packet_num++, 4, 3));
Yixin Wang46a273ec302018-01-23 17:59:568396 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8397
Bence Béky6e243aa2019-12-13 19:01:078398 if (VersionUsesHttp3(version_.transport_version)) {
8399 mock_quic_data.AddWrite(
8400 SYNCHRONOUS, ConstructClientDataPacket(
8401 packet_num++, GetQpackDecoderStreamId(), true, false,
Bence Békyf6bb6b22020-04-17 20:22:118402 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078403 }
Yixin Wang46a273ec302018-01-23 17:59:568404 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418405 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238406 ConstructClientRstPacket(packet_num++,
8407 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418408 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568409
8410 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8411
8412 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8413 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8414
8415 SSLSocketDataProvider ssl_data(ASYNC, OK);
8416 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8417
8418 CreateSession();
8419
8420 request_.url = GURL("https://mail.example.org/");
8421 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568422 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268423 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:568424 EXPECT_EQ(ERR_IO_PENDING, rv);
8425 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8426
8427 rv = trans.RestartIgnoringLastError(callback.callback());
8428 EXPECT_EQ(ERR_IO_PENDING, rv);
8429 EXPECT_EQ(OK, callback.WaitForResult());
8430
8431 CheckWasHttpResponse(&trans);
8432 CheckResponsePort(&trans, 70);
8433 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568434 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8435
8436 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8437 // proxy socket to disconnect.
8438 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8439
8440 base::RunLoop().RunUntilIdle();
8441 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8442 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8443}
8444
8445// Checks if a request's specified "user-agent" header shows up correctly in the
8446// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148447TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008448 const char kConfiguredUserAgent[] = "Configured User-Agent";
8449 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568450 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148451 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568452 proxy_resolution_service_ =
8453 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8454 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568455
Ryan Hamiltonabad59e2019-06-06 04:02:598456 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238457 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258458 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238459 mock_quic_data.AddWrite(SYNCHRONOUS,
8460 ConstructInitialSettingsPacket(packet_num++));
8461 }
Yixin Wang46a273ec302018-01-23 17:59:568462
Bence Béky4c325e52020-10-22 20:48:018463 spdy::Http2HeaderBlock headers =
8464 ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008465 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338466 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028467 SYNCHRONOUS,
8468 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238469 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498470 false,
8471 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578472 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498473 : HttpProxyConnectJob::kH2QuicTunnelPriority,
8474 std::move(headers), 0));
Yixin Wang46a273ec302018-01-23 17:59:568475 // Return an error, so the transaction stops here (this test isn't interested
8476 // in the rest).
8477 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8478
8479 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8480
Matt Menked732ea42019-03-08 12:05:008481 StaticHttpUserAgentSettings http_user_agent_settings(
8482 std::string() /* accept_language */, kConfiguredUserAgent);
8483 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568484 CreateSession();
8485
8486 request_.url = GURL("https://mail.example.org/");
8487 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008488 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568489 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568490 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268491 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:568492 EXPECT_EQ(ERR_IO_PENDING, rv);
8493 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8494
8495 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8496 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8497}
8498
Yixin Wang00fc44c2018-01-23 21:12:208499// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8500// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148501TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208502 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148503 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568504 proxy_resolution_service_ =
8505 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8506 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208507
8508 const RequestPriority request_priority = MEDIUM;
8509
Ryan Hamiltonabad59e2019-06-06 04:02:598510 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238511 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258512 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238513 mock_quic_data.AddWrite(SYNCHRONOUS,
8514 ConstructInitialSettingsPacket(packet_num++));
8515 }
Zhongyi Shi32f2fd02018-04-16 18:23:438516 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238517 SYNCHRONOUS,
8518 ConstructClientRequestHeadersPacket(
8519 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498520 false,
8521 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578522 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498523 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238524 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:208525 // Return an error, so the transaction stops here (this test isn't interested
8526 // in the rest).
8527 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8528
8529 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8530
8531 CreateSession();
8532
8533 request_.url = GURL("https://mail.example.org/");
8534 HttpNetworkTransaction trans(request_priority, session_.get());
8535 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268536 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang00fc44c2018-01-23 21:12:208537 EXPECT_EQ(ERR_IO_PENDING, rv);
8538 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8539
8540 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8541 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8542}
8543
Matt Menkeedaf3b82019-03-14 21:39:448544// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8545// HTTP/2 stream dependency and weights given the request priority.
8546TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8547 session_params_.enable_quic = true;
8548 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568549 proxy_resolution_service_ =
8550 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8551 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeedaf3b82019-03-14 21:39:448552
8553 const RequestPriority kRequestPriority = MEDIUM;
8554 const RequestPriority kRequestPriority2 = LOWEST;
8555
Ryan Hamiltonabad59e2019-06-06 04:02:598556 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:258557 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238558 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
8559 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8560 } else {
8561 mock_quic_data.AddWrite(
8562 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8563 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
8564 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8565 ConnectRequestHeaders("mail.example.org:443"), 0));
8566 }
Matt Menkeedaf3b82019-03-14 21:39:448567 // This should never be reached.
8568 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8569 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8570
8571 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:598572 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:448573 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8574 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8575
8576 int original_max_sockets_per_group =
8577 ClientSocketPoolManager::max_sockets_per_group(
8578 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8579 ClientSocketPoolManager::set_max_sockets_per_group(
8580 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8581 int original_max_sockets_per_pool =
8582 ClientSocketPoolManager::max_sockets_per_pool(
8583 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8584 ClientSocketPoolManager::set_max_sockets_per_pool(
8585 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8586 CreateSession();
8587
8588 request_.url = GURL("https://mail.example.org/");
8589 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8590 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268591 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeedaf3b82019-03-14 21:39:448592 EXPECT_EQ(ERR_IO_PENDING, rv);
8593
8594 HttpRequestInfo request2;
8595 request2.url = GURL("https://mail.example.org/some/other/path/");
8596 request2.traffic_annotation =
8597 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8598
8599 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8600 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:268601 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
Matt Menkeedaf3b82019-03-14 21:39:448602 EXPECT_EQ(ERR_IO_PENDING, rv2);
8603
8604 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8605 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8606
8607 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8608
8609 ClientSocketPoolManager::set_max_sockets_per_pool(
8610 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8611 original_max_sockets_per_pool);
8612 ClientSocketPoolManager::set_max_sockets_per_group(
8613 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8614 original_max_sockets_per_group);
8615}
8616
Yixin Wang46a273ec302018-01-23 17:59:568617// Test the request-challenge-retry sequence for basic auth, over a QUIC
8618// connection when setting up a QUIC proxy tunnel.
Bence Békyf6bb6b22020-04-17 20:22:118619TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Jan Wilken Dörriec92a6d7242021-03-23 17:43:488620 const std::u16string kBaz(u"baz");
8621 const std::u16string kFoo(u"foo");
Yixin Wang46a273ec302018-01-23 17:59:568622
Yixin Wang46a273ec302018-01-23 17:59:568623 // On the second pass, the body read of the auth challenge is synchronous, so
8624 // IsConnectedAndIdle returns false. The socket should still be drained and
8625 // reused. See http://crbug.com/544255.
8626 for (int i = 0; i < 2; ++i) {
Bence Béky6e243aa2019-12-13 19:01:078627 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:228628 version_,
8629 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8630 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky6e243aa2019-12-13 19:01:078631 client_headers_include_h2_stream_dependency_);
8632 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:228633 version_,
8634 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8635 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Bence Béky6e243aa2019-12-13 19:01:078636 false);
Yixin Wang46a273ec302018-01-23 17:59:568637
8638 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148639 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568640 proxy_resolution_service_ =
Nicolas Arciniegad2013f92020-02-07 23:00:568641 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498642 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568643
Ryan Hamiltonabad59e2019-06-06 04:02:598644 MockQuicData mock_quic_data(version_);
Yixin Wang46a273ec302018-01-23 17:59:568645
Renjie Tangaadb84b2019-08-31 01:00:238646 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258647 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238648 mock_quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:078649 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Renjie Tangaadb84b2019-08-31 01:00:238650 }
Yixin Wang46a273ec302018-01-23 17:59:568651
8652 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438653 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:078654 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238655 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8656 false,
Renjie Tangee921d12020-02-06 00:41:498657 VersionUsesHttp3(version_.transport_version)
Dan Zhangfc4c085b2020-11-10 16:33:168658 ? quic::QuicStream::kDefaultUrgency
Renjie Tangee921d12020-02-06 00:41:498659 : ConvertRequestPriorityToQuicPriority(
8660 HttpProxyConnectJob::kH2QuicTunnelPriority),
Bence Béky6e243aa2019-12-13 19:01:078661 client_maker.ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028662 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568663
Kenichi Ishibashif8634ab2021-03-16 23:41:288664 spdy::Http2HeaderBlock headers = server_maker.GetResponseHeaders("407");
Yixin Wang46a273ec302018-01-23 17:59:568665 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8666 headers["content-length"] = "10";
8667 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078668 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338669 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028670 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568671
8672 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438673 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078674 ASYNC, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338675 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178676 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568677 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438678 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078679 SYNCHRONOUS, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338680 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:178681 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568682 }
Yixin Wang46a273ec302018-01-23 17:59:568683
Bence Béky7a45d4d2020-05-08 01:59:238684 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348685 client_maker.MakeAckPacket(packet_num++, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:078686
8687 if (VersionUsesHttp3(version_.transport_version)) {
8688 mock_quic_data.AddWrite(
8689 SYNCHRONOUS,
8690 client_maker.MakeDataPacket(
8691 packet_num++, GetQpackDecoderStreamId(),
8692 /* should_include_version = */ true,
8693 /* fin = */ false, StreamCancellationQpackDecoderInstruction(0)));
8694 }
Yixin Wang46a273ec302018-01-23 17:59:568695
8696 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338697 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:078698 client_maker.MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:238699 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418700 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:188701 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568702
Bence Béky6e243aa2019-12-13 19:01:078703 headers = client_maker.ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:568704 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8705 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048706 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:078707 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238708 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8709 false,
Renjie Tangee921d12020-02-06 00:41:498710 VersionUsesHttp3(version_.transport_version)
Dan Zhangfc4c085b2020-11-10 16:33:168711 ? quic::QuicStream::kDefaultUrgency
Renjie Tangee921d12020-02-06 00:41:498712 : ConvertRequestPriorityToQuicPriority(
8713 HttpProxyConnectJob::kH2QuicTunnelPriority),
Matt Menke6e879bd2019-03-18 17:26:048714 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:028715 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568716
8717 // Response to wrong password
Kenichi Ishibashif8634ab2021-03-16 23:41:288718 headers = server_maker.GetResponseHeaders("407");
Yixin Wang46a273ec302018-01-23 17:59:568719 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8720 headers["content-length"] = "10";
8721 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078722 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338723 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028724 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568725 mock_quic_data.AddRead(SYNCHRONOUS,
8726 ERR_IO_PENDING); // No more data to read
8727
Bence Béky6e243aa2019-12-13 19:01:078728 if (VersionUsesHttp3(version_.transport_version)) {
8729 mock_quic_data.AddWrite(
8730 SYNCHRONOUS,
8731 client_maker.MakeAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:348732 packet_num++, false, GetQpackDecoderStreamId(), 3, 3, false,
Bence Békyf6bb6b22020-04-17 20:22:118733 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078734 mock_quic_data.AddWrite(SYNCHRONOUS,
8735 client_maker.MakeRstPacket(
8736 packet_num++, false,
8737 GetNthClientInitiatedBidirectionalStreamId(1),
8738 quic::QUIC_STREAM_CANCELLED));
8739 } else {
8740 mock_quic_data.AddWrite(SYNCHRONOUS,
8741 client_maker.MakeAckAndRstPacket(
8742 packet_num++, false,
8743 GetNthClientInitiatedBidirectionalStreamId(1),
Renjie Tangcd594f32020-07-11 20:18:348744 quic::QUIC_STREAM_CANCELLED, 3, 3));
Bence Béky6e243aa2019-12-13 19:01:078745 }
Yixin Wang46a273ec302018-01-23 17:59:568746
8747 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8748 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8749
8750 CreateSession();
8751
8752 request_.url = GURL("https://mail.example.org/");
8753 // Ensure that proxy authentication is attempted even
Matt Menke25eaa432020-08-25 00:10:008754 // when privacy mode is enabled.
8755 request_.privacy_mode = PRIVACY_MODE_ENABLED;
Yixin Wang46a273ec302018-01-23 17:59:568756 {
8757 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568758 RunTransaction(&trans);
8759
8760 const HttpResponseInfo* response = trans.GetResponseInfo();
8761 ASSERT_TRUE(response != nullptr);
8762 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:288763 EXPECT_EQ("HTTP/1.1 407", response->headers->GetStatusLine());
Yixin Wang46a273ec302018-01-23 17:59:568764 EXPECT_TRUE(response->headers->IsKeepAlive());
8765 EXPECT_EQ(407, response->headers->response_code());
8766 EXPECT_EQ(10, response->headers->GetContentLength());
8767 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Anton Bikineev068d2912021-05-15 20:43:528768 absl::optional<AuthChallengeInfo> auth_challenge =
Emily Starkf2c9bbd2019-04-09 17:08:588769 response->auth_challenge;
8770 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568771 EXPECT_TRUE(auth_challenge->is_proxy);
8772 EXPECT_EQ("https://proxy.example.org:70",
8773 auth_challenge->challenger.Serialize());
8774 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8775 EXPECT_EQ("basic", auth_challenge->scheme);
8776
8777 TestCompletionCallback callback;
8778 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8779 callback.callback());
8780 EXPECT_EQ(ERR_IO_PENDING, rv);
8781 EXPECT_EQ(OK, callback.WaitForResult());
8782
8783 response = trans.GetResponseInfo();
8784 ASSERT_TRUE(response != nullptr);
8785 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:288786 EXPECT_EQ("HTTP/1.1 407", response->headers->GetStatusLine());
Yixin Wang46a273ec302018-01-23 17:59:568787 EXPECT_TRUE(response->headers->IsKeepAlive());
8788 EXPECT_EQ(407, response->headers->response_code());
8789 EXPECT_EQ(10, response->headers->GetContentLength());
8790 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588791 auth_challenge = response->auth_challenge;
8792 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568793 EXPECT_TRUE(auth_challenge->is_proxy);
8794 EXPECT_EQ("https://proxy.example.org:70",
8795 auth_challenge->challenger.Serialize());
8796 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8797 EXPECT_EQ("basic", auth_challenge->scheme);
8798 }
8799 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8800 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8801 // reused because it's not connected).
8802 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8803 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8804 }
8805}
8806
Yixin Wang385652a2018-02-16 02:37:238807TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8808 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8809 // in HEADERS frames for requests and PRIORITY frames).
David Schinazi84c58bb2020-06-04 20:14:338810 if (!client_headers_include_h2_stream_dependency_) {
Yixin Wang385652a2018-02-16 02:37:238811 return;
8812 }
8813
Victor Vasiliev7da08172019-10-14 06:04:258814 if (quic::VersionUsesHttp3(version_.transport_version)) {
Renjie Tangba21e032019-09-27 21:52:288815 // HTTP/3 currently doesn't support PRIORITY.
Ryan Hamiltone940bd12019-06-30 02:46:458816 return;
8817 }
8818
Victor Vasilieva1e66d72019-12-05 17:55:388819 context_.params()->origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:238820 HostPortPair::FromString("mail.example.org:443"));
8821
Fan Yang32c5a112018-12-10 20:06:338822 const quic::QuicStreamId client_stream_0 =
8823 GetNthClientInitiatedBidirectionalStreamId(0);
8824 const quic::QuicStreamId client_stream_1 =
8825 GetNthClientInitiatedBidirectionalStreamId(1);
8826 const quic::QuicStreamId client_stream_2 =
8827 GetNthClientInitiatedBidirectionalStreamId(2);
8828 const quic::QuicStreamId push_stream_0 =
8829 GetNthServerInitiatedUnidirectionalStreamId(0);
8830 const quic::QuicStreamId push_stream_1 =
8831 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238832
Ryan Hamiltonabad59e2019-06-06 04:02:598833 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238834 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258835 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238836 mock_quic_data.AddWrite(SYNCHRONOUS,
8837 ConstructInitialSettingsPacket(packet_num++));
8838 }
Yixin Wang385652a2018-02-16 02:37:238839
8840 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:238841 mock_quic_data.AddWrite(
8842 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8843 packet_num++, client_stream_0, true, true, HIGHEST,
8844 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:028845 mock_quic_data.AddWrite(
8846 SYNCHRONOUS,
8847 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238848 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028849 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
8850 mock_quic_data.AddWrite(
8851 SYNCHRONOUS,
8852 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238853 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028854 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:238855
8856 // Server replies "OK" for the three requests.
Kenichi Ishibashif8634ab2021-03-16 23:41:288857 mock_quic_data.AddRead(
8858 ASYNC, ConstructServerResponseHeadersPacket(
8859 1, client_stream_0, false, false, GetResponseHeaders("200")));
8860 mock_quic_data.AddRead(
8861 ASYNC, ConstructServerResponseHeadersPacket(
8862 2, client_stream_1, false, false, GetResponseHeaders("200")));
Renjie Tangaadb84b2019-08-31 01:00:238863 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348864 ConstructClientAckPacket(packet_num++, 2, 1));
Kenichi Ishibashif8634ab2021-03-16 23:41:288865 mock_quic_data.AddRead(
8866 ASYNC, ConstructServerResponseHeadersPacket(
8867 3, client_stream_2, false, false, GetResponseHeaders("200")));
Yixin Wang385652a2018-02-16 02:37:238868
8869 // Server sends two push promises associated with |client_stream_0|; client
8870 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8871 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:028872 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:478873 ASYNC, ConstructServerPushPromisePacket(
8874 4, client_stream_0, push_stream_0, false,
8875 GetRequestHeaders("GET", "https", "/pushed_0.jpg")));
Yixin Wang385652a2018-02-16 02:37:238876 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438877 SYNCHRONOUS,
8878 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangcd594f32020-07-11 20:18:348879 packet_num++, false, 4, 3,
Zhongyi Shi32f2fd02018-04-16 18:23:438880 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:028881 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
8882 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:478883 ASYNC, ConstructServerPushPromisePacket(
8884 5, client_stream_0, push_stream_1, false,
8885 GetRequestHeaders("GET", "https", "/pushed_1.jpg")));
8886 mock_quic_data.AddWrite(SYNCHRONOUS,
8887 ConstructClientAckAndPriorityPacket(
8888 packet_num++, false,
8889 /*largest_received=*/5, /*smallest_received=*/4,
8890 push_stream_1, push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:238891
8892 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438893 mock_quic_data.AddRead(
8894 ASYNC, ConstructServerResponseHeadersPacket(
Kenichi Ishibashif8634ab2021-03-16 23:41:288895 6, push_stream_0, false, false, GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:438896 mock_quic_data.AddRead(
8897 ASYNC, ConstructServerResponseHeadersPacket(
Kenichi Ishibashif8634ab2021-03-16 23:41:288898 7, push_stream_1, false, false, GetResponseHeaders("200")));
Renjie Tangcd594f32020-07-11 20:18:348899 mock_quic_data.AddWrite(SYNCHRONOUS,
8900 ConstructClientAckPacket(packet_num++, 7, 5));
Yixin Wang385652a2018-02-16 02:37:238901
8902 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8903 // priority updates to match the request's priority. Client sends PRIORITY
8904 // frames to inform server of new HTTP/2 stream dependencies.
Bence Béky319388a882020-09-23 18:42:528905 mock_quic_data.AddWrite(
8906 SYNCHRONOUS,
8907 ConstructClientPriorityFramesPacket(
8908 packet_num++, false,
8909 {{push_stream_1, client_stream_2,
8910 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8911 {push_stream_0, client_stream_0,
8912 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:238913
8914 // Server sends data for the three requests and the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438915 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178916 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Bence Béky319388a882020-09-23 18:42:528917 ConstructDataFrame("hello 0!")));
Zhongyi Shi32f2fd02018-04-16 18:23:438918 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178919 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Bence Béky319388a882020-09-23 18:42:528920 ConstructDataFrame("hello 1!")));
Renjie Tangaadb84b2019-08-31 01:00:238921 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348922 ConstructClientAckPacket(packet_num++, 9, 8));
Zhongyi Shi32f2fd02018-04-16 18:23:438923 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178924 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Bence Béky319388a882020-09-23 18:42:528925 ConstructDataFrame("hello 2!")));
8926 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
8927 11, push_stream_0, false, true,
8928 ConstructDataFrame("and hello 0!")));
Renjie Tangaadb84b2019-08-31 01:00:238929 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348930 ConstructClientAckPacket(packet_num++, 11, 10));
Zhongyi Shi32f2fd02018-04-16 18:23:438931 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178932 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Bence Béky319388a882020-09-23 18:42:528933 ConstructDataFrame("and hello 1!")));
Yixin Wang385652a2018-02-16 02:37:238934
Yixin Wang385652a2018-02-16 02:37:238935 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:218936 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang385652a2018-02-16 02:37:238937 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8938
8939 // The non-alternate protocol job needs to hang in order to guarantee that
8940 // the alternate-protocol job will "win".
8941 AddHangingNonAlternateProtocolSocketData();
8942
8943 CreateSession();
8944
8945 request_.url = GURL("https://mail.example.org/0.jpg");
8946 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8947 TestCompletionCallback callback_0;
Matt Reichhoff0049a0b72021-10-20 20:44:268948 EXPECT_EQ(ERR_IO_PENDING, trans_0.Start(&request_, callback_0.callback(),
8949 net_log_with_source_));
Yixin Wang385652a2018-02-16 02:37:238950 base::RunLoop().RunUntilIdle();
8951
8952 request_.url = GURL("https://mail.example.org/1.jpg");
8953 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8954 TestCompletionCallback callback_1;
Matt Reichhoff0049a0b72021-10-20 20:44:268955 EXPECT_EQ(ERR_IO_PENDING, trans_1.Start(&request_, callback_1.callback(),
8956 net_log_with_source_));
Yixin Wang385652a2018-02-16 02:37:238957 base::RunLoop().RunUntilIdle();
8958
8959 request_.url = GURL("https://mail.example.org/2.jpg");
8960 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8961 TestCompletionCallback callback_2;
Matt Reichhoff0049a0b72021-10-20 20:44:268962 EXPECT_EQ(ERR_IO_PENDING, trans_2.Start(&request_, callback_2.callback(),
8963 net_log_with_source_));
Yixin Wang385652a2018-02-16 02:37:238964 base::RunLoop().RunUntilIdle();
8965
8966 // Client makes request that matches resource pushed in |pushed_stream_0|.
8967 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8968 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8969 TestCompletionCallback callback_3;
Matt Reichhoff0049a0b72021-10-20 20:44:268970 EXPECT_EQ(ERR_IO_PENDING, trans_3.Start(&request_, callback_3.callback(),
8971 net_log_with_source_));
Yixin Wang385652a2018-02-16 02:37:238972 base::RunLoop().RunUntilIdle();
8973
8974 EXPECT_TRUE(callback_0.have_result());
8975 EXPECT_EQ(OK, callback_0.WaitForResult());
8976 EXPECT_TRUE(callback_1.have_result());
8977 EXPECT_EQ(OK, callback_1.WaitForResult());
8978 EXPECT_TRUE(callback_2.have_result());
8979 EXPECT_EQ(OK, callback_2.WaitForResult());
8980
8981 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8982 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8983 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8984 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8985
8986 mock_quic_data.Resume();
8987 base::RunLoop().RunUntilIdle();
8988 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8989 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8990}
8991
Matt Menke26e41542019-06-05 01:09:518992// Test that NetworkIsolationKey is respected by QUIC connections, when
8993// kPartitionConnectionsByNetworkIsolationKey is enabled.
8994TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Matt Menke4807a9a2020-11-21 00:14:418995 const SchemefulSite kSite1(GURL("http://origin1/"));
8996 const SchemefulSite kSite2(GURL("http://origin2/"));
8997 NetworkIsolationKey network_isolation_key1(kSite1, kSite1);
8998 NetworkIsolationKey network_isolation_key2(kSite2, kSite2);
Matt Menke26e41542019-06-05 01:09:518999
Victor Vasilieva1e66d72019-12-05 17:55:389000 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519001 HostPortPair::FromString("mail.example.org:443"));
9002
9003 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
9004 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
9005 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
9006 // the same way as the HTTP over H2 proxy case.
9007 for (bool use_proxy : {false, true}) {
9008 SCOPED_TRACE(use_proxy);
9009
9010 if (use_proxy) {
9011 proxy_resolution_service_ =
Nicolas Arciniegad2013f92020-02-07 23:00:569012 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Matt Menke26e41542019-06-05 01:09:519013 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
9014 } else {
Nicolas Arciniegad2013f92020-02-07 23:00:569015 proxy_resolution_service_ =
9016 ConfiguredProxyResolutionService::CreateDirect();
Matt Menke26e41542019-06-05 01:09:519017 }
9018
9019 GURL url1;
9020 GURL url2;
9021 GURL url3;
9022 if (use_proxy) {
9023 url1 = GURL("http://mail.example.org/1");
9024 url2 = GURL("http://mail.example.org/2");
9025 url3 = GURL("http://mail.example.org/3");
9026 } else {
9027 url1 = GURL("https://mail.example.org/1");
9028 url2 = GURL("https://mail.example.org/2");
9029 url3 = GURL("https://mail.example.org/3");
9030 }
9031
9032 for (bool partition_connections : {false, true}) {
9033 SCOPED_TRACE(partition_connections);
9034
9035 base::test::ScopedFeatureList feature_list;
9036 if (partition_connections) {
9037 feature_list.InitAndEnableFeature(
9038 features::kPartitionConnectionsByNetworkIsolationKey);
9039 } else {
9040 feature_list.InitAndDisableFeature(
9041 features::kPartitionConnectionsByNetworkIsolationKey);
9042 }
9043
9044 // Reads and writes for the unpartitioned case, where only one socket is
9045 // used.
9046
Victor Vasilieva1e66d72019-12-05 17:55:389047 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519048 HostPortPair::FromString("mail.example.org:443"));
9049
Ryan Hamiltonabad59e2019-06-06 04:02:599050 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:519051 QuicTestPacketMaker client_maker1(
9052 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229053 quic::QuicUtils::CreateRandomConnectionId(
9054 context_.random_generator()),
9055 context_.clock(), kDefaultServerHostName,
9056 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519057 client_headers_include_h2_stream_dependency_);
9058 QuicTestPacketMaker server_maker1(
9059 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229060 quic::QuicUtils::CreateRandomConnectionId(
9061 context_.random_generator()),
9062 context_.clock(), kDefaultServerHostName,
9063 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519064
Renjie Tangaadb84b2019-08-31 01:00:239065 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259066 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239067 unpartitioned_mock_quic_data.AddWrite(
9068 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
9069 }
Matt Menke26e41542019-06-05 01:09:519070
9071 unpartitioned_mock_quic_data.AddWrite(
9072 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029073 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239074 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9075 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029076 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519077 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029078 ASYNC, server_maker1.MakeResponseHeadersPacket(
9079 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289080 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519081 unpartitioned_mock_quic_data.AddRead(
9082 ASYNC, server_maker1.MakeDataPacket(
9083 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529084 true, ConstructDataFrame("1")));
Matt Menke26e41542019-06-05 01:09:519085 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349086 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menke26e41542019-06-05 01:09:519087
9088 unpartitioned_mock_quic_data.AddWrite(
9089 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029090 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239091 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
9092 false, true,
Matt Menke26e41542019-06-05 01:09:519093 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029094 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519095 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029096 ASYNC, server_maker1.MakeResponseHeadersPacket(
9097 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289098 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519099 unpartitioned_mock_quic_data.AddRead(
9100 ASYNC, server_maker1.MakeDataPacket(
9101 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:529102 true, ConstructDataFrame("2")));
Matt Menke26e41542019-06-05 01:09:519103 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangb7afea82020-07-15 23:35:479104 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3));
Matt Menke26e41542019-06-05 01:09:519105
9106 unpartitioned_mock_quic_data.AddWrite(
9107 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029108 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239109 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
9110 false, true,
Matt Menke26e41542019-06-05 01:09:519111 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029112 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519113 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029114 ASYNC, server_maker1.MakeResponseHeadersPacket(
9115 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289116 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519117 unpartitioned_mock_quic_data.AddRead(
9118 ASYNC, server_maker1.MakeDataPacket(
9119 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Bence Béky319388a882020-09-23 18:42:529120 true, ConstructDataFrame("3")));
Matt Menke26e41542019-06-05 01:09:519121 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangb7afea82020-07-15 23:35:479122 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 6, 5));
Matt Menke26e41542019-06-05 01:09:519123
9124 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9125
9126 // Reads and writes for the partitioned case, where two sockets are used.
9127
Ryan Hamiltonabad59e2019-06-06 04:02:599128 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:519129 QuicTestPacketMaker client_maker2(
9130 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229131 quic::QuicUtils::CreateRandomConnectionId(
9132 context_.random_generator()),
9133 context_.clock(), kDefaultServerHostName,
9134 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519135 client_headers_include_h2_stream_dependency_);
9136 QuicTestPacketMaker server_maker2(
9137 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229138 quic::QuicUtils::CreateRandomConnectionId(
9139 context_.random_generator()),
9140 context_.clock(), kDefaultServerHostName,
9141 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519142
Renjie Tangaadb84b2019-08-31 01:00:239143 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259144 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239145 partitioned_mock_quic_data1.AddWrite(
9146 SYNCHRONOUS,
9147 client_maker2.MakeInitialSettingsPacket(packet_num2++));
9148 }
Matt Menke26e41542019-06-05 01:09:519149
9150 partitioned_mock_quic_data1.AddWrite(
9151 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029152 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239153 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
9154 true, true,
Matt Menke26e41542019-06-05 01:09:519155 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029156 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519157 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029158 ASYNC, server_maker2.MakeResponseHeadersPacket(
9159 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289160 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519161 partitioned_mock_quic_data1.AddRead(
9162 ASYNC, server_maker2.MakeDataPacket(
9163 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529164 true, ConstructDataFrame("1")));
Matt Menke26e41542019-06-05 01:09:519165 partitioned_mock_quic_data1.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349166 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 2, 1));
Matt Menke26e41542019-06-05 01:09:519167
9168 partitioned_mock_quic_data1.AddWrite(
9169 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029170 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239171 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
9172 false, true,
Matt Menke26e41542019-06-05 01:09:519173 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029174 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519175 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029176 ASYNC, server_maker2.MakeResponseHeadersPacket(
9177 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289178 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519179 partitioned_mock_quic_data1.AddRead(
9180 ASYNC, server_maker2.MakeDataPacket(
9181 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:529182 true, ConstructDataFrame("3")));
Matt Menke26e41542019-06-05 01:09:519183 partitioned_mock_quic_data1.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349184 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 4, 3));
Matt Menke26e41542019-06-05 01:09:519185
9186 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9187
Ryan Hamiltonabad59e2019-06-06 04:02:599188 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:519189 QuicTestPacketMaker client_maker3(
9190 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229191 quic::QuicUtils::CreateRandomConnectionId(
9192 context_.random_generator()),
9193 context_.clock(), kDefaultServerHostName,
9194 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519195 client_headers_include_h2_stream_dependency_);
9196 QuicTestPacketMaker server_maker3(
9197 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229198 quic::QuicUtils::CreateRandomConnectionId(
9199 context_.random_generator()),
9200 context_.clock(), kDefaultServerHostName,
9201 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519202
Renjie Tangaadb84b2019-08-31 01:00:239203 int packet_num3 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259204 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239205 partitioned_mock_quic_data2.AddWrite(
9206 SYNCHRONOUS,
9207 client_maker3.MakeInitialSettingsPacket(packet_num3++));
9208 }
Matt Menke26e41542019-06-05 01:09:519209
9210 partitioned_mock_quic_data2.AddWrite(
9211 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029212 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239213 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9214 true, true,
Matt Menke26e41542019-06-05 01:09:519215 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029216 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519217 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029218 ASYNC, server_maker3.MakeResponseHeadersPacket(
9219 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289220 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519221 partitioned_mock_quic_data2.AddRead(
9222 ASYNC, server_maker3.MakeDataPacket(
9223 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529224 true, ConstructDataFrame("2")));
Matt Menke26e41542019-06-05 01:09:519225 partitioned_mock_quic_data2.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349226 SYNCHRONOUS, client_maker3.MakeAckPacket(packet_num3++, 2, 1));
Matt Menke26e41542019-06-05 01:09:519227
9228 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9229
9230 if (partition_connections) {
9231 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9232 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9233 } else {
9234 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9235 }
9236
9237 CreateSession();
9238
9239 TestCompletionCallback callback;
9240 HttpRequestInfo request1;
9241 request1.method = "GET";
9242 request1.url = GURL(url1);
9243 request1.traffic_annotation =
9244 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9245 request1.network_isolation_key = network_isolation_key1;
9246 HttpNetworkTransaction trans1(LOWEST, session_.get());
9247 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9248 EXPECT_THAT(callback.GetResult(rv), IsOk());
9249 std::string response_data1;
9250 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9251 EXPECT_EQ("1", response_data1);
9252
9253 HttpRequestInfo request2;
9254 request2.method = "GET";
9255 request2.url = GURL(url2);
9256 request2.traffic_annotation =
9257 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9258 request2.network_isolation_key = network_isolation_key2;
9259 HttpNetworkTransaction trans2(LOWEST, session_.get());
9260 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9261 EXPECT_THAT(callback.GetResult(rv), IsOk());
9262 std::string response_data2;
9263 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9264 EXPECT_EQ("2", response_data2);
9265
9266 HttpRequestInfo request3;
9267 request3.method = "GET";
9268 request3.url = GURL(url3);
9269 request3.traffic_annotation =
9270 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9271 request3.network_isolation_key = network_isolation_key1;
9272 HttpNetworkTransaction trans3(LOWEST, session_.get());
9273 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9274 EXPECT_THAT(callback.GetResult(rv), IsOk());
9275 std::string response_data3;
9276 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9277 EXPECT_EQ("3", response_data3);
9278
9279 if (partition_connections) {
9280 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9281 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9282 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9283 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9284 } else {
9285 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9286 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9287 }
9288 }
9289 }
9290}
9291
9292// Test that two requests to the same origin over QUIC tunnels use different
9293// QUIC sessions if their NetworkIsolationKeys don't match, and
9294// kPartitionConnectionsByNetworkIsolationKey is enabled.
9295TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9296 base::test::ScopedFeatureList feature_list;
9297 feature_list.InitAndEnableFeature(
9298 features::kPartitionConnectionsByNetworkIsolationKey);
9299
9300 session_params_.enable_quic = true;
9301 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:569302 proxy_resolution_service_ =
9303 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
9304 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menke26e41542019-06-05 01:09:519305
9306 const char kGetRequest[] =
9307 "GET / HTTP/1.1\r\n"
9308 "Host: mail.example.org\r\n"
9309 "Connection: keep-alive\r\n\r\n";
9310 const char kGetResponse[] =
9311 "HTTP/1.1 200 OK\r\n"
9312 "Content-Length: 10\r\n\r\n";
9313
Ryan Hamiltonabad59e2019-06-06 04:02:599314 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9315 std::make_unique<MockQuicData>(version_),
9316 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519317
9318 for (int index : {0, 1}) {
9319 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229320 version_,
9321 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9322 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519323 client_headers_include_h2_stream_dependency_);
9324 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229325 version_,
9326 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9327 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9328 false);
Matt Menke26e41542019-06-05 01:09:519329
Renjie Tangaadb84b2019-08-31 01:00:239330 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259331 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239332 mock_quic_data[index]->AddWrite(
9333 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
9334 }
Matt Menke26e41542019-06-05 01:09:519335
Ryan Hamiltonabad59e2019-06-06 04:02:599336 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519337 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029338 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239339 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9340 false,
Renjie Tangee921d12020-02-06 00:41:499341 VersionUsesHttp3(version_.transport_version)
Dan Zhangfc4c085b2020-11-10 16:33:169342 ? quic::QuicStream::kDefaultUrgency
Renjie Tangee921d12020-02-06 00:41:499343 : ConvertRequestPriorityToQuicPriority(
9344 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:029345 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:599346 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029347 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:519348 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289349 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519350
Bence Béky319388a882020-09-23 18:42:529351 mock_quic_data[index]->AddWrite(
9352 SYNCHRONOUS,
9353 client_maker.MakeAckAndDataPacket(
9354 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
9355 1, 1, false, ConstructDataFrame(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:519356
Ryan Hamiltonabad59e2019-06-06 04:02:599357 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519358 ASYNC, server_maker.MakeDataPacket(
9359 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529360 false, ConstructDataFrame(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599361 mock_quic_data[index]->AddRead(
Bence Béky319388a882020-09-23 18:42:529362 SYNCHRONOUS, server_maker.MakeDataPacket(
9363 3, GetNthClientInitiatedBidirectionalStreamId(0),
9364 false, false, ConstructDataFrame("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599365 mock_quic_data[index]->AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349366 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2));
Ryan Hamiltonabad59e2019-06-06 04:02:599367 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9368 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:519369
Ryan Hamiltonabad59e2019-06-06 04:02:599370 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:519371 }
9372
9373 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9374 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9375 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9376
9377 CreateSession();
9378
9379 request_.url = GURL("https://mail.example.org/");
9380 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9381 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9382 RunTransaction(&trans);
9383 CheckResponseData(&trans, "0123456789");
9384
9385 HttpRequestInfo request2;
Matt Menke4807a9a2020-11-21 00:14:419386 const SchemefulSite kSite1(GURL("http://origin1/"));
9387 request_.network_isolation_key = NetworkIsolationKey(kSite1, kSite1);
Matt Menke26e41542019-06-05 01:09:519388 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9389 RunTransaction(&trans2);
9390 CheckResponseData(&trans2, "0123456789");
9391
Ryan Hamiltonabad59e2019-06-06 04:02:599392 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9393 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9394 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9395 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:519396}
9397
Yoichi Osato4c75c0c2020-06-24 08:03:579398TEST_P(QuicNetworkTransactionTest, AllowHTTP1FalseProhibitsH1) {
9399 MockRead http_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING),
9400 MockRead(ASYNC, OK)};
9401 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
9402 socket_factory_.AddSocketDataProvider(&http_data);
9403 AddCertificate(&ssl_data_);
9404 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9405
9406 CreateSession();
9407
9408 request_.method = "POST";
9409 UploadDataStreamNotAllowHTTP1 upload_data("");
9410 request_.upload_data_stream = &upload_data;
9411
9412 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9413 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:269414 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:579415 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9416 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_H2_OR_QUIC_REQUIRED));
9417}
9418
9419// Confirm mock class UploadDataStreamNotAllowHTTP1 can upload content over
9420// QUIC.
9421TEST_P(QuicNetworkTransactionTest, AllowHTTP1MockTest) {
9422 context_.params()->origins_to_force_quic_on.insert(
9423 HostPortPair::FromString("mail.example.org:443"));
9424
9425 MockQuicData mock_quic_data(version_);
9426 int write_packet_index = 1;
9427 if (VersionUsesHttp3(version_.transport_version)) {
9428 mock_quic_data.AddWrite(
9429 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9430 }
9431 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:529432 mock_quic_data.AddWrite(
9433 SYNCHRONOUS,
9434 ConstructClientRequestHeadersAndDataFramesPacket(
9435 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9436 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9437 0, nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:579438 mock_quic_data.AddRead(
9439 ASYNC, ConstructServerResponseHeadersPacket(
9440 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289441 GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:579442
Yoichi Osato4c75c0c2020-06-24 08:03:579443 mock_quic_data.AddRead(
9444 ASYNC, ConstructServerDataPacket(
9445 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:529446 ConstructDataFrame("hello!")));
Yoichi Osato4c75c0c2020-06-24 08:03:579447
Renjie Tangcd594f32020-07-11 20:18:349448 mock_quic_data.AddWrite(SYNCHRONOUS,
9449 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:579450
9451 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:219452 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:579453 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9454
9455 // The non-alternate protocol job needs to hang in order to guarantee that
9456 // the alternate-protocol job will "win".
9457 AddHangingNonAlternateProtocolSocketData();
9458
9459 CreateSession();
9460 request_.method = "POST";
9461 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9462 request_.upload_data_stream = &upload_data;
9463
9464 SendRequestAndExpectQuicResponse("hello!");
9465}
9466
9467TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadPauseAndResume) {
9468 context_.params()->origins_to_force_quic_on.insert(
9469 HostPortPair::FromString("mail.example.org:443"));
9470
9471 MockQuicData mock_quic_data(version_);
9472 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
9473 int write_packet_index = 1;
9474 mock_quic_data.AddWrite(
9475 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
9476 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
9477 if (VersionUsesHttp3(version_.transport_version)) {
9478 mock_quic_data.AddWrite(
9479 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9480 }
9481 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:529482 mock_quic_data.AddWrite(
9483 SYNCHRONOUS,
9484 ConstructClientRequestHeadersAndDataFramesPacket(
9485 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9486 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9487 0, nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:579488 mock_quic_data.AddRead(
9489 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
9490 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289491 false, GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:579492 mock_quic_data.AddRead(
9493 SYNCHRONOUS, ConstructServerDataPacket(
9494 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529495 true, ConstructDataFrame("hello!")));
Yoichi Osato4c75c0c2020-06-24 08:03:579496
Renjie Tangcd594f32020-07-11 20:18:349497 mock_quic_data.AddWrite(SYNCHRONOUS,
9498 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:579499 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:219500 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:579501 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9502 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
9503
9504 CreateSession();
9505
9506 AddQuicAlternateProtocolMapping(
9507 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
9508
9509 // Set up request.
9510 request_.method = "POST";
9511 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9512 request_.upload_data_stream = &upload_data;
9513
9514 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9515 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:269516 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:579517 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9518 base::RunLoop().RunUntilIdle();
9519 // Resume QUIC job
9520 crypto_client_stream_factory_.last_stream()
9521 ->NotifySessionOneRttKeyAvailable();
9522 socket_data->Resume();
9523
9524 base::RunLoop().RunUntilIdle();
9525 CheckResponseData(&trans, "hello!");
9526}
9527
9528TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadFailH1AndResumeQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:359529 if (version_.AlpnDeferToRFCv1()) {
9530 // These versions currently do not support Alt-Svc.
9531 return;
9532 }
Yoichi Osato4c75c0c2020-06-24 08:03:579533 // This test confirms failed main job should not bother quic job.
9534 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:459535 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yoichi Osato4c75c0c2020-06-24 08:03:579536 MockRead("1.1 Body"),
9537 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9538 MockRead(ASYNC, OK)};
9539 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
9540 socket_factory_.AddSocketDataProvider(&http_data);
9541 AddCertificate(&ssl_data_);
9542 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9543
9544 MockQuicData mock_quic_data(version_);
9545 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
9546 int write_packet_index = 1;
9547 mock_quic_data.AddWrite(
9548 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
9549 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
9550 if (VersionUsesHttp3(version_.transport_version)) {
9551 mock_quic_data.AddWrite(
9552 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9553 }
9554 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:529555 mock_quic_data.AddWrite(
9556 SYNCHRONOUS,
9557 ConstructClientRequestHeadersAndDataFramesPacket(
9558 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9559 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9560 0, nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:579561 mock_quic_data.AddRead(
9562 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
9563 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289564 false, GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:579565 mock_quic_data.AddRead(
9566 SYNCHRONOUS, ConstructServerDataPacket(
9567 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529568 true, ConstructDataFrame("hello!")));
Renjie Tangcd594f32020-07-11 20:18:349569 mock_quic_data.AddWrite(SYNCHRONOUS,
9570 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:579571 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:219572 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:579573 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9574 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
9575
9576 // This packet won't be read because AllowHTTP1:false doesn't allow H/1
9577 // connection.
9578 MockRead http_reads2[] = {MockRead("HTTP/1.1 200 OK\r\n")};
9579 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
9580 socket_factory_.AddSocketDataProvider(&http_data2);
9581 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9582
9583 CreateSession();
9584
9585 // Send the first request via TCP and set up alternative service (QUIC) for
9586 // the origin.
9587 SendRequestAndExpectHttpResponse("1.1 Body");
9588
9589 // Settings to resume main H/1 job quickly while pausing quic job.
9590 AddQuicAlternateProtocolMapping(
9591 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
9592 ServerNetworkStats stats1;
Peter Kastinge5a38ed2021-10-02 03:06:359593 stats1.srtt = base::Microseconds(10);
Yoichi Osato4c75c0c2020-06-24 08:03:579594 http_server_properties_->SetServerNetworkStats(
9595 url::SchemeHostPort(request_.url), NetworkIsolationKey(), stats1);
9596
9597 // Set up request.
9598 request_.method = "POST";
9599 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9600 request_.upload_data_stream = &upload_data;
9601
9602 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9603 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:269604 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:579605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9606 // Confirm TCP job was resumed.
9607 // We can not check its failure because HttpStreamFactory::JobController.
9608 // main_job_net_error is not exposed.
9609 while (socket_factory_.mock_data().next_index() < 3u)
9610 base::RunLoop().RunUntilIdle();
9611 // Resume QUIC job.
9612 crypto_client_stream_factory_.last_stream()
9613 ->NotifySessionOneRttKeyAvailable();
9614 socket_data->Resume();
9615 base::RunLoop().RunUntilIdle();
9616 CheckResponseData(&trans, "hello!");
9617}
9618
Bence Békyc164e0d22020-09-22 20:08:599619TEST_P(QuicNetworkTransactionTest, IncorrectHttp3GoAway) {
9620 if (!version_.HasIetfQuicFrames()) {
9621 return;
9622 }
9623
9624 context_.params()->retry_without_alt_svc_on_quic_errors = false;
9625
9626 MockQuicData mock_quic_data(version_);
9627 int write_packet_number = 1;
9628 mock_quic_data.AddWrite(
9629 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number++));
9630 mock_quic_data.AddWrite(
9631 SYNCHRONOUS,
9632 ConstructClientRequestHeadersPacket(
9633 write_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
9634 true, true, GetRequestHeaders("GET", "https", "/")));
9635
9636 int read_packet_number = 1;
9637 mock_quic_data.AddRead(
9638 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number++));
9639 // The GOAWAY frame sent by the server MUST have a stream ID corresponding to
9640 // a client-initiated bidirectional stream. Any other kind of stream ID
9641 // should cause the client to close the connection.
9642 quic::GoAwayFrame goaway{3};
9643 std::unique_ptr<char[]> goaway_buffer;
9644 auto goaway_length =
9645 quic::HttpEncoder::SerializeGoAwayFrame(goaway, &goaway_buffer);
9646 const quic::QuicStreamId control_stream_id =
9647 quic::QuicUtils::GetFirstUnidirectionalStreamId(
9648 version_.transport_version, quic::Perspective::IS_SERVER);
9649 mock_quic_data.AddRead(
Victor Vasiliev47ecb6a2020-10-14 17:22:109650 ASYNC, ConstructServerDataPacket(
9651 read_packet_number++, control_stream_id, false, false,
9652 absl::string_view(goaway_buffer.get(), goaway_length)));
Bence Békyc164e0d22020-09-22 20:08:599653 mock_quic_data.AddWrite(
9654 SYNCHRONOUS,
9655 ConstructClientAckAndConnectionClosePacket(
9656 write_packet_number++, 2, 4, quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
9657 "GOAWAY with invalid stream ID", 0));
9658 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9659
9660 // In order for a new QUIC session to be established via alternate-protocol
9661 // without racing an HTTP connection, we need the host resolution to happen
9662 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
9663 // connection to the the server, in this test we require confirmation
9664 // before encrypting so the HTTP job will still start.
9665 host_resolver_.set_synchronous_mode(true);
9666 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
9667 "");
9668
9669 CreateSession();
9670 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9671
9672 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9673 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:269674 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Bence Békyc164e0d22020-09-22 20:08:599675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9676
9677 crypto_client_stream_factory_.last_stream()
9678 ->NotifySessionOneRttKeyAvailable();
9679 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
9680
9681 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9682 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9683
9684 NetErrorDetails details;
9685 trans.PopulateNetErrorDetails(&details);
9686 EXPECT_THAT(details.quic_connection_error,
9687 quic::test::IsError(quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID));
9688}
9689
Bence Béky2ee18922020-09-25 12:11:329690TEST_P(QuicNetworkTransactionTest, RetryOnHttp3GoAway) {
9691 if (!version_.HasIetfQuicFrames()) {
9692 return;
9693 }
9694
9695 MockQuicData mock_quic_data1(version_);
9696 int write_packet_number1 = 1;
9697 mock_quic_data1.AddWrite(
9698 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number1++));
9699 const quic::QuicStreamId stream_id1 =
9700 GetNthClientInitiatedBidirectionalStreamId(0);
9701 mock_quic_data1.AddWrite(SYNCHRONOUS,
9702 ConstructClientRequestHeadersPacket(
9703 write_packet_number1++, stream_id1, true, true,
9704 GetRequestHeaders("GET", "https", "/")));
9705 const quic::QuicStreamId stream_id2 =
9706 GetNthClientInitiatedBidirectionalStreamId(1);
9707 mock_quic_data1.AddWrite(SYNCHRONOUS,
9708 ConstructClientRequestHeadersPacket(
9709 write_packet_number1++, stream_id2, true, true,
9710 GetRequestHeaders("GET", "https", "/foo")));
9711
9712 int read_packet_number1 = 1;
9713 mock_quic_data1.AddRead(
9714 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number1++));
9715
9716 // GOAWAY with stream_id2 informs the client that stream_id2 (and streams with
9717 // larger IDs) have not been processed and can safely be retried.
9718 quic::GoAwayFrame goaway{stream_id2};
9719 std::unique_ptr<char[]> goaway_buffer;
9720 auto goaway_length =
9721 quic::HttpEncoder::SerializeGoAwayFrame(goaway, &goaway_buffer);
9722 const quic::QuicStreamId control_stream_id =
9723 quic::QuicUtils::GetFirstUnidirectionalStreamId(
9724 version_.transport_version, quic::Perspective::IS_SERVER);
9725 mock_quic_data1.AddRead(
Victor Vasiliev47ecb6a2020-10-14 17:22:109726 ASYNC, ConstructServerDataPacket(
9727 read_packet_number1++, control_stream_id, false, false,
9728 absl::string_view(goaway_buffer.get(), goaway_length)));
Bence Béky2ee18922020-09-25 12:11:329729 mock_quic_data1.AddWrite(
9730 ASYNC, ConstructClientAckPacket(write_packet_number1++, 2, 1));
9731
9732 // Response to first request is accepted after GOAWAY.
9733 mock_quic_data1.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9734 read_packet_number1++, stream_id1, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289735 false, GetResponseHeaders("200")));
Bence Béky2ee18922020-09-25 12:11:329736 mock_quic_data1.AddRead(
9737 ASYNC, ConstructServerDataPacket(
9738 read_packet_number1++, stream_id1, false, true,
9739 ConstructDataFrame("response on the first connection")));
9740 mock_quic_data1.AddWrite(
9741 ASYNC, ConstructClientAckPacket(write_packet_number1++, 4, 1));
Bence Békye7426ec2021-02-02 18:18:199742 // Make socket hang to make sure connection stays in connection pool.
9743 // This should not prevent the retry from opening a new connection.
9744 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING);
David Schinazi395918c2021-02-05 18:56:219745 mock_quic_data1.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Bence Béky2ee18922020-09-25 12:11:329746 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9747
9748 // Second request is retried on a new connection.
9749 MockQuicData mock_quic_data2(version_);
9750 QuicTestPacketMaker client_maker2(
9751 version_,
9752 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9753 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9754 client_headers_include_h2_stream_dependency_);
9755 int write_packet_number2 = 1;
9756 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(
9757 write_packet_number2++));
9758 spdy::SpdyPriority priority =
9759 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
9760 mock_quic_data2.AddWrite(
9761 SYNCHRONOUS, client_maker2.MakeRequestHeadersPacket(
9762 write_packet_number2++, stream_id1, true, true, priority,
9763 GetRequestHeaders("GET", "https", "/foo"), 0, nullptr));
9764
9765 QuicTestPacketMaker server_maker2(
9766 version_,
9767 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9768 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9769 false);
9770 int read_packet_number2 = 1;
9771 mock_quic_data2.AddRead(ASYNC,
9772 server_maker2.MakeResponseHeadersPacket(
9773 read_packet_number2++, stream_id1, false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289774 GetResponseHeaders("200"), nullptr));
Bence Béky2ee18922020-09-25 12:11:329775 mock_quic_data2.AddRead(
9776 ASYNC, server_maker2.MakeDataPacket(
9777 read_packet_number2++, stream_id1, false, true,
9778 ConstructDataFrame("response on the second connection")));
9779 mock_quic_data2.AddWrite(
9780 ASYNC, client_maker2.MakeAckPacket(write_packet_number2++, 2, 1));
9781 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9782 mock_quic_data2.AddRead(ASYNC, 0); // EOF
9783 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9784
9785 AddHangingNonAlternateProtocolSocketData();
9786 CreateSession();
9787 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9788
9789 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
9790 TestCompletionCallback callback1;
Matt Reichhoff0049a0b72021-10-20 20:44:269791 int rv = trans1.Start(&request_, callback1.callback(), net_log_with_source_);
Bence Béky2ee18922020-09-25 12:11:329792 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9793 base::RunLoop().RunUntilIdle();
9794
9795 HttpRequestInfo request2;
9796 request2.method = "GET";
9797 std::string url("https://");
9798 url.append(kDefaultServerHostName);
9799 url.append("/foo");
9800 request2.url = GURL(url);
9801 request2.load_flags = 0;
9802 request2.traffic_annotation =
9803 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9804 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9805 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:269806 rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
Bence Béky2ee18922020-09-25 12:11:329807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9808
9809 EXPECT_THAT(callback1.WaitForResult(), IsOk());
9810 CheckResponseData(&trans1, "response on the first connection");
9811
9812 EXPECT_THAT(callback2.WaitForResult(), IsOk());
9813 CheckResponseData(&trans2, "response on the second connection");
9814
Bence Békye7426ec2021-02-02 18:18:199815 mock_quic_data1.Resume();
Bence Béky2ee18922020-09-25 12:11:329816 mock_quic_data2.Resume();
9817 EXPECT_TRUE(mock_quic_data1.AllWriteDataConsumed());
9818 EXPECT_TRUE(mock_quic_data1.AllReadDataConsumed());
9819 EXPECT_TRUE(mock_quic_data2.AllWriteDataConsumed());
9820 EXPECT_TRUE(mock_quic_data2.AllReadDataConsumed());
9821}
9822
Yoichi Osato4c75c0c2020-06-24 08:03:579823// TODO(yoichio): Add the TCP job reuse case. See crrev.com/c/2174099.
9824
[email protected]61a527782013-02-21 03:58:009825} // namespace test
9826} // namespace net