blob: 61ea4c5680f06c18e7831e4d3671d26da155840a [file] [log] [blame]
Avi Drissman64595482022-09-14 20:52:291// Copyright 2012 The Chromium Authors
[email protected]61a527782013-02-21 03:58:002// 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
[email protected]61a527782013-02-21 03:58:0011#include "base/compiler_specific.h"
Avi Drissman41c4a412023-01-11 22:45:3712#include "base/functional/bind.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"
Brianna Goldsteind22b0642022-10-11 16:30:5026#include "net/base/network_anonymization_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"
Patrick Meenan885a00652023-02-15 20:07:0255#include "net/quic/quic_context.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0856#include "net/quic/quic_http_stream.h"
57#include "net/quic/quic_http_utils.h"
58#include "net/quic/quic_stream_factory_peer.h"
59#include "net/quic/quic_test_packet_maker.h"
60#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0061#include "net/socket/client_socket_factory.h"
62#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2163#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2864#include "net/socket/socket_performance_watcher.h"
65#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0066#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5867#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5768#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2969#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0170#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4371#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4072#include "net/test/test_with_task_environment.h"
Ryan Hamiltonea4fa192022-04-12 18:30:4973#include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_decrypter.h"
74#include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_encrypter.h"
75#include "net/third_party/quiche/src/quiche/quic/core/quic_framer.h"
76#include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
77#include "net/third_party/quiche/src/quiche/quic/platform/api/quic_test.h"
78#include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
79#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_clock.h"
80#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
81#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_session_peer.h"
82#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
83#include "net/third_party/quiche/src/quiche/spdy/core/spdy_frame_builder.h"
84#include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2985#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0086#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4887#include "net/url_request/url_request.h"
Matt Menkea9606a0eb2020-09-11 20:36:3888#include "net/url_request/url_request_job_factory.h"
allada71b2efb2016-09-09 04:57:4889#include "net/url_request/url_request_test_util.h"
Momoka Yamamotoff688972022-11-02 03:37:4690#include "net/websockets/websocket_test_util.h"
robpercival214763f2016-07-01 23:27:0191#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0092#include "testing/gtest/include/gtest/gtest.h"
93#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4694#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0095
Reilly Grant89a7e512018-01-20 01:57:1696using ::testing::ElementsAre;
97using ::testing::Key;
98
Tsuyoshi Horo4f516be2022-06-14 11:53:1399namespace net::test {
[email protected]61a527782013-02-21 03:58:00100
101namespace {
102
bnc359ed2a2016-04-29 20:43:45103enum DestinationType {
104 // In pooling tests with two requests for different origins to the same
105 // destination, the destination should be
106 SAME_AS_FIRST, // the same as the first origin,
107 SAME_AS_SECOND, // the same as the second origin, or
108 DIFFERENT, // different from both.
109};
110
rch9ae5b3b2016-02-11 00:36:29111const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45112const char kDifferentHostname[] = "different.example.com";
113
David Schinazi09e9a6012019-10-03 17:37:57114struct TestParams {
115 quic::ParsedQuicVersion version;
Patrick Meenanf741c6082023-01-03 18:06:43116 bool enable_quic_priority_incremental_support;
David Schinazi09e9a6012019-10-03 17:37:57117};
118
119// Used by ::testing::PrintToStringParamName().
120std::string PrintToString(const TestParams& p) {
Bence Béky957bab12023-01-31 16:40:10121 return base::StrCat({ParsedQuicVersionToString(p.version), "_",
122 (p.enable_quic_priority_incremental_support ? "" : "No"),
123 "Incremental"});
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;
131};
132
David Schinazi09e9a6012019-10-03 17:37:57133// Used by ::testing::PrintToStringParamName().
134std::string PrintToString(const PoolingTestParams& p) {
135 const char* destination_string = "";
136 switch (p.destination_type) {
137 case SAME_AS_FIRST:
138 destination_string = "SAME_AS_FIRST";
139 break;
140 case SAME_AS_SECOND:
141 destination_string = "SAME_AS_SECOND";
142 break;
143 case DIFFERENT:
144 destination_string = "DIFFERENT";
145 break;
146 }
Victor Vasiliev62c09dc2020-11-06 18:18:29147 return base::StrCat(
Bence Béky957bab12023-01-31 16:40:10148 {ParsedQuicVersionToString(p.version), "_", destination_string});
David Schinazi09e9a6012019-10-03 17:37:57149}
150
Ryan Hamiltona2dcbae2022-02-09 19:02:45151std::string GenerateQuicAltSvcHeaderValue(
152 const quic::ParsedQuicVersionVector& versions,
153 std::string host,
154 uint16_t port) {
155 std::string value;
Bence Békyb89104962020-01-24 00:05:17156 std::string version_string;
David Schinazifbd4c432020-04-07 19:23:55157 bool first_version = true;
158 for (const auto& version : versions) {
159 if (first_version) {
160 first_version = false;
Bence Békyb89104962020-01-24 00:05:17161 } else {
Ryan Hamiltona2dcbae2022-02-09 19:02:45162 value.append(", ");
David Schinazifbd4c432020-04-07 19:23:55163 }
Ryan Hamiltona2dcbae2022-02-09 19:02:45164 value.append(base::StrCat({quic::AlpnForVersion(version), "=\"", host, ":",
165 base::NumberToString(port), "\""}));
zhongyie537a002017-06-27 16:48:21166 }
Ryan Hamiltona2dcbae2022-02-09 19:02:45167 return value;
168}
Bence Békyb89104962020-01-24 00:05:17169
Ryan Hamiltona2dcbae2022-02-09 19:02:45170std::string GenerateQuicAltSvcHeaderValue(
171 const quic::ParsedQuicVersionVector& versions,
172 uint16_t port) {
173 return GenerateQuicAltSvcHeaderValue(versions, "", port);
174}
175
176std::string GenerateQuicAltSvcHeader(
177 const quic::ParsedQuicVersionVector& versions) {
178 std::string altsvc_header = "Alt-Svc: ";
179 altsvc_header.append(GenerateQuicAltSvcHeaderValue(versions, 443));
180 altsvc_header.append("\r\n");
Bence Békyb89104962020-01-24 00:05:17181 return altsvc_header;
zhongyie537a002017-06-27 16:48:21182}
183
David Schinazi09e9a6012019-10-03 17:37:57184std::vector<TestParams> GetTestParams() {
185 std::vector<TestParams> params;
186 quic::ParsedQuicVersionVector all_supported_versions =
Patrick Meenan885a00652023-02-15 20:07:02187 AllSupportedQuicVersions();
Nico Weber6dcde5b2020-02-22 20:49:20188 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
Patrick Meenan885a00652023-02-15 20:07:02189 params.push_back(TestParams{version, false});
190 params.push_back(TestParams{version, true});
David Schinazi09e9a6012019-10-03 17:37:57191 }
192 return params;
193}
194
bnc359ed2a2016-04-29 20:43:45195std::vector<PoolingTestParams> GetPoolingTestParams() {
196 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56197 quic::ParsedQuicVersionVector all_supported_versions =
Patrick Meenan885a00652023-02-15 20:07:02198 AllSupportedQuicVersions();
Nico Weber6dcde5b2020-02-22 20:49:20199 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
Bence Béky957bab12023-01-31 16:40:10200 params.push_back(PoolingTestParams{version, SAME_AS_FIRST});
201 params.push_back(PoolingTestParams{version, SAME_AS_SECOND});
202 params.push_back(PoolingTestParams{version, DIFFERENT});
bnc359ed2a2016-04-29 20:43:45203 }
204 return params;
205}
bncb07c05532015-05-14 19:07:20206
Bence Béky319388a882020-09-23 18:42:52207std::string ConstructDataFrameForVersion(base::StringPiece body,
208 quic::ParsedQuicVersion version) {
Victor Vasilievc617d452022-03-07 15:54:25209 quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
210 body.size(), quiche::SimpleBufferAllocator::Get());
Ian Swett17d4d1c02021-06-08 19:52:41211 return base::StrCat({base::StringPiece(buffer.data(), buffer.size()), body});
Bence Béky319388a882020-09-23 18:42:52212}
213
[email protected]61a527782013-02-21 03:58:00214} // namespace
215
tbansal0f56a39a2016-04-07 22:03:38216class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40217 public:
tbansal180587c2017-02-16 15:13:23218 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
219 bool* rtt_notification_received)
220 : should_notify_updated_rtt_(should_notify_updated_rtt),
221 rtt_notification_received_(rtt_notification_received) {}
Peter Boström293b1342021-09-22 17:31:43222
223 TestSocketPerformanceWatcher(const TestSocketPerformanceWatcher&) = delete;
224 TestSocketPerformanceWatcher& operator=(const TestSocketPerformanceWatcher&) =
225 delete;
226
Tsuyoshi Horo07c3f0e2022-06-16 07:30:47227 ~TestSocketPerformanceWatcher() override = default;
tbansalfdf5665b2015-09-21 22:46:40228
tbansal180587c2017-02-16 15:13:23229 bool ShouldNotifyUpdatedRTT() const override {
230 return *should_notify_updated_rtt_;
231 }
tbansalfdf5665b2015-09-21 22:46:40232
tbansal0f56a39a2016-04-07 22:03:38233 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
234 *rtt_notification_received_ = true;
235 }
236
237 void OnConnectionChanged() override {}
238
239 private:
Keishi Hattori0e45c022021-11-27 09:25:52240 raw_ptr<bool> should_notify_updated_rtt_;
241 raw_ptr<bool> rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38242};
243
244class TestSocketPerformanceWatcherFactory
245 : public SocketPerformanceWatcherFactory {
246 public:
Tsuyoshi Horo4478fd32022-06-09 01:41:25247 TestSocketPerformanceWatcherFactory() = default;
Peter Boström293b1342021-09-22 17:31:43248
249 TestSocketPerformanceWatcherFactory(
250 const TestSocketPerformanceWatcherFactory&) = delete;
251 TestSocketPerformanceWatcherFactory& operator=(
252 const TestSocketPerformanceWatcherFactory&) = delete;
253
Tsuyoshi Horo07c3f0e2022-06-16 07:30:47254 ~TestSocketPerformanceWatcherFactory() override = default;
tbansal0f56a39a2016-04-07 22:03:38255
256 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42257 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41258 const Protocol protocol,
David Benjamin5241b582023-02-17 03:51:51259 const IPAddress& /* address */) override {
tbansalc8a94ea2015-11-02 23:58:51260 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38261 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51262 }
263 ++watcher_count_;
Tsuyoshi Horof8861cb2022-07-05 23:50:20264 return std::make_unique<TestSocketPerformanceWatcher>(
265 &should_notify_updated_rtt_, &rtt_notification_received_);
tbansalfdf5665b2015-09-21 22:46:40266 }
267
tbansalc8a94ea2015-11-02 23:58:51268 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40269
tbansalc8a94ea2015-11-02 23:58:51270 bool rtt_notification_received() const { return rtt_notification_received_; }
271
tbansal180587c2017-02-16 15:13:23272 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
273 should_notify_updated_rtt_ = should_notify_updated_rtt;
274 }
275
tbansalc8a94ea2015-11-02 23:58:51276 private:
Tsuyoshi Horo4478fd32022-06-09 01:41:25277 size_t watcher_count_ = 0u;
278 bool should_notify_updated_rtt_ = true;
279 bool rtt_notification_received_ = false;
tbansalc8a94ea2015-11-02 23:58:51280};
281
Ryan Hamilton8d9ee76e2018-05-29 23:52:52282class QuicNetworkTransactionTest
283 : public PlatformTest,
David Schinazi09e9a6012019-10-03 17:37:57284 public ::testing::WithParamInterface<TestParams>,
Gabriel Charette694c3c332019-08-19 14:53:05285 public WithTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00286 protected:
[email protected]1c04f9522013-02-21 20:32:43287 QuicNetworkTransactionTest()
David Schinazi09e9a6012019-10-03 17:37:57288 : version_(GetParam().version),
Nick Harper23290b82019-05-02 00:02:56289 supported_versions_(quic::test::SupportedVersions(version_)),
Tsuyoshi Horof8861cb2022-07-05 23:50:20290 client_maker_(std::make_unique<QuicTestPacketMaker>(
Zhongyi Shi1c022d22020-03-20 19:00:16291 version_,
292 quic::QuicUtils::CreateRandomConnectionId(
293 context_.random_generator()),
294 context_.clock(),
295 kDefaultServerHostName,
296 quic::Perspective::IS_CLIENT,
Patrick Meenanf741c6082023-01-03 18:06:43297 true)),
Victor Vasiliev7752898d2019-11-14 21:30:22298 server_maker_(version_,
299 quic::QuicUtils::CreateRandomConnectionId(
300 context_.random_generator()),
301 context_.clock(),
302 kDefaultServerHostName,
303 quic::Perspective::IS_SERVER,
304 false),
Tsuyoshi Horo2c0a5042022-07-06 05:53:07305 quic_task_runner_(
306 base::MakeRefCounted<TestTaskRunner>(context_.mock_clock())),
Tsuyoshi Horof8861cb2022-07-05 23:50:20307 ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()),
Nicolas Arciniegad2013f92020-02-07 23:00:56308 proxy_resolution_service_(
309 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11310 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke3233d8f22019-08-20 21:01:49311 http_server_properties_(std::make_unique<HttpServerProperties>()),
rchf114d982015-10-21 01:34:56312 ssl_data_(ASYNC, OK) {
Patrick Meenanf741c6082023-01-03 18:06:43313 scoped_feature_list_.InitWithFeatureState(
314 features::kPriorityIncremental,
315 GetParam().enable_quic_priority_incremental_support);
Renjie Tang98b4d512020-02-08 01:24:19316 FLAGS_quic_enable_http3_grease_randomness = false;
[email protected]aa9b14d2013-05-10 23:45:19317 request_.method = "GET";
rchf114d982015-10-21 01:34:56318 std::string url("https://");
bncb07c05532015-05-14 19:07:20319 url.append(kDefaultServerHostName);
320 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19321 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10322 request_.traffic_annotation =
323 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Victor Vasiliev7752898d2019-11-14 21:30:22324 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56325
326 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29327 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56328 verify_details_.cert_verify_result.verified_cert = cert;
329 verify_details_.cert_verify_result.is_issued_by_known_root = true;
330 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43331 }
[email protected]61a527782013-02-21 03:58:00332
dcheng67be2b1f2014-10-27 21:47:29333 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00334 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55335 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00336 }
337
dcheng67be2b1f2014-10-27 21:47:29338 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00339 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
340 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55341 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00342 PlatformTest::TearDown();
343 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55344 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40345 session_.reset();
[email protected]61a527782013-02-21 03:58:00346 }
347
Ryan Hamilton8d9ee76e2018-05-29 23:52:52348 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23349 ConstructClientConnectionClosePacket(uint64_t num) {
Zhongyi Shi1c022d22020-03-20 19:00:16350 return client_maker_->MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52351 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30352 }
353
Ryan Hamilton8d9ee76e2018-05-29 23:52:52354 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23355 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03356 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52357 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58358 }
359
Ryan Hamilton8d9ee76e2018-05-29 23:52:52360 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23361 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52362 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20363 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58364 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20365 }
366
Ryan Hamilton8d9ee76e2018-05-29 23:52:52367 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23368 uint64_t packet_number,
369 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34370 uint64_t smallest_received) {
Zhongyi Shi1c022d22020-03-20 19:00:16371 return client_maker_->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34372 smallest_received);
fayang3bcb8b502016-12-07 21:44:37373 }
374
Ryan Hamilton8d9ee76e2018-05-29 23:52:52375 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23376 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52377 quic::QuicStreamId stream_id,
378 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23379 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34380 uint64_t smallest_received) {
381 return client_maker_->MakeAckAndRstPacket(
382 num, false, stream_id, error_code, largest_received, smallest_received);
zhongyi6b5a3892016-03-12 04:46:20383 }
384
Ryan Hamilton8d9ee76e2018-05-29 23:52:52385 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23386 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52387 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41388 quic::QuicRstStreamErrorCode error_code) {
Zhongyi Shi1c022d22020-03-20 19:00:16389 return client_maker_->MakeRstPacket(num, false, stream_id, error_code,
390 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56391 }
392
Ryan Hamilton8d9ee76e2018-05-29 23:52:52393 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58394 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23395 uint64_t num,
Fan Yangac867502019-01-28 21:10:23396 uint64_t largest_received,
397 uint64_t smallest_received,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52398 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29399 const std::string& quic_error_details,
400 uint64_t frame_type) {
Zhongyi Shi1c022d22020-03-20 19:00:16401 return client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:34402 num, false, largest_received, smallest_received, quic_error,
403 quic_error_details, frame_type);
zhongyica364fbb2015-12-12 03:39:12404 }
405
Ryan Hamilton8d9ee76e2018-05-29 23:52:52406 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23407 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12408 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52409 quic::QuicStreamId stream_id,
410 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58411 return server_maker_.MakeRstPacket(num, include_version, stream_id,
412 error_code);
zhongyica364fbb2015-12-12 03:39:12413 }
414
Ryan Hamilton8d9ee76e2018-05-29 23:52:52415 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02416 uint64_t packet_number) {
Zhongyi Shi1c022d22020-03-20 19:00:16417 return client_maker_->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37418 }
419
Ryan Hamilton8d9ee76e2018-05-29 23:52:52420 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23421 uint64_t packet_number,
422 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34423 uint64_t smallest_received) {
fayang3bcb8b502016-12-07 21:44:37424 return server_maker_.MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34425 smallest_received);
fayang3bcb8b502016-12-07 21:44:37426 }
427
Ryan Hamilton8d9ee76e2018-05-29 23:52:52428 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23429 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57430 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52431 quic::QuicStreamId id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02432 RequestPriority request_priority) {
Zhongyi Shi1c022d22020-03-20 19:00:16433 return client_maker_->MakePriorityPacket(
Bence Béky957bab12023-01-31 16:40:10434 packet_number, should_include_version, id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02435 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wang385652a2018-02-16 02:37:23436 }
437
Haoyue Wang9d70d65c2020-05-29 22:45:34438 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckAndPriorityPacket(
439 uint64_t packet_number,
440 bool should_include_version,
441 uint64_t largest_received,
442 uint64_t smallest_received,
443 quic::QuicStreamId id,
Haoyue Wang9d70d65c2020-05-29 22:45:34444 RequestPriority request_priority) {
445 return client_maker_->MakeAckAndPriorityPacket(
446 packet_number, should_include_version, largest_received,
Bence Béky957bab12023-01-31 16:40:10447 smallest_received, id,
Haoyue Wang9d70d65c2020-05-29 22:45:34448 ConvertRequestPriorityToQuicPriority(request_priority));
449 }
450
zhongyi32569c62016-01-08 02:54:30451 // Uses default QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01452 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
453 const std::string& scheme,
454 const std::string& path) {
Zhongyi Shi1c022d22020-03-20 19:00:16455 return GetRequestHeaders(method, scheme, path, client_maker_.get());
zhongyi32569c62016-01-08 02:54:30456 }
457
458 // Uses customized QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01459 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
460 const std::string& scheme,
461 const std::string& path,
462 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50463 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00464 }
465
Bence Béky4c325e52020-10-22 20:48:01466 spdy::Http2HeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Zhongyi Shi1c022d22020-03-20 19:00:16467 return client_maker_->ConnectRequestHeaders(host_port);
Yixin Wang46a273ec302018-01-23 17:59:56468 }
469
Bence Béky4c325e52020-10-22 20:48:01470 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58471 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00472 }
473
zhongyi32569c62016-01-08 02:54:30474 // Appends alt_svc headers in the response headers.
Bence Béky4c325e52020-10-22 20:48:01475 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status,
476 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58477 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30478 }
479
Ryan Hamilton8d9ee76e2018-05-29 23:52:52480 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23481 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52482 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05483 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00484 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10485 absl::string_view data) {
Ryan Hamilton7505eb92019-06-08 00:22:17486 return server_maker_.MakeDataPacket(packet_number, stream_id,
487 should_include_version, fin, data);
[email protected]61a527782013-02-21 03:58:00488 }
489
Ryan Hamilton8d9ee76e2018-05-29 23:52:52490 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23491 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52492 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36493 bool should_include_version,
494 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10495 absl::string_view data) {
Zhongyi Shi1c022d22020-03-20 19:00:16496 return client_maker_->MakeDataPacket(packet_number, stream_id,
497 should_include_version, fin, data);
ckrasicda193a82016-07-09 00:39:36498 }
499
Ryan Hamilton8d9ee76e2018-05-29 23:52:52500 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23501 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56502 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52503 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23504 uint64_t largest_received,
505 uint64_t smallest_received,
Yixin Wang46a273ec302018-01-23 17:59:56506 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10507 absl::string_view data) {
Renjie Tangcd594f32020-07-11 20:18:34508 return client_maker_->MakeAckAndDataPacket(packet_number, include_version,
509 stream_id, largest_received,
510 smallest_received, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56511 }
512
Kenichi Ishibashi10111e82021-03-23 02:19:06513 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckDataAndRst(
514 uint64_t packet_number,
515 bool include_version,
516 quic::QuicStreamId stream_id,
517 quic::QuicRstStreamErrorCode error_code,
518 uint64_t largest_received,
519 uint64_t smallest_received,
520 quic::QuicStreamId data_id,
521 bool fin,
522 absl::string_view data) {
523 return client_maker_->MakeAckDataAndRst(
524 packet_number, include_version, stream_id, error_code, largest_received,
525 smallest_received, data_id, fin, data);
526 }
527
Ryan Hamilton8d9ee76e2018-05-29 23:52:52528 std::unique_ptr<quic::QuicEncryptedPacket>
Patrick Meenanf741c6082023-01-03 18:06:43529 ConstructClientRequestHeadersPacket(
530 uint64_t packet_number,
531 quic::QuicStreamId stream_id,
532 bool should_include_version,
533 bool fin,
534 spdy::Http2HeaderBlock headers,
535 bool should_include_priority_frame = true) {
536 return ConstructClientRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56537 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Bence Béky957bab12023-01-31 16:40:10538 std::move(headers), should_include_priority_frame);
zhongyi32569c62016-01-08 02:54:30539 }
540
Ryan Hamilton8d9ee76e2018-05-29 23:52:52541 std::unique_ptr<quic::QuicEncryptedPacket>
Patrick Meenanf741c6082023-01-03 18:06:43542 ConstructClientRequestHeadersPacket(
543 uint64_t packet_number,
544 quic::QuicStreamId stream_id,
545 bool should_include_version,
546 bool fin,
547 RequestPriority request_priority,
548 spdy::Http2HeaderBlock headers,
Patrick Meenanf741c6082023-01-03 18:06:43549 bool should_include_priority_frame = true) {
Ryan Hamilton0239aac2018-05-19 00:03:13550 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56551 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16552 return client_maker_->MakeRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56553 packet_number, stream_id, should_include_version, fin, priority,
Bence Béky957bab12023-01-31 16:40:10554 std::move(headers), nullptr, should_include_priority_frame);
Patrick Meenanf741c6082023-01-03 18:06:43555 }
556
557 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
558 uint64_t packet_number,
559 quic::QuicStreamId id,
560 RequestPriority request_priority) {
561 spdy::SpdyPriority spdy_priority =
562 ConvertRequestPriorityToQuicPriority(request_priority);
Bence Béky957bab12023-01-31 16:40:10563 return client_maker_->MakePriorityPacket(packet_number, true, id,
Patrick Meenanf741c6082023-01-03 18:06:43564 spdy_priority);
[email protected]61a527782013-02-21 03:58:00565 }
566
Ryan Hamilton8d9ee76e2018-05-29 23:52:52567 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25568 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23569 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52570 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25571 bool should_include_version,
572 bool fin,
573 RequestPriority request_priority,
Bence Béky4c325e52020-10-22 20:48:01574 spdy::Http2HeaderBlock headers,
Yixin Wange7ecc472018-03-06 19:00:25575 size_t* spdy_headers_frame_length,
576 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13577 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25578 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16579 return client_maker_->MakeRequestHeadersAndMultipleDataFramesPacket(
Yixin Wange7ecc472018-03-06 19:00:25580 packet_number, stream_id, should_include_version, fin, priority,
Bence Béky957bab12023-01-31 16:40:10581 std::move(headers), spdy_headers_frame_length, data_writes);
Yixin Wange7ecc472018-03-06 19:00:25582 }
583
Ryan Hamilton8d9ee76e2018-05-29 23:52:52584 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23585 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52586 quic::QuicStreamId stream_id,
587 bool should_include_version,
588 bool fin,
Bence Béky4c325e52020-10-22 20:48:01589 spdy::Http2HeaderBlock headers) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02590 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
591 should_include_version, fin,
592 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30593 }
594
Bence Béky319388a882020-09-23 18:42:52595 std::string ConstructDataFrame(base::StringPiece body) {
596 return ConstructDataFrameForVersion(body, version_);
Renjief49758b2019-01-11 23:32:41597 }
598
Nick Harper23290b82019-05-02 00:02:56599 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41600 session_params_.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:38601 context_.params()->supported_versions = supported_versions;
[email protected]61a527782013-02-21 03:58:00602
Victor Vasiliev7752898d2019-11-14 21:30:22603 session_context_.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:41604 session_context_.client_socket_factory = &socket_factory_;
605 session_context_.quic_crypto_client_stream_factory =
606 &crypto_client_stream_factory_;
607 session_context_.host_resolver = &host_resolver_;
608 session_context_.cert_verifier = &cert_verifier_;
609 session_context_.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:41610 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
611 session_context_.socket_performance_watcher_factory =
612 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59613 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41614 session_context_.ssl_config_service = ssl_config_service_.get();
615 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49616 session_context_.http_server_properties = http_server_properties_.get();
Matt Reichhoff0049a0b72021-10-20 20:44:26617 session_context_.net_log = NetLog::Get();
mmenke6ddfbea2017-05-31 21:48:41618
Renjie Tang6ff9a9b2021-02-03 22:11:09619 session_ =
620 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
Matt Menkeb566c392019-09-11 23:22:43621 session_->quic_stream_factory()
622 ->set_is_quic_known_to_work_on_current_network(true);
Yixin Wang46a273ec302018-01-23 17:59:56623 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
624 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00625 }
626
zhongyi86838d52017-06-30 01:19:44627 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21628
David Schinazif832cb82019-11-08 22:25:27629 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
Zhongyi Shi1c022d22020-03-20 19:00:16630 const std::string& status_line,
631 const quic::ParsedQuicVersion& version) {
[email protected]aa9b14d2013-05-10 23:45:19632 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42633 ASSERT_TRUE(response != nullptr);
634 ASSERT_TRUE(response->headers.get() != nullptr);
David Schinazif832cb82019-11-08 22:25:27635 EXPECT_EQ(status_line, response->headers->GetStatusLine());
[email protected]aa9b14d2013-05-10 23:45:19636 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52637 EXPECT_TRUE(response->was_alpn_negotiated);
Victor Vasiliev22dd3f212022-02-11 21:57:29638 auto connection_info =
639 QuicHttpStream::ConnectionInfoFromQuicVersion(version);
640 if (connection_info == response->connection_info) {
641 return;
642 }
643 // QUIC v1 and QUIC v2 are considered a match, because they have the same
644 // ALPN token.
645 if ((connection_info == HttpResponseInfo::CONNECTION_INFO_QUIC_RFC_V1 ||
Nidhi Jaju3787b8ab2022-12-15 23:20:34646 connection_info == HttpResponseInfo::CONNECTION_INFO_QUIC_2_DRAFT_8) &&
Victor Vasiliev22dd3f212022-02-11 21:57:29647 (response->connection_info ==
648 HttpResponseInfo::CONNECTION_INFO_QUIC_RFC_V1 ||
649 response->connection_info ==
Nidhi Jaju3787b8ab2022-12-15 23:20:34650 HttpResponseInfo::CONNECTION_INFO_QUIC_2_DRAFT_8)) {
Victor Vasiliev22dd3f212022-02-11 21:57:29651 return;
652 }
653
654 // They do not match. This EXPECT_EQ will fail and print useful
655 // information.
656 EXPECT_EQ(connection_info, response->connection_info);
[email protected]aa9b14d2013-05-10 23:45:19657 }
658
Zhongyi Shi1c022d22020-03-20 19:00:16659 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
660 const std::string& status_line) {
661 CheckWasQuicResponse(trans, status_line, version_);
662 }
663
David Schinazif832cb82019-11-08 22:25:27664 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
Kenichi Ishibashif8634ab2021-03-16 23:41:28665 CheckWasQuicResponse(trans, "HTTP/1.1 200", version_);
David Schinazif832cb82019-11-08 22:25:27666 }
667
bnc691fda62016-08-12 00:43:16668 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41669 const HttpResponseInfo* response = trans->GetResponseInfo();
670 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37671 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41672 }
673
bnc691fda62016-08-12 00:43:16674 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19675 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42676 ASSERT_TRUE(response != nullptr);
677 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19678 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
679 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52680 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52681 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19682 response->connection_info);
683 }
684
Yixin Wang46a273ec302018-01-23 17:59:56685 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
686 const HttpResponseInfo* response = trans->GetResponseInfo();
687 ASSERT_TRUE(response != nullptr);
688 ASSERT_TRUE(response->headers.get() != nullptr);
689 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
690 EXPECT_TRUE(response->was_fetched_via_spdy);
691 EXPECT_TRUE(response->was_alpn_negotiated);
692 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
693 response->connection_info);
694 }
695
bnc691fda62016-08-12 00:43:16696 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19697 const std::string& expected) {
698 std::string response_data;
bnc691fda62016-08-12 00:43:16699 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19700 EXPECT_EQ(expected, response_data);
701 }
702
bnc691fda62016-08-12 00:43:16703 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19704 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:26705 int rv = trans->Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:01706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
707 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19708 }
709
710 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16711 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
712 RunTransaction(&trans);
713 CheckWasHttpResponse(&trans);
714 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19715 }
716
tbansalc3308d72016-08-27 10:25:04717 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
718 bool used_proxy,
719 uint16_t port) {
720 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalc3308d72016-08-27 10:25:04721 RunTransaction(&trans);
722 CheckWasHttpResponse(&trans);
723 CheckResponsePort(&trans, port);
724 CheckResponseData(&trans, expected);
tbansal2ecbbc72016-10-06 17:15:47725 if (used_proxy) {
726 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
727 } else {
728 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
729 }
tbansalc3308d72016-08-27 10:25:04730 }
David Schinazif832cb82019-11-08 22:25:27731 void SendRequestAndExpectQuicResponse(const std::string& expected,
732 const std::string& status_line) {
733 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443,
734 status_line);
735 }
tbansalc3308d72016-08-27 10:25:04736
[email protected]aa9b14d2013-05-10 23:45:19737 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56738 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12739 }
740
bnc62a44f022015-04-02 15:59:41741 void SendRequestAndExpectQuicResponseFromProxyOnPort(
742 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46743 uint16_t port) {
bnc62a44f022015-04-02 15:59:41744 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19745 }
746
747 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05748 MockCryptoClientStream::HandshakeMode handshake_mode,
Brianna Goldstein02cb74f2022-09-29 05:41:01749 const NetworkAnonymizationKey& network_anonymization_key =
750 NetworkAnonymizationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19751 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46752 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21753 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
Peter Kastinge5a38ed2021-10-02 03:06:35754 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:49755 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:01756 server, network_anonymization_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07757 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19758 }
759
rchbe69cb902016-02-11 01:10:48760 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27761 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48762 const HostPortPair& alternative) {
763 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46764 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21765 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48766 alternative.port());
Peter Kastinge5a38ed2021-10-02 03:06:35767 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:49768 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:01769 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07770 supported_versions_);
rchbe69cb902016-02-11 01:10:48771 }
772
Matt Menkeb32ba5122019-09-10 19:17:05773 void ExpectBrokenAlternateProtocolMapping(
Brianna Goldstein02cb74f2022-09-29 05:41:01774 const NetworkAnonymizationKey& network_anonymization_key =
775 NetworkAnonymizationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46776 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34777 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49778 http_server_properties_->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:01779 server, network_anonymization_key);
zhongyic4de03032017-05-19 04:07:34780 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49781 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05782 alternative_service_info_vector[0].alternative_service(),
Brianna Goldstein02cb74f2022-09-29 05:41:01783 network_anonymization_key));
[email protected]aa9b14d2013-05-10 23:45:19784 }
785
Matt Menkeb32ba5122019-09-10 19:17:05786 void ExpectQuicAlternateProtocolMapping(
Brianna Goldstein02cb74f2022-09-29 05:41:01787 const NetworkAnonymizationKey& network_anonymization_key =
788 NetworkAnonymizationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46789 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34790 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49791 http_server_properties_->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:01792 server, network_anonymization_key);
zhongyic4de03032017-05-19 04:07:34793 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54794 EXPECT_EQ(
795 kProtoQUIC,
796 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49797 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05798 alternative_service_info_vector[0].alternative_service(),
Brianna Goldstein02cb74f2022-09-29 05:41:01799 network_anonymization_key));
[email protected]4d590c9c2014-05-02 05:14:33800 }
801
[email protected]aa9b14d2013-05-10 23:45:19802 void AddHangingNonAlternateProtocolSocketData() {
Lei Zhange00db752021-04-17 00:48:46803 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
[email protected]dda75ab2013-06-22 22:43:30804 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30805 hanging_data->set_connect_data(hanging_connect);
806 hanging_data_.push_back(std::move(hanging_data));
807 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
[email protected]aa9b14d2013-05-10 23:45:19808 }
809
Zhongyi Shia6b68d112018-09-24 07:49:03810 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Victor Vasilieva1e66d72019-12-05 17:55:38811 context_.params()->migrate_sessions_on_network_change_v2 = true;
812 context_.params()->migrate_sessions_early_v2 = true;
813 context_.params()->retry_on_alternate_network_before_handshake = true;
Renjie Tang6ff9a9b2021-02-03 22:11:09814 scoped_mock_change_notifier_ =
815 std::make_unique<ScopedMockNetworkChangeNotifier>();
Zhongyi Shia6b68d112018-09-24 07:49:03816 MockNetworkChangeNotifier* mock_ncn =
817 scoped_mock_change_notifier_->mock_network_change_notifier();
818 mock_ncn->ForceNetworkHandlesSupported();
819 mock_ncn->SetConnectedNetworksList(
820 {kDefaultNetworkForTests, kNewNetworkForTests});
821 }
822
Matt Menkeb32ba5122019-09-10 19:17:05823 // Adds a new socket data provider for an HTTP request, and runs a request,
824 // expecting it to be used.
825 void AddHttpDataAndRunRequest() {
826 MockWrite http_writes[] = {
827 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
828 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
829 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
830
Ryan Hamiltona2dcbae2022-02-09 19:02:45831 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
832 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
833 MockRead(SYNCHRONOUS, 5, "http used"),
834 // Connection closed.
835 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:05836 SequencedSocketData http_data(http_reads, http_writes);
837 socket_factory_.AddSocketDataProvider(&http_data);
838 SSLSocketDataProvider ssl_data(ASYNC, OK);
839 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
840 SendRequestAndExpectHttpResponse("http used");
841 EXPECT_TRUE(http_data.AllWriteDataConsumed());
842 EXPECT_TRUE(http_data.AllReadDataConsumed());
843 }
844
845 // Adds a new socket data provider for a QUIC request, and runs a request,
846 // expecting it to be used. The new QUIC session is not closed.
847 void AddQuicDataAndRunRequest() {
848 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22849 version_,
850 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
851 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky957bab12023-01-31 16:40:10852 true);
Matt Menkeb32ba5122019-09-10 19:17:05853 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22854 version_,
855 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
856 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
857 false);
Matt Menkeb32ba5122019-09-10 19:17:05858 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56859 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05860 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:02861 quic_data.AddWrite(SYNCHRONOUS,
862 client_maker.MakeInitialSettingsPacket(packet_number++));
Matt Menkeb32ba5122019-09-10 19:17:05863 quic_data.AddWrite(
864 SYNCHRONOUS,
865 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56866 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
867 true, true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:10868 GetRequestHeaders("GET", "https", "/", &client_maker), nullptr));
Matt Menkeb32ba5122019-09-10 19:17:05869 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Fan Yang1ef6dfef2021-07-24 16:20:16870 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Matt Menkeb32ba5122019-09-10 19:17:05871 quic_data.AddRead(
872 ASYNC, server_maker.MakeResponseHeadersPacket(
873 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:28874 false, server_maker.GetResponseHeaders("200"), nullptr));
Matt Menkeb32ba5122019-09-10 19:17:05875 quic_data.AddRead(
876 ASYNC, server_maker.MakeDataPacket(
877 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:52878 true, ConstructDataFrame("quic used")));
Matt Menkeb32ba5122019-09-10 19:17:05879 // Don't care about the final ack.
880 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
881 // No more data to read.
882 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
883 quic_data.AddSocketDataToFactory(&socket_factory_);
Fan Yang1ef6dfef2021-07-24 16:20:16884
885 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
886 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:26887 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Fan Yang1ef6dfef2021-07-24 16:20:16888 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
889
890 // Pump the message loop to get the request started.
891 base::RunLoop().RunUntilIdle();
892 // Explicitly confirm the handshake.
893 crypto_client_stream_factory_.last_stream()
894 ->NotifySessionOneRttKeyAvailable();
895
896 ASSERT_FALSE(quic_data.AllReadDataConsumed());
897 quic_data.Resume();
898
899 // Run the QUIC session to completion.
900 base::RunLoop().RunUntilIdle();
Matt Menkeb32ba5122019-09-10 19:17:05901
902 EXPECT_TRUE(quic_data.AllReadDataConsumed());
903 }
904
Bence Béky6e243aa2019-12-13 19:01:07905 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56906 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
907 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36908 }
909
Bence Béky6e243aa2019-12-13 19:01:07910 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56911 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
912 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36913 }
914
Bence Béky6e243aa2019-12-13 19:01:07915 quic::QuicStreamId GetQpackDecoderStreamId() const {
916 return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
917 version_.transport_version, 1);
918 }
919
920 std::string StreamCancellationQpackDecoderInstruction(int n) const {
Ian Swettb70d9f8f2020-04-10 23:38:43921 return StreamCancellationQpackDecoderInstruction(n, true);
922 }
923
924 std::string StreamCancellationQpackDecoderInstruction(
925 int n,
926 bool create_stream) const {
Bence Béky6e243aa2019-12-13 19:01:07927 const quic::QuicStreamId cancelled_stream_id =
928 GetNthClientInitiatedBidirectionalStreamId(n);
929 EXPECT_LT(cancelled_stream_id, 63u);
930
Peter Kasting241e6d22021-06-09 17:24:58931 const char opcode = 0x40;
Ian Swettb70d9f8f2020-04-10 23:38:43932 if (create_stream) {
Peter Kasting241e6d22021-06-09 17:24:58933 return {0x03, static_cast<char>(opcode | cancelled_stream_id)};
Ian Swettb70d9f8f2020-04-10 23:38:43934 } else {
Peter Kasting241e6d22021-06-09 17:24:58935 return {static_cast<char>(opcode | cancelled_stream_id)};
Ian Swettb70d9f8f2020-04-10 23:38:43936 }
Bence Béky6e243aa2019-12-13 19:01:07937 }
938
Bence Béky230ac612017-08-30 19:17:08939 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49940 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08941 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49942 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08943 }
944
Zhongyi Shi1c022d22020-03-20 19:00:16945 void SendRequestAndExpectQuicResponseMaybeFromProxy(
946 const std::string& expected,
947 bool used_proxy,
948 uint16_t port,
949 const std::string& status_line,
950 const quic::ParsedQuicVersion& version) {
951 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Zhongyi Shi1c022d22020-03-20 19:00:16952 RunTransaction(&trans);
953 CheckWasQuicResponse(&trans, status_line, version);
954 CheckResponsePort(&trans, port);
955 CheckResponseData(&trans, expected);
Zhongyi Shi1c022d22020-03-20 19:00:16956 if (used_proxy) {
957 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
Cammie Smith Barnesbf91e2a2020-12-23 20:49:04958
959 // DNS aliases should be empty when using a proxy.
960 EXPECT_TRUE(trans.GetResponseInfo()->dns_aliases.empty());
Zhongyi Shi1c022d22020-03-20 19:00:16961 } else {
962 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
963 }
964 }
965
Victor Vasiliev22dd3f212022-02-11 21:57:29966 // Verify that the set of QUIC protocols in `alt_svc_info_vector` and
967 // `supported_versions` is the same. Since QUICv1 and QUICv2 have the same
968 // ALPN token "h3", they cannot be distinguished when parsing ALPN, so
969 // consider them equal. This is accomplished by comparing the set of ALPN
970 // strings (instead of comparing the set of ParsedQuicVersion entities).
971 static void VerifyQuicVersionsInAlternativeServices(
972 const AlternativeServiceInfoVector& alt_svc_info_vector,
973 const quic::ParsedQuicVersionVector& supported_versions) {
974 // Process supported versions.
975 std::set<std::string> supported_alpn;
976 for (const auto& version : supported_versions) {
977 if (version.AlpnDeferToRFCv1()) {
978 // These versions currently do not support Alt-Svc.
979 return;
980 }
981 supported_alpn.insert(quic::ParsedQuicVersionToString(version));
982 }
983
984 // Versions that support the legacy Google-specific Alt-Svc format are sent
985 // in a single Alt-Svc entry, therefore they are accumulated in a single
986 // AlternativeServiceInfo, whereas more recent versions all have their own
987 // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
988 std::set<std::string> alt_svc_negotiated_alpn;
989 for (const auto& alt_svc_info : alt_svc_info_vector) {
990 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
991 for (const auto& version : alt_svc_info.advertised_versions()) {
992 alt_svc_negotiated_alpn.insert(
993 quic::ParsedQuicVersionToString(version));
994 }
995 }
996
997 // Compare.
998 EXPECT_EQ(alt_svc_negotiated_alpn, supported_alpn);
999 }
1000
Nick Harper23290b82019-05-02 00:02:561001 const quic::ParsedQuicVersion version_;
Ryan Hamiltona2dcbae2022-02-09 19:02:451002 const std::string alt_svc_header_ =
1003 GenerateQuicAltSvcHeader({version_}) + "\r\n";
Patrick Meenanf741c6082023-01-03 18:06:431004 base::test::ScopedFeatureList scoped_feature_list_;
Nick Harper23290b82019-05-02 00:02:561005 quic::ParsedQuicVersionVector supported_versions_;
Patrick Meenan0041f332022-05-19 23:48:351006 quic::test::QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Victor Vasiliev7752898d2019-11-14 21:30:221007 MockQuicContext context_;
Zhongyi Shi1c022d22020-03-20 19:00:161008 std::unique_ptr<QuicTestPacketMaker> client_maker_;
alyssar2adf3ac2016-05-03 17:12:581009 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:091010 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:421011 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:001012 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:561013 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:051014 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Eric Orthbe86fee2021-10-28 22:31:111015 MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
1016 RuleResolver::GetLocalhostResult()};
[email protected]1c04f9522013-02-21 20:32:431017 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:111018 TransportSecurityState transport_security_state_;
Ryan Sleevi8a9c9c12018-05-09 02:36:231019 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:381020 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:071021 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:261022 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:421023 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:491024 std::unique_ptr<HttpServerProperties> http_server_properties_;
Matt Menke30a878c2021-07-20 22:25:091025 HttpNetworkSessionParams session_params_;
1026 HttpNetworkSessionContext session_context_;
[email protected]aa9b14d2013-05-10 23:45:191027 HttpRequestInfo request_;
Matt Reichhoff0049a0b72021-10-20 20:44:261028 NetLogWithSource net_log_with_source_{
1029 NetLogWithSource::Make(NetLogSourceType::NONE)};
1030 RecordingNetLogObserver net_log_observer_;
danakjad1777e2016-04-16 00:56:421031 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:561032 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:031033 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:121034
1035 private:
1036 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1037 const std::string& expected,
bnc62a44f022015-04-02 15:59:411038 bool used_proxy,
David Schinazif832cb82019-11-08 22:25:271039 uint16_t port,
1040 const std::string& status_line) {
Zhongyi Shi1c022d22020-03-20 19:00:161041 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
1042 status_line, version_);
tbansal7cec3812015-02-05 21:25:121043 }
David Schinazif832cb82019-11-08 22:25:271044
1045 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1046 const std::string& expected,
1047 bool used_proxy,
1048 uint16_t port) {
1049 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
Kenichi Ishibashif8634ab2021-03-16 23:41:281050 "HTTP/1.1 200", version_);
David Schinazif832cb82019-11-08 22:25:271051 }
[email protected]61a527782013-02-21 03:58:001052};
1053
David Schinazi09e9a6012019-10-03 17:37:571054INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1055 QuicNetworkTransactionTest,
1056 ::testing::ValuesIn(GetTestParams()),
1057 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201058
Ryan Hamiltona64a5bcf2017-11-30 07:35:281059TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:381060 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281061 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381062 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281063 HostPortPair::FromString("mail.example.org:443"));
1064 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271065 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281066
Ryan Hamiltonabad59e2019-06-06 04:02:591067 MockQuicData mock_quic_data(version_);
Patrick Meenan885a00652023-02-15 20:07:021068 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281069 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1070 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211071 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281072
1073 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1074
1075 CreateSession();
1076
1077 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1078 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261079 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1081 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1082
1083 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1084 -ERR_INTERNET_DISCONNECTED, 1);
1085 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1086 -ERR_INTERNET_DISCONNECTED, 1);
1087}
1088
1089TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Victor Vasilieva1e66d72019-12-05 17:55:381090 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281091 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381092 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281093 HostPortPair::FromString("mail.example.org:443"));
1094 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271095 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281096
Ryan Hamiltonabad59e2019-06-06 04:02:591097 MockQuicData mock_quic_data(version_);
Patrick Meenan885a00652023-02-15 20:07:021098 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281099 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1100 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211101 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281102
1103 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1104
1105 CreateSession();
1106
1107 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1108 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261109 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1111 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1112
1113 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1114 -ERR_INTERNET_DISCONNECTED, 1);
1115 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1116 -ERR_INTERNET_DISCONNECTED, 1);
1117}
1118
tbansal180587c2017-02-16 15:13:231119TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381120 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231121 HostPortPair::FromString("mail.example.org:443"));
1122
Ryan Hamiltonabad59e2019-06-06 04:02:591123 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231124 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021125 mock_quic_data.AddWrite(SYNCHRONOUS,
1126 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361127 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231128 SYNCHRONOUS,
1129 ConstructClientRequestHeadersPacket(
1130 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1131 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431132 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331133 ASYNC, ConstructServerResponseHeadersPacket(
1134 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281135 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331136 mock_quic_data.AddRead(
1137 ASYNC, ConstructServerDataPacket(
1138 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521139 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231140 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341141 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231142 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1143
1144 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1145
1146 CreateSession();
1147 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1148
1149 EXPECT_FALSE(
1150 test_socket_performance_watcher_factory_.rtt_notification_received());
1151 SendRequestAndExpectQuicResponse("hello!");
1152 EXPECT_TRUE(
1153 test_socket_performance_watcher_factory_.rtt_notification_received());
1154}
1155
1156TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381157 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231158 HostPortPair::FromString("mail.example.org:443"));
1159
Ryan Hamiltonabad59e2019-06-06 04:02:591160 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231161 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021162 mock_quic_data.AddWrite(SYNCHRONOUS,
1163 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361164 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231165 SYNCHRONOUS,
1166 ConstructClientRequestHeadersPacket(
1167 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1168 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431169 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331170 ASYNC, ConstructServerResponseHeadersPacket(
1171 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281172 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331173 mock_quic_data.AddRead(
1174 ASYNC, ConstructServerDataPacket(
1175 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521176 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231177 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341178 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231179 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1180
1181 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1182
1183 CreateSession();
1184 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1185
1186 EXPECT_FALSE(
1187 test_socket_performance_watcher_factory_.rtt_notification_received());
1188 SendRequestAndExpectQuicResponse("hello!");
1189 EXPECT_FALSE(
1190 test_socket_performance_watcher_factory_.rtt_notification_received());
1191}
1192
[email protected]1e960032013-12-20 19:00:201193TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:381194 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571195 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471196
Ryan Hamiltonabad59e2019-06-06 04:02:591197 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231198 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021199 mock_quic_data.AddWrite(SYNCHRONOUS,
1200 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361201 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231202 SYNCHRONOUS,
1203 ConstructClientRequestHeadersPacket(
1204 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1205 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431206 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331207 ASYNC, ConstructServerResponseHeadersPacket(
1208 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281209 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331210 mock_quic_data.AddRead(
1211 ASYNC, ConstructServerDataPacket(
1212 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521213 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231214 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341215 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:591216 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471217
rcha5399e02015-04-21 19:32:041218 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471219
[email protected]4dca587c2013-03-07 16:54:471220 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471221
[email protected]aa9b14d2013-05-10 23:45:191222 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471223
[email protected]98b20ce2013-05-10 05:55:261224 // Check that the NetLog was filled reasonably.
Matt Reichhoff0049a0b72021-10-20 20:44:261225 auto entries = net_log_observer_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261226 EXPECT_LT(0u, entries.size());
1227
1228 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291229 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001230 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1231 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261232 EXPECT_LT(0, pos);
1233
David Schinazi24bfaa02020-10-22 19:54:381234 // ... and also a TYPE_QUIC_SESSION_PACKET_SENT.
1235 pos = ExpectLogContainsSomewhere(entries, 0,
1236 NetLogEventType::QUIC_SESSION_PACKET_SENT,
1237 NetLogEventPhase::NONE);
1238 EXPECT_LT(0, pos);
1239
rchfd527212015-08-25 00:41:261240 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291241 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261242 entries, 0,
mikecirone8b85c432016-09-08 19:11:001243 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1244 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261245 EXPECT_LT(0, pos);
1246
Eric Roman79cc7552019-07-19 02:17:541247 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261248
rchfd527212015-08-25 00:41:261249 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1250 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001251 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1252 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261253 EXPECT_LT(0, pos);
1254
[email protected]98b20ce2013-05-10 05:55:261255 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291256 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001257 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1258 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261259 EXPECT_LT(0, pos);
1260
Eric Roman79cc7552019-07-19 02:17:541261 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Patrick Meenan885a00652023-02-15 20:07:021262 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1263 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471264}
1265
Bence Békyb6300042020-01-28 21:18:201266// Regression test for https://crbug.com/1043531.
1267TEST_P(QuicNetworkTransactionTest, ResetOnEmptyResponseHeaders) {
Kenichi Ishibashi10111e82021-03-23 02:19:061268 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Bence Békyb6300042020-01-28 21:18:201269 context_.params()->origins_to_force_quic_on.insert(
1270 HostPortPair::FromString("mail.example.org:443"));
1271
1272 MockQuicData mock_quic_data(version_);
1273 int write_packet_num = 1;
1274 mock_quic_data.AddWrite(SYNCHRONOUS,
1275 ConstructInitialSettingsPacket(write_packet_num++));
1276 mock_quic_data.AddWrite(
1277 SYNCHRONOUS,
1278 ConstructClientRequestHeadersPacket(
1279 write_packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1280 true, true, GetRequestHeaders("GET", "https", "/")));
1281
1282 const quic::QuicStreamId request_stream_id =
1283 GetNthClientInitiatedBidirectionalStreamId(0);
Bence Béky4c325e52020-10-22 20:48:011284 spdy::Http2HeaderBlock empty_response_headers;
Bence Békyb6300042020-01-28 21:18:201285 const std::string response_data = server_maker_.QpackEncodeHeaders(
1286 request_stream_id, std::move(empty_response_headers), nullptr);
1287 uint64_t read_packet_num = 1;
1288 mock_quic_data.AddRead(
1289 ASYNC, ConstructServerDataPacket(read_packet_num++, request_stream_id,
1290 false, false, response_data));
1291 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1292
1293 mock_quic_data.AddWrite(
Kenichi Ishibashi10111e82021-03-23 02:19:061294 ASYNC, ConstructClientAckDataAndRst(
1295 write_packet_num++, true, request_stream_id,
1296 quic::QUIC_STREAM_GENERAL_PROTOCOL_ERROR, 1, 1,
1297 GetQpackDecoderStreamId(), false,
1298 StreamCancellationQpackDecoderInstruction(request_stream_id)));
Bence Békyb6300042020-01-28 21:18:201299
1300 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1301
1302 CreateSession();
1303
1304 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1305 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261306 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Bence Békyb6300042020-01-28 21:18:201307 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Kenichi Ishibashi10111e82021-03-23 02:19:061308 EXPECT_THAT(callback.WaitForResult(), IsError(net::ERR_QUIC_PROTOCOL_ERROR));
1309 base::RunLoop().RunUntilIdle();
1310 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1311 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
Bence Békyb6300042020-01-28 21:18:201312}
1313
rchbd089ab2017-05-26 23:05:041314TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381315 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041316 HostPortPair::FromString("mail.example.org:443"));
1317
Ryan Hamiltonabad59e2019-06-06 04:02:591318 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231319 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021320 mock_quic_data.AddWrite(SYNCHRONOUS,
1321 ConstructInitialSettingsPacket(packet_num++));
rchbd089ab2017-05-26 23:05:041322 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231323 SYNCHRONOUS,
1324 ConstructClientRequestHeadersPacket(
1325 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1326 true, GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashif8634ab2021-03-16 23:41:281327 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200");
rchbd089ab2017-05-26 23:05:041328 response_headers["key1"] = std::string(30000, 'A');
1329 response_headers["key2"] = std::string(30000, 'A');
1330 response_headers["key3"] = std::string(30000, 'A');
1331 response_headers["key4"] = std::string(30000, 'A');
1332 response_headers["key5"] = std::string(30000, 'A');
1333 response_headers["key6"] = std::string(30000, 'A');
1334 response_headers["key7"] = std::string(30000, 'A');
1335 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451336 quic::QuicStreamId stream_id;
1337 std::string response_data;
Patrick Meenan885a00652023-02-15 20:07:021338 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1339 response_data = server_maker_.QpackEncodeHeaders(
1340 stream_id, std::move(response_headers), nullptr);
rchbd089ab2017-05-26 23:05:041341
Fan Yangac867502019-01-28 21:10:231342 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041343 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451344 for (size_t offset = 0; offset < response_data.length();
1345 offset += chunk_size) {
1346 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431347 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451348 ASYNC, ConstructServerDataPacket(
1349 packet_number++, stream_id, false, false,
Victor Vasiliev502ba582020-09-15 23:16:151350 absl::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041351 }
1352
1353 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331354 ASYNC, ConstructServerDataPacket(
1355 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Bence Béky319388a882020-09-23 18:42:521356 false, true, ConstructDataFrame("hello!")));
rchbd089ab2017-05-26 23:05:041357 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341358 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Renjie Tangaadb84b2019-08-31 01:00:231359 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341360 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3));
rchbd089ab2017-05-26 23:05:041361
1362 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1363
1364 CreateSession();
1365
1366 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421367 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1368 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041369}
1370
1371TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381372 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1373 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041374 HostPortPair::FromString("mail.example.org:443"));
1375
Ryan Hamiltonabad59e2019-06-06 04:02:591376 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231377 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021378 mock_quic_data.AddWrite(SYNCHRONOUS,
1379 ConstructInitialSettingsPacket(packet_num++));
rchbd089ab2017-05-26 23:05:041380 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231381 SYNCHRONOUS,
1382 ConstructClientRequestHeadersPacket(
1383 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1384 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451385
Kenichi Ishibashif8634ab2021-03-16 23:41:281386 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200");
rchbd089ab2017-05-26 23:05:041387 response_headers["key1"] = std::string(30000, 'A');
1388 response_headers["key2"] = std::string(30000, 'A');
1389 response_headers["key3"] = std::string(30000, 'A');
1390 response_headers["key4"] = std::string(30000, 'A');
1391 response_headers["key5"] = std::string(30000, 'A');
1392 response_headers["key6"] = std::string(30000, 'A');
1393 response_headers["key7"] = std::string(30000, 'A');
1394 response_headers["key8"] = std::string(30000, 'A');
1395 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451396
1397 quic::QuicStreamId stream_id;
1398 std::string response_data;
Patrick Meenan885a00652023-02-15 20:07:021399 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1400 response_data = server_maker_.QpackEncodeHeaders(
1401 stream_id, std::move(response_headers), nullptr);
rchbd089ab2017-05-26 23:05:041402
Fan Yangac867502019-01-28 21:10:231403 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041404 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451405 for (size_t offset = 0; offset < response_data.length();
1406 offset += chunk_size) {
1407 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431408 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451409 ASYNC, ConstructServerDataPacket(
1410 packet_number++, stream_id, false, false,
Victor Vasiliev502ba582020-09-15 23:16:151411 absl::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041412 }
1413
1414 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331415 ASYNC, ConstructServerDataPacket(
1416 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Bence Béky319388a882020-09-23 18:42:521417 false, true, ConstructDataFrame("hello!")));
rchbd089ab2017-05-26 23:05:041418 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341419 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431420 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331421 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231422 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:341423 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3));
rchbd089ab2017-05-26 23:05:041424
1425 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1426
1427 CreateSession();
1428
1429 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1430 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261431 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rchbd089ab2017-05-26 23:05:041432 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1433 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1434}
1435
Kenichi Ishibashifd2d3e62022-03-01 22:54:051436TEST_P(QuicNetworkTransactionTest, RedirectMultipleLocations) {
1437 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1438 context_.params()->origins_to_force_quic_on.insert(
1439 HostPortPair::FromString("mail.example.org:443"));
1440
1441 MockQuicData mock_quic_data(version_);
1442 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021443 mock_quic_data.AddWrite(SYNCHRONOUS,
1444 ConstructInitialSettingsPacket(packet_num++));
Kenichi Ishibashifd2d3e62022-03-01 22:54:051445 mock_quic_data.AddWrite(
1446 SYNCHRONOUS,
1447 ConstructClientRequestHeadersPacket(
1448 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1449 true, GetRequestHeaders("GET", "https", "/")));
1450
1451 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("301");
1452 response_headers.AppendValueOrAddHeader("location", "https://example1.test");
1453 response_headers.AppendValueOrAddHeader("location", "https://example2.test");
1454
Patrick Meenan885a00652023-02-15 20:07:021455 const quic::QuicStreamId stream_id =
1456 GetNthClientInitiatedBidirectionalStreamId(0);
1457 const std::string response_data = server_maker_.QpackEncodeHeaders(
1458 stream_id, std::move(response_headers), nullptr);
1459 ASSERT_LT(response_data.size(), 1200u);
1460 mock_quic_data.AddRead(
1461 ASYNC, ConstructServerDataPacket(/*packet_number=*/1, stream_id,
1462 /*should_include_version=*/false,
1463 /*fin=*/true, response_data));
Kenichi Ishibashifd2d3e62022-03-01 22:54:051464 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1465
1466 mock_quic_data.AddWrite(
1467 ASYNC, ConstructClientAckAndRstPacket(
1468 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1469 quic::QUIC_STREAM_CANCELLED,
1470 /*largest_received=*/1, /*smallest_received=*/1));
1471
1472 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1473
1474 CreateSession();
1475
1476 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1477 TestCompletionCallback callback;
1478 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
1479 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1480 ASSERT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1481}
1482
rcha2bd44b2016-07-02 00:42:551483TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Victor Vasilieva1e66d72019-12-05 17:55:381484 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551485
Ryan Hamilton9835e662018-08-02 05:36:271486 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551487
Ryan Hamiltonabad59e2019-06-06 04:02:591488 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231489 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021490 mock_quic_data.AddWrite(SYNCHRONOUS,
1491 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361492 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231493 SYNCHRONOUS,
1494 ConstructClientRequestHeadersPacket(
1495 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1496 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431497 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331498 ASYNC, ConstructServerResponseHeadersPacket(
1499 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281500 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331501 mock_quic_data.AddRead(
1502 ASYNC, ConstructServerDataPacket(
1503 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521504 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231505 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341506 ConstructClientAckPacket(packet_num++, 2, 1));
rcha2bd44b2016-07-02 00:42:551507 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1508
1509 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1510
1511 CreateSession();
1512
1513 SendRequestAndExpectQuicResponse("hello!");
1514 EXPECT_TRUE(
1515 test_socket_performance_watcher_factory_.rtt_notification_received());
1516}
1517
David Schinazif832cb82019-11-08 22:25:271518// Regression test for https://crbug.com/695225
1519TEST_P(QuicNetworkTransactionTest, 408Response) {
Victor Vasilieva1e66d72019-12-05 17:55:381520 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
David Schinazif832cb82019-11-08 22:25:271521
1522 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1523
1524 MockQuicData mock_quic_data(version_);
1525 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021526 mock_quic_data.AddWrite(SYNCHRONOUS,
1527 ConstructInitialSettingsPacket(packet_num++));
David Schinazif832cb82019-11-08 22:25:271528 mock_quic_data.AddWrite(
1529 SYNCHRONOUS,
1530 ConstructClientRequestHeadersPacket(
1531 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1532 true, GetRequestHeaders("GET", "https", "/")));
1533 mock_quic_data.AddRead(
1534 ASYNC, ConstructServerResponseHeadersPacket(
1535 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281536 GetResponseHeaders("408")));
David Schinazif832cb82019-11-08 22:25:271537 mock_quic_data.AddRead(
1538 ASYNC, ConstructServerDataPacket(
1539 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521540 ConstructDataFrame("hello!")));
David Schinazif832cb82019-11-08 22:25:271541 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341542 ConstructClientAckPacket(packet_num++, 2, 1));
David Schinazif832cb82019-11-08 22:25:271543 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1544
1545 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1546
1547 CreateSession();
1548
Kenichi Ishibashif8634ab2021-03-16 23:41:281549 SendRequestAndExpectQuicResponse("hello!", "HTTP/1.1 408");
David Schinazif832cb82019-11-08 22:25:271550}
1551
[email protected]cf3e3cd62014-02-05 16:16:161552TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411553 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561554 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:271555 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:561556 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161557
Ryan Hamiltonabad59e2019-06-06 04:02:591558 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231559 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021560 mock_quic_data.AddWrite(SYNCHRONOUS,
1561 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361562 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231563 SYNCHRONOUS,
1564 ConstructClientRequestHeadersPacket(
1565 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1566 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431567 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331568 ASYNC, ConstructServerResponseHeadersPacket(
1569 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281570 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331571 mock_quic_data.AddRead(
1572 ASYNC, ConstructServerDataPacket(
1573 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521574 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231575 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341576 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:501577 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211578 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
[email protected]cf3e3cd62014-02-05 16:16:161579
rcha5399e02015-04-21 19:32:041580 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161581
tbansal0f56a39a2016-04-07 22:03:381582 EXPECT_FALSE(
1583 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161584 // There is no need to set up an alternate protocol job, because
1585 // no attempt will be made to speak to the proxy over TCP.
1586
rch9ae5b3b2016-02-11 00:36:291587 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161588 CreateSession();
1589
bnc62a44f022015-04-02 15:59:411590 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381591 EXPECT_TRUE(
1592 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161593}
1594
bnc313ba9c2015-06-11 15:42:311595// Regression test for https://crbug.com/492458. Test that for an HTTP
1596// connection through a QUIC proxy, the certificate exhibited by the proxy is
1597// checked against the proxy hostname, not the origin hostname.
1598TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291599 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311600 const std::string proxy_host = "www.example.org";
1601
mmenke6ddfbea2017-05-31 21:48:411602 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561603 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:271604 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:561605 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311606
Zhongyi Shi1c022d22020-03-20 19:00:161607 client_maker_->set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591608 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231609 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021610 mock_quic_data.AddWrite(SYNCHRONOUS,
1611 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361612 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231613 SYNCHRONOUS,
1614 ConstructClientRequestHeadersPacket(
1615 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1616 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431617 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331618 ASYNC, ConstructServerResponseHeadersPacket(
1619 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281620 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331621 mock_quic_data.AddRead(
1622 ASYNC, ConstructServerDataPacket(
1623 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521624 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231625 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341626 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:501627 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211628 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc313ba9c2015-06-11 15:42:311629 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1630
1631 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291632 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311633 ASSERT_TRUE(cert.get());
1634 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241635 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1636 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311637 ProofVerifyDetailsChromium verify_details;
1638 verify_details.cert_verify_result.verified_cert = cert;
1639 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561640 ProofVerifyDetailsChromium verify_details2;
1641 verify_details2.cert_verify_result.verified_cert = cert;
1642 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311643
1644 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091645 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321646 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271647 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311648 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1649}
1650
rchbe69cb902016-02-11 01:10:481651TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Victor Vasilieva1e66d72019-12-05 17:55:381652 context_.params()->allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481653 HostPortPair origin("www.example.org", 443);
1654 HostPortPair alternative("mail.example.org", 443);
1655
1656 base::FilePath certs_dir = GetTestCertsDirectory();
1657 scoped_refptr<X509Certificate> cert(
1658 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1659 ASSERT_TRUE(cert.get());
1660 // TODO(rch): the connection should be "to" the origin, so if the cert is
1661 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241662 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1663 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481664 ProofVerifyDetailsChromium verify_details;
1665 verify_details.cert_verify_result.verified_cert = cert;
1666 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1667
Zhongyi Shi1c022d22020-03-20 19:00:161668 client_maker_->set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591669 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021670
Renjie Tangaadb84b2019-08-31 01:00:231671 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021672 mock_quic_data.AddWrite(SYNCHRONOUS,
1673 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361674 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231675 SYNCHRONOUS,
1676 ConstructClientRequestHeadersPacket(
1677 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1678 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431679 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331680 ASYNC, ConstructServerResponseHeadersPacket(
1681 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281682 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331683 mock_quic_data.AddRead(
1684 ASYNC, ConstructServerDataPacket(
1685 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521686 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231687 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341688 ConstructClientAckPacket(packet_num++, 2, 1));
rchbe69cb902016-02-11 01:10:481689 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211690 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rchbe69cb902016-02-11 01:10:481691 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1692
1693 request_.url = GURL("https://" + origin.host());
1694 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271695 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091696 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321697 CreateSession();
rchbe69cb902016-02-11 01:10:481698
1699 SendRequestAndExpectQuicResponse("hello!");
1700}
1701
zhongyief3f4ce52017-07-05 23:53:281702TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
David Schinazi84c58bb2020-06-04 20:14:331703 quic::ParsedQuicVersion unsupported_version =
1704 quic::ParsedQuicVersion::Unsupported();
Bence Békyb89104962020-01-24 00:05:171705 // Add support for another QUIC version besides |version_|. Also find an
zhongyief3f4ce52017-07-05 23:53:281706 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561707 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281708 if (version == version_)
1709 continue;
1710 if (supported_versions_.size() != 2) {
1711 supported_versions_.push_back(version);
1712 continue;
1713 }
1714 unsupported_version = version;
1715 break;
1716 }
Bence Békyb89104962020-01-24 00:05:171717 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:331718 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), unsupported_version);
zhongyief3f4ce52017-07-05 23:53:281719
1720 // Set up alternative service to use QUIC with a version that is not
1721 // supported.
1722 url::SchemeHostPort server(request_.url);
1723 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1724 443);
Peter Kastinge5a38ed2021-10-02 03:06:351725 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:491726 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:011727 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:071728 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281729
1730 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491731 http_server_properties_->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:011732 server, NetworkAnonymizationKey());
zhongyief3f4ce52017-07-05 23:53:281733 EXPECT_EQ(1u, alt_svc_info_vector.size());
1734 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1735 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1736 EXPECT_EQ(unsupported_version,
1737 alt_svc_info_vector[0].advertised_versions()[0]);
1738
1739 // First request should still be sent via TCP as the QUIC version advertised
1740 // in the stored AlternativeService is not supported by the client. However,
1741 // the response from the server will advertise new Alt-Svc with supported
1742 // versions.
David Schinazifbd4c432020-04-07 19:23:551743 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyief3f4ce52017-07-05 23:53:281744 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:171745 MockRead("HTTP/1.1 200 OK\r\n"),
1746 MockRead(altsvc_header.c_str()),
1747 MockRead("\r\n"),
zhongyief3f4ce52017-07-05 23:53:281748 MockRead("hello world"),
1749 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1750 MockRead(ASYNC, OK)};
1751
Ryan Sleevib8d7ea02018-05-07 20:01:011752 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281753 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081754 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281755 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1756
1757 // Second request should be sent via QUIC as a new list of verions supported
1758 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591759 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231760 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021761 mock_quic_data.AddWrite(SYNCHRONOUS,
1762 ConstructInitialSettingsPacket(packet_num++));
zhongyief3f4ce52017-07-05 23:53:281763 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231764 SYNCHRONOUS,
1765 ConstructClientRequestHeadersPacket(
1766 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1767 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431768 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331769 ASYNC, ConstructServerResponseHeadersPacket(
1770 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281771 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331772 mock_quic_data.AddRead(
1773 ASYNC, ConstructServerDataPacket(
1774 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521775 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231776 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341777 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyief3f4ce52017-07-05 23:53:281778 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211779 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyief3f4ce52017-07-05 23:53:281780
1781 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1782
1783 AddHangingNonAlternateProtocolSocketData();
1784
1785 CreateSession(supported_versions_);
1786
1787 SendRequestAndExpectHttpResponse("hello world");
1788 SendRequestAndExpectQuicResponse("hello!");
1789
1790 // Check alternative service list is updated with new versions.
1791 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491792 session_->http_server_properties()->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:011793 server, NetworkAnonymizationKey());
Victor Vasiliev22dd3f212022-02-11 21:57:291794 VerifyQuicVersionsInAlternativeServices(alt_svc_info_vector,
1795 supported_versions_);
zhongyief3f4ce52017-07-05 23:53:281796}
1797
bncaccd4962017-04-06 21:00:261798// Regression test for https://crbug.com/546991.
1799// The server might not be able to serve a request on an alternative connection,
1800// and might send a 421 Misdirected Request response status to indicate this.
1801// HttpNetworkTransaction should reset the request and retry without using
1802// alternative services.
1803TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1804 // Set up alternative service to use QUIC.
1805 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1806 // that overrides |enable_alternative_services|.
1807 url::SchemeHostPort server(request_.url);
1808 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1809 443);
Peter Kastinge5a38ed2021-10-02 03:06:351810 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:491811 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:011812 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:071813 supported_versions_);
bncaccd4962017-04-06 21:00:261814
davidbena4449722017-05-05 23:30:531815 // First try: The alternative job uses QUIC and reports an HTTP 421
1816 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1817 // paused at Connect(), so it will never exit the socket pool. This ensures
1818 // that the alternate job always wins the race and keeps whether the
1819 // |http_data| exits the socket pool before the main job is aborted
1820 // deterministic. The first main job gets aborted without the socket pool ever
1821 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591822 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231823 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021824 mock_quic_data.AddWrite(SYNCHRONOUS,
1825 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361826 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231827 SYNCHRONOUS,
1828 ConstructClientRequestHeadersPacket(
1829 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1830 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331831 mock_quic_data.AddRead(
1832 ASYNC, ConstructServerResponseHeadersPacket(
1833 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021834 GetResponseHeaders("421")));
David Schinazi395918c2021-02-05 18:56:211835 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncaccd4962017-04-06 21:00:261836 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1837
davidbena4449722017-05-05 23:30:531838 // Second try: The main job uses TCP, and there is no alternate job. Once the
1839 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1840 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261841 // Note that if there was an alternative QUIC Job created for the second try,
1842 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1843 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531844 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1845 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1846 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1847 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1848 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1849 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011850 reads, writes);
bncaccd4962017-04-06 21:00:261851 socket_factory_.AddSocketDataProvider(&http_data);
1852 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1853
bncaccd4962017-04-06 21:00:261854 CreateSession();
1855 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531856
1857 // Run until |mock_quic_data| has failed and |http_data| has paused.
1858 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261859 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
davidbena4449722017-05-05 23:30:531860 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1861 base::RunLoop().RunUntilIdle();
1862
1863 // |mock_quic_data| must have run to completion.
1864 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1865 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1866
1867 // Now that the QUIC data has been consumed, unblock |http_data|.
1868 http_data.socket()->OnConnectComplete(MockConnect());
1869
1870 // The retry logic must hide the 421 status. The transaction succeeds on
1871 // |http_data|.
1872 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261873 CheckWasHttpResponse(&trans);
1874 CheckResponsePort(&trans, 443);
1875 CheckResponseData(&trans, "hello!");
1876}
1877
[email protected]1e960032013-12-20 19:00:201878TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Victor Vasilieva1e66d72019-12-05 17:55:381879 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571880 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301881
Ryan Hamiltonabad59e2019-06-06 04:02:591882 MockQuicData mock_quic_data1(version_);
Patrick Meenan885a00652023-02-15 20:07:021883 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401884 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Zhongyi Shi1c022d22020-03-20 19:00:161885 client_maker_->Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591886 MockQuicData mock_quic_data2(version_);
Patrick Meenan885a00652023-02-15 20:07:021887 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301888 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401889 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431890 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401891
1892 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1893 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301894
1895 CreateSession();
1896
tbansal0f56a39a2016-04-07 22:03:381897 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401898 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161899 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401900 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261901 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:011902 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1903 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381904 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531905
1906 NetErrorDetails details;
1907 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521908 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401909 }
[email protected]cebe3282013-05-22 23:49:301910}
1911
tbansalc8a94ea2015-11-02 23:58:511912TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1913 // Attempt to "force" quic on 443, which will not be honored.
Victor Vasilieva1e66d72019-12-05 17:55:381914 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571915 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511916
1917 MockRead http_reads[] = {
1918 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1919 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1920 MockRead(ASYNC, OK)};
1921
Ryan Sleevib8d7ea02018-05-07 20:01:011922 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511923 socket_factory_.AddSocketDataProvider(&data);
1924 SSLSocketDataProvider ssl(ASYNC, OK);
1925 socket_factory_.AddSSLSocketDataProvider(&ssl);
1926
1927 CreateSession();
1928
1929 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381930 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511931}
1932
bncc958faa2015-07-31 18:14:521933TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:351934 if (version_.AlpnDeferToRFCv1()) {
1935 // These versions currently do not support Alt-Svc.
1936 return;
1937 }
bncc958faa2015-07-31 18:14:521938 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:451939 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:561940 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521941 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1942 MockRead(ASYNC, OK)};
1943
Ryan Sleevib8d7ea02018-05-07 20:01:011944 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521945 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081946 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561947 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521948
Ryan Hamiltonabad59e2019-06-06 04:02:591949 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231950 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021951 mock_quic_data.AddWrite(SYNCHRONOUS,
1952 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361953 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231954 SYNCHRONOUS,
1955 ConstructClientRequestHeadersPacket(
1956 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1957 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431958 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331959 ASYNC, ConstructServerResponseHeadersPacket(
1960 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281961 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331962 mock_quic_data.AddRead(
1963 ASYNC, ConstructServerDataPacket(
1964 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521965 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231966 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341967 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:521968 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211969 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:521970
1971 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1972
rtennetib8e80fb2016-05-16 00:12:091973 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321974 CreateSession();
bncc958faa2015-07-31 18:14:521975
1976 SendRequestAndExpectHttpResponse("hello world");
1977 SendRequestAndExpectQuicResponse("hello!");
1978}
1979
Ryan Hamilton64f21d52019-08-31 07:10:511980TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:351981 if (version_.AlpnDeferToRFCv1()) {
1982 // These versions currently do not support Alt-Svc.
1983 return;
1984 }
Ryan Hamilton64f21d52019-08-31 07:10:511985 std::string alt_svc_header =
1986 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
1987 MockRead http_reads[] = {
1988 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
1989 MockRead("hello world"),
1990 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1991 MockRead(ASYNC, OK)};
1992
1993 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
1994 socket_factory_.AddSocketDataProvider(&http_data);
1995 AddCertificate(&ssl_data_);
1996 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1997
1998 MockQuicData mock_quic_data(version_);
1999 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022000 mock_quic_data.AddWrite(SYNCHRONOUS,
2001 ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton64f21d52019-08-31 07:10:512002 mock_quic_data.AddWrite(
2003 SYNCHRONOUS,
2004 ConstructClientRequestHeadersPacket(
2005 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2006 true, GetRequestHeaders("GET", "https", "/")));
2007 mock_quic_data.AddRead(
2008 ASYNC, ConstructServerResponseHeadersPacket(
2009 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282010 GetResponseHeaders("200")));
Ryan Hamilton64f21d52019-08-31 07:10:512011 mock_quic_data.AddRead(
2012 ASYNC, ConstructServerDataPacket(
2013 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522014 ConstructDataFrame("hello!")));
Ryan Hamilton64f21d52019-08-31 07:10:512015 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342016 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton64f21d52019-08-31 07:10:512017 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212018 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamilton64f21d52019-08-31 07:10:512019
2020 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2021
2022 AddHangingNonAlternateProtocolSocketData();
2023 CreateSession();
2024
2025 SendRequestAndExpectHttpResponse("hello world");
2026 SendRequestAndExpectQuicResponse("hello!");
2027}
2028
Brianna Goldstein02cb74f2022-09-29 05:41:012029// Much like above, but makes sure NetworkAnonymizationKey is respected.
Matt Menke3233d8f22019-08-20 21:01:492030TEST_P(QuicNetworkTransactionTest,
Brianna Goldstein02cb74f2022-09-29 05:41:012031 UseAlternativeServiceForQuicWithNetworkAnonymizationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:352032 if (version_.AlpnDeferToRFCv1()) {
2033 // These versions currently do not support Alt-Svc.
2034 return;
2035 }
Matt Menke3233d8f22019-08-20 21:01:492036 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:052037 feature_list.InitWithFeatures(
2038 // enabled_features
2039 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2040 features::kPartitionConnectionsByNetworkIsolationKey},
2041 // disabled_features
2042 {});
Matt Menke3233d8f22019-08-20 21:01:492043 // Since HttpServerProperties caches the feature value, have to create a new
2044 // one.
2045 http_server_properties_ = std::make_unique<HttpServerProperties>();
2046
Matt Menke4807a9a2020-11-21 00:14:412047 const SchemefulSite kSite1(GURL("https://foo.test/"));
2048 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Brianna Goldstein314ddf722022-09-24 02:00:522049 const net::NetworkAnonymizationKey kNetworkAnonymizationKey1(kSite1, kSite1);
2050
Matt Menke4807a9a2020-11-21 00:14:412051 const SchemefulSite kSite2(GURL("https://bar.test/"));
2052 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Brianna Goldstein314ddf722022-09-24 02:00:522053 const net::NetworkAnonymizationKey kNetworkAnonymizationKey2(kSite2, kSite2);
Matt Menke3233d8f22019-08-20 21:01:492054
2055 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452056 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Matt Menke3233d8f22019-08-20 21:01:492057 MockRead("hello world"),
2058 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2059 MockRead(ASYNC, OK)};
2060
2061 AddCertificate(&ssl_data_);
2062
Brianna Goldsteind22b0642022-10-11 16:30:502063 // Request with empty NetworkAnonymizationKey.
Matt Menke3233d8f22019-08-20 21:01:492064 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2065 socket_factory_.AddSocketDataProvider(&http_data1);
2066 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2067
2068 // First request with kNetworkIsolationKey1.
2069 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2070 socket_factory_.AddSocketDataProvider(&http_data2);
2071 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2072
2073 // Request with kNetworkIsolationKey2.
2074 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2075 socket_factory_.AddSocketDataProvider(&http_data3);
2076 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2077
2078 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2079 // alternative service infrmation has been received in this context before.
2080 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232081 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022082 mock_quic_data.AddWrite(SYNCHRONOUS,
2083 ConstructInitialSettingsPacket(packet_num++));
Matt Menke3233d8f22019-08-20 21:01:492084 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232085 SYNCHRONOUS,
2086 ConstructClientRequestHeadersPacket(
2087 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2088 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492089 mock_quic_data.AddRead(
2090 ASYNC, ConstructServerResponseHeadersPacket(
2091 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282092 GetResponseHeaders("200")));
Matt Menke3233d8f22019-08-20 21:01:492093 mock_quic_data.AddRead(
2094 ASYNC, ConstructServerDataPacket(
2095 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522096 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232097 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342098 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menke3233d8f22019-08-20 21:01:492099 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212100 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Matt Menke3233d8f22019-08-20 21:01:492101
2102 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2103
2104 AddHangingNonAlternateProtocolSocketData();
2105 CreateSession();
2106
2107 // This is first so that the test fails if alternative service info is
Brianna Goldsteind22b0642022-10-11 16:30:502108 // written with the right NetworkAnonymizationKey, but always queried with an
Matt Menke3233d8f22019-08-20 21:01:492109 // empty one.
Brianna Goldsteind22b0642022-10-11 16:30:502110 request_.network_isolation_key = NetworkIsolationKey();
Brianna Goldstein314ddf722022-09-24 02:00:522111 request_.network_anonymization_key = NetworkAnonymizationKey();
Matt Menke3233d8f22019-08-20 21:01:492112 SendRequestAndExpectHttpResponse("hello world");
2113 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:522114 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Menke3233d8f22019-08-20 21:01:492115 SendRequestAndExpectHttpResponse("hello world");
2116 request_.network_isolation_key = kNetworkIsolationKey2;
Brianna Goldstein314ddf722022-09-24 02:00:522117 request_.network_anonymization_key = kNetworkAnonymizationKey2;
Matt Menke3233d8f22019-08-20 21:01:492118 SendRequestAndExpectHttpResponse("hello world");
2119
Brianna Goldsteind22b0642022-10-11 16:30:502120 // Only use QUIC when using a NetworkAnonymizationKey which has been used when
Matt Menke3233d8f22019-08-20 21:01:492121 // alternative service information was received.
2122 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:522123 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Menke3233d8f22019-08-20 21:01:492124 SendRequestAndExpectQuicResponse("hello!");
2125}
2126
zhongyia00ca012017-07-06 23:36:392127TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
Ryan Hamiltona51800a2022-02-12 19:34:352128 if (version_.AlpnDeferToRFCv1()) {
2129 // These versions currently do not support Alt-Svc.
2130 return;
2131 }
Victor Vasiliev22dd3f212022-02-11 21:57:292132 // Both client and server supports two QUIC versions:
2133 // Client supports |supported_versions_[0]| and |supported_versions_[1]|,
2134 // server supports |version_| and |advertised_version_2|.
2135 // Only |version_| (same as |supported_versions_[0]|) is supported by both.
zhongyia00ca012017-07-06 23:36:392136 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2137 // PacketMakers are using |version_|.
2138
Victor Vasiliev22dd3f212022-02-11 21:57:292139 // Compare ALPN strings instead of ParsedQuicVersions because QUIC v1 and v2
2140 // have the same ALPN string.
2141 ASSERT_EQ(1u, supported_versions_.size());
2142 ASSERT_EQ(supported_versions_[0], version_);
David Schinazi84c58bb2020-06-04 20:14:332143 quic::ParsedQuicVersion advertised_version_2 =
2144 quic::ParsedQuicVersion::Unsupported();
Nick Harper23290b82019-05-02 00:02:562145 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Victor Vasiliev22dd3f212022-02-11 21:57:292146 if (quic::AlpnForVersion(version) == quic::AlpnForVersion(version_)) {
zhongyia00ca012017-07-06 23:36:392147 continue;
Victor Vasiliev22dd3f212022-02-11 21:57:292148 }
zhongyia00ca012017-07-06 23:36:392149 if (supported_versions_.size() != 2) {
2150 supported_versions_.push_back(version);
2151 continue;
2152 }
Victor Vasiliev22dd3f212022-02-11 21:57:292153 if (supported_versions_.size() == 2 &&
2154 quic::AlpnForVersion(supported_versions_[1]) ==
2155 quic::AlpnForVersion(version)) {
2156 continue;
2157 }
zhongyia00ca012017-07-06 23:36:392158 advertised_version_2 = version;
2159 break;
2160 }
Bence Békyb89104962020-01-24 00:05:172161 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:332162 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), advertised_version_2);
zhongyia00ca012017-07-06 23:36:392163
Bence Békyb89104962020-01-24 00:05:172164 std::string QuicAltSvcWithVersionHeader =
2165 base::StringPrintf("Alt-Svc: %s=\":443\", %s=\":443\"\r\n\r\n",
2166 quic::AlpnForVersion(advertised_version_2).c_str(),
2167 quic::AlpnForVersion(version_).c_str());
zhongyia00ca012017-07-06 23:36:392168
2169 MockRead http_reads[] = {
2170 MockRead("HTTP/1.1 200 OK\r\n"),
2171 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2172 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2173 MockRead(ASYNC, OK)};
2174
Ryan Sleevib8d7ea02018-05-07 20:01:012175 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392176 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082177 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392178 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2179
Ryan Hamiltonabad59e2019-06-06 04:02:592180 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232181 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022182 mock_quic_data.AddWrite(SYNCHRONOUS,
2183 ConstructInitialSettingsPacket(packet_num++));
zhongyia00ca012017-07-06 23:36:392184 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232185 SYNCHRONOUS,
2186 ConstructClientRequestHeadersPacket(
2187 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2188 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432189 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332190 ASYNC, ConstructServerResponseHeadersPacket(
2191 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282192 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332193 mock_quic_data.AddRead(
2194 ASYNC, ConstructServerDataPacket(
2195 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522196 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232197 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342198 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392199 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212200 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyia00ca012017-07-06 23:36:392201
2202 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2203
2204 AddHangingNonAlternateProtocolSocketData();
2205 CreateSession(supported_versions_);
2206
2207 SendRequestAndExpectHttpResponse("hello world");
2208 SendRequestAndExpectQuicResponse("hello!");
2209}
2210
Zhongyi Shi1c022d22020-03-20 19:00:162211TEST_P(QuicNetworkTransactionTest,
2212 PickQuicVersionWhenMultipleVersionsAreSupported) {
2213 // Client and server both support more than one QUIC_VERSION.
Patrick Meenan885a00652023-02-15 20:07:022214 // Client prefers common_version_2, and then |version_|.
2215 // Server prefers |version_| common_version_2.
David Schinazifbd4c432020-04-07 19:23:552216 // We should honor the server's preference.
Zhongyi Shi1c022d22020-03-20 19:00:162217 // The picked version is verified via checking the version used by the
2218 // TestPacketMakers and the response.
Patrick Meenan885a00652023-02-15 20:07:022219 // Since Chrome only supports one ALPN-negotiated version, common_version_2
2220 // will be another version that the common library supports even though
2221 // Chrome may consider it obsolete.
Bence Békyb89104962020-01-24 00:05:172222
Zhongyi Shi1c022d22020-03-20 19:00:162223 // Find an alternative commonly supported version other than |version_|.
David Schinazi84c58bb2020-06-04 20:14:332224 quic::ParsedQuicVersion common_version_2 =
2225 quic::ParsedQuicVersion::Unsupported();
2226 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Ryan Hamiltona51800a2022-02-12 19:34:352227 if (version != version_ && !version.AlpnDeferToRFCv1()) {
Zhongyi Shi1c022d22020-03-20 19:00:162228 common_version_2 = version;
2229 break;
2230 }
zhongyia00ca012017-07-06 23:36:392231 }
David Schinazi84c58bb2020-06-04 20:14:332232 ASSERT_NE(common_version_2, quic::ParsedQuicVersion::Unsupported());
zhongyia00ca012017-07-06 23:36:392233
Zhongyi Shi1c022d22020-03-20 19:00:162234 // Setting up client's preference list: {|version_|, |common_version_2|}.
2235 supported_versions_.clear();
Zhongyi Shi1c022d22020-03-20 19:00:162236 supported_versions_.push_back(common_version_2);
Patrick Meenan885a00652023-02-15 20:07:022237 supported_versions_.push_back(version_);
zhongyia00ca012017-07-06 23:36:392238
Zhongyi Shi1c022d22020-03-20 19:00:162239 // Setting up server's Alt-Svc header in the following preference order:
Patrick Meenan885a00652023-02-15 20:07:022240 // |version_|, |common_version_2|.
Zhongyi Shi1c022d22020-03-20 19:00:162241 std::string QuicAltSvcWithVersionHeader;
David Schinazi84c58bb2020-06-04 20:14:332242 quic::ParsedQuicVersion picked_version =
2243 quic::ParsedQuicVersion::Unsupported();
2244 QuicAltSvcWithVersionHeader =
Patrick Meenan885a00652023-02-15 20:07:022245 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"; ma=3600, " +
2246 quic::AlpnForVersion(common_version_2) + "=\":443\"; ma=3600\r\n\r\n";
2247 picked_version = version_; // Use server's preference.
zhongyia00ca012017-07-06 23:36:392248
2249 MockRead http_reads[] = {
2250 MockRead("HTTP/1.1 200 OK\r\n"),
2251 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2252 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2253 MockRead(ASYNC, OK)};
2254
Ryan Sleevib8d7ea02018-05-07 20:01:012255 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392256 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082257 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392258 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2259
Zhongyi Shi1c022d22020-03-20 19:00:162260 MockQuicData mock_quic_data(picked_version);
2261
2262 // Reset QuicTestPacket makers as the version picked may not be |version_|.
Renjie Tang6ff9a9b2021-02-03 22:11:092263 client_maker_ = std::make_unique<QuicTestPacketMaker>(
Zhongyi Shi1c022d22020-03-20 19:00:162264 picked_version,
2265 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2266 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky957bab12023-01-31 16:40:102267 true);
Zhongyi Shi1c022d22020-03-20 19:00:162268 QuicTestPacketMaker server_maker(
2269 picked_version,
2270 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2271 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
2272 false);
2273
Renjie Tangaadb84b2019-08-31 01:00:232274 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:162275 if (VersionUsesHttp3(picked_version.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232276 mock_quic_data.AddWrite(SYNCHRONOUS,
2277 ConstructInitialSettingsPacket(packet_num++));
2278 }
Zhongyi Shi1c022d22020-03-20 19:00:162279
2280 quic::QuicStreamId client_stream_0 =
2281 quic::test::GetNthClientInitiatedBidirectionalStreamId(
2282 picked_version.transport_version, 0);
2283 mock_quic_data.AddWrite(SYNCHRONOUS,
2284 ConstructClientRequestHeadersPacket(
2285 packet_num++, client_stream_0, true, true,
2286 GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashif8634ab2021-03-16 23:41:282287 mock_quic_data.AddRead(ASYNC,
2288 server_maker.MakeResponseHeadersPacket(
2289 1, client_stream_0, false, false,
2290 server_maker.GetResponseHeaders("200"), nullptr));
Fan Yang32c5a112018-12-10 20:06:332291 mock_quic_data.AddRead(
Bence Béky319388a882020-09-23 18:42:522292 ASYNC, server_maker.MakeDataPacket(
2293 2, client_stream_0, false, true,
2294 ConstructDataFrameForVersion("hello!", picked_version)));
Renjie Tangaadb84b2019-08-31 01:00:232295 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342296 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392297 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212298 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyia00ca012017-07-06 23:36:392299
2300 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2301
2302 AddHangingNonAlternateProtocolSocketData();
2303 CreateSession(supported_versions_);
2304
2305 SendRequestAndExpectHttpResponse("hello world");
Zhongyi Shi1c022d22020-03-20 19:00:162306 SendRequestAndExpectQuicResponseMaybeFromProxy(
Kenichi Ishibashif8634ab2021-03-16 23:41:282307 "hello!", false, 443, "HTTP/1.1 200", picked_version);
zhongyia00ca012017-07-06 23:36:392308}
2309
zhongyi3d4a55e72016-04-22 20:36:462310TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
Ryan Hamiltona51800a2022-02-12 19:34:352311 if (version_.AlpnDeferToRFCv1()) {
2312 // These versions currently do not support Alt-Svc.
2313 return;
2314 }
Ryan Hamiltona2dcbae2022-02-09 19:02:452315 std::string alt_svc_header = base::StrCat(
2316 {"Alt-Svc: ",
2317 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.com", 443), ",",
2318 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
zhongyi3d4a55e72016-04-22 20:36:462319 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452320 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
zhongyi3d4a55e72016-04-22 20:36:462321 MockRead("hello world"),
2322 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2323 MockRead(ASYNC, OK)};
2324
Ryan Sleevib8d7ea02018-05-07 20:01:012325 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462326 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082327 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462328 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2329
2330 CreateSession();
bncb26024382016-06-29 02:39:452331 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462332 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452333 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462334 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402335 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462336 session_->http_server_properties();
2337 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2338 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2339 // Check alternative service is set for the correct origin.
Brianna Goldstein02cb74f2022-09-29 05:41:012340 EXPECT_EQ(2u, http_server_properties
2341 ->GetAlternativeServiceInfos(https_server,
2342 NetworkAnonymizationKey())
2343 .size());
bncb26024382016-06-29 02:39:452344 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492345 http_server_properties
Brianna Goldstein02cb74f2022-09-29 05:41:012346 ->GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
Matt Menke3233d8f22019-08-20 21:01:492347 .empty());
zhongyi3d4a55e72016-04-22 20:36:462348}
2349
2350TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
Ryan Hamiltona51800a2022-02-12 19:34:352351 if (version_.AlpnDeferToRFCv1()) {
2352 // These versions currently do not support Alt-Svc.
2353 return;
2354 }
Ryan Hamiltona2dcbae2022-02-09 19:02:452355 std::string alt_svc_header = base::StrCat(
2356 {"Alt-Svc: ",
2357 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.com", 443), ",",
2358 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
zhongyi3d4a55e72016-04-22 20:36:462359 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452360 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
zhongyi3d4a55e72016-04-22 20:36:462361 MockRead("hello world"),
2362 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2363 MockRead(ASYNC, OK)};
2364
Ryan Sleevib8d7ea02018-05-07 20:01:012365 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082366 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462367
2368 socket_factory_.AddSocketDataProvider(&http_data);
2369 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2370 socket_factory_.AddSocketDataProvider(&http_data);
2371 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2372
2373 CreateSession();
2374
2375 // Send https request and set alternative services if response header
2376 // advertises alternative service for mail.example.org.
2377 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402378 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462379 session_->http_server_properties();
2380
2381 const url::SchemeHostPort https_server(request_.url);
2382 // Check alternative service is set.
Brianna Goldstein02cb74f2022-09-29 05:41:012383 EXPECT_EQ(2u, http_server_properties
2384 ->GetAlternativeServiceInfos(https_server,
2385 NetworkAnonymizationKey())
2386 .size());
zhongyi3d4a55e72016-04-22 20:36:462387
2388 // Send http request to the same origin but with diffrent scheme, should not
2389 // use QUIC.
2390 request_.url = GURL("http://mail.example.org:443");
2391 SendRequestAndExpectHttpResponse("hello world");
2392}
2393
zhongyie537a002017-06-27 16:48:212394TEST_P(QuicNetworkTransactionTest,
2395 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442396 // Add support for another QUIC version besides |version_|.
Patrick Meenan885a00652023-02-15 20:07:022397 for (const quic::ParsedQuicVersion& version : AllSupportedQuicVersions()) {
Bence Békyb89104962020-01-24 00:05:172398 if (version != version_) {
2399 supported_versions_.push_back(version);
2400 break;
2401 }
zhongyi86838d52017-06-30 01:19:442402 }
2403
David Schinazifbd4c432020-04-07 19:23:552404 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyie537a002017-06-27 16:48:212405 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:172406 MockRead("HTTP/1.1 200 OK\r\n"),
2407 MockRead(altsvc_header.c_str()),
2408 MockRead("\r\n"),
zhongyie537a002017-06-27 16:48:212409 MockRead("hello world"),
2410 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2411 MockRead(ASYNC, OK)};
2412
Ryan Sleevib8d7ea02018-05-07 20:01:012413 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212414 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082415 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212416 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2417
Ryan Hamiltonabad59e2019-06-06 04:02:592418 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232419 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022420 mock_quic_data.AddWrite(SYNCHRONOUS,
2421 ConstructInitialSettingsPacket(packet_num++));
zhongyie537a002017-06-27 16:48:212422 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232423 SYNCHRONOUS,
2424 ConstructClientRequestHeadersPacket(
2425 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2426 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432427 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332428 ASYNC, ConstructServerResponseHeadersPacket(
2429 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282430 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332431 mock_quic_data.AddRead(
2432 ASYNC, ConstructServerDataPacket(
2433 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522434 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232435 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342436 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyie537a002017-06-27 16:48:212437 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212438 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyie537a002017-06-27 16:48:212439
2440 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2441
2442 AddHangingNonAlternateProtocolSocketData();
2443
zhongyi86838d52017-06-30 01:19:442444 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212445
2446 SendRequestAndExpectHttpResponse("hello world");
2447 SendRequestAndExpectQuicResponse("hello!");
2448
Bence Békyb89104962020-01-24 00:05:172449 // Alt-Svc header contains all possible versions, so alternative services
2450 // should contain all of |supported_versions_|.
zhongyie537a002017-06-27 16:48:212451 const url::SchemeHostPort https_server(request_.url);
2452 const AlternativeServiceInfoVector alt_svc_info_vector =
2453 session_->http_server_properties()->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:012454 https_server, NetworkAnonymizationKey());
Victor Vasiliev22dd3f212022-02-11 21:57:292455 VerifyQuicVersionsInAlternativeServices(alt_svc_info_vector,
2456 supported_versions_);
zhongyie537a002017-06-27 16:48:212457}
2458
danzh3134c2562016-08-12 14:07:522459TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Ryan Hamiltona51800a2022-02-12 19:34:352460 if (version_.AlpnDeferToRFCv1()) {
2461 // These versions currently do not support Alt-Svc.
2462 return;
2463 }
Nick Harper23290b82019-05-02 00:02:562464 std::string altsvc_header = base::StringPrintf(
Bence Békyb89104962020-01-24 00:05:172465 "Alt-Svc: %s=\":443\"\r\n\r\n", quic::AlpnForVersion(version_).c_str());
bnc8be55ebb2015-10-30 14:12:072466 MockRead http_reads[] = {
2467 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2468 MockRead("hello world"),
2469 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2470 MockRead(ASYNC, OK)};
2471
Ryan Sleevib8d7ea02018-05-07 20:01:012472 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072473 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082474 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072475 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2476
Ryan Hamiltonabad59e2019-06-06 04:02:592477 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232478 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022479 mock_quic_data.AddWrite(SYNCHRONOUS,
2480 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:362481 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232482 SYNCHRONOUS,
2483 ConstructClientRequestHeadersPacket(
2484 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2485 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432486 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332487 ASYNC, ConstructServerResponseHeadersPacket(
2488 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282489 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332490 mock_quic_data.AddRead(
2491 ASYNC, ConstructServerDataPacket(
2492 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522493 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232494 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342495 ConstructClientAckPacket(packet_num++, 2, 1));
bnc8be55ebb2015-10-30 14:12:072496 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212497 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc8be55ebb2015-10-30 14:12:072498
2499 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2500
rtennetib8e80fb2016-05-16 00:12:092501 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322502 CreateSession();
bnc8be55ebb2015-10-30 14:12:072503
2504 SendRequestAndExpectHttpResponse("hello world");
2505 SendRequestAndExpectQuicResponse("hello!");
2506}
2507
rch9ecde09b2017-04-08 00:18:232508// Verify that if a QUIC connection times out, the QuicHttpStream will
2509// return QUIC_PROTOCOL_ERROR.
2510TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:382511 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Peter Kastinge5a38ed2021-10-02 03:06:352512 context_.params()->idle_connection_timeout = base::Seconds(5);
Renjie Tangd05389fe2022-07-13 23:46:232513 // Turn off port migration to avoid dealing with unnecessary complexity in
2514 // this test.
2515 context_.params()->allow_port_migration = false;
rch9ecde09b2017-04-08 00:18:232516
2517 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592518 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:132519 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232520 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2521
Zhongyi Shi1c022d22020-03-20 19:00:162522 client_maker_->set_save_packet_frames(true);
2523 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:492524 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022525 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton0d65a8c2019-06-07 00:46:022526 quic_data.AddWrite(
2527 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162528 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:492529 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky957bab12023-01-31 16:40:102530 true, priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:452531
Zhongyi Shi1c022d22020-03-20 19:00:162532 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:232533
Patrick Meenan885a00652023-02-15 20:07:022534 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2535 // sending PTO packets.
2536 packet_num++;
2537 // PTO 1
2538 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
2539 1, packet_num++, true));
2540 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2541 // sending PTO packets.
2542 packet_num++;
2543 // PTO 2
2544 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
2545 2, packet_num++, true));
2546 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2547 // sending PTO packets.
2548 packet_num++;
2549 // PTO 3
2550 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
2551 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:232552
Patrick Meenan885a00652023-02-15 20:07:022553 quic_data.AddWrite(SYNCHRONOUS,
2554 client_maker_->MakeConnectionClosePacket(
2555 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2556 "No recent network activity after 4s. Timeout:4s"));
Fan Yang928f1632017-12-14 18:55:222557
rch9ecde09b2017-04-08 00:18:232558 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2559 quic_data.AddRead(ASYNC, OK);
2560 quic_data.AddSocketDataToFactory(&socket_factory_);
2561
2562 // In order for a new QUIC session to be established via alternate-protocol
2563 // without racing an HTTP connection, we need the host resolution to happen
2564 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2565 // connection to the the server, in this test we require confirmation
2566 // before encrypting so the HTTP job will still start.
2567 host_resolver_.set_synchronous_mode(true);
2568 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2569 "");
rch9ecde09b2017-04-08 00:18:232570
2571 CreateSession();
2572 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232573 QuicStreamFactoryPeer::SetAlarmFactory(
2574 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192575 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222576 context_.clock()));
rch9ecde09b2017-04-08 00:18:232577
Ryan Hamilton9835e662018-08-02 05:36:272578 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232579
2580 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2581 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262582 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch9ecde09b2017-04-08 00:18:232583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2584
2585 // Pump the message loop to get the request started.
2586 base::RunLoop().RunUntilIdle();
2587 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:282588 crypto_client_stream_factory_.last_stream()
2589 ->NotifySessionOneRttKeyAvailable();
rch9ecde09b2017-04-08 00:18:232590
2591 // Run the QUIC session to completion.
2592 quic_task_runner_->RunUntilIdle();
2593
2594 ExpectQuicAlternateProtocolMapping();
2595 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2596 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2597}
2598
David Schinazi7e980ab2020-05-13 20:26:552599// TODO(fayang): Add time driven TOO_MANY_RTOS test.
rch9ecde09b2017-04-08 00:18:232600
rch2f2991c2017-04-13 19:28:172601// Verify that if a QUIC protocol error occurs after the handshake is confirmed
2602// the request fails with QUIC_PROTOCOL_ERROR.
2603TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:382604 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:172605 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592606 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:162607 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:492608 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022609 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Nick Harper057264a82019-09-12 23:33:492610 quic_data.AddWrite(
2611 SYNCHRONOUS,
2612 ConstructClientRequestHeadersPacket(
2613 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2614 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:162615 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:552616 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:172617 // Peer sending data from an non-existing stream causes this end to raise
2618 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:332619 quic_data.AddRead(
2620 ASYNC, ConstructServerRstPacket(
2621 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
2622 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:172623 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:342624 quic_data.AddWrite(
2625 SYNCHRONOUS,
2626 ConstructClientAckAndConnectionClosePacket(
Patrick Meenan885a00652023-02-15 20:07:022627 packet_num++, 1, 1, quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
2628 quic_error_details, quic::IETF_STOP_SENDING));
rch2f2991c2017-04-13 19:28:172629 quic_data.AddSocketDataToFactory(&socket_factory_);
2630
2631 // In order for a new QUIC session to be established via alternate-protocol
2632 // without racing an HTTP connection, we need the host resolution to happen
2633 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2634 // connection to the the server, in this test we require confirmation
2635 // before encrypting so the HTTP job will still start.
2636 host_resolver_.set_synchronous_mode(true);
2637 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2638 "");
rch2f2991c2017-04-13 19:28:172639
2640 CreateSession();
2641
Ryan Hamilton9835e662018-08-02 05:36:272642 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:172643
2644 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2645 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262646 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:172647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2648
2649 // Pump the message loop to get the request started.
2650 base::RunLoop().RunUntilIdle();
2651 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:282652 crypto_client_stream_factory_.last_stream()
2653 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:172654
2655 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:552656 quic_data.Resume();
rch2f2991c2017-04-13 19:28:172657
2658 // Run the QUIC session to completion.
2659 base::RunLoop().RunUntilIdle();
2660 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2661 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2662
2663 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2664 ExpectQuicAlternateProtocolMapping();
2665 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2666}
2667
rch2f2991c2017-04-13 19:28:172668// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
2669// connection times out, then QUIC will be marked as broken and the request
2670// retried over TCP.
2671TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Ryan Hamiltona51800a2022-02-12 19:34:352672 if (version_.AlpnDeferToRFCv1()) {
2673 // These versions currently do not support Alt-Svc.
2674 return;
2675 }
Peter Kastinge5a38ed2021-10-02 03:06:352676 context_.params()->idle_connection_timeout = base::Seconds(5);
Renjie Tangd05389fe2022-07-13 23:46:232677 // Turn off port migration to avoid dealing with unnecessary complexity in
2678 // this test.
2679 context_.params()->allow_port_migration = false;
rch2f2991c2017-04-13 19:28:172680
2681 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592682 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:132683 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:172684 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2685
Zhongyi Shi1c022d22020-03-20 19:00:162686 client_maker_->set_save_packet_frames(true);
2687 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:492688 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022689 quic_data.AddWrite(SYNCHRONOUS,
2690 client_maker_->MakeInitialSettingsPacket(packet_num++));
Ryan Hamilton0d65a8c2019-06-07 00:46:022691 quic_data.AddWrite(
2692 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162693 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:492694 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky957bab12023-01-31 16:40:102695 true, priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:452696
Zhongyi Shi1c022d22020-03-20 19:00:162697 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Patrick Meenan885a00652023-02-15 20:07:022698 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2699 // sending PTO packets.
2700 packet_num++;
2701 // PTO 1
2702 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
2703 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:232704
Patrick Meenan885a00652023-02-15 20:07:022705 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2706 // sending PTO packets.
2707 packet_num++;
2708 // PTO 2
2709 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
2710 2, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:232711
Patrick Meenan885a00652023-02-15 20:07:022712 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2713 // sending PTO packets.
2714 packet_num++;
2715 // PTO 3
2716 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
2717 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:232718
Patrick Meenan885a00652023-02-15 20:07:022719 quic_data.AddWrite(SYNCHRONOUS,
2720 client_maker_->MakeConnectionClosePacket(
2721 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2722 "No recent network activity after 4s. Timeout:4s"));
Fan Yang928f1632017-12-14 18:55:222723
rch2f2991c2017-04-13 19:28:172724 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2725 quic_data.AddRead(ASYNC, OK);
2726 quic_data.AddSocketDataToFactory(&socket_factory_);
2727
2728 // After that fails, it will be resent via TCP.
2729 MockWrite http_writes[] = {
2730 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2731 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2732 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2733
Ryan Hamiltona2dcbae2022-02-09 19:02:452734 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2735 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
2736 MockRead(SYNCHRONOUS, 5, "hello world"),
2737 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:012738 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:172739 socket_factory_.AddSocketDataProvider(&http_data);
2740 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2741
2742 // In order for a new QUIC session to be established via alternate-protocol
2743 // without racing an HTTP connection, we need the host resolution to happen
2744 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2745 // connection to the the server, in this test we require confirmation
2746 // before encrypting so the HTTP job will still start.
2747 host_resolver_.set_synchronous_mode(true);
2748 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2749 "");
rch2f2991c2017-04-13 19:28:172750
2751 CreateSession();
2752 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:172753 QuicStreamFactoryPeer::SetAlarmFactory(
2754 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192755 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222756 context_.clock()));
rch2f2991c2017-04-13 19:28:172757
Ryan Hamilton9835e662018-08-02 05:36:272758 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:172759
2760 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2761 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262762 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:172763 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2764
2765 // Pump the message loop to get the request started.
2766 base::RunLoop().RunUntilIdle();
2767 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:282768 crypto_client_stream_factory_.last_stream()
2769 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:172770
2771 // Run the QUIC session to completion.
2772 quic_task_runner_->RunUntilIdle();
2773 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2774
2775 ExpectQuicAlternateProtocolMapping();
2776
2777 // Let the transaction proceed which will result in QUIC being marked
2778 // as broken and the request falling back to TCP.
2779 EXPECT_THAT(callback.WaitForResult(), IsOk());
2780
2781 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2782 ASSERT_FALSE(http_data.AllReadDataConsumed());
2783
2784 // Read the response body over TCP.
2785 CheckResponseData(&trans, "hello world");
2786 ExpectBrokenAlternateProtocolMapping();
2787 ASSERT_TRUE(http_data.AllWriteDataConsumed());
2788 ASSERT_TRUE(http_data.AllReadDataConsumed());
2789}
2790
rch2f2991c2017-04-13 19:28:172791// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
2792// protocol error occurs after the handshake is confirmed, the request
2793// retried over TCP and the QUIC will be marked as broken.
2794TEST_P(QuicNetworkTransactionTest,
2795 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:352796 if (version_.AlpnDeferToRFCv1()) {
2797 // These versions currently do not support Alt-Svc.
2798 return;
2799 }
Peter Kastinge5a38ed2021-10-02 03:06:352800 context_.params()->idle_connection_timeout = base::Seconds(5);
rch2f2991c2017-04-13 19:28:172801
2802 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592803 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:162804 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:492805 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022806 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Nick Harper057264a82019-09-12 23:33:492807 quic_data.AddWrite(
2808 SYNCHRONOUS,
2809 ConstructClientRequestHeadersPacket(
2810 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2811 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:162812 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:552813 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2814
rch2f2991c2017-04-13 19:28:172815 // Peer sending data from an non-existing stream causes this end to raise
2816 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:332817 quic_data.AddRead(
2818 ASYNC, ConstructServerRstPacket(
2819 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
2820 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:172821 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:342822 quic_data.AddWrite(
2823 SYNCHRONOUS,
2824 ConstructClientAckAndConnectionClosePacket(
Patrick Meenan885a00652023-02-15 20:07:022825 packet_num++, 1, 1, quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
2826 quic_error_details, quic::IETF_STOP_SENDING));
rch2f2991c2017-04-13 19:28:172827 quic_data.AddSocketDataToFactory(&socket_factory_);
2828
2829 // After that fails, it will be resent via TCP.
2830 MockWrite http_writes[] = {
2831 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2832 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2833 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2834
Ryan Hamiltona2dcbae2022-02-09 19:02:452835 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2836 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
2837 MockRead(SYNCHRONOUS, 5, "hello world"),
2838 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:012839 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:172840 socket_factory_.AddSocketDataProvider(&http_data);
2841 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2842
2843 // In order for a new QUIC session to be established via alternate-protocol
2844 // without racing an HTTP connection, we need the host resolution to happen
2845 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2846 // connection to the the server, in this test we require confirmation
2847 // before encrypting so the HTTP job will still start.
2848 host_resolver_.set_synchronous_mode(true);
2849 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2850 "");
rch2f2991c2017-04-13 19:28:172851
2852 CreateSession();
2853
Ryan Hamilton9835e662018-08-02 05:36:272854 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:172855
2856 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2857 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262858 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:172859 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2860
2861 // Pump the message loop to get the request started.
2862 base::RunLoop().RunUntilIdle();
2863 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:282864 crypto_client_stream_factory_.last_stream()
2865 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:552866 quic_data.Resume();
rch2f2991c2017-04-13 19:28:172867
2868 // Run the QUIC session to completion.
2869 base::RunLoop().RunUntilIdle();
2870 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2871
2872 ExpectQuicAlternateProtocolMapping();
2873
2874 // Let the transaction proceed which will result in QUIC being marked
2875 // as broken and the request falling back to TCP.
2876 EXPECT_THAT(callback.WaitForResult(), IsOk());
2877
2878 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2879 ASSERT_FALSE(http_data.AllReadDataConsumed());
2880
2881 // Read the response body over TCP.
2882 CheckResponseData(&trans, "hello world");
2883 ExpectBrokenAlternateProtocolMapping();
2884 ASSERT_TRUE(http_data.AllWriteDataConsumed());
2885 ASSERT_TRUE(http_data.AllReadDataConsumed());
2886}
2887
Brianna Goldsteind22b0642022-10-11 16:30:502888// Much like above test, but verifies that NetworkAnonymizationKey is respected.
Matt Menkeb32ba5122019-09-10 19:17:052889TEST_P(QuicNetworkTransactionTest,
2890 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:352891 if (version_.AlpnDeferToRFCv1()) {
2892 // These versions currently do not support Alt-Svc.
2893 return;
2894 }
Matt Menke4807a9a2020-11-21 00:14:412895 const SchemefulSite kSite1(GURL("https://foo.test/"));
2896 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Brianna Goldstein314ddf722022-09-24 02:00:522897 const net::NetworkAnonymizationKey kNetworkAnonymizationKey1(kSite1, kSite1);
Matt Menke4807a9a2020-11-21 00:14:412898 const SchemefulSite kSite2(GURL("https://bar.test/"));
2899 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Brianna Goldstein314ddf722022-09-24 02:00:522900 const net::NetworkAnonymizationKey kNetworkAnonymizationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:052901
2902 base::test::ScopedFeatureList feature_list;
2903 feature_list.InitWithFeatures(
2904 // enabled_features
2905 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2906 features::kPartitionConnectionsByNetworkIsolationKey},
2907 // disabled_features
2908 {});
2909 // Since HttpServerProperties caches the feature value, have to create a new
2910 // one.
2911 http_server_properties_ = std::make_unique<HttpServerProperties>();
2912
Peter Kastinge5a38ed2021-10-02 03:06:352913 context_.params()->idle_connection_timeout = base::Seconds(5);
Matt Menkeb32ba5122019-09-10 19:17:052914
2915 // The request will initially go out over QUIC.
2916 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:562917 uint64_t packet_number = 1;
Zhongyi Shi1c022d22020-03-20 19:00:162918 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:022919 quic_data.AddWrite(SYNCHRONOUS,
2920 ConstructInitialSettingsPacket(packet_number++));
Renjie Tang874398a2019-09-13 18:32:562921 quic_data.AddWrite(
2922 SYNCHRONOUS,
2923 ConstructClientRequestHeadersPacket(
2924 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2925 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:162926 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:052927 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2928
2929 // Peer sending data from an non-existing stream causes this end to raise
2930 // error and close connection.
2931 quic_data.AddRead(
2932 ASYNC, ConstructServerRstPacket(
2933 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
2934 quic::QUIC_STREAM_LAST_ERROR));
2935 std::string quic_error_details = "Data for nonexistent stream";
Nick Harper1ccb0ce2020-10-07 00:28:582936 quic::QuicErrorCode quic_error_code = quic::QUIC_INVALID_STREAM_ID;
Patrick Meenan885a00652023-02-15 20:07:022937 quic_error_code = quic::QUIC_HTTP_STREAM_WRONG_DIRECTION;
2938 quic_data.AddWrite(SYNCHRONOUS,
2939 ConstructClientAckAndConnectionClosePacket(
2940 packet_number++, 1, 1, quic_error_code,
2941 quic_error_details, quic::IETF_STOP_SENDING));
Matt Menkeb32ba5122019-09-10 19:17:052942 quic_data.AddSocketDataToFactory(&socket_factory_);
2943
2944 // After that fails, it will be resent via TCP.
2945 MockWrite http_writes[] = {
2946 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2947 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2948 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2949
Ryan Hamiltona2dcbae2022-02-09 19:02:452950 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2951 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
2952 MockRead(SYNCHRONOUS, 5, "hello world"),
2953 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:052954 SequencedSocketData http_data(http_reads, http_writes);
2955 socket_factory_.AddSocketDataProvider(&http_data);
2956 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2957
2958 // In order for a new QUIC session to be established via alternate-protocol
2959 // without racing an HTTP connection, we need the host resolution to happen
2960 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2961 // connection to the the server, in this test we require confirmation
2962 // before encrypting so the HTTP job will still start.
2963 host_resolver_.set_synchronous_mode(true);
2964 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2965 "");
2966
2967 CreateSession();
2968
2969 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
Brianna Goldstein02cb74f2022-09-29 05:41:012970 kNetworkAnonymizationKey1);
Matt Menkeb32ba5122019-09-10 19:17:052971 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
Brianna Goldstein02cb74f2022-09-29 05:41:012972 kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:052973
2974 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2975 TestCompletionCallback callback;
2976 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:522977 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Reichhoff0049a0b72021-10-20 20:44:262978 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeb32ba5122019-09-10 19:17:052979 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2980
2981 // Pump the message loop to get the request started.
2982 base::RunLoop().RunUntilIdle();
2983 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:282984 crypto_client_stream_factory_.last_stream()
2985 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:052986 quic_data.Resume();
2987
2988 // Run the QUIC session to completion.
2989 base::RunLoop().RunUntilIdle();
2990 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2991
2992 // Let the transaction proceed which will result in QUIC being marked
2993 // as broken and the request falling back to TCP.
2994 EXPECT_THAT(callback.WaitForResult(), IsOk());
2995 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2996 ASSERT_FALSE(http_data.AllReadDataConsumed());
2997
2998 // Read the response body over TCP.
2999 CheckResponseData(&trans, "hello world");
3000 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3001 ASSERT_TRUE(http_data.AllReadDataConsumed());
3002
3003 // The alternative service shouldhave been marked as broken under
3004 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
Brianna Goldstein02cb74f2022-09-29 05:41:013005 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
3006 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:053007
3008 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3009 AddHttpDataAndRunRequest();
3010 // Requests using other NetworkIsolationKeys can still use QUIC.
3011 request_.network_isolation_key = kNetworkIsolationKey2;
Brianna Goldstein314ddf722022-09-24 02:00:523012 request_.network_anonymization_key = kNetworkAnonymizationKey2;
3013
Matt Menkeb32ba5122019-09-10 19:17:053014 AddQuicDataAndRunRequest();
3015
3016 // The last two requests should not have changed the alternative service
3017 // mappings.
Brianna Goldstein02cb74f2022-09-29 05:41:013018 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
3019 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:053020}
3021
Tsuyoshi Horo0f740832022-11-28 22:36:213022TEST_P(QuicNetworkTransactionTest,
3023 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithUseDnsHttpsSvcbAlpn) {
Tsuyoshi Horo94cc9fa2023-01-19 00:04:573024 session_params_.use_dns_https_svcb_alpn = true;
Tsuyoshi Horo0f740832022-11-28 22:36:213025 context_.params()->idle_connection_timeout = base::Seconds(5);
3026
3027 // The request will initially go out over QUIC.
3028 MockQuicData quic_data(version_);
3029 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
3030 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023031 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Tsuyoshi Horo0f740832022-11-28 22:36:213032 quic_data.AddWrite(
3033 SYNCHRONOUS,
3034 ConstructClientRequestHeadersPacket(
3035 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3036 true, GetRequestHeaders("GET", "https", "/")));
3037 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
3038 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3039
3040 // Peer sending data from an non-existing stream causes this end to raise
3041 // error and close connection.
3042 quic_data.AddRead(
3043 ASYNC, ConstructServerRstPacket(
3044 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3045 quic::QUIC_STREAM_LAST_ERROR));
3046 std::string quic_error_details = "Data for nonexistent stream";
3047 quic_data.AddWrite(
3048 SYNCHRONOUS,
3049 ConstructClientAckAndConnectionClosePacket(
Patrick Meenan885a00652023-02-15 20:07:023050 packet_num++, 1, 1, quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
3051 quic_error_details, quic::IETF_STOP_SENDING));
Tsuyoshi Horo0f740832022-11-28 22:36:213052 quic_data.AddSocketDataToFactory(&socket_factory_);
3053
3054 // After that fails, it will be resent via TCP.
3055 MockWrite http_writes[] = {
3056 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3057 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3058 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3059
3060 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3061 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3062 MockRead(SYNCHRONOUS, 5, "hello world"),
3063 MockRead(SYNCHRONOUS, OK, 6)};
3064 SequencedSocketData http_data(http_reads, http_writes);
3065 socket_factory_.AddSocketDataProvider(&http_data);
3066 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3067
3068 HostResolverEndpointResult endpoint_result1;
3069 endpoint_result1.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
3070 endpoint_result1.metadata.supported_protocol_alpns = {
3071 quic::QuicVersionLabelToString(quic::CreateQuicVersionLabel(version_))};
3072 HostResolverEndpointResult endpoint_result2;
3073 endpoint_result2.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
3074 std::vector<HostResolverEndpointResult> endpoints;
3075 endpoints.push_back(endpoint_result1);
3076 endpoints.push_back(endpoint_result2);
3077 host_resolver_.rules()->AddRule(
3078 "mail.example.org",
3079 MockHostResolverBase::RuleResolver::RuleResult(
3080 std::move(endpoints),
3081 /*aliases=*/std::set<std::string>{"mail.example.org"}));
3082
3083 CreateSession();
3084
3085 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
3086
3087 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3088 TestCompletionCallback callback;
3089 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
3090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3091
3092 // Pump the message loop to get the request started.
3093 base::RunLoop().RunUntilIdle();
3094 // Explicitly confirm the handshake.
3095 crypto_client_stream_factory_.last_stream()
3096 ->NotifySessionOneRttKeyAvailable();
3097 quic_data.Resume();
3098
3099 // Run the QUIC session to completion.
3100 base::RunLoop().RunUntilIdle();
3101 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3102
3103 ExpectQuicAlternateProtocolMapping();
3104
3105 // Let the transaction proceed which will result in QUIC being marked
3106 // as broken and the request falling back to TCP.
3107 EXPECT_THAT(callback.WaitForResult(), IsOk());
3108
3109 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3110 ASSERT_FALSE(http_data.AllReadDataConsumed());
3111
3112 // Read the response body over TCP.
3113 CheckResponseData(&trans, "hello world");
3114 ExpectBrokenAlternateProtocolMapping();
3115 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3116 ASSERT_TRUE(http_data.AllReadDataConsumed());
3117}
3118
rch30943ee2017-06-12 21:28:443119// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3120// request is reset from, then QUIC will be marked as broken and the request
3121// retried over TCP.
3122TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:353123 if (version_.AlpnDeferToRFCv1()) {
3124 // These versions currently do not support Alt-Svc.
3125 return;
3126 }
rch30943ee2017-06-12 21:28:443127 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593128 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133129 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443130 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3131
Zhongyi Shi1c022d22020-03-20 19:00:163132 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493133 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023134 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton0d65a8c2019-06-07 00:46:023135 quic_data.AddWrite(
3136 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163137 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493138 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky957bab12023-01-31 16:40:103139 true, priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453140
Zhongyi Shi1c022d22020-03-20 19:00:163141 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553142 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443143
Fan Yang32c5a112018-12-10 20:06:333144 quic_data.AddRead(ASYNC,
3145 ConstructServerRstPacket(
3146 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3147 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443148
Patrick Meenan885a00652023-02-15 20:07:023149 quic_data.AddWrite(
3150 SYNCHRONOUS,
3151 client_maker_->MakeAckRstAndDataPacket(
3152 packet_num++, true, GetNthClientInitiatedBidirectionalStreamId(0),
3153 quic::QUIC_HEADERS_TOO_LARGE, 1, 1, GetQpackDecoderStreamId(), false,
3154 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:073155
rch30943ee2017-06-12 21:28:443156 quic_data.AddRead(ASYNC, OK);
3157 quic_data.AddSocketDataToFactory(&socket_factory_);
3158
3159 // After that fails, it will be resent via TCP.
3160 MockWrite http_writes[] = {
3161 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3162 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3163 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3164
Ryan Hamiltona2dcbae2022-02-09 19:02:453165 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3166 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3167 MockRead(SYNCHRONOUS, 5, "hello world"),
3168 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013169 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443170 socket_factory_.AddSocketDataProvider(&http_data);
3171 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3172
3173 // In order for a new QUIC session to be established via alternate-protocol
3174 // without racing an HTTP connection, we need the host resolution to happen
3175 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3176 // connection to the the server, in this test we require confirmation
3177 // before encrypting so the HTTP job will still start.
3178 host_resolver_.set_synchronous_mode(true);
3179 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3180 "");
rch30943ee2017-06-12 21:28:443181
3182 CreateSession();
3183
Ryan Hamilton9835e662018-08-02 05:36:273184 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443185
3186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3187 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263188 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch30943ee2017-06-12 21:28:443189 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3190
3191 // Pump the message loop to get the request started.
3192 base::RunLoop().RunUntilIdle();
3193 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283194 crypto_client_stream_factory_.last_stream()
3195 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553196 quic_data.Resume();
rch30943ee2017-06-12 21:28:443197
3198 // Run the QUIC session to completion.
3199 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3200
3201 ExpectQuicAlternateProtocolMapping();
3202
3203 // Let the transaction proceed which will result in QUIC being marked
3204 // as broken and the request falling back to TCP.
3205 EXPECT_THAT(callback.WaitForResult(), IsOk());
3206
3207 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3208 ASSERT_FALSE(http_data.AllReadDataConsumed());
3209
3210 // Read the response body over TCP.
3211 CheckResponseData(&trans, "hello world");
3212 ExpectBrokenAlternateProtocolMapping();
3213 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3214 ASSERT_TRUE(http_data.AllReadDataConsumed());
3215}
3216
Ryan Hamilton6c2a2a82017-12-15 02:06:283217// Verify that when an origin has two alt-svc advertisements, one local and one
3218// remote, that when the local is broken the request will go over QUIC via
3219// the remote Alt-Svc.
3220// This is a regression test for crbug/825646.
3221TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:383222 context_.params()->allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:283223
3224 GURL origin1 = request_.url; // mail.example.org
3225 GURL origin2("https://www.example.org/");
3226 ASSERT_NE(origin1.host(), origin2.host());
3227
3228 scoped_refptr<X509Certificate> cert(
3229 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243230 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3231 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283232
3233 ProofVerifyDetailsChromium verify_details;
3234 verify_details.cert_verify_result.verified_cert = cert;
3235 verify_details.cert_verify_result.is_issued_by_known_root = true;
3236 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3237
Ryan Hamiltonabad59e2019-06-06 04:02:593238 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233239 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023240 mock_quic_data.AddWrite(SYNCHRONOUS,
3241 ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton6c2a2a82017-12-15 02:06:283242 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233243 SYNCHRONOUS,
3244 ConstructClientRequestHeadersPacket(
3245 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3246 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433247 mock_quic_data.AddRead(
3248 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333249 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283250 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433251 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333252 ASYNC, ConstructServerDataPacket(
3253 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523254 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233255 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343256 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283257 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213258 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamilton6c2a2a82017-12-15 02:06:283259
3260 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:593261 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:283262 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3263 AddHangingNonAlternateProtocolSocketData();
3264
3265 CreateSession();
3266
3267 // Set up alternative service for |origin1|.
3268 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3269 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
Peter Kastinge5a38ed2021-10-02 03:06:353270 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamilton6c2a2a82017-12-15 02:06:283271 AlternativeServiceInfoVector alternative_services;
3272 alternative_services.push_back(
3273 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3274 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383275 context_.params()->supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:283276 alternative_services.push_back(
3277 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3278 remote_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383279 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:493280 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
Brianna Goldstein02cb74f2022-09-29 05:41:013281 NetworkAnonymizationKey(),
Matt Menke3233d8f22019-08-20 21:01:493282 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:283283
Brianna Goldstein02cb74f2022-09-29 05:41:013284 http_server_properties_->MarkAlternativeServiceBroken(
3285 local_alternative, NetworkAnonymizationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:283286
3287 SendRequestAndExpectQuicResponse("hello!");
3288}
3289
Ryan Hamilton899c2e082019-11-14 01:22:023290// Verify that when multiple alternatives are broken,
3291// ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
3292// This is a regression test for crbug/1024613.
3293TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
Ryan Hamiltona51800a2022-02-12 19:34:353294 if (version_.AlpnDeferToRFCv1()) {
3295 // These versions currently do not support Alt-Svc.
3296 return;
3297 }
Ryan Hamilton899c2e082019-11-14 01:22:023298 base::HistogramTester histogram_tester;
3299
3300 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453301 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Ryan Hamilton899c2e082019-11-14 01:22:023302 MockRead("hello world"),
3303 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3304 MockRead(ASYNC, OK)};
3305
3306 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
3307 socket_factory_.AddSocketDataProvider(&http_data);
3308 AddCertificate(&ssl_data_);
3309 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3310
3311 GURL origin1 = request_.url; // mail.example.org
3312
3313 scoped_refptr<X509Certificate> cert(
3314 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
3315 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
3316
3317 ProofVerifyDetailsChromium verify_details;
3318 verify_details.cert_verify_result.verified_cert = cert;
3319 verify_details.cert_verify_result.is_issued_by_known_root = true;
3320 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3321
3322 CreateSession();
3323
3324 // Set up alternative service for |origin1|.
3325 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
Peter Kastinge5a38ed2021-10-02 03:06:353326 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamilton899c2e082019-11-14 01:22:023327 AlternativeServiceInfoVector alternative_services;
3328 alternative_services.push_back(
3329 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3330 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383331 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:023332 alternative_services.push_back(
3333 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3334 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383335 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:023336 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
Brianna Goldstein02cb74f2022-09-29 05:41:013337 NetworkAnonymizationKey(),
Ryan Hamilton899c2e082019-11-14 01:22:023338 alternative_services);
3339
Brianna Goldstein02cb74f2022-09-29 05:41:013340 http_server_properties_->MarkAlternativeServiceBroken(
3341 local_alternative, NetworkAnonymizationKey());
Ryan Hamilton899c2e082019-11-14 01:22:023342
3343 SendRequestAndExpectHttpResponse("hello world");
3344
3345 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
3346 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
3347}
3348
rch30943ee2017-06-12 21:28:443349// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3350// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:053351// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:443352// connection instead of going back to the broken QUIC connection.
3353// This is a regression tests for crbug/731303.
3354TEST_P(QuicNetworkTransactionTest,
3355 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:353356 if (version_.AlpnDeferToRFCv1()) {
3357 // These versions currently do not support Alt-Svc.
3358 return;
3359 }
Victor Vasilieva1e66d72019-12-05 17:55:383360 context_.params()->allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:443361
3362 GURL origin1 = request_.url;
3363 GURL origin2("https://www.example.org/");
3364 ASSERT_NE(origin1.host(), origin2.host());
3365
Ryan Hamiltonabad59e2019-06-06 04:02:593366 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:443367
3368 scoped_refptr<X509Certificate> cert(
3369 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243370 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3371 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:443372
3373 ProofVerifyDetailsChromium verify_details;
3374 verify_details.cert_verify_result.verified_cert = cert;
3375 verify_details.cert_verify_result.is_issued_by_known_root = true;
3376 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3377
Renjie Tangaadb84b2019-08-31 01:00:233378 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023379 mock_quic_data.AddWrite(SYNCHRONOUS,
3380 ConstructInitialSettingsPacket(packet_num++));
rch30943ee2017-06-12 21:28:443381 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433382 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233383 SYNCHRONOUS,
3384 ConstructClientRequestHeadersPacket(
3385 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3386 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433387 mock_quic_data.AddRead(
3388 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333389 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283390 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433391 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333392 ASYNC, ConstructServerDataPacket(
3393 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523394 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233395 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343396 ConstructClientAckPacket(packet_num++, 2, 1));
rch30943ee2017-06-12 21:28:443397
3398 // Second request will go over the pooled QUIC connection, but will be
3399 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:053400 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:223401 version_,
3402 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Bence Béky957bab12023-01-31 16:40:103403 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT, true);
David Schinazic8281052019-01-24 06:14:173404 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:223405 version_,
3406 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
3407 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:433408 mock_quic_data.AddWrite(
3409 SYNCHRONOUS,
3410 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:233411 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky957bab12023-01-31 16:40:103412 true, GetRequestHeaders("GET", "https", "/", &client_maker2)));
Fan Yang32c5a112018-12-10 20:06:333413 mock_quic_data.AddRead(
3414 ASYNC, ConstructServerRstPacket(
3415 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
3416 quic::QUIC_HEADERS_TOO_LARGE));
Bence Béky6e243aa2019-12-13 19:01:073417
Patrick Meenan885a00652023-02-15 20:07:023418 mock_quic_data.AddWrite(
3419 SYNCHRONOUS,
3420 client_maker_->MakeAckRstAndDataPacket(
3421 packet_num++, /*include_version=*/true,
3422 GetNthClientInitiatedBidirectionalStreamId(1),
3423 quic::QUIC_HEADERS_TOO_LARGE, 3, 2, GetQpackDecoderStreamId(),
3424 /*fin=*/false, StreamCancellationQpackDecoderInstruction(1)));
Bence Béky6e243aa2019-12-13 19:01:073425
rch30943ee2017-06-12 21:28:443426 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213427 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rch30943ee2017-06-12 21:28:443428
3429 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3430
3431 // After that fails, it will be resent via TCP.
3432 MockWrite http_writes[] = {
3433 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3434 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
3435 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3436
Ryan Hamiltona2dcbae2022-02-09 19:02:453437 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3438 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3439 MockRead(SYNCHRONOUS, 5, "hello world"),
3440 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013441 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443442 socket_factory_.AddSocketDataProvider(&http_data);
3443 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3444
Ryan Hamilton6c2a2a82017-12-15 02:06:283445 // Then the next request to the second origin will be sent over TCP.
3446 socket_factory_.AddSocketDataProvider(&http_data);
3447 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:443448
3449 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563450 QuicStreamFactoryPeer::SetAlarmFactory(
3451 session_->quic_stream_factory(),
3452 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223453 context_.clock()));
rch30943ee2017-06-12 21:28:443454
3455 // Set up alternative service for |origin1|.
Peter Kastinge5a38ed2021-10-02 03:06:353456 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:243457 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:493458 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013459 url::SchemeHostPort(origin1), NetworkAnonymizationKey(), alternative1,
Matt Menke9aa86262019-08-21 15:52:073460 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:443461
3462 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:243463 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:493464 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013465 url::SchemeHostPort(origin2), NetworkAnonymizationKey(), alternative2,
Matt Menke9aa86262019-08-21 15:52:073466 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:343467
rch30943ee2017-06-12 21:28:443468 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:523469 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:443470 SendRequestAndExpectQuicResponse("hello!");
3471
3472 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:523473 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:053474 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:443475 request_.url = origin2;
3476 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:053477 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:013478 alternative1, NetworkAnonymizationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:243479 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:053480 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:013481 alternative2, NetworkAnonymizationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:243482 << alternative2.ToString();
rch30943ee2017-06-12 21:28:443483
Matt Menkeb32ba5122019-09-10 19:17:053484 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:443485 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:283486 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:443487}
3488
bnc8be55ebb2015-10-30 14:12:073489TEST_P(QuicNetworkTransactionTest,
3490 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Ryan Hamiltona51800a2022-02-12 19:34:353491 if (version_.AlpnDeferToRFCv1()) {
3492 // These versions currently do not support Alt-Svc.
3493 return;
3494 }
Nick Harper23290b82019-05-02 00:02:563495 std::string altsvc_header =
3496 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
3497 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:073498 MockRead http_reads[] = {
3499 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
3500 MockRead("hello world"),
3501 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3502 MockRead(ASYNC, OK)};
3503
Ryan Sleevib8d7ea02018-05-07 20:01:013504 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:073505 socket_factory_.AddSocketDataProvider(&http_data);
3506 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3507 socket_factory_.AddSocketDataProvider(&http_data);
3508 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3509
rch3f4b8452016-02-23 16:59:323510 CreateSession();
bnc8be55ebb2015-10-30 14:12:073511
3512 SendRequestAndExpectHttpResponse("hello world");
3513 SendRequestAndExpectHttpResponse("hello world");
3514}
3515
Xida Chen9bfe0b62018-04-24 19:52:213516// When multiple alternative services are advertised, HttpStreamFactory should
3517// select the alternative service which uses existing QUIC session if available.
3518// If no existing QUIC session can be used, use the first alternative service
3519// from the list.
zhongyi32569c62016-01-08 02:54:303520TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:353521 if (version_.AlpnDeferToRFCv1()) {
3522 // These versions currently do not support Alt-Svc.
3523 return;
3524 }
Victor Vasilieva1e66d72019-12-05 17:55:383525 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltona2dcbae2022-02-09 19:02:453526 std::string alt_svc_header = base::StrCat(
3527 {"Alt-Svc: ",
3528 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.org", 443), ",",
3529 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
bncc958faa2015-07-31 18:14:523530 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453531 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
bncc958faa2015-07-31 18:14:523532 MockRead("hello world"),
3533 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3534 MockRead(ASYNC, OK)};
3535
Ryan Sleevib8d7ea02018-05-07 20:01:013536 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:523537 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:083538 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:563539 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:523540
zhongyi32569c62016-01-08 02:54:303541 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:293542 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:303543 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:593544 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233545 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023546 mock_quic_data.AddWrite(SYNCHRONOUS,
3547 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:363548 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233549 SYNCHRONOUS,
3550 ConstructClientRequestHeadersPacket(
3551 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3552 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:303553
Ryan Hamiltona2dcbae2022-02-09 19:02:453554 std::string alt_svc_list = base::StrCat(
3555 {GenerateQuicAltSvcHeaderValue({version_}, "mail.example.org", 444), ",",
3556 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.org", 443), ",",
3557 GenerateQuicAltSvcHeaderValue({version_}, "bar.example.org", 445)});
Zhongyi Shi32f2fd02018-04-16 18:23:433558 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:023559 ASYNC, ConstructServerResponseHeadersPacket(
3560 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283561 GetResponseHeaders("200", alt_svc_list)));
Zhongyi Shi32f2fd02018-04-16 18:23:433562 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333563 ASYNC, ConstructServerDataPacket(
3564 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523565 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233566 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343567 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:303568
3569 // Second QUIC request data.
3570 // Connection pooling, using existing session, no need to include version
3571 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:583572 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233573 SYNCHRONOUS,
3574 ConstructClientRequestHeadersPacket(
3575 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky957bab12023-01-31 16:40:103576 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433577 mock_quic_data.AddRead(
3578 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333579 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283580 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433581 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333582 ASYNC, ConstructServerDataPacket(
3583 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:523584 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:473585 mock_quic_data.AddWrite(SYNCHRONOUS,
3586 ConstructClientAckPacket(packet_num++, 4, 3));
bncc958faa2015-07-31 18:14:523587 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213588 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:523589
3590 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3591
rtennetib8e80fb2016-05-16 00:12:093592 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:323593 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563594 QuicStreamFactoryPeer::SetAlarmFactory(
3595 session_->quic_stream_factory(),
3596 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223597 context_.clock()));
bncc958faa2015-07-31 18:14:523598
3599 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:303600
bnc359ed2a2016-04-29 20:43:453601 SendRequestAndExpectQuicResponse("hello!");
3602 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:303603}
3604
Ryan Hamilton8d9ee76e2018-05-29 23:52:523605// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:453606// even if alternative service destination is different.
3607TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Victor Vasilieva1e66d72019-12-05 17:55:383608 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:593609 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:453610
Renjie Tangaadb84b2019-08-31 01:00:233611 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023612 mock_quic_data.AddWrite(SYNCHRONOUS,
3613 ConstructInitialSettingsPacket(packet_num++));
bnc359ed2a2016-04-29 20:43:453614 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433615 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233616 SYNCHRONOUS,
3617 ConstructClientRequestHeadersPacket(
3618 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3619 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433620 mock_quic_data.AddRead(
3621 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333622 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283623 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433624 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333625 ASYNC, ConstructServerDataPacket(
3626 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523627 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233628 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343629 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:303630
bnc359ed2a2016-04-29 20:43:453631 // Second request.
alyssar2adf3ac2016-05-03 17:12:583632 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233633 SYNCHRONOUS,
3634 ConstructClientRequestHeadersPacket(
3635 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky957bab12023-01-31 16:40:103636 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433637 mock_quic_data.AddRead(
3638 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333639 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283640 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433641 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333642 ASYNC, ConstructServerDataPacket(
3643 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:523644 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:473645 mock_quic_data.AddWrite(SYNCHRONOUS,
3646 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:303647 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213648 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi32569c62016-01-08 02:54:303649
3650 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:453651
3652 AddHangingNonAlternateProtocolSocketData();
3653 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:303654
rch3f4b8452016-02-23 16:59:323655 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563656 QuicStreamFactoryPeer::SetAlarmFactory(
3657 session_->quic_stream_factory(),
3658 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223659 context_.clock()));
zhongyi32569c62016-01-08 02:54:303660
bnc359ed2a2016-04-29 20:43:453661 const char destination1[] = "first.example.com";
3662 const char destination2[] = "second.example.com";
3663
3664 // Set up alternative service entry to destination1.
3665 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:213666 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
Peter Kastinge5a38ed2021-10-02 03:06:353667 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:493668 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013669 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:073670 supported_versions_);
bnc359ed2a2016-04-29 20:43:453671 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:523672 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:453673 SendRequestAndExpectQuicResponse("hello!");
3674
3675 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:213676 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:493677 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013678 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:073679 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523680 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:453681 // even though alternative service destination is different.
3682 SendRequestAndExpectQuicResponse("hello!");
3683}
3684
3685// Pool to existing session with matching destination and matching certificate
3686// even if origin is different, and even if the alternative service with
3687// matching destination is not the first one on the list.
3688TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Victor Vasilieva1e66d72019-12-05 17:55:383689 context_.params()->allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:453690 GURL origin1 = request_.url;
3691 GURL origin2("https://www.example.org/");
3692 ASSERT_NE(origin1.host(), origin2.host());
3693
Ryan Hamiltonabad59e2019-06-06 04:02:593694 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:453695
Renjie Tangaadb84b2019-08-31 01:00:233696 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023697 mock_quic_data.AddWrite(SYNCHRONOUS,
3698 ConstructInitialSettingsPacket(packet_num++));
bnc359ed2a2016-04-29 20:43:453699 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433700 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233701 SYNCHRONOUS,
3702 ConstructClientRequestHeadersPacket(
3703 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3704 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433705 mock_quic_data.AddRead(
3706 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333707 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283708 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433709 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333710 ASYNC, ConstructServerDataPacket(
3711 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523712 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233713 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343714 ConstructClientAckPacket(packet_num++, 2, 1));
bnc359ed2a2016-04-29 20:43:453715
3716 // Second request.
Yixin Wang079ad542018-01-11 04:06:053717 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:223718 version_,
3719 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Bence Béky957bab12023-01-31 16:40:103720 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT, true);
David Schinazic8281052019-01-24 06:14:173721 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:223722 version_,
3723 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
3724 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:583725 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433726 SYNCHRONOUS,
3727 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:233728 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky957bab12023-01-31 16:40:103729 true, GetRequestHeaders("GET", "https", "/", &client_maker2)));
Zhongyi Shi32f2fd02018-04-16 18:23:433730 mock_quic_data.AddRead(
3731 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333732 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283733 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433734 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333735 ASYNC, ConstructServerDataPacket(
3736 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:523737 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:473738 mock_quic_data.AddWrite(SYNCHRONOUS,
3739 ConstructClientAckPacket(packet_num++, 4, 3));
bnc359ed2a2016-04-29 20:43:453740 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213741 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:453742
3743 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3744
3745 AddHangingNonAlternateProtocolSocketData();
3746 AddHangingNonAlternateProtocolSocketData();
3747
3748 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563749 QuicStreamFactoryPeer::SetAlarmFactory(
3750 session_->quic_stream_factory(),
3751 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223752 context_.clock()));
bnc359ed2a2016-04-29 20:43:453753
3754 const char destination1[] = "first.example.com";
3755 const char destination2[] = "second.example.com";
3756
3757 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:213758 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
Peter Kastinge5a38ed2021-10-02 03:06:353759 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:493760 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013761 url::SchemeHostPort(origin1), NetworkAnonymizationKey(),
3762 alternative_service1, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:453763
3764 // Set up multiple alternative service entries for |origin2|,
3765 // the first one with a different destination as for |origin1|,
3766 // the second one with the same. The second one should be used,
3767 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:213768 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:453769 AlternativeServiceInfoVector alternative_services;
3770 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:213771 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3772 alternative_service2, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383773 context_.params()->supported_versions));
bnc359ed2a2016-04-29 20:43:453774 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:213775 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3776 alternative_service1, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383777 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:493778 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
Brianna Goldstein02cb74f2022-09-29 05:41:013779 NetworkAnonymizationKey(),
Matt Menke3233d8f22019-08-20 21:01:493780 alternative_services);
bnc359ed2a2016-04-29 20:43:453781 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:523782 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:453783 SendRequestAndExpectQuicResponse("hello!");
3784
3785 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:523786 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:453787 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:583788
bnc359ed2a2016-04-29 20:43:453789 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:303790}
3791
3792// Multiple origins have listed the same alternative services. When there's a
3793// existing QUIC session opened by a request to other origin,
3794// if the cert is valid, should select this QUIC session to make the request
3795// if this is also the first existing QUIC session.
3796TEST_P(QuicNetworkTransactionTest,
3797 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltona51800a2022-02-12 19:34:353798 if (version_.AlpnDeferToRFCv1()) {
3799 // These versions currently do not support Alt-Svc.
3800 return;
3801 }
Victor Vasilieva1e66d72019-12-05 17:55:383802 context_.params()->allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:293803 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:303804
rch9ae5b3b2016-02-11 00:36:293805 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:303806 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453807 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rch9ae5b3b2016-02-11 00:36:293808 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:303809 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3810 MockRead(ASYNC, OK)};
3811
Ryan Sleevib8d7ea02018-05-07 20:01:013812 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:303813 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:083814 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:303815 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3816
3817 // HTTP data for request to mail.example.org.
Ryan Hamiltona2dcbae2022-02-09 19:02:453818 std::string alt_svc_header2 = base::StrCat(
3819 {"Alt-Svc: ", GenerateQuicAltSvcHeaderValue({version_}, 444), ",",
3820 GenerateQuicAltSvcHeaderValue({version_}, "www.example.org", 443),
3821 "\r\n\r\n"});
zhongyi32569c62016-01-08 02:54:303822 MockRead http_reads2[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453823 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header2.data()),
zhongyi32569c62016-01-08 02:54:303824 MockRead("hello world from mail.example.org"),
3825 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3826 MockRead(ASYNC, OK)};
3827
Ryan Sleevib8d7ea02018-05-07 20:01:013828 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:303829 socket_factory_.AddSocketDataProvider(&http_data2);
3830 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3831
Yixin Wang079ad542018-01-11 04:06:053832 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:223833 version_,
3834 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Bence Béky957bab12023-01-31 16:40:103835 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT, true);
alyssar2adf3ac2016-05-03 17:12:583836 server_maker_.set_hostname("www.example.org");
Zhongyi Shi1c022d22020-03-20 19:00:163837 client_maker_->set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:593838 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233839 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023840 mock_quic_data.AddWrite(SYNCHRONOUS,
3841 ConstructInitialSettingsPacket(packet_num++));
zhongyi32569c62016-01-08 02:54:303842 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:583843 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233844 SYNCHRONOUS,
3845 ConstructClientRequestHeadersPacket(
3846 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3847 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433848
3849 mock_quic_data.AddRead(
3850 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333851 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283852 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:333853 mock_quic_data.AddRead(
3854 ASYNC, ConstructServerDataPacket(
3855 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523856 ConstructDataFrame("hello from mail QUIC!")));
Renjie Tangaadb84b2019-08-31 01:00:233857 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343858 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:433859 // Second QUIC request data.
3860 mock_quic_data.AddWrite(
3861 SYNCHRONOUS,
3862 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:233863 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky957bab12023-01-31 16:40:103864 true, GetRequestHeaders("GET", "https", "/", &client_maker)));
Zhongyi Shi32f2fd02018-04-16 18:23:433865 mock_quic_data.AddRead(
3866 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333867 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283868 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:333869 mock_quic_data.AddRead(
3870 ASYNC, ConstructServerDataPacket(
3871 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:523872 ConstructDataFrame("hello from mail QUIC!")));
Renjie Tangb7afea82020-07-15 23:35:473873 mock_quic_data.AddWrite(SYNCHRONOUS,
3874 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:303875 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213876 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi32569c62016-01-08 02:54:303877
3878 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:303879
rtennetib8e80fb2016-05-16 00:12:093880 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:323881 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563882 QuicStreamFactoryPeer::SetAlarmFactory(
3883 session_->quic_stream_factory(),
3884 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223885 context_.clock()));
zhongyi32569c62016-01-08 02:54:303886
3887 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:293888 request_.url = GURL("https://www.example.org/");
3889 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:303890 request_.url = GURL("https://mail.example.org/");
3891 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
3892
rch9ae5b3b2016-02-11 00:36:293893 // Open a QUIC session to mail.example.org:443 when making request
3894 // to mail.example.org.
3895 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:453896 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:303897
rch9ae5b3b2016-02-11 00:36:293898 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:303899 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:453900 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:523901}
3902
3903TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
Ryan Hamiltona51800a2022-02-12 19:34:353904 if (version_.AlpnDeferToRFCv1()) {
3905 // These versions currently do not support Alt-Svc.
3906 return;
3907 }
Ryan Hamiltona2dcbae2022-02-09 19:02:453908 std::string alt_svc_header =
3909 base::StrCat({"Alt-Svc: ", GenerateQuicAltSvcHeaderValue({version_}, 137),
3910 "\r\n\r\n"});
bncc958faa2015-07-31 18:14:523911 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453912 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
bncc958faa2015-07-31 18:14:523913 MockRead("hello world"),
3914 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3915 MockRead(ASYNC, OK)};
3916
Ryan Sleevib8d7ea02018-05-07 20:01:013917 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:523918 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:083919 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:563920 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:523921
rtennetib8e80fb2016-05-16 00:12:093922 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:323923 CreateSession();
bncc958faa2015-07-31 18:14:523924
3925 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:453926
3927 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:343928 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:493929 http_server_properties_->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:013930 http_server, NetworkAnonymizationKey());
zhongyic4de03032017-05-19 04:07:343931 ASSERT_EQ(1u, alternative_service_info_vector.size());
3932 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:543933 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:343934 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
3935 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
3936 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:523937}
3938
3939TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
Ryan Hamiltona51800a2022-02-12 19:34:353940 if (version_.AlpnDeferToRFCv1()) {
3941 // These versions currently do not support Alt-Svc.
3942 return;
3943 }
bncc958faa2015-07-31 18:14:523944 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453945 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:563946 MockRead("hello world"),
bncc958faa2015-07-31 18:14:523947 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3948 MockRead(ASYNC, OK)};
3949
Ryan Sleevib8d7ea02018-05-07 20:01:013950 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:523951 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:083952 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:563953 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:523954
Ryan Hamiltonabad59e2019-06-06 04:02:593955 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233956 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023957 mock_quic_data.AddWrite(SYNCHRONOUS,
3958 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:363959 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233960 SYNCHRONOUS,
3961 ConstructClientRequestHeadersPacket(
3962 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3963 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433964 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333965 ASYNC, ConstructServerResponseHeadersPacket(
3966 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283967 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:333968 mock_quic_data.AddRead(
3969 ASYNC, ConstructServerDataPacket(
3970 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523971 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233972 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343973 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:523974 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213975 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:523976
3977 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3978
rtennetib8e80fb2016-05-16 00:12:093979 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:323980 CreateSession();
bncc958faa2015-07-31 18:14:523981
bnc3472afd2016-11-17 15:27:213982 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:523983 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:493984 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:013985 alternative_service, NetworkAnonymizationKey());
Matt Menke3233d8f22019-08-20 21:01:493986 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:013987 alternative_service, NetworkAnonymizationKey()));
bncc958faa2015-07-31 18:14:523988
3989 SendRequestAndExpectHttpResponse("hello world");
3990 SendRequestAndExpectQuicResponse("hello!");
3991
mmenkee24011922015-12-17 22:12:593992 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:523993
Matt Menke3233d8f22019-08-20 21:01:493994 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:013995 alternative_service, NetworkAnonymizationKey()));
Matt Menke19475f72019-08-21 18:57:443996 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
3997 url::SchemeHostPort("https", request_.url.host(), 443),
Brianna Goldstein02cb74f2022-09-29 05:41:013998 NetworkAnonymizationKey()));
bncc958faa2015-07-31 18:14:523999}
4000
Matt Menkeb32ba5122019-09-10 19:17:054001TEST_P(QuicNetworkTransactionTest,
4002 ConfirmAlternativeServiceWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:354003 if (version_.AlpnDeferToRFCv1()) {
4004 // These versions currently do not support Alt-Svc.
4005 return;
4006 }
Matt Menke4807a9a2020-11-21 00:14:414007 const SchemefulSite kSite1(GURL("https://foo.test/"));
4008 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Brianna Goldstein314ddf722022-09-24 02:00:524009 const net::NetworkAnonymizationKey kNetworkAnonymizationKey1(kSite1, kSite1);
Matt Menke4807a9a2020-11-21 00:14:414010 const SchemefulSite kSite2(GURL("https://bar.test/"));
4011 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Brianna Goldstein314ddf722022-09-24 02:00:524012 const net::NetworkAnonymizationKey kNetworkAnonymizationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:054013
4014 base::test::ScopedFeatureList feature_list;
4015 feature_list.InitWithFeatures(
4016 // enabled_features
4017 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4018 features::kPartitionConnectionsByNetworkIsolationKey},
4019 // disabled_features
4020 {});
4021 // Since HttpServerProperties caches the feature value, have to create a new
4022 // one.
4023 http_server_properties_ = std::make_unique<HttpServerProperties>();
4024
4025 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454026 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Matt Menkeb32ba5122019-09-10 19:17:054027 MockRead("hello world"),
4028 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4029 MockRead(ASYNC, OK)};
4030
4031 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4032 socket_factory_.AddSocketDataProvider(&http_data);
4033 AddCertificate(&ssl_data_);
4034 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4035
4036 MockQuicData mock_quic_data(version_);
4037 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:024038 mock_quic_data.AddWrite(SYNCHRONOUS,
4039 ConstructInitialSettingsPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:054040 mock_quic_data.AddWrite(
4041 SYNCHRONOUS,
4042 ConstructClientRequestHeadersPacket(
4043 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4044 true, GetRequestHeaders("GET", "https", "/")));
4045 mock_quic_data.AddRead(
4046 ASYNC, ConstructServerResponseHeadersPacket(
4047 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284048 GetResponseHeaders("200")));
Matt Menkeb32ba5122019-09-10 19:17:054049 mock_quic_data.AddRead(
4050 ASYNC, ConstructServerDataPacket(
4051 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524052 ConstructDataFrame("hello!")));
Matt Menkeb32ba5122019-09-10 19:17:054053 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344054 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menkeb32ba5122019-09-10 19:17:054055 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214056 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Matt Menkeb32ba5122019-09-10 19:17:054057
4058 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4059
4060 CreateSession();
4061
4062 AlternativeService alternative_service(kProtoQUIC,
4063 HostPortPair::FromURL(request_.url));
4064 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014065 alternative_service, kNetworkAnonymizationKey1);
Matt Menkeb32ba5122019-09-10 19:17:054066 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014067 alternative_service, kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:054068 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014069 alternative_service, kNetworkAnonymizationKey1));
Matt Menkeb32ba5122019-09-10 19:17:054070 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014071 alternative_service, kNetworkAnonymizationKey2));
Matt Menkeb32ba5122019-09-10 19:17:054072
4073 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:524074 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Menkeb32ba5122019-09-10 19:17:054075 SendRequestAndExpectHttpResponse("hello world");
4076 SendRequestAndExpectQuicResponse("hello!");
4077
4078 mock_quic_data.Resume();
4079
4080 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014081 alternative_service, kNetworkAnonymizationKey1));
Matt Menkeb32ba5122019-09-10 19:17:054082 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4083 url::SchemeHostPort("https", request_.url.host(), 443),
Brianna Goldstein02cb74f2022-09-29 05:41:014084 kNetworkAnonymizationKey1));
Matt Menkeb32ba5122019-09-10 19:17:054085 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014086 alternative_service, kNetworkAnonymizationKey2));
Matt Menkeb32ba5122019-09-10 19:17:054087 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4088 url::SchemeHostPort("https", request_.url.host(), 443),
Brianna Goldstein02cb74f2022-09-29 05:41:014089 kNetworkAnonymizationKey2));
Matt Menkeb32ba5122019-09-10 19:17:054090}
4091
bncc958faa2015-07-31 18:14:524092TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
Ryan Hamiltona51800a2022-02-12 19:34:354093 if (version_.AlpnDeferToRFCv1()) {
4094 // These versions currently do not support Alt-Svc.
4095 return;
4096 }
bncc958faa2015-07-31 18:14:524097 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454098 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:564099 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524100 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4101 MockRead(ASYNC, OK)};
4102
Ryan Sleevib8d7ea02018-05-07 20:01:014103 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524104 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564105 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524106
Ryan Hamiltonabad59e2019-06-06 04:02:594107 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234108 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:024109 mock_quic_data.AddWrite(SYNCHRONOUS,
4110 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:364111 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234112 SYNCHRONOUS,
4113 ConstructClientRequestHeadersPacket(
4114 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4115 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434116 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334117 ASYNC, ConstructServerResponseHeadersPacket(
4118 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284119 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334120 mock_quic_data.AddRead(
4121 ASYNC, ConstructServerDataPacket(
4122 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524123 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234124 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344125 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:524126 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4127
4128 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4129
4130 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324131 CreateSession();
bncc958faa2015-07-31 18:14:524132
4133 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4134 SendRequestAndExpectHttpResponse("hello world");
4135}
4136
bnc1c196c6e2016-05-28 13:51:484137TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
Ryan Hamiltona51800a2022-02-12 19:34:354138 if (version_.AlpnDeferToRFCv1()) {
4139 // These versions currently do not support Alt-Svc.
4140 return;
4141 }
[email protected]dda75ab2013-06-22 22:43:304142 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274143 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304144
4145 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564146 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294147 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564148 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304149
Ryan Hamiltona2dcbae2022-02-09 19:02:454150 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4151 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
4152 MockRead(SYNCHRONOUS, 5, "hello world"),
4153 MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304154
Ryan Sleevib8d7ea02018-05-07 20:01:014155 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504156 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084157 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504158 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304159
4160 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454161 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304162 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454163 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304164 };
Ryan Sleevib8d7ea02018-05-07 20:01:014165 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504166 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304167
4168 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014169 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504170 socket_factory_.AddSocketDataProvider(&http_data2);
4171 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304172
bnc912a04b2016-04-20 14:19:504173 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304174
4175 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304176 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174177 ASSERT_TRUE(http_data.AllReadDataConsumed());
4178 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304179
4180 // Now run the second request in which the QUIC socket hangs,
4181 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304182 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454183 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304184
rch37de576c2015-05-17 20:28:174185 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4186 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454187 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304188}
4189
[email protected]1e960032013-12-20 19:00:204190TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594191 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164192 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494193 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:024194 mock_quic_data.AddWrite(SYNCHRONOUS,
4195 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi32f2fd02018-04-16 18:23:434196 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494197 SYNCHRONOUS,
4198 ConstructClientRequestHeadersPacket(
4199 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4200 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:164201 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4202 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Zhongyi Shi32f2fd02018-04-16 18:23:434203 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334204 ASYNC, ConstructServerResponseHeadersPacket(
4205 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284206 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334207 mock_quic_data.AddRead(
4208 ASYNC, ConstructServerDataPacket(
4209 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524210 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:494211 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344212 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:504213 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214214 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
[email protected]8ba81212013-05-03 13:11:484215
rcha5399e02015-04-21 19:32:044216 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484217
rtennetib8e80fb2016-05-16 00:12:094218 // The non-alternate protocol job needs to hang in order to guarantee that
4219 // the alternate-protocol job will "win".
4220 AddHangingNonAlternateProtocolSocketData();
4221
rch3f4b8452016-02-23 16:59:324222 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274223 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yang1ef6dfef2021-07-24 16:20:164224 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4225 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264226 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Fan Yang1ef6dfef2021-07-24 16:20:164227 IsError(ERR_IO_PENDING));
4228 // Complete host resolution in next message loop so that QUIC job could
4229 // proceed.
4230 base::RunLoop().RunUntilIdle();
4231 // Explicitly confirm the handshake.
4232 crypto_client_stream_factory_.last_stream()
4233 ->NotifySessionOneRttKeyAvailable();
4234
4235 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
4236 mock_quic_data.Resume();
4237
4238 // Run the QUIC session to completion.
4239 base::RunLoop().RunUntilIdle();
4240
4241 EXPECT_THAT(callback.WaitForResult(), IsOk());
4242
4243 CheckWasQuicResponse(&trans);
4244 CheckResponseData(&trans, "hello!");
rchac7f35e2017-03-15 20:42:304245
Matt Menke19475f72019-08-21 18:57:444246 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4247 url::SchemeHostPort("https", request_.url.host(), 443),
Brianna Goldstein02cb74f2022-09-29 05:41:014248 NetworkAnonymizationKey()));
[email protected]8ba81212013-05-03 13:11:484249}
4250
[email protected]1e960032013-12-20 19:00:204251TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594252 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164253 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494254 int packet_number = 1;
Patrick Meenan885a00652023-02-15 20:07:024255 mock_quic_data.AddWrite(
4256 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Fan Yang32c5a112018-12-10 20:06:334257 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494258 SYNCHRONOUS,
4259 ConstructClientRequestHeadersPacket(
4260 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4261 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:164262 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4263 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Zhongyi Shi32f2fd02018-04-16 18:23:434264 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334265 ASYNC, ConstructServerResponseHeadersPacket(
4266 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284267 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334268 mock_quic_data.AddRead(
4269 ASYNC, ConstructServerDataPacket(
4270 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524271 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:494272 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344273 ConstructClientAckPacket(packet_number++, 2, 1));
rchb27683c2015-07-29 23:53:504274 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214275 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rcha5399e02015-04-21 19:32:044276 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274277
4278 // In order for a new QUIC session to be established via alternate-protocol
4279 // without racing an HTTP connection, we need the host resolution to happen
4280 // synchronously.
4281 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294282 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564283 "");
[email protected]3a120a6b2013-06-25 01:08:274284
rtennetib8e80fb2016-05-16 00:12:094285 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324286 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274287 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yang1ef6dfef2021-07-24 16:20:164288 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4289 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264290 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Fan Yang1ef6dfef2021-07-24 16:20:164291 IsError(ERR_IO_PENDING));
4292 // Complete host resolution in next message loop so that QUIC job could
4293 // proceed.
4294 base::RunLoop().RunUntilIdle();
4295 // Explicitly confirm the handshake.
4296 crypto_client_stream_factory_.last_stream()
4297 ->NotifySessionOneRttKeyAvailable();
4298
4299 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
4300 mock_quic_data.Resume();
4301
4302 // Run the QUIC session to completion.
4303 base::RunLoop().RunUntilIdle();
4304
4305 EXPECT_THAT(callback.WaitForResult(), IsOk());
4306
4307 CheckWasQuicResponse(&trans);
4308 CheckResponseData(&trans, "hello!");
[email protected]3a120a6b2013-06-25 01:08:274309}
4310
[email protected]0fc924b2014-03-31 04:34:154311TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ryan Hamiltona51800a2022-02-12 19:34:354312 if (version_.AlpnDeferToRFCv1()) {
4313 // These versions currently do not support Alt-Svc.
4314 return;
4315 }
Nicolas Arciniegad2013f92020-02-07 23:00:564316 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:274317 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:564318 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154319
4320 // Since we are using a proxy, the QUIC job will not succeed.
4321 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294322 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4323 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564324 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154325
Ryan Hamiltona2dcbae2022-02-09 19:02:454326 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4327 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
4328 MockRead(SYNCHRONOUS, 5, "hello world"),
4329 MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154330
Ryan Sleevib8d7ea02018-05-07 20:01:014331 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154332 socket_factory_.AddSocketDataProvider(&http_data);
4333
4334 // In order for a new QUIC session to be established via alternate-protocol
4335 // without racing an HTTP connection, we need the host resolution to happen
4336 // synchronously.
4337 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294338 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564339 "");
[email protected]0fc924b2014-03-31 04:34:154340
rch9ae5b3b2016-02-11 00:36:294341 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324342 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274343 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154344 SendRequestAndExpectHttpResponse("hello world");
4345}
4346
[email protected]1e960032013-12-20 19:00:204347TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:594348 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234349 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164350 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024351 mock_quic_data.AddWrite(SYNCHRONOUS,
4352 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164353 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364354 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234355 SYNCHRONOUS,
4356 ConstructClientRequestHeadersPacket(
4357 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4358 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434359 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334360 ASYNC, ConstructServerResponseHeadersPacket(
4361 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284362 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334363 mock_quic_data.AddRead(
4364 ASYNC, ConstructServerDataPacket(
4365 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524366 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234367 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344368 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:594369 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044370 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124371
rtennetib8e80fb2016-05-16 00:12:094372 // The non-alternate protocol job needs to hang in order to guarantee that
4373 // the alternate-protocol job will "win".
4374 AddHangingNonAlternateProtocolSocketData();
4375
[email protected]11c05872013-08-20 02:04:124376 // In order for a new QUIC session to be established via alternate-protocol
4377 // without racing an HTTP connection, we need the host resolution to happen
4378 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4379 // connection to the the server, in this test we require confirmation
4380 // before encrypting so the HTTP job will still start.
4381 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294382 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564383 "");
[email protected]11c05872013-08-20 02:04:124384
rch3f4b8452016-02-23 16:59:324385 CreateSession();
Matt Menkeb566c392019-09-11 23:22:434386 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
4387 false);
Ryan Hamilton9835e662018-08-02 05:36:274388 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:124389
bnc691fda62016-08-12 00:43:164390 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:124391 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264392 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014393 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Liza Burakova80b8ebd2023-02-15 16:29:584394 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284395 crypto_client_stream_factory_.last_stream()
4396 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:014397 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:504398
bnc691fda62016-08-12 00:43:164399 CheckWasQuicResponse(&trans);
4400 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:124401}
4402
Steven Valdez58097ec32018-07-16 18:29:044403TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:014404 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594405 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164406 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024407 mock_quic_data.AddWrite(
4408 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Steven Valdez58097ec32018-07-16 18:29:044409 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014410 SYNCHRONOUS,
4411 ConstructClientRequestHeadersPacket(
4412 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4413 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334414 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024415 ASYNC, ConstructServerResponseHeadersPacket(
4416 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284417 GetResponseHeaders("425")));
Patrick Meenan885a00652023-02-15 20:07:024418 mock_quic_data.AddWrite(
4419 SYNCHRONOUS, ConstructClientAckAndDataPacket(
4420 packet_number++, false, GetQpackDecoderStreamId(), 1, 1,
4421 false, StreamCancellationQpackDecoderInstruction(0)));
4422 mock_quic_data.AddWrite(
4423 SYNCHRONOUS,
4424 client_maker_->MakeRstPacket(
4425 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
4426 quic::QUIC_STREAM_CANCELLED));
Steven Valdez58097ec32018-07-16 18:29:044427
Zhongyi Shi1c022d22020-03-20 19:00:164428 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:044429
Steven Valdez58097ec32018-07-16 18:29:044430 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014431 SYNCHRONOUS,
4432 ConstructClientRequestHeadersPacket(
4433 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky957bab12023-01-31 16:40:104434 true, GetRequestHeaders("GET", "https", "/")));
Steven Valdez58097ec32018-07-16 18:29:044435 mock_quic_data.AddRead(
4436 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334437 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284438 GetResponseHeaders("200")));
Steven Valdez58097ec32018-07-16 18:29:044439 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334440 ASYNC, ConstructServerDataPacket(
4441 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524442 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474443 mock_quic_data.AddWrite(SYNCHRONOUS,
4444 ConstructClientAckPacket(packet_number++, 3, 1));
Steven Valdez58097ec32018-07-16 18:29:044445 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214446 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Steven Valdez58097ec32018-07-16 18:29:044447
4448 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4449
4450 // In order for a new QUIC session to be established via alternate-protocol
4451 // without racing an HTTP connection, we need the host resolution to happen
4452 // synchronously.
4453 host_resolver_.set_synchronous_mode(true);
4454 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4455 "");
Steven Valdez58097ec32018-07-16 18:29:044456
4457 AddHangingNonAlternateProtocolSocketData();
4458 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274459 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:564460 QuicStreamFactoryPeer::SetAlarmFactory(
4461 session_->quic_stream_factory(),
4462 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224463 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:044464
4465 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4466 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264467 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Steven Valdez58097ec32018-07-16 18:29:044468 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4469
4470 // Confirm the handshake after the 425 Too Early.
4471 base::RunLoop().RunUntilIdle();
4472
4473 // The handshake hasn't been confirmed yet, so the retry should not have
4474 // succeeded.
4475 EXPECT_FALSE(callback.have_result());
4476
Fan Yang3673cc72020-02-07 14:49:284477 crypto_client_stream_factory_.last_stream()
4478 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:044479
4480 EXPECT_THAT(callback.WaitForResult(), IsOk());
4481 CheckWasQuicResponse(&trans);
4482 CheckResponseData(&trans, "hello!");
4483}
4484
4485TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:014486 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594487 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164488 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024489 mock_quic_data.AddWrite(
4490 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Steven Valdez58097ec32018-07-16 18:29:044491 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014492 SYNCHRONOUS,
4493 ConstructClientRequestHeadersPacket(
4494 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4495 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334496 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024497 ASYNC, ConstructServerResponseHeadersPacket(
4498 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284499 GetResponseHeaders("425")));
Patrick Meenan885a00652023-02-15 20:07:024500 mock_quic_data.AddWrite(
4501 SYNCHRONOUS, ConstructClientAckAndDataPacket(
4502 packet_number++, false, GetQpackDecoderStreamId(), 1, 1,
4503 false, StreamCancellationQpackDecoderInstruction(0)));
4504 mock_quic_data.AddWrite(
4505 SYNCHRONOUS,
4506 client_maker_->MakeRstPacket(
4507 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
4508 quic::QUIC_STREAM_CANCELLED));
Steven Valdez58097ec32018-07-16 18:29:044509
Zhongyi Shi1c022d22020-03-20 19:00:164510 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:044511
Steven Valdez58097ec32018-07-16 18:29:044512 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014513 SYNCHRONOUS,
4514 ConstructClientRequestHeadersPacket(
4515 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky957bab12023-01-31 16:40:104516 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334517 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024518 ASYNC, ConstructServerResponseHeadersPacket(
4519 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284520 GetResponseHeaders("425")));
Patrick Meenan885a00652023-02-15 20:07:024521 mock_quic_data.AddWrite(
4522 SYNCHRONOUS,
4523 ConstructClientAckAndDataPacket(
4524 packet_number++, false, GetQpackDecoderStreamId(), 2, 1, false,
4525 StreamCancellationQpackDecoderInstruction(1, false)));
4526 mock_quic_data.AddWrite(
4527 SYNCHRONOUS,
4528 client_maker_->MakeRstPacket(
4529 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(1),
4530 quic::QUIC_STREAM_CANCELLED));
Steven Valdez58097ec32018-07-16 18:29:044531 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214532 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Steven Valdez58097ec32018-07-16 18:29:044533
4534 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4535
4536 // In order for a new QUIC session to be established via alternate-protocol
4537 // without racing an HTTP connection, we need the host resolution to happen
4538 // synchronously.
4539 host_resolver_.set_synchronous_mode(true);
4540 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4541 "");
Steven Valdez58097ec32018-07-16 18:29:044542
4543 AddHangingNonAlternateProtocolSocketData();
4544 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274545 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:564546 QuicStreamFactoryPeer::SetAlarmFactory(
4547 session_->quic_stream_factory(),
4548 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224549 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:044550
4551 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4552 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264553 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Steven Valdez58097ec32018-07-16 18:29:044554 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4555
4556 // Confirm the handshake after the 425 Too Early.
4557 base::RunLoop().RunUntilIdle();
4558
4559 // The handshake hasn't been confirmed yet, so the retry should not have
4560 // succeeded.
4561 EXPECT_FALSE(callback.have_result());
4562
Fan Yang3673cc72020-02-07 14:49:284563 crypto_client_stream_factory_.last_stream()
4564 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:044565
4566 EXPECT_THAT(callback.WaitForResult(), IsOk());
4567 const HttpResponseInfo* response = trans.GetResponseInfo();
4568 ASSERT_TRUE(response != nullptr);
4569 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:284570 EXPECT_EQ("HTTP/1.1 425", response->headers->GetStatusLine());
Steven Valdez58097ec32018-07-16 18:29:044571 EXPECT_TRUE(response->was_fetched_via_spdy);
4572 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:084573 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
4574 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:044575}
4576
zhongyica364fbb2015-12-12 03:39:124577TEST_P(QuicNetworkTransactionTest,
4578 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Victor Vasilieva1e66d72019-12-05 17:55:384579 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:594580 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234581 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164582 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024583 mock_quic_data.AddWrite(SYNCHRONOUS,
4584 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164585 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364586 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234587 SYNCHRONOUS,
4588 ConstructClientRequestHeadersPacket(
4589 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4590 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:124591 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:524592 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:434593 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:124594 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4595
4596 // The non-alternate protocol job needs to hang in order to guarantee that
4597 // the alternate-protocol job will "win".
4598 AddHangingNonAlternateProtocolSocketData();
4599
4600 // In order for a new QUIC session to be established via alternate-protocol
4601 // without racing an HTTP connection, we need the host resolution to happen
4602 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4603 // connection to the the server, in this test we require confirmation
4604 // before encrypting so the HTTP job will still start.
4605 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294606 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:124607 "");
zhongyica364fbb2015-12-12 03:39:124608
rch3f4b8452016-02-23 16:59:324609 CreateSession();
Matt Menkeb566c392019-09-11 23:22:434610 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
4611 false);
Ryan Hamilton9835e662018-08-02 05:36:274612 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:124613
bnc691fda62016-08-12 00:43:164614 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:124615 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264616 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014617 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Liza Burakova80b8ebd2023-02-15 16:29:584618 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284619 crypto_client_stream_factory_.last_stream()
4620 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:014621 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:124622
4623 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524624 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124625
bnc691fda62016-08-12 00:43:164626 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:124627 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:524628 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
4629 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124630}
4631
4632TEST_P(QuicNetworkTransactionTest,
4633 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Victor Vasilieva1e66d72019-12-05 17:55:384634 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:594635 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234636 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164637 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024638 mock_quic_data.AddWrite(SYNCHRONOUS,
4639 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164640 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364641 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234642 SYNCHRONOUS,
4643 ConstructClientRequestHeadersPacket(
4644 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4645 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:214646 // Peer sending data from an non-existing stream causes this end to raise
4647 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:334648 mock_quic_data.AddRead(
4649 ASYNC, ConstructServerRstPacket(
4650 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
4651 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:214652 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:374653 mock_quic_data.AddWrite(
Renjie Tang248e36ea2020-06-26 00:12:344654 SYNCHRONOUS,
4655 ConstructClientAckAndConnectionClosePacket(
Patrick Meenan885a00652023-02-15 20:07:024656 packet_num++, 1, 1, quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
4657 quic_error_details, quic::IETF_STOP_SENDING));
zhongyica364fbb2015-12-12 03:39:124658 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4659
4660 // The non-alternate protocol job needs to hang in order to guarantee that
4661 // the alternate-protocol job will "win".
4662 AddHangingNonAlternateProtocolSocketData();
4663
4664 // In order for a new QUIC session to be established via alternate-protocol
4665 // without racing an HTTP connection, we need the host resolution to happen
4666 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4667 // connection to the the server, in this test we require confirmation
4668 // before encrypting so the HTTP job will still start.
4669 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294670 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:124671 "");
zhongyica364fbb2015-12-12 03:39:124672
rch3f4b8452016-02-23 16:59:324673 CreateSession();
Matt Menkeb566c392019-09-11 23:22:434674 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
4675 false);
Ryan Hamilton9835e662018-08-02 05:36:274676 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:124677
bnc691fda62016-08-12 00:43:164678 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:124679 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264680 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014681 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Liza Burakova80b8ebd2023-02-15 16:29:584682 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284683 crypto_client_stream_factory_.last_stream()
4684 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:014685 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:124686 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524687 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124688
bnc691fda62016-08-12 00:43:164689 trans.PopulateNetErrorDetails(&details);
Patrick Meenan885a00652023-02-15 20:07:024690 EXPECT_EQ(quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
Renjie Tang248e36ea2020-06-26 00:12:344691 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124692}
4693
Nick Harper057264a82019-09-12 23:33:494694TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:594695 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234696 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164697 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024698 mock_quic_data.AddWrite(SYNCHRONOUS,
4699 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164700 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364701 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234702 SYNCHRONOUS,
4703 ConstructClientRequestHeadersPacket(
4704 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4705 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:484706 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:334707 mock_quic_data.AddRead(
4708 ASYNC, ConstructServerResponseHeadersPacket(
4709 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284710 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334711 mock_quic_data.AddRead(
4712 ASYNC, ConstructServerRstPacket(
4713 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
4714 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:074715
Patrick Meenan885a00652023-02-15 20:07:024716 mock_quic_data.AddWrite(
4717 SYNCHRONOUS,
4718 client_maker_->MakeAckRstAndDataPacket(
4719 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
4720 quic::QUIC_STREAM_CANCELLED, 2, 1, GetQpackDecoderStreamId(), false,
4721 StreamCancellationQpackDecoderInstruction(0)));
rchcd5f1c62016-06-23 02:43:484722 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
4723 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4724
4725 // The non-alternate protocol job needs to hang in order to guarantee that
4726 // the alternate-protocol job will "win".
4727 AddHangingNonAlternateProtocolSocketData();
4728
4729 // In order for a new QUIC session to be established via alternate-protocol
4730 // without racing an HTTP connection, we need the host resolution to happen
4731 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4732 // connection to the the server, in this test we require confirmation
4733 // before encrypting so the HTTP job will still start.
4734 host_resolver_.set_synchronous_mode(true);
4735 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4736 "");
rchcd5f1c62016-06-23 02:43:484737
4738 CreateSession();
Matt Menkeb566c392019-09-11 23:22:434739 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
4740 false);
Ryan Hamilton9835e662018-08-02 05:36:274741 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:484742
bnc691fda62016-08-12 00:43:164743 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:484744 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264745 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014746 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:484747
Liza Burakova80b8ebd2023-02-15 16:29:584748 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284749 crypto_client_stream_factory_.last_stream()
4750 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:484751 // Read the headers.
robpercival214763f2016-07-01 23:27:014752 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:484753
bnc691fda62016-08-12 00:43:164754 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:484755 ASSERT_TRUE(response != nullptr);
4756 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:284757 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
rchcd5f1c62016-06-23 02:43:484758 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:524759 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:084760 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
4761 response->connection_info);
rchcd5f1c62016-06-23 02:43:484762
4763 std::string response_data;
bnc691fda62016-08-12 00:43:164764 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:484765}
4766
Nick Harper057264a82019-09-12 23:33:494767TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:384768 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:594769 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234770 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164771 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024772 mock_quic_data.AddWrite(SYNCHRONOUS,
4773 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164774 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364775 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234776 SYNCHRONOUS,
4777 ConstructClientRequestHeadersPacket(
4778 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4779 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334780 mock_quic_data.AddRead(
4781 ASYNC, ConstructServerRstPacket(
4782 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
4783 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:074784
Patrick Meenan885a00652023-02-15 20:07:024785 mock_quic_data.AddWrite(
4786 SYNCHRONOUS,
4787 client_maker_->MakeAckRstAndDataPacket(
4788 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
4789 quic::QUIC_STREAM_CANCELLED, 1, 1, GetQpackDecoderStreamId(), false,
4790 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:074791
rchcd5f1c62016-06-23 02:43:484792 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
4793 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4794
4795 // The non-alternate protocol job needs to hang in order to guarantee that
4796 // the alternate-protocol job will "win".
4797 AddHangingNonAlternateProtocolSocketData();
4798
4799 // In order for a new QUIC session to be established via alternate-protocol
4800 // without racing an HTTP connection, we need the host resolution to happen
4801 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4802 // connection to the the server, in this test we require confirmation
4803 // before encrypting so the HTTP job will still start.
4804 host_resolver_.set_synchronous_mode(true);
4805 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4806 "");
rchcd5f1c62016-06-23 02:43:484807
4808 CreateSession();
Matt Menkeb566c392019-09-11 23:22:434809 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
4810 false);
Ryan Hamilton9835e662018-08-02 05:36:274811 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:484812
bnc691fda62016-08-12 00:43:164813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:484814 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264815 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:484817
Liza Burakova80b8ebd2023-02-15 16:29:584818 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284819 crypto_client_stream_factory_.last_stream()
4820 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:484821 // Read the headers.
robpercival214763f2016-07-01 23:27:014822 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:484823}
4824
[email protected]1e960032013-12-20 19:00:204825TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:304826 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:524827 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:584828 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:304829 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:504830 MockRead(ASYNC, close->data(), close->length()),
4831 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
4832 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:304833 };
Ryan Sleevib8d7ea02018-05-07 20:01:014834 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:304835 socket_factory_.AddSocketDataProvider(&quic_data);
4836
4837 // Main job which will succeed even though the alternate job fails.
4838 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:024839 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
4840 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4841 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:304842
Ryan Sleevib8d7ea02018-05-07 20:01:014843 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:304844 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564845 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:304846
rch3f4b8452016-02-23 16:59:324847 CreateSession();
David Schinazic8281052019-01-24 06:14:174848 AddQuicAlternateProtocolMapping(
4849 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:194850 SendRequestAndExpectHttpResponse("hello from http");
4851 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:304852}
4853
Matt Menkeb32ba5122019-09-10 19:17:054854TEST_P(QuicNetworkTransactionTest,
4855 BrokenAlternateProtocolWithNetworkIsolationKey) {
Matt Menke4807a9a2020-11-21 00:14:414856 const SchemefulSite kSite1(GURL("https://foo.test/"));
4857 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Brianna Goldstein314ddf722022-09-24 02:00:524858 const net::NetworkAnonymizationKey kNetworkAnonymizationKey1(kSite1, kSite1);
Matt Menke4807a9a2020-11-21 00:14:414859 const SchemefulSite kSite2(GURL("https://bar.test/"));
4860 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Brianna Goldstein314ddf722022-09-24 02:00:524861 const net::NetworkAnonymizationKey kNetworkAnonymizationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:054862
4863 base::test::ScopedFeatureList feature_list;
4864 feature_list.InitWithFeatures(
4865 // enabled_features
4866 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4867 features::kPartitionConnectionsByNetworkIsolationKey},
4868 // disabled_features
4869 {});
4870 // Since HttpServerProperties caches the feature value, have to create a new
4871 // one.
4872 http_server_properties_ = std::make_unique<HttpServerProperties>();
4873
4874 // Alternate-protocol job
4875 std::unique_ptr<quic::QuicEncryptedPacket> close(
4876 ConstructServerConnectionClosePacket(1));
4877 MockRead quic_reads[] = {
4878 MockRead(ASYNC, close->data(), close->length()),
4879 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
4880 MockRead(ASYNC, OK), // EOF
4881 };
4882 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
4883 socket_factory_.AddSocketDataProvider(&quic_data);
4884
4885 // Main job which will succeed even though the alternate job fails.
4886 MockRead http_reads[] = {
4887 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
4888 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4889 MockRead(ASYNC, OK)};
4890
4891 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4892 socket_factory_.AddSocketDataProvider(&http_data);
4893 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4894
4895 CreateSession();
4896 AddQuicAlternateProtocolMapping(
Brianna Goldstein02cb74f2022-09-29 05:41:014897 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT,
4898 kNetworkAnonymizationKey1);
Matt Menkeb32ba5122019-09-10 19:17:054899 AddQuicAlternateProtocolMapping(
Brianna Goldstein02cb74f2022-09-29 05:41:014900 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT,
4901 kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:054902 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:524903 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Menkeb32ba5122019-09-10 19:17:054904 SendRequestAndExpectHttpResponse("hello from http");
4905
Brianna Goldstein02cb74f2022-09-29 05:41:014906 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
4907 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:054908}
4909
[email protected]1e960032013-12-20 19:00:204910TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:594911 // Alternate-protocol job
4912 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:024913 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:594914 };
Ryan Sleevib8d7ea02018-05-07 20:01:014915 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:594916 socket_factory_.AddSocketDataProvider(&quic_data);
4917
4918 // Main job which will succeed even though the alternate job fails.
4919 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:024920 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
4921 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4922 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:594923
Ryan Sleevib8d7ea02018-05-07 20:01:014924 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:594925 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564926 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:594927
rch3f4b8452016-02-23 16:59:324928 CreateSession();
[email protected]d03a66d2013-05-06 12:55:594929
Ryan Hamilton9835e662018-08-02 05:36:274930 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:194931 SendRequestAndExpectHttpResponse("hello from http");
4932 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:594933}
4934
[email protected]00c159f2014-05-21 22:38:164935TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:534936 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:164937 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:024938 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:164939 };
Ryan Sleevib8d7ea02018-05-07 20:01:014940 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:164941 socket_factory_.AddSocketDataProvider(&quic_data);
4942
[email protected]eb71ab62014-05-23 07:57:534943 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:164944 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:024945 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:164946 };
4947
Ryan Sleevib8d7ea02018-05-07 20:01:014948 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:164949 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
4950 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564951 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:164952
rtennetib8e80fb2016-05-16 00:12:094953 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324954 CreateSession();
[email protected]00c159f2014-05-21 22:38:164955
Ryan Hamilton9835e662018-08-02 05:36:274956 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:164957 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:164958 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264959 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014960 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4961 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:164962 ExpectQuicAlternateProtocolMapping();
4963}
4964
Zhongyi Shia0cef1082017-08-25 01:49:504965TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
4966 // Tests that TCP job is delayed and QUIC job does not require confirmation
4967 // if QUIC was recently supported on the same IP on start.
4968
4969 // Set QUIC support on the last IP address, which is same with the local IP
4970 // address. Require confirmation mode will be turned off immediately when
4971 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:434972 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
4973 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:504974
Ryan Hamiltonabad59e2019-06-06 04:02:594975 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164976 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494977 int packet_number = 1;
Patrick Meenan885a00652023-02-15 20:07:024978 mock_quic_data.AddWrite(SYNCHRONOUS,
4979 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:434980 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494981 SYNCHRONOUS,
4982 ConstructClientRequestHeadersPacket(
4983 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4984 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:164985 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4986 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
Zhongyi Shi32f2fd02018-04-16 18:23:434987 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334988 ASYNC, ConstructServerResponseHeadersPacket(
4989 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284990 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334991 mock_quic_data.AddRead(
4992 ASYNC, ConstructServerDataPacket(
4993 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524994 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:494995 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344996 ConstructClientAckPacket(packet_number++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:504997 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214998 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Zhongyi Shia0cef1082017-08-25 01:49:504999
5000 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5001 // No HTTP data is mocked as TCP job never starts in this case.
5002
5003 CreateSession();
5004 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:435005 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5006 false);
Zhongyi Shia0cef1082017-08-25 01:49:505007
Ryan Hamilton9835e662018-08-02 05:36:275008 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505009
5010 // Stall host resolution so that QUIC job will not succeed synchronously.
5011 // Socket will not be configured immediately and QUIC support is not sorted
5012 // out, TCP job will still be delayed as server properties indicates QUIC
5013 // support on last IP address.
5014 host_resolver_.set_synchronous_mode(false);
5015
5016 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5017 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265018 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Zhongyi Shia0cef1082017-08-25 01:49:505019 IsError(ERR_IO_PENDING));
5020 // Complete host resolution in next message loop so that QUIC job could
5021 // proceed.
5022 base::RunLoop().RunUntilIdle();
Fan Yang1ef6dfef2021-07-24 16:20:165023 // Explicitly confirm the handshake.
5024 crypto_client_stream_factory_.last_stream()
5025 ->NotifySessionOneRttKeyAvailable();
5026
5027 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
5028 mock_quic_data.Resume();
5029
5030 // Run the QUIC session to completion.
5031 base::RunLoop().RunUntilIdle();
Zhongyi Shia0cef1082017-08-25 01:49:505032 EXPECT_THAT(callback.WaitForResult(), IsOk());
5033
5034 CheckWasQuicResponse(&trans);
5035 CheckResponseData(&trans, "hello!");
5036}
5037
5038TEST_P(QuicNetworkTransactionTest,
5039 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5040 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5041 // was recently supported on a different IP address on start.
5042
5043 // Set QUIC support on the last IP address, which is different with the local
5044 // IP address. Require confirmation mode will remain when local IP address is
5045 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435046 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5047 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:505048
Ryan Hamiltonabad59e2019-06-06 04:02:595049 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235050 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165051 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:025052 mock_quic_data.AddWrite(SYNCHRONOUS,
5053 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:165054 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:505055 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235056 SYNCHRONOUS,
5057 ConstructClientRequestHeadersPacket(
5058 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5059 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435060 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335061 ASYNC, ConstructServerResponseHeadersPacket(
5062 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285063 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335064 mock_quic_data.AddRead(
5065 ASYNC, ConstructServerDataPacket(
5066 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525067 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235068 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345069 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505070 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5071 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5072 // No HTTP data is mocked as TCP job will be delayed and never starts.
5073
5074 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435075 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5076 false);
Ryan Hamilton9835e662018-08-02 05:36:275077 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505078
5079 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5080 // Socket will not be configured immediately and QUIC support is not sorted
5081 // out, TCP job will still be delayed as server properties indicates QUIC
5082 // support on last IP address.
5083 host_resolver_.set_synchronous_mode(false);
5084
5085 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5086 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265087 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Zhongyi Shia0cef1082017-08-25 01:49:505088 IsError(ERR_IO_PENDING));
5089
5090 // Complete host resolution in next message loop so that QUIC job could
5091 // proceed.
5092 base::RunLoop().RunUntilIdle();
5093 // Explicitly confirm the handshake so that QUIC job could succeed.
Fan Yang3673cc72020-02-07 14:49:285094 crypto_client_stream_factory_.last_stream()
5095 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia0cef1082017-08-25 01:49:505096 EXPECT_THAT(callback.WaitForResult(), IsOk());
5097
5098 CheckWasQuicResponse(&trans);
5099 CheckResponseData(&trans, "hello!");
5100}
5101
Ryan Hamilton75f197262017-08-17 14:00:075102TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5103 // Test that NetErrorDetails is correctly populated, even if the
5104 // handshake has not yet been confirmed and no stream has been created.
5105
5106 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595107 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075108 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5109 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5110 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5111
5112 // Main job will also fail.
5113 MockRead http_reads[] = {
5114 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5115 };
5116
Ryan Sleevib8d7ea02018-05-07 20:01:015117 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075118 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5119 socket_factory_.AddSocketDataProvider(&http_data);
5120 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5121
5122 AddHangingNonAlternateProtocolSocketData();
5123 CreateSession();
5124 // Require handshake confirmation to ensure that no QUIC streams are
5125 // created, and to ensure that the TCP job does not wait for the QUIC
5126 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:435127 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5128 false);
Ryan Hamilton75f197262017-08-17 14:00:075129
Ryan Hamilton9835e662018-08-02 05:36:275130 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075131 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5132 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265133 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton75f197262017-08-17 14:00:075134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5135 // Allow the TCP job to fail.
5136 base::RunLoop().RunUntilIdle();
5137 // Now let the QUIC job fail.
5138 mock_quic_data.Resume();
5139 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5140 ExpectQuicAlternateProtocolMapping();
5141 NetErrorDetails details;
5142 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525143 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075144}
5145
[email protected]1e960032013-12-20 19:00:205146TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455147 // Alternate-protocol job
5148 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025149 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455150 };
Ryan Sleevib8d7ea02018-05-07 20:01:015151 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455152 socket_factory_.AddSocketDataProvider(&quic_data);
5153
[email protected]c92c1b52014-05-31 04:16:065154 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015155 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065156 socket_factory_.AddSocketDataProvider(&quic_data2);
5157
[email protected]4d283b32013-10-17 12:57:275158 // Final job that will proceed when the QUIC job fails.
5159 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025160 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5161 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5162 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275163
Ryan Sleevib8d7ea02018-05-07 20:01:015164 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275165 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565166 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275167
rch3f4b8452016-02-23 16:59:325168 CreateSession();
[email protected]77c6c162013-08-17 02:57:455169
Ryan Hamilton9835e662018-08-02 05:36:275170 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455171
[email protected]4d283b32013-10-17 12:57:275172 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455173
5174 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275175
rch37de576c2015-05-17 20:28:175176 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5177 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455178}
5179
Matt Menkeb32ba5122019-09-10 19:17:055180TEST_P(QuicNetworkTransactionTest,
5181 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
5182 base::test::ScopedFeatureList feature_list;
5183 feature_list.InitWithFeatures(
5184 // enabled_features
5185 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5186 features::kPartitionConnectionsByNetworkIsolationKey},
5187 // disabled_features
5188 {});
5189 // Since HttpServerProperties caches the feature value, have to create a new
5190 // one.
5191 http_server_properties_ = std::make_unique<HttpServerProperties>();
5192
Matt Menke4807a9a2020-11-21 00:14:415193 const SchemefulSite kSite1(GURL("https://foo.test/"));
5194 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Brianna Goldstein314ddf722022-09-24 02:00:525195 const net::NetworkAnonymizationKey kNetworkAnonymizationKey1(kSite1, kSite1);
Matt Menke4807a9a2020-11-21 00:14:415196 const SchemefulSite kSite2(GURL("https://bar.test/"));
5197 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Brianna Goldstein314ddf722022-09-24 02:00:525198 const net::NetworkAnonymizationKey kNetworkAnonymizationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:055199
5200 // Alternate-protocol job
5201 MockRead quic_reads[] = {
5202 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5203 };
5204 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5205 socket_factory_.AddSocketDataProvider(&quic_data);
5206
5207 // Second Alternate-protocol job which will race with the TCP job.
5208 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
5209 socket_factory_.AddSocketDataProvider(&quic_data2);
5210
5211 // Final job that will proceed when the QUIC job fails.
5212 MockRead http_reads[] = {
5213 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5214 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5215 MockRead(ASYNC, OK)};
5216
5217 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5218 socket_factory_.AddSocketDataProvider(&http_data);
5219 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5220
5221 CreateSession();
5222
5223 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
Brianna Goldstein02cb74f2022-09-29 05:41:015224 kNetworkAnonymizationKey1);
Matt Menkeb32ba5122019-09-10 19:17:055225 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
Brianna Goldstein02cb74f2022-09-29 05:41:015226 kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:055227
5228 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:525229 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Menkeb32ba5122019-09-10 19:17:055230 SendRequestAndExpectHttpResponse("hello from http");
5231 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5232 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
5233
Brianna Goldstein02cb74f2022-09-29 05:41:015234 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
5235 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:055236
5237 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
5238 AddHttpDataAndRunRequest();
5239 // Requests using other NetworkIsolationKeys can still use QUIC.
5240 request_.network_isolation_key = kNetworkIsolationKey2;
Brianna Goldstein314ddf722022-09-24 02:00:525241 request_.network_anonymization_key = kNetworkAnonymizationKey2;
5242
Matt Menkeb32ba5122019-09-10 19:17:055243 AddQuicDataAndRunRequest();
5244
5245 // The last two requests should not have changed the alternative service
5246 // mappings.
Brianna Goldstein02cb74f2022-09-29 05:41:015247 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
5248 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:055249}
5250
[email protected]eb71ab62014-05-23 07:57:535251TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335252 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015253 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495254 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335255 socket_factory_.AddSocketDataProvider(&quic_data);
5256
5257 // Main job which will succeed even though the alternate job fails.
5258 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025259 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5260 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5261 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335262
Ryan Sleevib8d7ea02018-05-07 20:01:015263 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335264 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565265 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335266
rch3f4b8452016-02-23 16:59:325267 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275268 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335269 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535270
5271 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335272}
5273
Nidhi Jaju391105a2022-07-28 02:09:515274// TODO(crbug.com/1347664): This test is failing on various platforms.
5275TEST_P(QuicNetworkTransactionTest, DISABLED_ConnectionCloseDuringConnect) {
Ryan Hamiltona51800a2022-02-12 19:34:355276 if (version_.AlpnDeferToRFCv1()) {
5277 // These versions currently do not support Alt-Svc.
5278 return;
5279 }
Ryan Hamiltonabad59e2019-06-06 04:02:595280 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165281 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:175282 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045283 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155284
5285 // When the QUIC connection fails, we will try the request again over HTTP.
5286 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:455287 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:565288 MockRead("hello world"),
5289 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5290 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155291
Ryan Sleevib8d7ea02018-05-07 20:01:015292 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155293 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565294 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155295
5296 // In order for a new QUIC session to be established via alternate-protocol
5297 // without racing an HTTP connection, we need the host resolution to happen
5298 // synchronously.
5299 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295300 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565301 "");
[email protected]4fee9672014-01-08 14:47:155302
rch3f4b8452016-02-23 16:59:325303 CreateSession();
David Schinazic8281052019-01-24 06:14:175304 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5305 AddQuicAlternateProtocolMapping(
5306 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155307 SendRequestAndExpectHttpResponse("hello world");
5308}
5309
tbansalc3308d72016-08-27 10:25:045310TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltona51800a2022-02-12 19:34:355311 if (version_.AlpnDeferToRFCv1()) {
5312 // These versions currently do not support Alt-Svc.
5313 return;
5314 }
Ryan Hamiltonabad59e2019-06-06 04:02:595315 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165316 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:175317 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335318 mock_quic_data.AddWrite(
5319 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5320 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5321 true, GetRequestHeaders("GET", "https", "/")));
Renjie Tangcd594f32020-07-11 20:18:345322 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1));
tbansalc3308d72016-08-27 10:25:045323 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5324
5325 // When the QUIC connection fails, we will try the request again over HTTP.
5326 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:455327 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
tbansalc3308d72016-08-27 10:25:045328 MockRead("hello world"),
5329 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5330 MockRead(ASYNC, OK)};
5331
Ryan Sleevib8d7ea02018-05-07 20:01:015332 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045333 socket_factory_.AddSocketDataProvider(&http_data);
5334 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5335
5336 TestProxyDelegate test_proxy_delegate;
5337 const HostPortPair host_port_pair("myproxy.org", 443);
tbansalc3308d72016-08-27 10:25:045338
Nicolas Arciniegad2013f92020-02-07 23:00:565339 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:275340 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Matt Menke7bc4def2020-07-29 20:54:515341 "QUIC myproxy.org:443; HTTPS myproxy.org:443",
5342 TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525343 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045344 request_.url = GURL("http://mail.example.org/");
5345
5346 // In order for a new QUIC session to be established via alternate-protocol
5347 // without racing an HTTP connection, we need the host resolution to happen
5348 // synchronously.
5349 host_resolver_.set_synchronous_mode(true);
5350 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045351
5352 CreateSession();
David Schinazic8281052019-01-24 06:14:175353 crypto_client_stream_factory_.set_handshake_mode(
5354 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045355 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595356 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165357 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045358}
5359
bnc508835902015-05-12 20:10:295360TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
Zhongyi Shi1c022d22020-03-20 19:00:165361 client_maker_->set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385362 EXPECT_FALSE(
5363 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:595364 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235365 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025366 mock_quic_data.AddWrite(SYNCHRONOUS,
5367 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:365368 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235369 SYNCHRONOUS,
5370 ConstructClientRequestHeadersPacket(
5371 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5372 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435373 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335374 ASYNC, ConstructServerResponseHeadersPacket(
5375 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285376 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335377 mock_quic_data.AddRead(
5378 ASYNC, ConstructServerDataPacket(
5379 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525380 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235381 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345382 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:505383 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295384 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5385
bncb07c05532015-05-14 19:07:205386 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095387 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325388 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275389 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295390 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385391 EXPECT_TRUE(
5392 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295393}
5394
rtenneti56977812016-01-15 19:26:565395TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Victor Vasilieva1e66d72019-12-05 17:55:385396 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575397 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565398
Renjie Tangaadb84b2019-08-31 01:00:235399 MockQuicData mock_quic_data(version_);
Patrick Meenan885a00652023-02-15 20:07:025400 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:235401 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5402 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5403
5404 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5405 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
5406 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:015407 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:235408 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:565409
rtennetib8e80fb2016-05-16 00:12:095410 // The non-alternate protocol job needs to hang in order to guarantee that
5411 // the alternate-protocol job will "win".
5412 AddHangingNonAlternateProtocolSocketData();
5413
rtenneti56977812016-01-15 19:26:565414 CreateSession();
5415 request_.method = "POST";
5416 ChunkedUploadDataStream upload_data(0);
5417 upload_data.AppendData("1", 1, true);
5418
5419 request_.upload_data_stream = &upload_data;
5420
bnc691fda62016-08-12 00:43:165421 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:565422 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265423 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015424 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:565425 EXPECT_NE(OK, callback.WaitForResult());
5426}
5427
rche11300ef2016-09-02 01:44:285428TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Victor Vasilieva1e66d72019-12-05 17:55:385429 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:285430 ScopedMockNetworkChangeNotifier network_change_notifier;
5431 MockNetworkChangeNotifier* mock_ncn =
5432 network_change_notifier.mock_network_change_notifier();
5433 mock_ncn->ForceNetworkHandlesSupported();
5434 mock_ncn->SetConnectedNetworksList(
5435 {kDefaultNetworkForTests, kNewNetworkForTests});
5436
Victor Vasilieva1e66d72019-12-05 17:55:385437 context_.params()->origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:285438 HostPortPair::FromString("mail.example.org:443"));
Victor Vasilieva1e66d72019-12-05 17:55:385439 context_.params()->migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:285440
Ryan Hamiltonabad59e2019-06-06 04:02:595441 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:285442 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:235443 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025444 socket_data.AddWrite(SYNCHRONOUS,
5445 ConstructInitialSettingsPacket(packet_num++));
Fan Yang32c5a112018-12-10 20:06:335446 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235447 SYNCHRONOUS,
5448 ConstructClientRequestHeadersPacket(
5449 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5450 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:285451 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5452 socket_data.AddSocketDataToFactory(&socket_factory_);
5453
Ryan Hamiltonabad59e2019-06-06 04:02:595454 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:285455 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
5456 socket_data2.AddSocketDataToFactory(&socket_factory_);
5457
5458 // The non-alternate protocol job needs to hang in order to guarantee that
5459 // the alternate-protocol job will "win".
5460 AddHangingNonAlternateProtocolSocketData();
5461
5462 CreateSession();
5463 request_.method = "POST";
5464 ChunkedUploadDataStream upload_data(0);
5465
5466 request_.upload_data_stream = &upload_data;
5467
Tsuyoshi Horof8861cb2022-07-05 23:50:205468 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5469 session_.get());
rche11300ef2016-09-02 01:44:285470 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265471 int rv = trans->Start(&request_, callback.callback(), net_log_with_source_);
rche11300ef2016-09-02 01:44:285472 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5473
5474 base::RunLoop().RunUntilIdle();
5475 upload_data.AppendData("1", 1, true);
5476 base::RunLoop().RunUntilIdle();
5477
5478 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:505479 trans.reset();
rche11300ef2016-09-02 01:44:285480 session_.reset();
5481}
5482
Ryan Hamilton4b3574532017-10-30 20:17:255483TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:385484 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255485 HostPortPair::FromString("mail.example.org:443"));
5486
Ryan Hamiltonabad59e2019-06-06 04:02:595487 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235488 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025489 socket_data.AddWrite(SYNCHRONOUS,
5490 ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton4b3574532017-10-30 20:17:255491 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:335492 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235493 SYNCHRONOUS,
5494 ConstructClientRequestHeadersPacket(
5495 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5496 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435497 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335498 ASYNC, ConstructServerResponseHeadersPacket(
5499 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285500 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335501 socket_data.AddRead(
5502 ASYNC, ConstructServerDataPacket(
5503 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525504 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235505 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345506 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:255507 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi1c022d22020-03-20 19:00:165508 socket_data.AddWrite(SYNCHRONOUS,
5509 client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:345510 packet_num++, false, 2, 1,
Zhongyi Shi1c022d22020-03-20 19:00:165511 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:255512
5513 socket_data.AddSocketDataToFactory(&socket_factory_);
5514
5515 CreateSession();
5516
5517 SendRequestAndExpectQuicResponse("hello!");
5518 session_.reset();
5519}
5520
5521TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:385522 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255523 HostPortPair::FromString("mail.example.org:443"));
5524
Ryan Hamiltonabad59e2019-06-06 04:02:595525 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235526 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025527 socket_data.AddWrite(SYNCHRONOUS,
5528 ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton4b3574532017-10-30 20:17:255529 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:335530 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235531 SYNCHRONOUS,
5532 ConstructClientRequestHeadersPacket(
5533 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5534 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435535 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335536 ASYNC, ConstructServerResponseHeadersPacket(
5537 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285538 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335539 socket_data.AddRead(
5540 ASYNC, ConstructServerDataPacket(
5541 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525542 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235543 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345544 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:255545 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi1c022d22020-03-20 19:00:165546 socket_data.AddWrite(SYNCHRONOUS,
5547 client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:345548 packet_num++, false, 2, 1,
Zhongyi Shi1c022d22020-03-20 19:00:165549 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:255550
5551 socket_data.AddSocketDataToFactory(&socket_factory_);
5552
5553 CreateSession();
5554
5555 SendRequestAndExpectQuicResponse("hello!");
5556 session_.reset();
5557}
5558
Ryan Hamilton9edcf1a2017-11-22 05:55:175559TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:385560 context_.params()->retry_without_alt_svc_on_quic_errors = false;
5561 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255562 HostPortPair::FromString("mail.example.org:443"));
5563
Ryan Hamiltonabad59e2019-06-06 04:02:595564 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:255565 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Patrick Meenan885a00652023-02-15 20:07:025566 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:175567 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:255568 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
5569 }
5570 socket_data.AddSocketDataToFactory(&socket_factory_);
5571
5572 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:175573 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:175574 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
5575 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:255576
Victor Vasiliev7752898d2019-11-14 21:30:225577 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:255578 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5579 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265580 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton4b3574532017-10-30 20:17:255581 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:175582 while (!callback.have_result()) {
5583 base::RunLoop().RunUntilIdle();
5584 quic_task_runner_->RunUntilIdle();
5585 }
5586 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:255587 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:175588 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5589 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5590 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:225591 EXPECT_TRUE(context_.clock()->Now() - start >
5592 quic::QuicTime::Delta::FromSeconds(4));
5593 EXPECT_TRUE(context_.clock()->Now() - start <
5594 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:255595}
5596
Ryan Hamilton9edcf1a2017-11-22 05:55:175597TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:385598 context_.params()->retry_without_alt_svc_on_quic_errors = false;
5599 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255600 HostPortPair::FromString("mail.example.org:443"));
5601
Ryan Hamiltonabad59e2019-06-06 04:02:595602 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:255603 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Patrick Meenan885a00652023-02-15 20:07:025604 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:175605 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:255606 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
5607 }
5608 socket_data.AddSocketDataToFactory(&socket_factory_);
5609
5610 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:175611 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:175612 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
5613 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:255614
Victor Vasiliev7752898d2019-11-14 21:30:225615 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:255616 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5617 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265618 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton4b3574532017-10-30 20:17:255619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:175620 while (!callback.have_result()) {
5621 base::RunLoop().RunUntilIdle();
5622 quic_task_runner_->RunUntilIdle();
5623 }
5624 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:255625 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:175626 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5627 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5628 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:225629 EXPECT_TRUE(context_.clock()->Now() - start >
5630 quic::QuicTime::Delta::FromSeconds(4));
5631 EXPECT_TRUE(context_.clock()->Now() - start <
5632 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:255633}
5634
Cherie Shi7596de632018-02-22 07:28:185635TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Victor Vasilieva1e66d72019-12-05 17:55:385636 context_.params()->retry_without_alt_svc_on_quic_errors = false;
5637 context_.params()->origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:185638 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev62c09dc2020-11-06 18:18:295639 const std::string error_details = base::StrCat(
5640 {"Write failed with error: ", base::NumberToString(ERR_MSG_TOO_BIG), " (",
5641 strerror(ERR_MSG_TOO_BIG), ")"});
Cherie Shi7596de632018-02-22 07:28:185642
Ryan Hamiltonabad59e2019-06-06 04:02:595643 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:185644 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:235645 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025646 socket_data.AddWrite(SYNCHRONOUS,
5647 ConstructInitialSettingsPacket(packet_num++));
Cherie Shi7596de632018-02-22 07:28:185648 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
5649 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525650 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235651 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165652 client_maker_->MakeConnectionClosePacket(
Renjie Tangaadb84b2019-08-31 01:00:235653 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:185654 socket_data.AddSocketDataToFactory(&socket_factory_);
5655
5656 CreateSession();
5657
5658 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5659 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265660 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Cherie Shi7596de632018-02-22 07:28:185661 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5662 base::RunLoop().RunUntilIdle();
5663 ASSERT_TRUE(callback.have_result());
5664 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5665 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5666 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5667}
5668
ckrasicda193a82016-07-09 00:39:365669TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Victor Vasilieva1e66d72019-12-05 17:55:385670 context_.params()->origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:365671 HostPortPair::FromString("mail.example.org:443"));
5672
Ryan Hamiltonabad59e2019-06-06 04:02:595673 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:365674
Renjief49758b2019-01-11 23:32:415675 int write_packet_index = 1;
Patrick Meenan885a00652023-02-15 20:07:025676 mock_quic_data.AddWrite(SYNCHRONOUS,
5677 ConstructInitialSettingsPacket(write_packet_index++));
ckrasicda193a82016-07-09 00:39:365678
Bence Béky319388a882020-09-23 18:42:525679 mock_quic_data.AddWrite(
5680 SYNCHRONOUS,
5681 ConstructClientRequestHeadersAndDataFramesPacket(
5682 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
5683 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
Bence Béky957bab12023-01-31 16:40:105684 nullptr, {ConstructDataFrame("1")}));
ckrasicda193a82016-07-09 00:39:365685
Zhongyi Shi32f2fd02018-04-16 18:23:435686 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335687 ASYNC, ConstructServerResponseHeadersPacket(
5688 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285689 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335690
5691 mock_quic_data.AddRead(
5692 ASYNC, ConstructServerDataPacket(
5693 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525694 ConstructDataFrame("hello!")));
ckrasicda193a82016-07-09 00:39:365695
Renjie Tangcd594f32020-07-11 20:18:345696 mock_quic_data.AddWrite(SYNCHRONOUS,
5697 ConstructClientAckPacket(write_packet_index++, 2, 1));
ckrasicda193a82016-07-09 00:39:365698
5699 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215700 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
ckrasicda193a82016-07-09 00:39:365701 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5702
5703 // The non-alternate protocol job needs to hang in order to guarantee that
5704 // the alternate-protocol job will "win".
5705 AddHangingNonAlternateProtocolSocketData();
5706
5707 CreateSession();
5708 request_.method = "POST";
5709 ChunkedUploadDataStream upload_data(0);
5710 upload_data.AppendData("1", 1, true);
5711
5712 request_.upload_data_stream = &upload_data;
5713
5714 SendRequestAndExpectQuicResponse("hello!");
5715}
5716
Ryan Sleevia9d6aa62019-07-26 13:32:185717TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
Ryan Hamiltona51800a2022-02-12 19:34:355718 if (version_.AlpnDeferToRFCv1()) {
5719 // These versions currently do not support Alt-Svc.
5720 return;
5721 }
Ryan Sleevia9d6aa62019-07-26 13:32:185722 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:205723
5724 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:455725 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yixin Wang10f477ed2017-11-21 04:20:205726 MockRead("hello world"),
5727 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5728 MockRead(ASYNC, OK)};
5729
Ryan Sleevib8d7ea02018-05-07 20:01:015730 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:205731 socket_factory_.AddSocketDataProvider(&http_data);
5732 AddCertificate(&ssl_data_);
5733 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5734
Ryan Hamiltonabad59e2019-06-06 04:02:595735 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235736 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025737 mock_quic_data.AddWrite(SYNCHRONOUS,
5738 ConstructInitialSettingsPacket(packet_num++));
Yixin Wang10f477ed2017-11-21 04:20:205739 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235740 SYNCHRONOUS,
5741 ConstructClientRequestHeadersPacket(
5742 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5743 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435744 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335745 ASYNC, ConstructServerResponseHeadersPacket(
5746 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285747 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335748 mock_quic_data.AddRead(
5749 ASYNC, ConstructServerDataPacket(
5750 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525751 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235752 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345753 ConstructClientAckPacket(packet_num++, 2, 1));
Yixin Wang10f477ed2017-11-21 04:20:205754 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215755 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang10f477ed2017-11-21 04:20:205756
5757 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5758
5759 AddHangingNonAlternateProtocolSocketData();
5760 CreateSession();
5761
5762 SendRequestAndExpectHttpResponse("hello world");
5763 SendRequestAndExpectQuicResponse("hello!");
5764}
5765
Ryan Sleevia9d6aa62019-07-26 13:32:185766TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
Ryan Hamiltona51800a2022-02-12 19:34:355767 if (version_.AlpnDeferToRFCv1()) {
5768 // These versions currently do not support Alt-Svc.
5769 return;
5770 }
Ryan Sleevia9d6aa62019-07-26 13:32:185771 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:205772
5773 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:455774 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yixin Wang10f477ed2017-11-21 04:20:205775 MockRead("hello world"),
5776 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5777 MockRead(ASYNC, OK)};
5778
Ryan Sleevib8d7ea02018-05-07 20:01:015779 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:205780 socket_factory_.AddSocketDataProvider(&http_data);
5781 AddCertificate(&ssl_data_);
5782 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5783 socket_factory_.AddSocketDataProvider(&http_data);
5784 AddCertificate(&ssl_data_);
5785 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5786
5787 AddHangingNonAlternateProtocolSocketData();
5788 CreateSession();
5789
5790 SendRequestAndExpectHttpResponse("hello world");
5791 SendRequestAndExpectHttpResponse("hello world");
5792}
5793
bnc359ed2a2016-04-29 20:43:455794class QuicNetworkTransactionWithDestinationTest
5795 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:015796 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:055797 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:455798 protected:
5799 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:555800 : version_(GetParam().version),
Nick Harper23290b82019-05-02 00:02:565801 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:455802 destination_type_(GetParam().destination_type),
Tsuyoshi Horof8861cb2022-07-05 23:50:205803 ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()),
Nicolas Arciniegad2013f92020-02-07 23:00:565804 proxy_resolution_service_(
5805 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:115806 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Ryan Hamiltonf9a421f2020-01-31 21:09:525807 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:195808 FLAGS_quic_enable_http3_grease_randomness = false;
Ryan Hamiltonf9a421f2020-01-31 21:09:525809 }
bnc359ed2a2016-04-29 20:43:455810
5811 void SetUp() override {
5812 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:555813 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:455814
Matt Menke30a878c2021-07-20 22:25:095815 HttpNetworkSessionParams session_params;
mmenke6ddfbea2017-05-31 21:48:415816 session_params.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:385817 context_.params()->allow_remote_alt_svc = true;
5818 context_.params()->supported_versions = supported_versions_;
mmenke6ddfbea2017-05-31 21:48:415819
Matt Menke30a878c2021-07-20 22:25:095820 HttpNetworkSessionContext session_context;
bnc359ed2a2016-04-29 20:43:455821
Victor Vasiliev7752898d2019-11-14 21:30:225822 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
bnc359ed2a2016-04-29 20:43:455823
5824 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:275825 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:415826 session_context.quic_crypto_client_stream_factory =
5827 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:455828
Victor Vasiliev7752898d2019-11-14 21:30:225829 session_context.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:415830 session_context.client_socket_factory = &socket_factory_;
5831 session_context.host_resolver = &host_resolver_;
5832 session_context.cert_verifier = &cert_verifier_;
5833 session_context.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:415834 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
5835 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:455836 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:415837 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:595838 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:415839 session_context.http_auth_handler_factory = auth_handler_factory_.get();
5840 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:455841
Renjie Tang6ff9a9b2021-02-03 22:11:095842 session_ =
5843 std::make_unique<HttpNetworkSession>(session_params, session_context);
Matt Menkeb566c392019-09-11 23:22:435844 session_->quic_stream_factory()
5845 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:455846 }
5847
5848 void TearDown() override {
5849 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
5850 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:555851 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:455852 PlatformTest::TearDown();
5853 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:555854 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:405855 session_.reset();
bnc359ed2a2016-04-29 20:43:455856 }
5857
zhongyie537a002017-06-27 16:48:215858 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:455859 HostPortPair destination;
5860 switch (destination_type_) {
5861 case SAME_AS_FIRST:
5862 destination = HostPortPair(origin1_, 443);
5863 break;
5864 case SAME_AS_SECOND:
5865 destination = HostPortPair(origin2_, 443);
5866 break;
5867 case DIFFERENT:
5868 destination = HostPortPair(kDifferentHostname, 443);
5869 break;
5870 }
bnc3472afd2016-11-17 15:27:215871 AlternativeService alternative_service(kProtoQUIC, destination);
Peter Kastinge5a38ed2021-10-02 03:06:355872 base::Time expiration = base::Time::Now() + base::Days(1);
zhongyie537a002017-06-27 16:48:215873 http_server_properties_.SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:015874 url::SchemeHostPort("https", origin, 443), NetworkAnonymizationKey(),
Matt Menke9aa86262019-08-21 15:52:075875 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:455876 }
5877
Ryan Hamilton8d9ee76e2018-05-29 23:52:525878 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:235879 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:525880 quic::QuicStreamId stream_id,
5881 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:525882 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:135883 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:455884 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Bence Béky4c325e52020-10-22 20:48:015885 spdy::Http2HeaderBlock headers(
Ryan Hamilton0239aac2018-05-19 00:03:135886 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:025887 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:455888 packet_number, stream_id, should_include_version, true, priority,
Bence Béky957bab12023-01-31 16:40:105889 std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:455890 }
5891
Ryan Hamilton8d9ee76e2018-05-29 23:52:525892 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:235893 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:525894 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:525895 QuicTestPacketMaker* maker) {
Kenichi Ishibashif8634ab2021-03-16 23:41:285896 spdy::Http2HeaderBlock headers(maker->GetResponseHeaders("200"));
Ryan Hamilton0d65a8c2019-06-07 00:46:025897 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
5898 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:455899 }
5900
Ryan Hamilton8d9ee76e2018-05-29 23:52:525901 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:235902 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:525903 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:455904 QuicTestPacketMaker* maker) {
Bence Béky319388a882020-09-23 18:42:525905 return maker->MakeDataPacket(
5906 packet_number, stream_id, false, true,
5907 ConstructDataFrameForVersion("hello", version_));
bnc359ed2a2016-04-29 20:43:455908 }
5909
Ryan Hamilton8d9ee76e2018-05-29 23:52:525910 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:235911 uint64_t packet_number,
5912 uint64_t largest_received,
5913 uint64_t smallest_received,
bnc359ed2a2016-04-29 20:43:455914 QuicTestPacketMaker* maker) {
5915 return maker->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:345916 smallest_received);
bnc359ed2a2016-04-29 20:43:455917 }
5918
Ryan Hamilton8d9ee76e2018-05-29 23:52:525919 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:235920 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:375921 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:025922 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:375923 }
5924
bnc359ed2a2016-04-29 20:43:455925 void AddRefusedSocketData() {
Tsuyoshi Horof8861cb2022-07-05 23:50:205926 auto refused_data = std::make_unique<StaticSocketDataProvider>();
bnc359ed2a2016-04-29 20:43:455927 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
5928 refused_data->set_connect_data(refused_connect);
5929 socket_factory_.AddSocketDataProvider(refused_data.get());
5930 static_socket_data_provider_vector_.push_back(std::move(refused_data));
5931 }
5932
5933 void AddHangingSocketData() {
Tsuyoshi Horof8861cb2022-07-05 23:50:205934 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
bnc359ed2a2016-04-29 20:43:455935 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
5936 hanging_data->set_connect_data(hanging_connect);
5937 socket_factory_.AddSocketDataProvider(hanging_data.get());
5938 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
5939 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5940 }
5941
5942 bool AllDataConsumed() {
5943 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
5944 if (!socket_data_ptr->AllReadDataConsumed() ||
5945 !socket_data_ptr->AllWriteDataConsumed()) {
5946 return false;
5947 }
5948 }
5949 return true;
5950 }
5951
5952 void SendRequestAndExpectQuicResponse(const std::string& host) {
5953 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5954 HttpRequestInfo request;
5955 std::string url("https://");
5956 url.append(host);
5957 request.url = GURL(url);
5958 request.load_flags = 0;
5959 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:105960 request.traffic_annotation =
5961 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:455962 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265963 int rv = trans.Start(&request, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015964 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:455965
5966 std::string response_data;
robpercival214763f2016-07-01 23:27:015967 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:455968 EXPECT_EQ("hello", response_data);
5969
5970 const HttpResponseInfo* response = trans.GetResponseInfo();
5971 ASSERT_TRUE(response != nullptr);
5972 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:285973 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
bnc359ed2a2016-04-29 20:43:455974 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525975 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085976 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:455977 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:375978 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:455979 }
5980
Fan Yang32c5a112018-12-10 20:06:335981 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:565982 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
5983 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:365984 }
5985
Patrick Meenan0041f332022-05-19 23:48:355986 quic::test::QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Nick Harper23290b82019-05-02 00:02:565987 const quic::ParsedQuicVersion version_;
Nick Harper23290b82019-05-02 00:02:565988 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:455989 DestinationType destination_type_;
5990 std::string origin1_;
5991 std::string origin2_;
Victor Vasiliev7752898d2019-11-14 21:30:225992 MockQuicContext context_;
bnc359ed2a2016-04-29 20:43:455993 std::unique_ptr<HttpNetworkSession> session_;
5994 MockClientSocketFactory socket_factory_;
Eric Orthbe86fee2021-10-28 22:31:115995 MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
5996 RuleResolver::GetLocalhostResult()};
bnc359ed2a2016-04-29 20:43:455997 MockCertVerifier cert_verifier_;
5998 TransportSecurityState transport_security_state_;
Ryan Sleevi8a9c9c12018-05-09 02:36:235999 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:456000 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:076001 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:266002 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:456003 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:266004 HttpServerProperties http_server_properties_;
Matt Reichhoff0049a0b72021-10-20 20:44:266005 NetLogWithSource net_log_with_source_{
6006 NetLogWithSource::Make(NetLogSourceType::NONE)};
bnc359ed2a2016-04-29 20:43:456007 MockCryptoClientStreamFactory crypto_client_stream_factory_;
6008 std::vector<std::unique_ptr<StaticSocketDataProvider>>
6009 static_socket_data_provider_vector_;
6010 SSLSocketDataProvider ssl_data_;
6011};
6012
Victor Costane635086f2019-01-27 05:20:306013INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
6014 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:576015 ::testing::ValuesIn(GetPoolingTestParams()),
6016 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:456017
6018// A single QUIC request fails because the certificate does not match the origin
6019// hostname, regardless of whether it matches the alternative service hostname.
6020TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
6021 if (destination_type_ == DIFFERENT)
6022 return;
6023
6024 GURL url("https://mail.example.com/");
6025 origin1_ = url.host();
6026
6027 // Not used for requests, but this provides a test case where the certificate
6028 // is valid for the hostname of the alternative service.
6029 origin2_ = "mail.example.org";
6030
zhongyie537a002017-06-27 16:48:216031 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:456032
6033 scoped_refptr<X509Certificate> cert(
6034 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246035 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
6036 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:456037
6038 ProofVerifyDetailsChromium verify_details;
6039 verify_details.cert_verify_result.verified_cert = cert;
6040 verify_details.cert_verify_result.is_issued_by_known_root = true;
6041 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6042
Ryan Hamiltonabad59e2019-06-06 04:02:596043 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:456044 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
David Schinazi395918c2021-02-05 18:56:216045 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:456046
6047 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6048
6049 AddRefusedSocketData();
6050
6051 HttpRequestInfo request;
6052 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:106053 request.traffic_annotation =
6054 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456055
6056 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6057 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266058 int rv = trans.Start(&request, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:016059 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:456060
6061 EXPECT_TRUE(AllDataConsumed());
6062}
6063
6064// First request opens QUIC session to alternative service. Second request
6065// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:526066// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:456067TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
6068 origin1_ = "mail.example.org";
6069 origin2_ = "news.example.org";
6070
zhongyie537a002017-06-27 16:48:216071 SetQuicAlternativeService(origin1_);
6072 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:456073
6074 scoped_refptr<X509Certificate> cert(
6075 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246076 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
6077 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
6078 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456079
6080 ProofVerifyDetailsChromium verify_details;
6081 verify_details.cert_verify_result.verified_cert = cert;
6082 verify_details.cert_verify_result.is_issued_by_known_root = true;
6083 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6084
Yixin Wang079ad542018-01-11 04:06:056085 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:226086 version_,
6087 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Bence Béky957bab12023-01-31 16:40:106088 context_.clock(), origin1_, quic::Perspective::IS_CLIENT, true);
David Schinazic8281052019-01-24 06:14:176089 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:226090 version_,
6091 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
6092 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:456093
Ryan Hamiltonabad59e2019-06-06 04:02:596094 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236095 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026096 mock_quic_data.AddWrite(
6097 SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++, &client_maker));
Fan Yang32c5a112018-12-10 20:06:336098 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236099 SYNCHRONOUS,
6100 ConstructClientRequestHeadersPacket(
6101 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6102 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:026103 mock_quic_data.AddRead(
6104 ASYNC,
6105 ConstructServerResponseHeadersPacket(
6106 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:436107 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336108 ASYNC,
6109 ConstructServerDataPacket(
6110 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:236111 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346112 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:456113
Yixin Wang079ad542018-01-11 04:06:056114 client_maker.set_hostname(origin2_);
6115 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:456116
Zhongyi Shi32f2fd02018-04-16 18:23:436117 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026118 SYNCHRONOUS,
6119 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:236120 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky957bab12023-01-31 16:40:106121 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:026122 mock_quic_data.AddRead(
6123 ASYNC,
6124 ConstructServerResponseHeadersPacket(
6125 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:436126 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336127 ASYNC,
6128 ConstructServerDataPacket(
6129 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:236130 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346131 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3, &client_maker));
bnc359ed2a2016-04-29 20:43:456132 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216133 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:456134
6135 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6136
6137 AddHangingSocketData();
6138 AddHangingSocketData();
6139
Tsuyoshi Horo2c0a5042022-07-06 05:53:076140 auto quic_task_runner =
6141 base::MakeRefCounted<TestTaskRunner>(context_.mock_clock());
Fan Yangc9e00dc2018-10-09 14:17:566142 QuicStreamFactoryPeer::SetAlarmFactory(
6143 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:096144 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Victor Vasiliev7752898d2019-11-14 21:30:226145 context_.clock()));
Fan Yangc9e00dc2018-10-09 14:17:566146
bnc359ed2a2016-04-29 20:43:456147 SendRequestAndExpectQuicResponse(origin1_);
6148 SendRequestAndExpectQuicResponse(origin2_);
6149
6150 EXPECT_TRUE(AllDataConsumed());
6151}
6152
6153// First request opens QUIC session to alternative service. Second request does
6154// not pool to it, even though destination matches, because certificate is not
6155// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:526156// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:456157TEST_P(QuicNetworkTransactionWithDestinationTest,
6158 DoNotPoolIfCertificateInvalid) {
6159 origin1_ = "news.example.org";
6160 origin2_ = "mail.example.com";
6161
zhongyie537a002017-06-27 16:48:216162 SetQuicAlternativeService(origin1_);
6163 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:456164
6165 scoped_refptr<X509Certificate> cert1(
6166 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246167 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
6168 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
6169 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456170
6171 scoped_refptr<X509Certificate> cert2(
6172 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246173 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
6174 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456175
6176 ProofVerifyDetailsChromium verify_details1;
6177 verify_details1.cert_verify_result.verified_cert = cert1;
6178 verify_details1.cert_verify_result.is_issued_by_known_root = true;
6179 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
6180
6181 ProofVerifyDetailsChromium verify_details2;
6182 verify_details2.cert_verify_result.verified_cert = cert2;
6183 verify_details2.cert_verify_result.is_issued_by_known_root = true;
6184 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
6185
Yixin Wang079ad542018-01-11 04:06:056186 QuicTestPacketMaker client_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:226187 version_,
6188 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Bence Béky957bab12023-01-31 16:40:106189 context_.clock(), origin1_, quic::Perspective::IS_CLIENT, true);
David Schinazic8281052019-01-24 06:14:176190 QuicTestPacketMaker server_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:226191 version_,
6192 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
6193 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:456194
Ryan Hamiltonabad59e2019-06-06 04:02:596195 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:236196 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026197 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6198 packet_num++, &client_maker1));
Fan Yang32c5a112018-12-10 20:06:336199 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236200 SYNCHRONOUS,
6201 ConstructClientRequestHeadersPacket(
6202 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6203 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:436204 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336205 ASYNC,
6206 ConstructServerResponseHeadersPacket(
6207 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:436208 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336209 ASYNC,
6210 ConstructServerDataPacket(
6211 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:436212 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236213 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346214 ConstructClientAckPacket(packet_num++, 2, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:456215 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6216 mock_quic_data1.AddRead(ASYNC, 0); // EOF
6217
6218 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
6219
Yixin Wang079ad542018-01-11 04:06:056220 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:226221 version_,
6222 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Bence Béky957bab12023-01-31 16:40:106223 context_.clock(), origin2_, quic::Perspective::IS_CLIENT, true);
David Schinazic8281052019-01-24 06:14:176224 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:226225 version_,
6226 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
6227 context_.clock(), origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:456228
Ryan Hamiltonabad59e2019-06-06 04:02:596229 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:236230 int packet_num2 = 1;
Patrick Meenan885a00652023-02-15 20:07:026231 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6232 packet_num2++, &client_maker2));
Fan Yang32c5a112018-12-10 20:06:336233 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236234 SYNCHRONOUS,
6235 ConstructClientRequestHeadersPacket(
6236 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6237 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:436238 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:336239 ASYNC,
6240 ConstructServerResponseHeadersPacket(
6241 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:436242 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:336243 ASYNC,
6244 ConstructServerDataPacket(
6245 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:436246 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236247 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346248 ConstructClientAckPacket(packet_num2++, 2, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:456249 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6250 mock_quic_data2.AddRead(ASYNC, 0); // EOF
6251
6252 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
6253
bnc359ed2a2016-04-29 20:43:456254 SendRequestAndExpectQuicResponse(origin1_);
6255 SendRequestAndExpectQuicResponse(origin2_);
6256
6257 EXPECT_TRUE(AllDataConsumed());
6258}
6259
Yixin Wang46a273ec302018-01-23 17:59:566260// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:146261TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:566262 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146263 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566264 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276265 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566266 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566267
Ryan Hamiltonabad59e2019-06-06 04:02:596268 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236269 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026270 mock_quic_data.AddWrite(SYNCHRONOUS,
6271 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:436272
Patrick Meenan885a00652023-02-15 20:07:026273 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
6274 mock_quic_data.AddWrite(
6275 SYNCHRONOUS,
6276 ConstructClientPriorityPacket(
6277 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6278 DEFAULT_PRIORITY));
Renjie Tangaadb84b2019-08-31 01:00:236279 }
Fan Yang32c5a112018-12-10 20:06:336280 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236281 SYNCHRONOUS,
6282 ConstructClientRequestHeadersPacket(
6283 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Patrick Meenan885a00652023-02-15 20:07:026284 false, DEFAULT_PRIORITY,
Bence Béky957bab12023-01-31 16:40:106285 ConnectRequestHeaders("mail.example.org:443"), false));
Fan Yang32c5a112018-12-10 20:06:336286 mock_quic_data.AddRead(
6287 ASYNC, ConstructServerResponseHeadersPacket(
6288 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286289 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566290
6291 const char get_request[] =
6292 "GET / HTTP/1.1\r\n"
6293 "Host: mail.example.org\r\n"
6294 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526295 mock_quic_data.AddWrite(
6296 SYNCHRONOUS,
6297 ConstructClientAckAndDataPacket(
6298 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
6299 1, false, ConstructDataFrame(get_request)));
Renjief49758b2019-01-11 23:32:416300
Yixin Wang46a273ec302018-01-23 17:59:566301 const char get_response[] =
6302 "HTTP/1.1 200 OK\r\n"
6303 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:436304 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336305 ASYNC, ConstructServerDataPacket(
6306 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:526307 ConstructDataFrame(get_response)));
Fan Yang32c5a112018-12-10 20:06:336308 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:416309 SYNCHRONOUS, ConstructServerDataPacket(
6310 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:526311 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:236312 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346313 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:566314 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6315
Patrick Meenan885a00652023-02-15 20:07:026316 mock_quic_data.AddWrite(
6317 SYNCHRONOUS, ConstructClientDataPacket(
6318 packet_num++, GetQpackDecoderStreamId(), true, false,
6319 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:076320
Yixin Wang46a273ec302018-01-23 17:59:566321 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:416322 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236323 ConstructClientRstPacket(packet_num++,
6324 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416325 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566326
6327 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6328
6329 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6330
6331 CreateSession();
6332
6333 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:096334 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:566335 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566336 RunTransaction(&trans);
6337 CheckWasHttpResponse(&trans);
6338 CheckResponsePort(&trans, 70);
6339 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:566340 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
6341
Cammie Smith Barnesbf91e2a2020-12-23 20:49:046342 // DNS aliases should be empty when using a proxy.
6343 EXPECT_TRUE(trans.GetResponseInfo()->dns_aliases.empty());
6344
Yixin Wang46a273ec302018-01-23 17:59:566345 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
6346 // proxy socket to disconnect.
6347 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6348
6349 base::RunLoop().RunUntilIdle();
6350 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6351 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6352}
6353
6354// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:146355TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:566356 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146357 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566358 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276359 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566360 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566361
Ryan Hamiltonabad59e2019-06-06 04:02:596362 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236363 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026364 mock_quic_data.AddWrite(SYNCHRONOUS,
6365 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:436366
Patrick Meenan885a00652023-02-15 20:07:026367 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
6368 mock_quic_data.AddWrite(
6369 SYNCHRONOUS,
6370 ConstructClientPriorityPacket(
6371 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6372 DEFAULT_PRIORITY));
Renjie Tangaadb84b2019-08-31 01:00:236373 }
Fan Yang32c5a112018-12-10 20:06:336374 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236375 SYNCHRONOUS,
6376 ConstructClientRequestHeadersPacket(
6377 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Patrick Meenan885a00652023-02-15 20:07:026378 false, DEFAULT_PRIORITY,
Bence Béky957bab12023-01-31 16:40:106379 ConnectRequestHeaders("mail.example.org:443"), false));
Fan Yang32c5a112018-12-10 20:06:336380 mock_quic_data.AddRead(
6381 ASYNC, ConstructServerResponseHeadersPacket(
6382 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286383 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566384
6385 SpdyTestUtil spdy_util;
6386
Ryan Hamilton0239aac2018-05-19 00:03:136387 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:566388 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:526389 mock_quic_data.AddWrite(
6390 SYNCHRONOUS,
6391 ConstructClientAckAndDataPacket(
6392 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
6393 1, false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Ryan Hamilton0239aac2018-05-19 00:03:136394 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:566395 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:436396 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:176397 ASYNC, ConstructServerDataPacket(
6398 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:526399 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:566400
Ryan Hamilton0239aac2018-05-19 00:03:136401 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:196402 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Zhongyi Shi32f2fd02018-04-16 18:23:436403 mock_quic_data.AddRead(
6404 SYNCHRONOUS,
6405 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:336406 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:526407 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Renjie Tangaadb84b2019-08-31 01:00:236408 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346409 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:566410 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6411
Patrick Meenan885a00652023-02-15 20:07:026412 mock_quic_data.AddWrite(
6413 SYNCHRONOUS, ConstructClientDataPacket(
6414 packet_num++, GetQpackDecoderStreamId(), true, false,
6415 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:076416
Yixin Wang46a273ec302018-01-23 17:59:566417 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436418 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236419 ConstructClientRstPacket(packet_num++,
6420 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416421 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566422
6423 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6424
6425 SSLSocketDataProvider ssl_data(ASYNC, OK);
6426 ssl_data.next_proto = kProtoHTTP2;
6427 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
6428
6429 CreateSession();
6430
6431 request_.url = GURL("https://mail.example.org/");
6432 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566433 RunTransaction(&trans);
6434 CheckWasSpdyResponse(&trans);
6435 CheckResponsePort(&trans, 70);
6436 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:566437 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
6438
Wez0e717112018-06-18 23:09:226439 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
6440 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:566441 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6442
6443 base::RunLoop().RunUntilIdle();
6444 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6445 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6446}
6447
6448// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
6449// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:146450TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:566451 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146452 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566453 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276454 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566455 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566456
Ryan Hamiltonabad59e2019-06-06 04:02:596457 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:416458 int write_packet_index = 1;
Patrick Meenan885a00652023-02-15 20:07:026459 mock_quic_data.AddWrite(SYNCHRONOUS,
6460 ConstructInitialSettingsPacket(write_packet_index++));
Patrick Meenanf741c6082023-01-03 18:06:436461
Patrick Meenan885a00652023-02-15 20:07:026462 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
6463 mock_quic_data.AddWrite(
6464 SYNCHRONOUS,
6465 ConstructClientPriorityPacket(
6466 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6467 DEFAULT_PRIORITY));
Renjie Tangaadb84b2019-08-31 01:00:236468 }
Fan Yang32c5a112018-12-10 20:06:336469 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:416470 SYNCHRONOUS,
6471 ConstructClientRequestHeadersPacket(
6472 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Patrick Meenan885a00652023-02-15 20:07:026473 true, false, DEFAULT_PRIORITY,
Bence Béky957bab12023-01-31 16:40:106474 ConnectRequestHeaders("mail.example.org:443"), false));
Fan Yang32c5a112018-12-10 20:06:336475 mock_quic_data.AddRead(
6476 ASYNC, ConstructServerResponseHeadersPacket(
6477 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286478 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566479
Yixin Wang46a273ec302018-01-23 17:59:566480 const char get_request_1[] =
6481 "GET / HTTP/1.1\r\n"
6482 "Host: mail.example.org\r\n"
6483 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526484 mock_quic_data.AddWrite(
6485 SYNCHRONOUS, ConstructClientAckAndDataPacket(
6486 write_packet_index++, false,
6487 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
6488 false, ConstructDataFrame(get_request_1)));
Renjief49758b2019-01-11 23:32:416489
Yixin Wang46a273ec302018-01-23 17:59:566490 const char get_response_1[] =
6491 "HTTP/1.1 200 OK\r\n"
6492 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:436493 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:436494 ASYNC, ConstructServerDataPacket(
6495 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:526496 ConstructDataFrame(get_response_1)));
Yixin Wang46a273ec302018-01-23 17:59:566497
Fan Yang32c5a112018-12-10 20:06:336498 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:176499 SYNCHRONOUS, ConstructServerDataPacket(
6500 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:526501 false, ConstructDataFrame("0123456789")));
Yixin Wang46a273ec302018-01-23 17:59:566502
Renjie Tangcd594f32020-07-11 20:18:346503 mock_quic_data.AddWrite(SYNCHRONOUS,
6504 ConstructClientAckPacket(write_packet_index++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:566505
6506 const char get_request_2[] =
6507 "GET /2 HTTP/1.1\r\n"
6508 "Host: mail.example.org\r\n"
6509 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526510 mock_quic_data.AddWrite(
6511 SYNCHRONOUS,
6512 ConstructClientDataPacket(
6513 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6514 false, false, ConstructDataFrame(get_request_2)));
Yixin Wang46a273ec302018-01-23 17:59:566515
6516 const char get_response_2[] =
6517 "HTTP/1.1 200 OK\r\n"
6518 "Content-Length: 7\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:436519 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:436520 ASYNC, ConstructServerDataPacket(
6521 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:526522 ConstructDataFrame(get_response_2)));
Yixin Wang46a273ec302018-01-23 17:59:566523
Ryan Hamilton8d9ee76e2018-05-29 23:52:526524 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:176525 SYNCHRONOUS, ConstructServerDataPacket(
6526 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:526527 false, ConstructDataFrame("0123456")));
Yixin Wang46a273ec302018-01-23 17:59:566528
Renjie Tangcd594f32020-07-11 20:18:346529 mock_quic_data.AddWrite(SYNCHRONOUS,
6530 ConstructClientAckPacket(write_packet_index++, 5, 4));
Yixin Wang46a273ec302018-01-23 17:59:566531 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6532
Patrick Meenan885a00652023-02-15 20:07:026533 mock_quic_data.AddWrite(
6534 SYNCHRONOUS, ConstructClientDataPacket(
6535 write_packet_index++, GetQpackDecoderStreamId(), true,
6536 false, StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:076537
Renjief49758b2019-01-11 23:32:416538 mock_quic_data.AddWrite(
6539 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416540 ConstructClientRstPacket(write_packet_index++,
6541 GetNthClientInitiatedBidirectionalStreamId(0),
6542 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566543
6544 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6545
6546 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6547
6548 CreateSession();
6549
6550 request_.url = GURL("https://mail.example.org/");
6551 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566552 RunTransaction(&trans_1);
6553 CheckWasHttpResponse(&trans_1);
6554 CheckResponsePort(&trans_1, 70);
6555 CheckResponseData(&trans_1, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:566556 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
6557
6558 request_.url = GURL("https://mail.example.org/2");
6559 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566560 RunTransaction(&trans_2);
6561 CheckWasHttpResponse(&trans_2);
6562 CheckResponsePort(&trans_2, 70);
6563 CheckResponseData(&trans_2, "0123456");
Yixin Wang46a273ec302018-01-23 17:59:566564 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
6565
6566 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
6567 // proxy socket to disconnect.
6568 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6569
6570 base::RunLoop().RunUntilIdle();
6571 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6572 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6573}
6574
6575// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
6576// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
6577// server is reused for the second request.
Bence Békyf6bb6b22020-04-17 20:22:116578TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:566579 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146580 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566581 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276582 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566583 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566584
Ryan Hamiltonabad59e2019-06-06 04:02:596585 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236586 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026587 mock_quic_data.AddWrite(SYNCHRONOUS,
6588 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:436589
Patrick Meenan885a00652023-02-15 20:07:026590 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
6591 mock_quic_data.AddWrite(
6592 SYNCHRONOUS,
6593 ConstructClientPriorityPacket(
6594 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6595 DEFAULT_PRIORITY));
Renjie Tangaadb84b2019-08-31 01:00:236596 }
Yixin Wang46a273ec302018-01-23 17:59:566597
6598 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:336599 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236600 SYNCHRONOUS,
6601 ConstructClientRequestHeadersPacket(
6602 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Patrick Meenan885a00652023-02-15 20:07:026603 false, DEFAULT_PRIORITY,
Bence Béky957bab12023-01-31 16:40:106604 ConnectRequestHeaders("mail.example.org:443"), false));
Zhongyi Shi32f2fd02018-04-16 18:23:436605 mock_quic_data.AddRead(
6606 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336607 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286608 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566609
6610 // GET request, response, and data over QUIC tunnel for first request
6611 const char get_request[] =
6612 "GET / HTTP/1.1\r\n"
6613 "Host: mail.example.org\r\n"
6614 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526615 mock_quic_data.AddWrite(
6616 SYNCHRONOUS,
6617 ConstructClientAckAndDataPacket(
6618 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
6619 1, false, ConstructDataFrame(get_request)));
Renjief49758b2019-01-11 23:32:416620
Yixin Wang46a273ec302018-01-23 17:59:566621 const char get_response[] =
6622 "HTTP/1.1 200 OK\r\n"
6623 "Content-Length: 10\r\n\r\n";
6624 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336625 ASYNC, ConstructServerDataPacket(
6626 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:526627 ConstructDataFrame(get_response)));
Fan Yang32c5a112018-12-10 20:06:336628 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:416629 SYNCHRONOUS, ConstructServerDataPacket(
6630 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:526631 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:236632 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346633 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:566634
6635 // CONNECT request and response for second request
Patrick Meenan885a00652023-02-15 20:07:026636 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
Patrick Meenanf741c6082023-01-03 18:06:436637 mock_quic_data.AddWrite(
6638 SYNCHRONOUS,
6639 ConstructClientPriorityPacket(
6640 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
6641 DEFAULT_PRIORITY));
6642 }
Zhongyi Shi32f2fd02018-04-16 18:23:436643 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236644 SYNCHRONOUS,
6645 ConstructClientRequestHeadersPacket(
6646 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Patrick Meenan885a00652023-02-15 20:07:026647 false, DEFAULT_PRIORITY,
Bence Béky957bab12023-01-31 16:40:106648 ConnectRequestHeaders("different.example.org:443"), false));
Zhongyi Shi32f2fd02018-04-16 18:23:436649 mock_quic_data.AddRead(
6650 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336651 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286652 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566653
6654 // GET request, response, and data over QUIC tunnel for second request
6655 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:136656 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:566657 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:526658 mock_quic_data.AddWrite(
6659 SYNCHRONOUS,
6660 ConstructClientAckAndDataPacket(
6661 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 4,
6662 4, false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:566663
Ryan Hamilton0239aac2018-05-19 00:03:136664 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:566665 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:436666 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:176667 ASYNC, ConstructServerDataPacket(
6668 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:526669 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:566670
Ryan Hamilton0239aac2018-05-19 00:03:136671 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:196672 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Zhongyi Shi32f2fd02018-04-16 18:23:436673 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:436674 ASYNC, ConstructServerDataPacket(
6675 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:526676 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:566677
Renjie Tangaadb84b2019-08-31 01:00:236678 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346679 ConstructClientAckPacket(packet_num++, 6, 5));
Yixin Wang46a273ec302018-01-23 17:59:566680 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Patrick Meenan885a00652023-02-15 20:07:026681 mock_quic_data.AddWrite(
6682 SYNCHRONOUS, ConstructClientDataPacket(
6683 packet_num++, GetQpackDecoderStreamId(), true, false,
6684 StreamCancellationQpackDecoderInstruction(0)));
Yixin Wang46a273ec302018-01-23 17:59:566685 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:416686 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236687 ConstructClientRstPacket(packet_num++,
6688 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416689 quic::QUIC_STREAM_CANCELLED));
Patrick Meenan885a00652023-02-15 20:07:026690 mock_quic_data.AddWrite(
6691 SYNCHRONOUS, ConstructClientDataPacket(
6692 packet_num++, GetQpackDecoderStreamId(), true, false,
6693 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:076694
Yixin Wang46a273ec302018-01-23 17:59:566695 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436696 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236697 ConstructClientRstPacket(packet_num++,
6698 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416699 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566700
6701 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6702
6703 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6704
6705 SSLSocketDataProvider ssl_data(ASYNC, OK);
6706 ssl_data.next_proto = kProtoHTTP2;
6707 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
6708
6709 CreateSession();
6710
6711 request_.url = GURL("https://mail.example.org/");
6712 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566713 RunTransaction(&trans_1);
6714 CheckWasHttpResponse(&trans_1);
6715 CheckResponsePort(&trans_1, 70);
6716 CheckResponseData(&trans_1, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:566717 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
6718
6719 request_.url = GURL("https://different.example.org/");
6720 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566721 RunTransaction(&trans_2);
6722 CheckWasSpdyResponse(&trans_2);
6723 CheckResponsePort(&trans_2, 70);
6724 CheckResponseData(&trans_2, "0123456");
Yixin Wang46a273ec302018-01-23 17:59:566725 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
6726
6727 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
6728 // proxy socket to disconnect.
6729 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6730
6731 base::RunLoop().RunUntilIdle();
6732 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6733 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6734}
6735
6736// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:146737TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:566738 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146739 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566740 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276741 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566742 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566743
Ryan Hamiltonabad59e2019-06-06 04:02:596744 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236745 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026746 mock_quic_data.AddWrite(SYNCHRONOUS,
6747 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:436748
Patrick Meenan885a00652023-02-15 20:07:026749 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
6750 mock_quic_data.AddWrite(
6751 SYNCHRONOUS,
6752 ConstructClientPriorityPacket(
6753 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6754 DEFAULT_PRIORITY));
Renjie Tangaadb84b2019-08-31 01:00:236755 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526756 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236757 SYNCHRONOUS,
6758 ConstructClientRequestHeadersPacket(
6759 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Patrick Meenan885a00652023-02-15 20:07:026760 false, DEFAULT_PRIORITY,
Bence Béky957bab12023-01-31 16:40:106761 ConnectRequestHeaders("mail.example.org:443"), false));
Fan Yang32c5a112018-12-10 20:06:336762 mock_quic_data.AddRead(
6763 ASYNC, ConstructServerResponseHeadersPacket(
6764 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6765 GetResponseHeaders("500")));
6766 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:236767 mock_quic_data.AddWrite(
6768 SYNCHRONOUS,
6769 ConstructClientAckAndRstPacket(
6770 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:346771 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:566772
6773 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6774
6775 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6776
6777 CreateSession();
6778
6779 request_.url = GURL("https://mail.example.org/");
6780 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566781 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266782 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:566783 EXPECT_EQ(ERR_IO_PENDING, rv);
6784 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
Yixin Wang46a273ec302018-01-23 17:59:566785
6786 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6787 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6788}
6789
6790// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:146791TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:566792 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146793 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566794 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276795 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566796 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566797
Ryan Hamiltonabad59e2019-06-06 04:02:596798 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236799 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026800 mock_quic_data.AddWrite(SYNCHRONOUS,
6801 ConstructInitialSettingsPacket(packet_num++));
6802 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
6803 mock_quic_data.AddWrite(
6804 SYNCHRONOUS,
6805 ConstructClientPriorityPacket(
6806 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6807 DEFAULT_PRIORITY));
Renjie Tangaadb84b2019-08-31 01:00:236808 }
Fan Yang32c5a112018-12-10 20:06:336809 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236810 SYNCHRONOUS,
6811 ConstructClientRequestHeadersPacket(
6812 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Patrick Meenan885a00652023-02-15 20:07:026813 false, DEFAULT_PRIORITY,
Bence Béky957bab12023-01-31 16:40:106814 ConnectRequestHeaders("mail.example.org:443"), false));
Yixin Wang46a273ec302018-01-23 17:59:566815 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
6816
6817 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6818
6819 CreateSession();
6820
6821 request_.url = GURL("https://mail.example.org/");
6822 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566823 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266824 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:566825 EXPECT_EQ(ERR_IO_PENDING, rv);
6826 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
6827
6828 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6829 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6830}
6831
6832// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
6833// host. Retries request and succeeds.
Bence Békyf6bb6b22020-04-17 20:22:116834TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:566835 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146836 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566837 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276838 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566839 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566840
Ryan Hamiltonabad59e2019-06-06 04:02:596841 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236842 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026843 mock_quic_data.AddWrite(SYNCHRONOUS,
6844 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:436845
Patrick Meenan885a00652023-02-15 20:07:026846 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
6847 mock_quic_data.AddWrite(
6848 SYNCHRONOUS,
6849 ConstructClientPriorityPacket(
6850 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6851 DEFAULT_PRIORITY));
Renjie Tangaadb84b2019-08-31 01:00:236852 }
Fan Yang32c5a112018-12-10 20:06:336853 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236854 SYNCHRONOUS,
6855 ConstructClientRequestHeadersPacket(
6856 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Patrick Meenan885a00652023-02-15 20:07:026857 false, DEFAULT_PRIORITY,
Bence Béky957bab12023-01-31 16:40:106858 ConnectRequestHeaders("mail.example.org:443"), false));
Zhongyi Shi32f2fd02018-04-16 18:23:436859 mock_quic_data.AddRead(
6860 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336861 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286862 GetResponseHeaders("200")));
Patrick Meenan885a00652023-02-15 20:07:026863 mock_quic_data.AddWrite(
6864 SYNCHRONOUS, ConstructClientAckAndDataPacket(
6865 packet_num++, false, GetQpackDecoderStreamId(), 1, 1,
6866 false, StreamCancellationQpackDecoderInstruction(0)));
6867 mock_quic_data.AddWrite(
6868 SYNCHRONOUS,
6869 ConstructClientRstPacket(packet_num++,
6870 GetNthClientInitiatedBidirectionalStreamId(0),
6871 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566872
Patrick Meenan885a00652023-02-15 20:07:026873 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
Patrick Meenanf741c6082023-01-03 18:06:436874 mock_quic_data.AddWrite(
6875 SYNCHRONOUS,
6876 ConstructClientPriorityPacket(
6877 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
6878 DEFAULT_PRIORITY));
6879 }
Zhongyi Shi32f2fd02018-04-16 18:23:436880 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236881 SYNCHRONOUS,
6882 ConstructClientRequestHeadersPacket(
6883 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Patrick Meenan885a00652023-02-15 20:07:026884 false, DEFAULT_PRIORITY,
Bence Béky957bab12023-01-31 16:40:106885 ConnectRequestHeaders("mail.example.org:443"), false));
Zhongyi Shi32f2fd02018-04-16 18:23:436886 mock_quic_data.AddRead(
6887 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336888 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286889 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566890
6891 const char get_request[] =
6892 "GET / HTTP/1.1\r\n"
6893 "Host: mail.example.org\r\n"
6894 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526895 mock_quic_data.AddWrite(
6896 SYNCHRONOUS,
6897 ConstructClientAckAndDataPacket(
6898 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 2,
6899 2, false, ConstructDataFrame(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:566900 const char get_response[] =
6901 "HTTP/1.1 200 OK\r\n"
6902 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:436903 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336904 ASYNC, ConstructServerDataPacket(
6905 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:526906 ConstructDataFrame(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526907
Fan Yang32c5a112018-12-10 20:06:336908 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:416909 SYNCHRONOUS, ConstructServerDataPacket(
6910 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:526911 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:236912 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346913 ConstructClientAckPacket(packet_num++, 4, 3));
Yixin Wang46a273ec302018-01-23 17:59:566914 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6915
Patrick Meenan885a00652023-02-15 20:07:026916 mock_quic_data.AddWrite(
6917 SYNCHRONOUS, ConstructClientDataPacket(
6918 packet_num++, GetQpackDecoderStreamId(), true, false,
6919 StreamCancellationQpackDecoderInstruction(1, false)));
Yixin Wang46a273ec302018-01-23 17:59:566920 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:416921 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236922 ConstructClientRstPacket(packet_num++,
6923 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416924 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566925
6926 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6927
6928 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6929 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
6930
6931 SSLSocketDataProvider ssl_data(ASYNC, OK);
6932 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
6933
6934 CreateSession();
6935
6936 request_.url = GURL("https://mail.example.org/");
6937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566938 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266939 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:566940 EXPECT_EQ(ERR_IO_PENDING, rv);
6941 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
6942
6943 rv = trans.RestartIgnoringLastError(callback.callback());
6944 EXPECT_EQ(ERR_IO_PENDING, rv);
6945 EXPECT_EQ(OK, callback.WaitForResult());
6946
6947 CheckWasHttpResponse(&trans);
6948 CheckResponsePort(&trans, 70);
6949 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:566950 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
6951
6952 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
6953 // proxy socket to disconnect.
6954 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6955
6956 base::RunLoop().RunUntilIdle();
6957 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6958 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6959}
6960
6961// Checks if a request's specified "user-agent" header shows up correctly in the
6962// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:146963TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:006964 const char kConfiguredUserAgent[] = "Configured User-Agent";
6965 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:566966 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146967 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566968 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276969 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566970 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566971
Ryan Hamiltonabad59e2019-06-06 04:02:596972 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236973 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026974 mock_quic_data.AddWrite(SYNCHRONOUS,
6975 ConstructInitialSettingsPacket(packet_num++));
6976 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
6977 mock_quic_data.AddWrite(
6978 SYNCHRONOUS,
6979 ConstructClientPriorityPacket(
6980 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6981 DEFAULT_PRIORITY));
Renjie Tangaadb84b2019-08-31 01:00:236982 }
Yixin Wang46a273ec302018-01-23 17:59:566983
Bence Béky4c325e52020-10-22 20:48:016984 spdy::Http2HeaderBlock headers =
6985 ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:006986 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:336987 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026988 SYNCHRONOUS,
6989 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:236990 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Patrick Meenan885a00652023-02-15 20:07:026991 false, DEFAULT_PRIORITY, std::move(headers), false));
Yixin Wang46a273ec302018-01-23 17:59:566992 // Return an error, so the transaction stops here (this test isn't interested
6993 // in the rest).
6994 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
6995
6996 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6997
Matt Menked732ea42019-03-08 12:05:006998 StaticHttpUserAgentSettings http_user_agent_settings(
6999 std::string() /* accept_language */, kConfiguredUserAgent);
7000 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:567001 CreateSession();
7002
7003 request_.url = GURL("https://mail.example.org/");
7004 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:007005 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:567006 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567007 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267008 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:567009 EXPECT_EQ(ERR_IO_PENDING, rv);
7010 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7011
7012 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7013 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7014}
7015
Yixin Wang00fc44c2018-01-23 21:12:207016// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
7017// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:147018TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:207019 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147020 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567021 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:277022 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:567023 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:207024
7025 const RequestPriority request_priority = MEDIUM;
7026
Ryan Hamiltonabad59e2019-06-06 04:02:597027 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237028 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:027029 mock_quic_data.AddWrite(SYNCHRONOUS,
7030 ConstructInitialSettingsPacket(packet_num++));
7031 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
7032 mock_quic_data.AddWrite(
7033 SYNCHRONOUS,
7034 ConstructClientPriorityPacket(
7035 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
7036 DEFAULT_PRIORITY));
Renjie Tangaadb84b2019-08-31 01:00:237037 }
Zhongyi Shi32f2fd02018-04-16 18:23:437038 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237039 SYNCHRONOUS,
7040 ConstructClientRequestHeadersPacket(
7041 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Patrick Meenan885a00652023-02-15 20:07:027042 false, DEFAULT_PRIORITY,
Bence Béky957bab12023-01-31 16:40:107043 ConnectRequestHeaders("mail.example.org:443"), false));
Yixin Wang00fc44c2018-01-23 21:12:207044 // Return an error, so the transaction stops here (this test isn't interested
7045 // in the rest).
7046 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7047
7048 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7049
7050 CreateSession();
7051
7052 request_.url = GURL("https://mail.example.org/");
7053 HttpNetworkTransaction trans(request_priority, session_.get());
7054 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267055 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang00fc44c2018-01-23 21:12:207056 EXPECT_EQ(ERR_IO_PENDING, rv);
7057 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7058
7059 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7060 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7061}
7062
Matt Menkeedaf3b82019-03-14 21:39:447063// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
7064// HTTP/2 stream dependency and weights given the request priority.
7065TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
7066 session_params_.enable_quic = true;
7067 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567068 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:277069 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:567070 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeedaf3b82019-03-14 21:39:447071
7072 const RequestPriority kRequestPriority = MEDIUM;
7073 const RequestPriority kRequestPriority2 = LOWEST;
7074
Ryan Hamiltonabad59e2019-06-06 04:02:597075 MockQuicData mock_quic_data(version_);
Patrick Meenan885a00652023-02-15 20:07:027076 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
7077 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
Matt Menkeedaf3b82019-03-14 21:39:447078 // This should never be reached.
7079 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7080 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7081
7082 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:597083 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:447084 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
7085 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7086
7087 int original_max_sockets_per_group =
7088 ClientSocketPoolManager::max_sockets_per_group(
7089 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
7090 ClientSocketPoolManager::set_max_sockets_per_group(
7091 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
7092 int original_max_sockets_per_pool =
7093 ClientSocketPoolManager::max_sockets_per_pool(
7094 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
7095 ClientSocketPoolManager::set_max_sockets_per_pool(
7096 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
7097 CreateSession();
7098
7099 request_.url = GURL("https://mail.example.org/");
7100 HttpNetworkTransaction trans(kRequestPriority, session_.get());
7101 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267102 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeedaf3b82019-03-14 21:39:447103 EXPECT_EQ(ERR_IO_PENDING, rv);
7104
7105 HttpRequestInfo request2;
7106 request2.url = GURL("https://mail.example.org/some/other/path/");
7107 request2.traffic_annotation =
7108 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7109
7110 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
7111 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:267112 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
Matt Menkeedaf3b82019-03-14 21:39:447113 EXPECT_EQ(ERR_IO_PENDING, rv2);
7114
7115 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7116 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7117
7118 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
7119
7120 ClientSocketPoolManager::set_max_sockets_per_pool(
7121 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
7122 original_max_sockets_per_pool);
7123 ClientSocketPoolManager::set_max_sockets_per_group(
7124 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
7125 original_max_sockets_per_group);
7126}
7127
Yixin Wang46a273ec302018-01-23 17:59:567128// Test the request-challenge-retry sequence for basic auth, over a QUIC
7129// connection when setting up a QUIC proxy tunnel.
Bence Békyf6bb6b22020-04-17 20:22:117130TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Jan Wilken Dörriec92a6d7242021-03-23 17:43:487131 const std::u16string kBaz(u"baz");
7132 const std::u16string kFoo(u"foo");
Yixin Wang46a273ec302018-01-23 17:59:567133
Yixin Wang46a273ec302018-01-23 17:59:567134 // On the second pass, the body read of the auth challenge is synchronous, so
7135 // IsConnectedAndIdle returns false. The socket should still be drained and
7136 // reused. See http://crbug.com/544255.
7137 for (int i = 0; i < 2; ++i) {
Bence Béky6e243aa2019-12-13 19:01:077138 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227139 version_,
7140 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7141 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky957bab12023-01-31 16:40:107142 true);
Bence Béky6e243aa2019-12-13 19:01:077143 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227144 version_,
7145 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7146 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Bence Béky6e243aa2019-12-13 19:01:077147 false);
Yixin Wang46a273ec302018-01-23 17:59:567148
7149 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147150 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567151 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:277152 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Ramin Halavatica8d5252018-03-12 05:33:497153 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567154
Ryan Hamiltonabad59e2019-06-06 04:02:597155 MockQuicData mock_quic_data(version_);
Yixin Wang46a273ec302018-01-23 17:59:567156
Renjie Tangaadb84b2019-08-31 01:00:237157 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:027158 mock_quic_data.AddWrite(
7159 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:437160
Patrick Meenan885a00652023-02-15 20:07:027161 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
7162 mock_quic_data.AddWrite(
7163 SYNCHRONOUS,
7164 client_maker.MakePriorityPacket(
7165 packet_num++, true, GetNthClientInitiatedBidirectionalStreamId(0),
7166 quic::QuicStreamPriority::kDefaultUrgency));
Renjie Tangaadb84b2019-08-31 01:00:237167 }
Yixin Wang46a273ec302018-01-23 17:59:567168
7169 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437170 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:077171 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237172 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Patrick Meenan885a00652023-02-15 20:07:027173 false, quic::QuicStreamPriority::kDefaultUrgency,
Bence Béky957bab12023-01-31 16:40:107174 client_maker.ConnectRequestHeaders("mail.example.org:443"), nullptr,
7175 false));
Yixin Wang46a273ec302018-01-23 17:59:567176
Kenichi Ishibashif8634ab2021-03-16 23:41:287177 spdy::Http2HeaderBlock headers = server_maker.GetResponseHeaders("407");
Yixin Wang46a273ec302018-01-23 17:59:567178 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
7179 headers["content-length"] = "10";
7180 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:077181 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337182 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027183 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:567184
7185 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:437186 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:077187 ASYNC, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:337188 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:177189 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:567190 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:437191 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:077192 SYNCHRONOUS, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:337193 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:177194 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:567195 }
Yixin Wang46a273ec302018-01-23 17:59:567196
Bence Béky7a45d4d2020-05-08 01:59:237197 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347198 client_maker.MakeAckPacket(packet_num++, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:077199
Patrick Meenan885a00652023-02-15 20:07:027200 mock_quic_data.AddWrite(
7201 SYNCHRONOUS,
7202 client_maker.MakeDataPacket(
7203 packet_num++, GetQpackDecoderStreamId(),
7204 /* should_include_version = */ true,
7205 /* fin = */ false, StreamCancellationQpackDecoderInstruction(0)));
Yixin Wang46a273ec302018-01-23 17:59:567206
7207 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337208 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:077209 client_maker.MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:237210 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417211 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:187212 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:567213
Patrick Meenan885a00652023-02-15 20:07:027214 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
Patrick Meenanf741c6082023-01-03 18:06:437215 mock_quic_data.AddWrite(
7216 SYNCHRONOUS,
7217 client_maker.MakePriorityPacket(
7218 packet_num++, true, GetNthClientInitiatedBidirectionalStreamId(1),
Bence Béky957bab12023-01-31 16:40:107219 quic::QuicStreamPriority::kDefaultUrgency));
Patrick Meenanf741c6082023-01-03 18:06:437220 }
7221
Bence Béky6e243aa2019-12-13 19:01:077222 headers = client_maker.ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:567223 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
7224 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:047225 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:077226 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237227 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Patrick Meenan885a00652023-02-15 20:07:027228 false, quic::QuicStreamPriority::kDefaultUrgency,
Bence Béky957bab12023-01-31 16:40:107229 std::move(headers), nullptr, false));
Yixin Wang46a273ec302018-01-23 17:59:567230
7231 // Response to wrong password
Kenichi Ishibashif8634ab2021-03-16 23:41:287232 headers = server_maker.GetResponseHeaders("407");
Yixin Wang46a273ec302018-01-23 17:59:567233 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
7234 headers["content-length"] = "10";
7235 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:077236 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337237 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027238 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:567239 mock_quic_data.AddRead(SYNCHRONOUS,
7240 ERR_IO_PENDING); // No more data to read
7241
Patrick Meenan885a00652023-02-15 20:07:027242 mock_quic_data.AddWrite(
7243 SYNCHRONOUS,
7244 client_maker.MakeAckAndDataPacket(
7245 packet_num++, false, GetQpackDecoderStreamId(), 3, 3, false,
7246 StreamCancellationQpackDecoderInstruction(1, false)));
7247 mock_quic_data.AddWrite(
7248 SYNCHRONOUS,
7249 client_maker.MakeRstPacket(
7250 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
7251 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567252
7253 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7254 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
7255
7256 CreateSession();
7257
7258 request_.url = GURL("https://mail.example.org/");
7259 // Ensure that proxy authentication is attempted even
Matt Menke25eaa432020-08-25 00:10:007260 // when privacy mode is enabled.
7261 request_.privacy_mode = PRIVACY_MODE_ENABLED;
Yixin Wang46a273ec302018-01-23 17:59:567262 {
7263 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567264 RunTransaction(&trans);
7265
7266 const HttpResponseInfo* response = trans.GetResponseInfo();
7267 ASSERT_TRUE(response != nullptr);
7268 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:287269 EXPECT_EQ("HTTP/1.1 407", response->headers->GetStatusLine());
Yixin Wang46a273ec302018-01-23 17:59:567270 EXPECT_TRUE(response->headers->IsKeepAlive());
7271 EXPECT_EQ(407, response->headers->response_code());
7272 EXPECT_EQ(10, response->headers->GetContentLength());
7273 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Anton Bikineev068d2912021-05-15 20:43:527274 absl::optional<AuthChallengeInfo> auth_challenge =
Emily Starkf2c9bbd2019-04-09 17:08:587275 response->auth_challenge;
7276 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:567277 EXPECT_TRUE(auth_challenge->is_proxy);
7278 EXPECT_EQ("https://proxy.example.org:70",
7279 auth_challenge->challenger.Serialize());
7280 EXPECT_EQ("MyRealm1", auth_challenge->realm);
7281 EXPECT_EQ("basic", auth_challenge->scheme);
7282
7283 TestCompletionCallback callback;
7284 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
7285 callback.callback());
7286 EXPECT_EQ(ERR_IO_PENDING, rv);
7287 EXPECT_EQ(OK, callback.WaitForResult());
7288
7289 response = trans.GetResponseInfo();
7290 ASSERT_TRUE(response != nullptr);
7291 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:287292 EXPECT_EQ("HTTP/1.1 407", response->headers->GetStatusLine());
Yixin Wang46a273ec302018-01-23 17:59:567293 EXPECT_TRUE(response->headers->IsKeepAlive());
7294 EXPECT_EQ(407, response->headers->response_code());
7295 EXPECT_EQ(10, response->headers->GetContentLength());
7296 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:587297 auth_challenge = response->auth_challenge;
7298 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:567299 EXPECT_TRUE(auth_challenge->is_proxy);
7300 EXPECT_EQ("https://proxy.example.org:70",
7301 auth_challenge->challenger.Serialize());
7302 EXPECT_EQ("MyRealm1", auth_challenge->realm);
7303 EXPECT_EQ("basic", auth_challenge->scheme);
7304 }
7305 // HttpNetworkTransaction is torn down now that it's out of scope, causing
7306 // the QUIC stream to be cleaned up (since the proxy socket cannot be
7307 // reused because it's not connected).
7308 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7309 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7310 }
7311}
7312
Brianna Goldsteind22b0642022-10-11 16:30:507313// Test that NetworkAnonymizationKey is respected by QUIC connections, when
Matt Menke26e41542019-06-05 01:09:517314// kPartitionConnectionsByNetworkIsolationKey is enabled.
7315TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Matt Menke4807a9a2020-11-21 00:14:417316 const SchemefulSite kSite1(GURL("http://origin1/"));
7317 const SchemefulSite kSite2(GURL("http://origin2/"));
7318 NetworkIsolationKey network_isolation_key1(kSite1, kSite1);
7319 NetworkIsolationKey network_isolation_key2(kSite2, kSite2);
Brianna Goldstein314ddf722022-09-24 02:00:527320 NetworkAnonymizationKey network_anonymization_key1(kSite1, kSite1);
7321 NetworkAnonymizationKey network_anonymization_key2(kSite2, kSite2);
Matt Menke26e41542019-06-05 01:09:517322
Victor Vasilieva1e66d72019-12-05 17:55:387323 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:517324 HostPortPair::FromString("mail.example.org:443"));
7325
7326 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
7327 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
7328 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
7329 // the same way as the HTTP over H2 proxy case.
7330 for (bool use_proxy : {false, true}) {
7331 SCOPED_TRACE(use_proxy);
7332
7333 if (use_proxy) {
7334 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:277335 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Matt Menke26e41542019-06-05 01:09:517336 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
7337 } else {
Nicolas Arciniegad2013f92020-02-07 23:00:567338 proxy_resolution_service_ =
7339 ConfiguredProxyResolutionService::CreateDirect();
Matt Menke26e41542019-06-05 01:09:517340 }
7341
7342 GURL url1;
7343 GURL url2;
7344 GURL url3;
7345 if (use_proxy) {
7346 url1 = GURL("http://mail.example.org/1");
7347 url2 = GURL("http://mail.example.org/2");
7348 url3 = GURL("http://mail.example.org/3");
7349 } else {
7350 url1 = GURL("https://mail.example.org/1");
7351 url2 = GURL("https://mail.example.org/2");
7352 url3 = GURL("https://mail.example.org/3");
7353 }
7354
7355 for (bool partition_connections : {false, true}) {
7356 SCOPED_TRACE(partition_connections);
7357
7358 base::test::ScopedFeatureList feature_list;
7359 if (partition_connections) {
7360 feature_list.InitAndEnableFeature(
7361 features::kPartitionConnectionsByNetworkIsolationKey);
7362 } else {
7363 feature_list.InitAndDisableFeature(
7364 features::kPartitionConnectionsByNetworkIsolationKey);
7365 }
7366
7367 // Reads and writes for the unpartitioned case, where only one socket is
7368 // used.
7369
Victor Vasilieva1e66d72019-12-05 17:55:387370 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:517371 HostPortPair::FromString("mail.example.org:443"));
7372
Ryan Hamiltonabad59e2019-06-06 04:02:597373 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:517374 QuicTestPacketMaker client_maker1(
7375 version_,
Victor Vasiliev7752898d2019-11-14 21:30:227376 quic::QuicUtils::CreateRandomConnectionId(
7377 context_.random_generator()),
7378 context_.clock(), kDefaultServerHostName,
Bence Béky957bab12023-01-31 16:40:107379 quic::Perspective::IS_CLIENT, true);
Matt Menke26e41542019-06-05 01:09:517380 QuicTestPacketMaker server_maker1(
7381 version_,
Victor Vasiliev7752898d2019-11-14 21:30:227382 quic::QuicUtils::CreateRandomConnectionId(
7383 context_.random_generator()),
7384 context_.clock(), kDefaultServerHostName,
7385 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:517386
Renjie Tangaadb84b2019-08-31 01:00:237387 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:027388 unpartitioned_mock_quic_data.AddWrite(
7389 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
Matt Menke26e41542019-06-05 01:09:517390
7391 unpartitioned_mock_quic_data.AddWrite(
7392 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027393 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237394 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7395 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:107396 GetRequestHeaders("GET", url1.scheme(), "/1"), nullptr));
Matt Menke26e41542019-06-05 01:09:517397 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027398 ASYNC, server_maker1.MakeResponseHeadersPacket(
7399 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287400 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517401 unpartitioned_mock_quic_data.AddRead(
7402 ASYNC, server_maker1.MakeDataPacket(
7403 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527404 true, ConstructDataFrame("1")));
Matt Menke26e41542019-06-05 01:09:517405 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347406 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menke26e41542019-06-05 01:09:517407
7408 unpartitioned_mock_quic_data.AddWrite(
7409 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027410 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237411 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
7412 false, true,
Matt Menke26e41542019-06-05 01:09:517413 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:107414 GetRequestHeaders("GET", url2.scheme(), "/2"), nullptr));
Matt Menke26e41542019-06-05 01:09:517415 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027416 ASYNC, server_maker1.MakeResponseHeadersPacket(
7417 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287418 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517419 unpartitioned_mock_quic_data.AddRead(
7420 ASYNC, server_maker1.MakeDataPacket(
7421 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:527422 true, ConstructDataFrame("2")));
Matt Menke26e41542019-06-05 01:09:517423 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangb7afea82020-07-15 23:35:477424 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3));
Matt Menke26e41542019-06-05 01:09:517425
7426 unpartitioned_mock_quic_data.AddWrite(
7427 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027428 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237429 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
7430 false, true,
Matt Menke26e41542019-06-05 01:09:517431 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:107432 GetRequestHeaders("GET", url3.scheme(), "/3"), nullptr));
Matt Menke26e41542019-06-05 01:09:517433 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027434 ASYNC, server_maker1.MakeResponseHeadersPacket(
7435 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287436 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517437 unpartitioned_mock_quic_data.AddRead(
7438 ASYNC, server_maker1.MakeDataPacket(
7439 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Bence Béky319388a882020-09-23 18:42:527440 true, ConstructDataFrame("3")));
Matt Menke26e41542019-06-05 01:09:517441 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangb7afea82020-07-15 23:35:477442 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 6, 5));
Matt Menke26e41542019-06-05 01:09:517443
7444 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
7445
7446 // Reads and writes for the partitioned case, where two sockets are used.
7447
Ryan Hamiltonabad59e2019-06-06 04:02:597448 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:517449 QuicTestPacketMaker client_maker2(
7450 version_,
Victor Vasiliev7752898d2019-11-14 21:30:227451 quic::QuicUtils::CreateRandomConnectionId(
7452 context_.random_generator()),
7453 context_.clock(), kDefaultServerHostName,
Bence Béky957bab12023-01-31 16:40:107454 quic::Perspective::IS_CLIENT, true);
Matt Menke26e41542019-06-05 01:09:517455 QuicTestPacketMaker server_maker2(
7456 version_,
Victor Vasiliev7752898d2019-11-14 21:30:227457 quic::QuicUtils::CreateRandomConnectionId(
7458 context_.random_generator()),
7459 context_.clock(), kDefaultServerHostName,
7460 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:517461
Renjie Tangaadb84b2019-08-31 01:00:237462 int packet_num2 = 1;
Patrick Meenan885a00652023-02-15 20:07:027463 partitioned_mock_quic_data1.AddWrite(
7464 SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(packet_num2++));
Matt Menke26e41542019-06-05 01:09:517465
7466 partitioned_mock_quic_data1.AddWrite(
7467 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027468 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237469 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
7470 true, true,
Matt Menke26e41542019-06-05 01:09:517471 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:107472 GetRequestHeaders("GET", url1.scheme(), "/1"), nullptr));
Matt Menke26e41542019-06-05 01:09:517473 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027474 ASYNC, server_maker2.MakeResponseHeadersPacket(
7475 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287476 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517477 partitioned_mock_quic_data1.AddRead(
7478 ASYNC, server_maker2.MakeDataPacket(
7479 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527480 true, ConstructDataFrame("1")));
Matt Menke26e41542019-06-05 01:09:517481 partitioned_mock_quic_data1.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347482 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 2, 1));
Matt Menke26e41542019-06-05 01:09:517483
7484 partitioned_mock_quic_data1.AddWrite(
7485 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027486 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237487 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
7488 false, true,
Matt Menke26e41542019-06-05 01:09:517489 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:107490 GetRequestHeaders("GET", url3.scheme(), "/3"), nullptr));
Matt Menke26e41542019-06-05 01:09:517491 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027492 ASYNC, server_maker2.MakeResponseHeadersPacket(
7493 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287494 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517495 partitioned_mock_quic_data1.AddRead(
7496 ASYNC, server_maker2.MakeDataPacket(
7497 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:527498 true, ConstructDataFrame("3")));
Matt Menke26e41542019-06-05 01:09:517499 partitioned_mock_quic_data1.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347500 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 4, 3));
Matt Menke26e41542019-06-05 01:09:517501
7502 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
7503
Ryan Hamiltonabad59e2019-06-06 04:02:597504 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:517505 QuicTestPacketMaker client_maker3(
7506 version_,
Victor Vasiliev7752898d2019-11-14 21:30:227507 quic::QuicUtils::CreateRandomConnectionId(
7508 context_.random_generator()),
7509 context_.clock(), kDefaultServerHostName,
Bence Béky957bab12023-01-31 16:40:107510 quic::Perspective::IS_CLIENT, true);
Matt Menke26e41542019-06-05 01:09:517511 QuicTestPacketMaker server_maker3(
7512 version_,
Victor Vasiliev7752898d2019-11-14 21:30:227513 quic::QuicUtils::CreateRandomConnectionId(
7514 context_.random_generator()),
7515 context_.clock(), kDefaultServerHostName,
7516 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:517517
Renjie Tangaadb84b2019-08-31 01:00:237518 int packet_num3 = 1;
Patrick Meenan885a00652023-02-15 20:07:027519 partitioned_mock_quic_data2.AddWrite(
7520 SYNCHRONOUS, client_maker3.MakeInitialSettingsPacket(packet_num3++));
Matt Menke26e41542019-06-05 01:09:517521
7522 partitioned_mock_quic_data2.AddWrite(
7523 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027524 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237525 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
7526 true, true,
Matt Menke26e41542019-06-05 01:09:517527 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:107528 GetRequestHeaders("GET", url2.scheme(), "/2"), nullptr));
Matt Menke26e41542019-06-05 01:09:517529 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027530 ASYNC, server_maker3.MakeResponseHeadersPacket(
7531 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287532 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517533 partitioned_mock_quic_data2.AddRead(
7534 ASYNC, server_maker3.MakeDataPacket(
7535 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527536 true, ConstructDataFrame("2")));
Matt Menke26e41542019-06-05 01:09:517537 partitioned_mock_quic_data2.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347538 SYNCHRONOUS, client_maker3.MakeAckPacket(packet_num3++, 2, 1));
Matt Menke26e41542019-06-05 01:09:517539
7540 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
7541
7542 if (partition_connections) {
7543 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7544 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7545 } else {
7546 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7547 }
7548
7549 CreateSession();
7550
7551 TestCompletionCallback callback;
7552 HttpRequestInfo request1;
7553 request1.method = "GET";
7554 request1.url = GURL(url1);
7555 request1.traffic_annotation =
7556 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7557 request1.network_isolation_key = network_isolation_key1;
Brianna Goldstein314ddf722022-09-24 02:00:527558 request1.network_anonymization_key = network_anonymization_key1;
Matt Menke26e41542019-06-05 01:09:517559 HttpNetworkTransaction trans1(LOWEST, session_.get());
7560 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
7561 EXPECT_THAT(callback.GetResult(rv), IsOk());
7562 std::string response_data1;
7563 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
7564 EXPECT_EQ("1", response_data1);
7565
7566 HttpRequestInfo request2;
7567 request2.method = "GET";
7568 request2.url = GURL(url2);
7569 request2.traffic_annotation =
7570 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7571 request2.network_isolation_key = network_isolation_key2;
Brianna Goldstein314ddf722022-09-24 02:00:527572 request2.network_anonymization_key = network_anonymization_key2;
Matt Menke26e41542019-06-05 01:09:517573 HttpNetworkTransaction trans2(LOWEST, session_.get());
7574 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
7575 EXPECT_THAT(callback.GetResult(rv), IsOk());
7576 std::string response_data2;
7577 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
7578 EXPECT_EQ("2", response_data2);
7579
7580 HttpRequestInfo request3;
7581 request3.method = "GET";
7582 request3.url = GURL(url3);
7583 request3.traffic_annotation =
7584 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7585 request3.network_isolation_key = network_isolation_key1;
Brianna Goldstein314ddf722022-09-24 02:00:527586 request3.network_anonymization_key = network_anonymization_key1;
7587
Matt Menke26e41542019-06-05 01:09:517588 HttpNetworkTransaction trans3(LOWEST, session_.get());
7589 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
7590 EXPECT_THAT(callback.GetResult(rv), IsOk());
7591 std::string response_data3;
7592 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
7593 EXPECT_EQ("3", response_data3);
7594
7595 if (partition_connections) {
7596 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
7597 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
7598 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
7599 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
7600 } else {
7601 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
7602 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
7603 }
7604 }
7605 }
7606}
7607
7608// Test that two requests to the same origin over QUIC tunnels use different
7609// QUIC sessions if their NetworkIsolationKeys don't match, and
7610// kPartitionConnectionsByNetworkIsolationKey is enabled.
7611TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
7612 base::test::ScopedFeatureList feature_list;
7613 feature_list.InitAndEnableFeature(
7614 features::kPartitionConnectionsByNetworkIsolationKey);
7615
7616 session_params_.enable_quic = true;
7617 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567618 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:277619 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:567620 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menke26e41542019-06-05 01:09:517621
7622 const char kGetRequest[] =
7623 "GET / HTTP/1.1\r\n"
7624 "Host: mail.example.org\r\n"
7625 "Connection: keep-alive\r\n\r\n";
7626 const char kGetResponse[] =
7627 "HTTP/1.1 200 OK\r\n"
7628 "Content-Length: 10\r\n\r\n";
7629
Ryan Hamiltonabad59e2019-06-06 04:02:597630 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
7631 std::make_unique<MockQuicData>(version_),
7632 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:517633
7634 for (int index : {0, 1}) {
7635 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227636 version_,
7637 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7638 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky957bab12023-01-31 16:40:107639 true);
Matt Menke26e41542019-06-05 01:09:517640 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227641 version_,
7642 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7643 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
7644 false);
Matt Menke26e41542019-06-05 01:09:517645
Renjie Tangaadb84b2019-08-31 01:00:237646 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:027647 mock_quic_data[index]->AddWrite(
7648 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:437649
Patrick Meenan885a00652023-02-15 20:07:027650 if (base::FeatureList::IsEnabled(features::kPriorityIncremental)) {
7651 mock_quic_data[index]->AddWrite(
7652 SYNCHRONOUS,
7653 client_maker.MakePriorityPacket(
7654 packet_num++, true, GetNthClientInitiatedBidirectionalStreamId(0),
7655 quic::QuicStreamPriority::kDefaultUrgency));
Renjie Tangaadb84b2019-08-31 01:00:237656 }
Matt Menke26e41542019-06-05 01:09:517657
Patrick Meenanf741c6082023-01-03 18:06:437658 std::cout << "MakeRequestHeadersPacket\n";
Ryan Hamiltonabad59e2019-06-06 04:02:597659 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:517660 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027661 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237662 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Patrick Meenan885a00652023-02-15 20:07:027663 false, quic::QuicStreamPriority::kDefaultUrgency,
Bence Béky957bab12023-01-31 16:40:107664 ConnectRequestHeaders("mail.example.org:443"), nullptr, false));
Ryan Hamiltonabad59e2019-06-06 04:02:597665 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027666 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:517667 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287668 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517669
Bence Béky319388a882020-09-23 18:42:527670 mock_quic_data[index]->AddWrite(
7671 SYNCHRONOUS,
7672 client_maker.MakeAckAndDataPacket(
7673 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7674 1, 1, false, ConstructDataFrame(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:517675
Ryan Hamiltonabad59e2019-06-06 04:02:597676 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:517677 ASYNC, server_maker.MakeDataPacket(
7678 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527679 false, ConstructDataFrame(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:597680 mock_quic_data[index]->AddRead(
Bence Béky319388a882020-09-23 18:42:527681 SYNCHRONOUS, server_maker.MakeDataPacket(
7682 3, GetNthClientInitiatedBidirectionalStreamId(0),
7683 false, false, ConstructDataFrame("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:597684 mock_quic_data[index]->AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347685 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2));
Ryan Hamiltonabad59e2019-06-06 04:02:597686 mock_quic_data[index]->AddRead(SYNCHRONOUS,
7687 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:517688
Ryan Hamiltonabad59e2019-06-06 04:02:597689 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:517690 }
7691
7692 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7693 SSLSocketDataProvider ssl_data2(ASYNC, OK);
7694 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
7695
7696 CreateSession();
7697
7698 request_.url = GURL("https://mail.example.org/");
7699 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
7700 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7701 RunTransaction(&trans);
7702 CheckResponseData(&trans, "0123456789");
7703
7704 HttpRequestInfo request2;
Matt Menke4807a9a2020-11-21 00:14:417705 const SchemefulSite kSite1(GURL("http://origin1/"));
7706 request_.network_isolation_key = NetworkIsolationKey(kSite1, kSite1);
Brianna Goldstein314ddf722022-09-24 02:00:527707 request_.network_anonymization_key = NetworkAnonymizationKey(kSite1, kSite1);
Matt Menke26e41542019-06-05 01:09:517708 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
7709 RunTransaction(&trans2);
7710 CheckResponseData(&trans2, "0123456789");
7711
Ryan Hamiltonabad59e2019-06-06 04:02:597712 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
7713 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
7714 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
7715 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:517716}
7717
Yoichi Osato4c75c0c2020-06-24 08:03:577718TEST_P(QuicNetworkTransactionTest, AllowHTTP1FalseProhibitsH1) {
7719 MockRead http_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING),
7720 MockRead(ASYNC, OK)};
7721 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
7722 socket_factory_.AddSocketDataProvider(&http_data);
7723 AddCertificate(&ssl_data_);
7724 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7725
7726 CreateSession();
7727
7728 request_.method = "POST";
7729 UploadDataStreamNotAllowHTTP1 upload_data("");
7730 request_.upload_data_stream = &upload_data;
7731
7732 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7733 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267734 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:577735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7736 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_H2_OR_QUIC_REQUIRED));
7737}
7738
7739// Confirm mock class UploadDataStreamNotAllowHTTP1 can upload content over
7740// QUIC.
7741TEST_P(QuicNetworkTransactionTest, AllowHTTP1MockTest) {
7742 context_.params()->origins_to_force_quic_on.insert(
7743 HostPortPair::FromString("mail.example.org:443"));
7744
7745 MockQuicData mock_quic_data(version_);
7746 int write_packet_index = 1;
Patrick Meenan885a00652023-02-15 20:07:027747 mock_quic_data.AddWrite(SYNCHRONOUS,
7748 ConstructInitialSettingsPacket(write_packet_index++));
Yoichi Osato4c75c0c2020-06-24 08:03:577749 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:527750 mock_quic_data.AddWrite(
7751 SYNCHRONOUS,
7752 ConstructClientRequestHeadersAndDataFramesPacket(
7753 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7754 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
Bence Béky957bab12023-01-31 16:40:107755 nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:577756 mock_quic_data.AddRead(
7757 ASYNC, ConstructServerResponseHeadersPacket(
7758 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287759 GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:577760
Yoichi Osato4c75c0c2020-06-24 08:03:577761 mock_quic_data.AddRead(
7762 ASYNC, ConstructServerDataPacket(
7763 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527764 ConstructDataFrame("hello!")));
Yoichi Osato4c75c0c2020-06-24 08:03:577765
Renjie Tangcd594f32020-07-11 20:18:347766 mock_quic_data.AddWrite(SYNCHRONOUS,
7767 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:577768
7769 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:217770 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:577771 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7772
7773 // The non-alternate protocol job needs to hang in order to guarantee that
7774 // the alternate-protocol job will "win".
7775 AddHangingNonAlternateProtocolSocketData();
7776
7777 CreateSession();
7778 request_.method = "POST";
7779 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
7780 request_.upload_data_stream = &upload_data;
7781
7782 SendRequestAndExpectQuicResponse("hello!");
7783}
7784
Nidhi Jaju391105a2022-07-28 02:09:517785// TODO(crbug.com/1347664): This test is failing on various platforms.
7786TEST_P(QuicNetworkTransactionTest, DISABLED_AllowHTTP1UploadPauseAndResume) {
Yoichi Osato4c75c0c2020-06-24 08:03:577787 context_.params()->origins_to_force_quic_on.insert(
7788 HostPortPair::FromString("mail.example.org:443"));
7789
7790 MockQuicData mock_quic_data(version_);
7791 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
7792 int write_packet_index = 1;
7793 mock_quic_data.AddWrite(
7794 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
7795 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Patrick Meenan885a00652023-02-15 20:07:027796 mock_quic_data.AddWrite(SYNCHRONOUS,
7797 ConstructInitialSettingsPacket(write_packet_index++));
Yoichi Osato4c75c0c2020-06-24 08:03:577798 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:527799 mock_quic_data.AddWrite(
7800 SYNCHRONOUS,
7801 ConstructClientRequestHeadersAndDataFramesPacket(
7802 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7803 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
Bence Béky957bab12023-01-31 16:40:107804 nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:577805 mock_quic_data.AddRead(
7806 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
7807 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287808 false, GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:577809 mock_quic_data.AddRead(
7810 SYNCHRONOUS, ConstructServerDataPacket(
7811 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527812 true, ConstructDataFrame("hello!")));
Yoichi Osato4c75c0c2020-06-24 08:03:577813
Renjie Tangcd594f32020-07-11 20:18:347814 mock_quic_data.AddWrite(SYNCHRONOUS,
7815 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:577816 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:217817 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:577818 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7819 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
7820
7821 CreateSession();
7822
7823 AddQuicAlternateProtocolMapping(
7824 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
7825
7826 // Set up request.
7827 request_.method = "POST";
7828 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
7829 request_.upload_data_stream = &upload_data;
7830
7831 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7832 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267833 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:577834 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7835 base::RunLoop().RunUntilIdle();
7836 // Resume QUIC job
7837 crypto_client_stream_factory_.last_stream()
7838 ->NotifySessionOneRttKeyAvailable();
7839 socket_data->Resume();
7840
7841 base::RunLoop().RunUntilIdle();
7842 CheckResponseData(&trans, "hello!");
7843}
7844
Nidhi Jaju391105a2022-07-28 02:09:517845// TODO(crbug.com/1347664): This test is failing on various platforms.
7846TEST_P(QuicNetworkTransactionTest,
7847 DISABLED_AllowHTTP1UploadFailH1AndResumeQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:357848 if (version_.AlpnDeferToRFCv1()) {
7849 // These versions currently do not support Alt-Svc.
7850 return;
7851 }
Yoichi Osato4c75c0c2020-06-24 08:03:577852 // This test confirms failed main job should not bother quic job.
7853 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:457854 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yoichi Osato4c75c0c2020-06-24 08:03:577855 MockRead("1.1 Body"),
7856 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7857 MockRead(ASYNC, OK)};
7858 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
7859 socket_factory_.AddSocketDataProvider(&http_data);
7860 AddCertificate(&ssl_data_);
7861 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7862
7863 MockQuicData mock_quic_data(version_);
7864 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
7865 int write_packet_index = 1;
7866 mock_quic_data.AddWrite(
7867 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
7868 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Patrick Meenan885a00652023-02-15 20:07:027869 mock_quic_data.AddWrite(SYNCHRONOUS,
7870 ConstructInitialSettingsPacket(write_packet_index++));
Yoichi Osato4c75c0c2020-06-24 08:03:577871 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:527872 mock_quic_data.AddWrite(
7873 SYNCHRONOUS,
7874 ConstructClientRequestHeadersAndDataFramesPacket(
7875 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7876 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
Bence Béky957bab12023-01-31 16:40:107877 nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:577878 mock_quic_data.AddRead(
7879 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
7880 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287881 false, GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:577882 mock_quic_data.AddRead(
7883 SYNCHRONOUS, ConstructServerDataPacket(
7884 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527885 true, ConstructDataFrame("hello!")));
Renjie Tangcd594f32020-07-11 20:18:347886 mock_quic_data.AddWrite(SYNCHRONOUS,
7887 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:577888 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:217889 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:577890 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7891 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
7892
7893 // This packet won't be read because AllowHTTP1:false doesn't allow H/1
7894 // connection.
7895 MockRead http_reads2[] = {MockRead("HTTP/1.1 200 OK\r\n")};
7896 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
7897 socket_factory_.AddSocketDataProvider(&http_data2);
7898 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7899
7900 CreateSession();
7901
7902 // Send the first request via TCP and set up alternative service (QUIC) for
7903 // the origin.
7904 SendRequestAndExpectHttpResponse("1.1 Body");
7905
7906 // Settings to resume main H/1 job quickly while pausing quic job.
7907 AddQuicAlternateProtocolMapping(
7908 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
7909 ServerNetworkStats stats1;
Peter Kastinge5a38ed2021-10-02 03:06:357910 stats1.srtt = base::Microseconds(10);
Yoichi Osato4c75c0c2020-06-24 08:03:577911 http_server_properties_->SetServerNetworkStats(
Brianna Goldstein02cb74f2022-09-29 05:41:017912 url::SchemeHostPort(request_.url), NetworkAnonymizationKey(), stats1);
Yoichi Osato4c75c0c2020-06-24 08:03:577913
7914 // Set up request.
7915 request_.method = "POST";
7916 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
7917 request_.upload_data_stream = &upload_data;
7918
7919 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7920 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267921 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:577922 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7923 // Confirm TCP job was resumed.
7924 // We can not check its failure because HttpStreamFactory::JobController.
7925 // main_job_net_error is not exposed.
7926 while (socket_factory_.mock_data().next_index() < 3u)
7927 base::RunLoop().RunUntilIdle();
7928 // Resume QUIC job.
7929 crypto_client_stream_factory_.last_stream()
7930 ->NotifySessionOneRttKeyAvailable();
7931 socket_data->Resume();
7932 base::RunLoop().RunUntilIdle();
7933 CheckResponseData(&trans, "hello!");
7934}
7935
Bence Békyc164e0d22020-09-22 20:08:597936TEST_P(QuicNetworkTransactionTest, IncorrectHttp3GoAway) {
Bence Békyc164e0d22020-09-22 20:08:597937 context_.params()->retry_without_alt_svc_on_quic_errors = false;
7938
7939 MockQuicData mock_quic_data(version_);
7940 int write_packet_number = 1;
7941 mock_quic_data.AddWrite(
7942 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number++));
7943 mock_quic_data.AddWrite(
7944 SYNCHRONOUS,
7945 ConstructClientRequestHeadersPacket(
7946 write_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7947 true, true, GetRequestHeaders("GET", "https", "/")));
7948
7949 int read_packet_number = 1;
7950 mock_quic_data.AddRead(
7951 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number++));
7952 // The GOAWAY frame sent by the server MUST have a stream ID corresponding to
7953 // a client-initiated bidirectional stream. Any other kind of stream ID
7954 // should cause the client to close the connection.
7955 quic::GoAwayFrame goaway{3};
Nidhi Jaju391105a2022-07-28 02:09:517956 auto goaway_buffer = quic::HttpEncoder::SerializeGoAwayFrame(goaway);
Bence Békyc164e0d22020-09-22 20:08:597957 const quic::QuicStreamId control_stream_id =
7958 quic::QuicUtils::GetFirstUnidirectionalStreamId(
7959 version_.transport_version, quic::Perspective::IS_SERVER);
7960 mock_quic_data.AddRead(
Nidhi Jaju391105a2022-07-28 02:09:517961 ASYNC, ConstructServerDataPacket(read_packet_number++, control_stream_id,
7962 false, false, goaway_buffer));
Bence Békyc164e0d22020-09-22 20:08:597963 mock_quic_data.AddWrite(
7964 SYNCHRONOUS,
7965 ConstructClientAckAndConnectionClosePacket(
7966 write_packet_number++, 2, 4, quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
7967 "GOAWAY with invalid stream ID", 0));
7968 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7969
7970 // In order for a new QUIC session to be established via alternate-protocol
7971 // without racing an HTTP connection, we need the host resolution to happen
7972 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
7973 // connection to the the server, in this test we require confirmation
7974 // before encrypting so the HTTP job will still start.
7975 host_resolver_.set_synchronous_mode(true);
7976 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
7977 "");
7978
7979 CreateSession();
Liza Burakova80b8ebd2023-02-15 16:29:587980 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ASYNC_ZERO_RTT);
Bence Békyc164e0d22020-09-22 20:08:597981
7982 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7983 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267984 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Bence Békyc164e0d22020-09-22 20:08:597985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Liza Burakova80b8ebd2023-02-15 16:29:587986 base::RunLoop().RunUntilIdle();
Bence Békyc164e0d22020-09-22 20:08:597987 crypto_client_stream_factory_.last_stream()
7988 ->NotifySessionOneRttKeyAvailable();
7989 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
7990
7991 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7992 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7993
7994 NetErrorDetails details;
7995 trans.PopulateNetErrorDetails(&details);
7996 EXPECT_THAT(details.quic_connection_error,
7997 quic::test::IsError(quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID));
7998}
7999
Bence Béky2ee18922020-09-25 12:11:328000TEST_P(QuicNetworkTransactionTest, RetryOnHttp3GoAway) {
Bence Béky2ee18922020-09-25 12:11:328001 MockQuicData mock_quic_data1(version_);
8002 int write_packet_number1 = 1;
8003 mock_quic_data1.AddWrite(
8004 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number1++));
8005 const quic::QuicStreamId stream_id1 =
8006 GetNthClientInitiatedBidirectionalStreamId(0);
8007 mock_quic_data1.AddWrite(SYNCHRONOUS,
8008 ConstructClientRequestHeadersPacket(
8009 write_packet_number1++, stream_id1, true, true,
8010 GetRequestHeaders("GET", "https", "/")));
8011 const quic::QuicStreamId stream_id2 =
8012 GetNthClientInitiatedBidirectionalStreamId(1);
8013 mock_quic_data1.AddWrite(SYNCHRONOUS,
8014 ConstructClientRequestHeadersPacket(
8015 write_packet_number1++, stream_id2, true, true,
8016 GetRequestHeaders("GET", "https", "/foo")));
8017
8018 int read_packet_number1 = 1;
8019 mock_quic_data1.AddRead(
8020 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number1++));
8021
8022 // GOAWAY with stream_id2 informs the client that stream_id2 (and streams with
8023 // larger IDs) have not been processed and can safely be retried.
8024 quic::GoAwayFrame goaway{stream_id2};
Nidhi Jaju391105a2022-07-28 02:09:518025 auto goaway_buffer = quic::HttpEncoder::SerializeGoAwayFrame(goaway);
Bence Béky2ee18922020-09-25 12:11:328026 const quic::QuicStreamId control_stream_id =
8027 quic::QuicUtils::GetFirstUnidirectionalStreamId(
8028 version_.transport_version, quic::Perspective::IS_SERVER);
8029 mock_quic_data1.AddRead(
Nidhi Jaju391105a2022-07-28 02:09:518030 ASYNC, ConstructServerDataPacket(read_packet_number1++, control_stream_id,
8031 false, false, goaway_buffer));
Bence Béky2ee18922020-09-25 12:11:328032 mock_quic_data1.AddWrite(
8033 ASYNC, ConstructClientAckPacket(write_packet_number1++, 2, 1));
8034
8035 // Response to first request is accepted after GOAWAY.
8036 mock_quic_data1.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8037 read_packet_number1++, stream_id1, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288038 false, GetResponseHeaders("200")));
Bence Béky2ee18922020-09-25 12:11:328039 mock_quic_data1.AddRead(
8040 ASYNC, ConstructServerDataPacket(
8041 read_packet_number1++, stream_id1, false, true,
8042 ConstructDataFrame("response on the first connection")));
8043 mock_quic_data1.AddWrite(
8044 ASYNC, ConstructClientAckPacket(write_packet_number1++, 4, 1));
Bence Békye7426ec2021-02-02 18:18:198045 // Make socket hang to make sure connection stays in connection pool.
8046 // This should not prevent the retry from opening a new connection.
8047 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING);
David Schinazi395918c2021-02-05 18:56:218048 mock_quic_data1.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Bence Béky2ee18922020-09-25 12:11:328049 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
8050
8051 // Second request is retried on a new connection.
8052 MockQuicData mock_quic_data2(version_);
8053 QuicTestPacketMaker client_maker2(
8054 version_,
8055 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8056 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky957bab12023-01-31 16:40:108057 true);
Bence Béky2ee18922020-09-25 12:11:328058 int write_packet_number2 = 1;
8059 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(
8060 write_packet_number2++));
8061 spdy::SpdyPriority priority =
8062 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8063 mock_quic_data2.AddWrite(
8064 SYNCHRONOUS, client_maker2.MakeRequestHeadersPacket(
8065 write_packet_number2++, stream_id1, true, true, priority,
Bence Béky957bab12023-01-31 16:40:108066 GetRequestHeaders("GET", "https", "/foo"), nullptr));
Bence Béky2ee18922020-09-25 12:11:328067
8068 QuicTestPacketMaker server_maker2(
8069 version_,
8070 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8071 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
8072 false);
8073 int read_packet_number2 = 1;
8074 mock_quic_data2.AddRead(ASYNC,
8075 server_maker2.MakeResponseHeadersPacket(
8076 read_packet_number2++, stream_id1, false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288077 GetResponseHeaders("200"), nullptr));
Bence Béky2ee18922020-09-25 12:11:328078 mock_quic_data2.AddRead(
8079 ASYNC, server_maker2.MakeDataPacket(
8080 read_packet_number2++, stream_id1, false, true,
8081 ConstructDataFrame("response on the second connection")));
8082 mock_quic_data2.AddWrite(
8083 ASYNC, client_maker2.MakeAckPacket(write_packet_number2++, 2, 1));
8084 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8085 mock_quic_data2.AddRead(ASYNC, 0); // EOF
8086 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8087
8088 AddHangingNonAlternateProtocolSocketData();
8089 CreateSession();
8090 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
8091
8092 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
8093 TestCompletionCallback callback1;
Matt Reichhoff0049a0b72021-10-20 20:44:268094 int rv = trans1.Start(&request_, callback1.callback(), net_log_with_source_);
Bence Béky2ee18922020-09-25 12:11:328095 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8096 base::RunLoop().RunUntilIdle();
8097
8098 HttpRequestInfo request2;
8099 request2.method = "GET";
8100 std::string url("https://");
8101 url.append(kDefaultServerHostName);
8102 url.append("/foo");
8103 request2.url = GURL(url);
8104 request2.load_flags = 0;
8105 request2.traffic_annotation =
8106 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8107 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8108 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:268109 rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
Bence Béky2ee18922020-09-25 12:11:328110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8111
8112 EXPECT_THAT(callback1.WaitForResult(), IsOk());
8113 CheckResponseData(&trans1, "response on the first connection");
8114
8115 EXPECT_THAT(callback2.WaitForResult(), IsOk());
8116 CheckResponseData(&trans2, "response on the second connection");
8117
Bence Békye7426ec2021-02-02 18:18:198118 mock_quic_data1.Resume();
Bence Béky2ee18922020-09-25 12:11:328119 mock_quic_data2.Resume();
8120 EXPECT_TRUE(mock_quic_data1.AllWriteDataConsumed());
8121 EXPECT_TRUE(mock_quic_data1.AllReadDataConsumed());
8122 EXPECT_TRUE(mock_quic_data2.AllWriteDataConsumed());
8123 EXPECT_TRUE(mock_quic_data2.AllReadDataConsumed());
8124}
8125
Yoichi Osato4c75c0c2020-06-24 08:03:578126// TODO(yoichio): Add the TCP job reuse case. See crrev.com/c/2174099.
8127
Momoka Yamamotoff688972022-11-02 03:37:468128#if BUILDFLAG(ENABLE_WEBSOCKETS)
8129
8130// This test verifies that when there is an HTTP/3 connection open to a server,
8131// a WebSocket request does not use it, but instead opens a new connection with
8132// HTTP/1.
8133TEST_P(QuicNetworkTransactionTest, WebsocketOpensNewConnectionWithHttp1) {
8134 context_.params()->origins_to_force_quic_on.insert(
8135 HostPortPair::FromString("mail.example.org:443"));
8136 context_.params()->retry_without_alt_svc_on_quic_errors = false;
8137
8138 MockQuicData mock_quic_data(version_);
8139
8140 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
8141
8142 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:028143 mock_quic_data.AddWrite(SYNCHRONOUS,
8144 ConstructInitialSettingsPacket(packet_num++));
Momoka Yamamotoff688972022-11-02 03:37:468145
8146 spdy::SpdyPriority priority =
8147 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8148
8149 // The request will initially go out over HTTP/3.
8150 mock_quic_data.AddWrite(
8151 SYNCHRONOUS,
8152 client_maker_->MakeRequestHeadersPacket(
8153 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky957bab12023-01-31 16:40:108154 true, priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Momoka Yamamotoff688972022-11-02 03:37:468155 mock_quic_data.AddRead(
8156 ASYNC, server_maker_.MakeResponseHeadersPacket(
8157 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8158 server_maker_.GetResponseHeaders("200"), nullptr));
8159 mock_quic_data.AddRead(
8160 ASYNC, server_maker_.MakeDataPacket(
8161 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8162 ConstructDataFrame("hello!")));
8163 mock_quic_data.AddWrite(SYNCHRONOUS,
8164 ConstructClientAckPacket(packet_num++, 2, 1));
8165 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read.
8166 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
8167
8168 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8169 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8170
8171 MockWrite http_writes[] = {
8172 MockWrite(SYNCHRONOUS, 0,
8173 "GET / HTTP/1.1\r\n"
8174 "Host: mail.example.org\r\n"
8175 "Connection: Upgrade\r\n"
8176 "Upgrade: websocket\r\n"
8177 "Origin: http://mail.example.org\r\n"
8178 "Sec-WebSocket-Version: 13\r\n"
8179 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
8180 "Sec-WebSocket-Extensions: permessage-deflate; "
8181 "client_max_window_bits\r\n\r\n")};
8182
8183 MockRead http_reads[] = {
8184 MockRead(SYNCHRONOUS, 1,
8185 "HTTP/1.1 101 Switching Protocols\r\n"
8186 "Upgrade: websocket\r\n"
8187 "Connection: Upgrade\r\n"
8188 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
8189
8190 SequencedSocketData http_data(http_reads, http_writes);
8191 socket_factory_.AddSocketDataProvider(&http_data);
8192
8193 CreateSession();
8194
8195 TestCompletionCallback callback1;
8196 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
8197 int rv = trans1.Start(&request_, callback1.callback(), net_log_with_source_);
8198 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8199 rv = callback1.WaitForResult();
8200 ASSERT_THAT(rv, IsOk());
8201
8202 const HttpResponseInfo* response = trans1.GetResponseInfo();
8203 ASSERT_TRUE(response->headers);
8204 EXPECT_TRUE(response->was_fetched_via_spdy);
8205 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
8206
8207 std::string response_data;
8208 rv = ReadTransaction(&trans1, &response_data);
8209 EXPECT_THAT(rv, IsOk());
8210 EXPECT_EQ("hello!", response_data);
8211
8212 HttpRequestInfo request2;
8213 request2.method = "GET";
8214 request2.url = GURL("wss://mail.example.org/");
8215 request2.traffic_annotation =
8216 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8217 EXPECT_TRUE(HostPortPair::FromURL(request_.url)
8218 .Equals(HostPortPair::FromURL(request2.url)));
8219 request2.extra_headers.SetHeader("Connection", "Upgrade");
8220 request2.extra_headers.SetHeader("Upgrade", "websocket");
8221 request2.extra_headers.SetHeader("Origin", "http://mail.example.org");
8222 request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
8223
8224 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
8225
8226 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8227 trans2.SetWebSocketHandshakeStreamCreateHelper(
8228 &websocket_stream_create_helper);
8229
8230 TestCompletionCallback callback2;
8231 rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
8232 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8233 rv = callback2.WaitForResult();
8234 ASSERT_THAT(rv, IsOk());
8235
8236 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
8237 mock_quic_data.Resume();
8238 // Run the QUIC session to completion.
8239 base::RunLoop().RunUntilIdle();
8240
8241 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8242 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8243}
Momoka Yamamoto751ecf72022-11-11 14:38:348244
8245// Much like above, but for Alt-Svc QUIC.
8246TEST_P(QuicNetworkTransactionTest,
8247 WebsocketOpensNewConnectionWithHttp1AfterAltSvcQuic) {
8248 if (version_.AlpnDeferToRFCv1()) {
8249 // These versions currently do not support Alt-Svc.
8250 return;
8251 }
8252 MockRead http_reads[] = {
8253 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
8254 MockRead("hello world"),
8255 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8256 MockRead(ASYNC, OK)};
8257
8258 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
8259 socket_factory_.AddSocketDataProvider(&http_data);
8260 AddCertificate(&ssl_data_);
8261 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8262
8263 MockQuicData mock_quic_data(version_);
8264 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:028265 mock_quic_data.AddWrite(SYNCHRONOUS,
8266 ConstructInitialSettingsPacket(packet_num++));
Momoka Yamamoto751ecf72022-11-11 14:38:348267 mock_quic_data.AddWrite(
8268 SYNCHRONOUS,
8269 ConstructClientRequestHeadersPacket(
8270 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8271 true, GetRequestHeaders("GET", "https", "/")));
8272 mock_quic_data.AddRead(
8273 ASYNC, ConstructServerResponseHeadersPacket(
8274 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8275 GetResponseHeaders("200")));
8276 mock_quic_data.AddRead(
8277 ASYNC, ConstructServerDataPacket(
8278 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8279 ConstructDataFrame("hello!")));
8280 mock_quic_data.AddWrite(SYNCHRONOUS,
8281 ConstructClientAckPacket(packet_num++, 2, 1));
8282 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8283 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
8284
8285 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8286 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8287
8288 MockWrite http_writes2[] = {
8289 MockWrite(SYNCHRONOUS, 0,
8290 "GET / HTTP/1.1\r\n"
8291 "Host: mail.example.org\r\n"
8292 "Connection: Upgrade\r\n"
8293 "Upgrade: websocket\r\n"
8294 "Origin: http://mail.example.org\r\n"
8295 "Sec-WebSocket-Version: 13\r\n"
8296 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
8297 "Sec-WebSocket-Extensions: permessage-deflate; "
8298 "client_max_window_bits\r\n\r\n")};
8299
8300 MockRead http_reads2[] = {
8301 MockRead(SYNCHRONOUS, 1,
8302 "HTTP/1.1 101 Switching Protocols\r\n"
8303 "Upgrade: websocket\r\n"
8304 "Connection: Upgrade\r\n"
8305 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
8306
8307 SequencedSocketData http_data2(http_reads2, http_writes2);
8308 socket_factory_.AddSocketDataProvider(&http_data2);
8309 AddCertificate(&ssl_data_);
8310 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8311
8312 CreateSession();
8313
8314 SendRequestAndExpectHttpResponse("hello world");
8315 SendRequestAndExpectQuicResponse("hello!");
8316
8317 HttpRequestInfo request2;
8318 request2.method = "GET";
8319 request2.url = GURL("wss://mail.example.org/");
8320 request2.traffic_annotation =
8321 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8322 EXPECT_TRUE(HostPortPair::FromURL(request_.url)
8323 .Equals(HostPortPair::FromURL(request2.url)));
8324 request2.extra_headers.SetHeader("Connection", "Upgrade");
8325 request2.extra_headers.SetHeader("Upgrade", "websocket");
8326 request2.extra_headers.SetHeader("Origin", "http://mail.example.org");
8327 request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
8328
8329 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
8330
8331 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8332 trans2.SetWebSocketHandshakeStreamCreateHelper(
8333 &websocket_stream_create_helper);
8334
8335 TestCompletionCallback callback2;
8336 int rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
8337 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8338 rv = callback2.WaitForResult();
8339 ASSERT_THAT(rv, IsOk());
8340 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
8341 mock_quic_data.Resume();
8342 // Run the QUIC session to completion.
8343 base::RunLoop().RunUntilIdle();
8344
8345 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8346 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8347}
Momoka Yamamotoff688972022-11-02 03:37:468348
Momoka Yamamoto8d36ce22023-01-19 02:56:498349// Much like above, but for DnsHttpsSvcbAlpn QUIC.
8350TEST_P(QuicNetworkTransactionTest,
8351 WebsocketOpensNewConnectionWithHttp1AfterDnsHttpsSvcbAlpn) {
8352 session_params_.use_dns_https_svcb_alpn = true;
8353
8354 MockQuicData mock_quic_data(version_);
8355
8356 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:028357 mock_quic_data.AddWrite(SYNCHRONOUS,
8358 ConstructInitialSettingsPacket(packet_num++));
Momoka Yamamoto8d36ce22023-01-19 02:56:498359
8360 spdy::SpdyPriority priority =
8361 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8362
8363 // The request will initially go out over HTTP/3.
8364 mock_quic_data.AddWrite(
8365 SYNCHRONOUS,
8366 client_maker_->MakeRequestHeadersPacket(
8367 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky957bab12023-01-31 16:40:108368 true, priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Momoka Yamamoto8d36ce22023-01-19 02:56:498369 mock_quic_data.AddRead(
8370 ASYNC, server_maker_.MakeResponseHeadersPacket(
8371 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8372 server_maker_.GetResponseHeaders("200"), nullptr));
8373 mock_quic_data.AddRead(
8374 ASYNC, server_maker_.MakeDataPacket(
8375 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8376 ConstructDataFrame("hello!")));
8377 mock_quic_data.AddWrite(SYNCHRONOUS,
8378 ConstructClientAckPacket(packet_num++, 2, 1));
8379 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read.
8380 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
8381
8382 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8383
8384 MockWrite http_writes[] = {
8385 MockWrite(SYNCHRONOUS, 0,
8386 "GET / HTTP/1.1\r\n"
8387 "Host: mail.example.org\r\n"
8388 "Connection: Upgrade\r\n"
8389 "Upgrade: websocket\r\n"
8390 "Origin: http://mail.example.org\r\n"
8391 "Sec-WebSocket-Version: 13\r\n"
8392 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
8393 "Sec-WebSocket-Extensions: permessage-deflate; "
8394 "client_max_window_bits\r\n\r\n")};
8395
8396 MockRead http_reads[] = {
8397 MockRead(SYNCHRONOUS, 1,
8398 "HTTP/1.1 101 Switching Protocols\r\n"
8399 "Upgrade: websocket\r\n"
8400 "Connection: Upgrade\r\n"
8401 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
8402
8403 SequencedSocketData http_data(http_reads, http_writes);
8404 socket_factory_.AddSocketDataProvider(&http_data);
8405 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8406
8407 HostResolverEndpointResult endpoint_result1;
8408 endpoint_result1.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
8409 endpoint_result1.metadata.supported_protocol_alpns = {
8410 quic::QuicVersionLabelToString(quic::CreateQuicVersionLabel(version_))};
8411 HostResolverEndpointResult endpoint_result2;
8412 endpoint_result2.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
8413 std::vector<HostResolverEndpointResult> endpoints;
8414 endpoints.push_back(endpoint_result1);
8415 endpoints.push_back(endpoint_result2);
8416 host_resolver_.rules()->AddRule(
8417 "mail.example.org",
8418 MockHostResolverBase::RuleResolver::RuleResult(
8419 std::move(endpoints),
8420 /*aliases=*/std::set<std::string>{"mail.example.org"}));
8421
8422 CreateSession();
8423 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
8424 TestCompletionCallback callback1;
8425 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
8426 int rv = trans1.Start(&request_, callback1.callback(), net_log_with_source_);
8427 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8428 rv = callback1.WaitForResult();
8429 ASSERT_THAT(rv, IsOk());
8430
8431 const HttpResponseInfo* response = trans1.GetResponseInfo();
8432 ASSERT_TRUE(response->headers);
8433 EXPECT_TRUE(response->was_fetched_via_spdy);
8434 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
8435
8436 std::string response_data;
8437 rv = ReadTransaction(&trans1, &response_data);
8438 EXPECT_THAT(rv, IsOk());
8439 EXPECT_EQ("hello!", response_data);
8440
8441 HttpRequestInfo request2;
8442 request2.method = "GET";
8443 request2.url = GURL("wss://mail.example.org/");
8444 request2.traffic_annotation =
8445 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8446 EXPECT_TRUE(HostPortPair::FromURL(request_.url)
8447 .Equals(HostPortPair::FromURL(request2.url)));
8448 request2.extra_headers.SetHeader("Connection", "Upgrade");
8449 request2.extra_headers.SetHeader("Upgrade", "websocket");
8450 request2.extra_headers.SetHeader("Origin", "http://mail.example.org");
8451 request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
8452
8453 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
8454
8455 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8456 trans2.SetWebSocketHandshakeStreamCreateHelper(
8457 &websocket_stream_create_helper);
8458
8459 TestCompletionCallback callback2;
8460 rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
8461 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8462 rv = callback2.WaitForResult();
8463 ASSERT_THAT(rv, IsOk());
8464
8465 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
8466 mock_quic_data.Resume();
8467 // Run the QUIC session to completion.
8468 base::RunLoop().RunUntilIdle();
8469
8470 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8471 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8472}
8473
Momoka Yamamotoff688972022-11-02 03:37:468474#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
8475
Tsuyoshi Horo4f516be2022-06-14 11:53:138476} // namespace net::test