blob: 16d29da8157d66960da8529e7c9c806f1e168931 [file] [log] [blame]
[email protected]61a527782013-02-21 03:58:001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
rchbd089ab2017-05-26 23:05:045#include <algorithm>
bnc359ed2a2016-04-29 20:43:456#include <ostream>
bnc912a04b2016-04-20 14:19:507#include <string>
8#include <utility>
[email protected]1e960032013-12-20 19:00:209#include <vector>
10
Sebastien Marchand6d0558fd2019-01-25 16:49:3711#include "base/bind.h"
[email protected]61a527782013-02-21 03:58:0012#include "base/compiler_specific.h"
Keishi Hattori0e45c022021-11-27 09:25:5213#include "base/memory/raw_ptr.h"
mmenke651bae7f2015-12-18 21:26:4514#include "base/run_loop.h"
Bence Béky319388a882020-09-23 18:42:5215#include "base/strings/strcat.h"
zhongyie537a002017-06-27 16:48:2116#include "base/strings/string_number_conversions.h"
Bence Békyd74f4382018-02-20 18:26:1917#include "base/strings/string_piece.h"
bnc8be55ebb2015-10-30 14:12:0718#include "base/strings/stringprintf.h"
Devlin Cronine4bcb40e2018-06-05 18:02:4719#include "base/test/metrics/histogram_tester.h"
Matt Menke26e41542019-06-05 01:09:5120#include "base/test/scoped_feature_list.h"
rtenneti56977812016-01-15 19:26:5621#include "net/base/chunked_upload_data_stream.h"
Bence Békyd8a21fc32018-06-27 18:29:5822#include "net/base/completion_once_callback.h"
Matt Menke26e41542019-06-05 01:09:5123#include "net/base/features.h"
Tsuyoshi Horo01faed62019-02-20 22:11:3724#include "net/base/ip_endpoint.h"
mgershaf9a9232017-04-13 20:19:0325#include "net/base/mock_network_change_notifier.h"
Matt Menke9aa86262019-08-21 15:52:0726#include "net/base/network_isolation_key.h"
Matt Menke4807a9a2020-11-21 00:14:4127#include "net/base/schemeful_site.h"
[email protected]61a527782013-02-21 03:58:0028#include "net/base/test_completion_callback.h"
tbansalc3308d72016-08-27 10:25:0429#include "net/base/test_proxy_delegate.h"
rsleevid6de8302016-06-21 01:33:2030#include "net/cert/ct_policy_enforcer.h"
[email protected]6e7845ae2013-03-29 21:48:1131#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5332#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0033#include "net/http/http_auth_handler_factory.h"
34#include "net/http/http_network_session.h"
35#include "net/http/http_network_transaction.h"
Matt Menke6e879bd2019-03-18 17:26:0436#include "net/http/http_proxy_connect_job.h"
Matt Menke609160742019-08-02 18:47:2637#include "net/http/http_server_properties.h"
[email protected]61a527782013-02-21 03:58:0038#include "net/http/http_stream.h"
39#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1940#include "net/http/http_transaction_test_util.h"
Yoichi Osato4c75c0c2020-06-24 08:03:5741#include "net/http/test_upload_data_stream_not_allow_http1.h"
[email protected]b1c988b2013-06-13 06:48:1142#include "net/http/transport_security_state.h"
Matt Reichhoff0049a0b72021-10-20 20:44:2643#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0044#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5145#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4646#include "net/log/test_net_log_util.h"
Nicolas Arciniegad2013f92020-02-07 23:00:5647#include "net/proxy_resolution/configured_proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4048#include "net/proxy_resolution/proxy_config_service_fixed.h"
49#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0850#include "net/quic/crypto/proof_verifier_chromium.h"
51#include "net/quic/mock_crypto_client_stream_factory.h"
Victor Vasiliev7752898d2019-11-14 21:30:2252#include "net/quic/mock_quic_context.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0853#include "net/quic/mock_quic_data.h"
54#include "net/quic/quic_chromium_alarm_factory.h"
55#include "net/quic/quic_http_stream.h"
56#include "net/quic/quic_http_utils.h"
57#include "net/quic/quic_stream_factory_peer.h"
58#include "net/quic/quic_test_packet_maker.h"
59#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0060#include "net/socket/client_socket_factory.h"
61#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2162#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2863#include "net/socket/socket_performance_watcher.h"
64#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0065#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5866#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5767#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2968#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0169#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4370#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4071#include "net/test/test_with_task_environment.h"
Ryan Hamiltonea4fa192022-04-12 18:30:4972#include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_decrypter.h"
73#include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_encrypter.h"
74#include "net/third_party/quiche/src/quiche/quic/core/quic_framer.h"
75#include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
76#include "net/third_party/quiche/src/quiche/quic/platform/api/quic_test.h"
77#include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
78#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_clock.h"
79#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
80#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_session_peer.h"
81#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
82#include "net/third_party/quiche/src/quiche/spdy/core/spdy_frame_builder.h"
83#include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2984#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0085#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4886#include "net/url_request/url_request.h"
Matt Menkea9606a0eb2020-09-11 20:36:3887#include "net/url_request/url_request_job_factory.h"
allada71b2efb2016-09-09 04:57:4888#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0189#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0090#include "testing/gtest/include/gtest/gtest.h"
91#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4692#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0093
Reilly Grant89a7e512018-01-20 01:57:1694using ::testing::ElementsAre;
95using ::testing::Key;
96
Tsuyoshi Horo4f516be2022-06-14 11:53:1397namespace net::test {
[email protected]61a527782013-02-21 03:58:0098
99namespace {
100
bnc359ed2a2016-04-29 20:43:45101enum DestinationType {
102 // In pooling tests with two requests for different origins to the same
103 // destination, the destination should be
104 SAME_AS_FIRST, // the same as the first origin,
105 SAME_AS_SECOND, // the same as the second origin, or
106 DIFFERENT, // different from both.
107};
108
rch9ae5b3b2016-02-11 00:36:29109const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45110const char kDifferentHostname[] = "different.example.com";
111
David Schinazi09e9a6012019-10-03 17:37:57112struct TestParams {
113 quic::ParsedQuicVersion version;
114 bool client_headers_include_h2_stream_dependency;
115};
116
117// Used by ::testing::PrintToStringParamName().
118std::string PrintToString(const TestParams& p) {
Victor Vasiliev62c09dc2020-11-06 18:18:29119 return base::StrCat(
120 {ParsedQuicVersionToString(p.version), "_",
121 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
122 "Dependency"});
David Schinazi09e9a6012019-10-03 17:37:57123}
124
bnc359ed2a2016-04-29 20:43:45125// Run QuicNetworkTransactionWithDestinationTest instances with all value
126// combinations of version and destination_type.
127struct PoolingTestParams {
Nick Harper23290b82019-05-02 00:02:56128 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45129 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05130 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45131};
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(
148 {ParsedQuicVersionToString(p.version), "_", destination_string, "_",
149 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
150 "Dependency"});
David Schinazi09e9a6012019-10-03 17:37:57151}
152
Ryan Hamiltona2dcbae2022-02-09 19:02:45153std::string GenerateQuicAltSvcHeaderValue(
154 const quic::ParsedQuicVersionVector& versions,
155 std::string host,
156 uint16_t port) {
157 std::string value;
Bence Békyb89104962020-01-24 00:05:17158 std::string version_string;
David Schinazifbd4c432020-04-07 19:23:55159 bool first_version = true;
160 for (const auto& version : versions) {
161 if (first_version) {
162 first_version = false;
Bence Békyb89104962020-01-24 00:05:17163 } else {
Ryan Hamiltona2dcbae2022-02-09 19:02:45164 value.append(", ");
David Schinazifbd4c432020-04-07 19:23:55165 }
Ryan Hamiltona2dcbae2022-02-09 19:02:45166 value.append(base::StrCat({quic::AlpnForVersion(version), "=\"", host, ":",
167 base::NumberToString(port), "\""}));
zhongyie537a002017-06-27 16:48:21168 }
Ryan Hamiltona2dcbae2022-02-09 19:02:45169 return value;
170}
Bence Békyb89104962020-01-24 00:05:17171
Ryan Hamiltona2dcbae2022-02-09 19:02:45172std::string GenerateQuicAltSvcHeaderValue(
173 const quic::ParsedQuicVersionVector& versions,
174 uint16_t port) {
175 return GenerateQuicAltSvcHeaderValue(versions, "", port);
176}
177
178std::string GenerateQuicAltSvcHeader(
179 const quic::ParsedQuicVersionVector& versions) {
180 std::string altsvc_header = "Alt-Svc: ";
181 altsvc_header.append(GenerateQuicAltSvcHeaderValue(versions, 443));
182 altsvc_header.append("\r\n");
Bence Békyb89104962020-01-24 00:05:17183 return altsvc_header;
zhongyie537a002017-06-27 16:48:21184}
185
David Schinazi09e9a6012019-10-03 17:37:57186std::vector<TestParams> GetTestParams() {
187 std::vector<TestParams> params;
188 quic::ParsedQuicVersionVector all_supported_versions =
189 quic::AllSupportedVersions();
Nico Weber6dcde5b2020-02-22 20:49:20190 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
Renjie Tang3d8a6ddd2019-11-20 00:18:43191 params.push_back(TestParams{version, false});
192 params.push_back(TestParams{version, true});
David Schinazi09e9a6012019-10-03 17:37:57193 }
194 return params;
195}
196
bnc359ed2a2016-04-29 20:43:45197std::vector<PoolingTestParams> GetPoolingTestParams() {
198 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56199 quic::ParsedQuicVersionVector all_supported_versions =
Ryan Hamilton93424eb82019-08-23 04:28:40200 quic::AllSupportedVersions();
Nico Weber6dcde5b2020-02-22 20:49:20201 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
Renjie Tang3d8a6ddd2019-11-20 00:18:43202 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
203 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
204 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
205 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
206 params.push_back(PoolingTestParams{version, DIFFERENT, false});
207 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45208 }
209 return params;
210}
bncb07c05532015-05-14 19:07:20211
Bence Béky319388a882020-09-23 18:42:52212std::string ConstructDataFrameForVersion(base::StringPiece body,
213 quic::ParsedQuicVersion version) {
214 if (!version.HasIetfQuicFrames()) {
Jan Wilken Dörrie14a065b2021-02-12 14:28:32215 return std::string(body);
Bence Béky319388a882020-09-23 18:42:52216 }
Victor Vasilievc617d452022-03-07 15:54:25217 quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
218 body.size(), quiche::SimpleBufferAllocator::Get());
Ian Swett17d4d1c02021-06-08 19:52:41219 return base::StrCat({base::StringPiece(buffer.data(), buffer.size()), body});
Bence Béky319388a882020-09-23 18:42:52220}
221
[email protected]61a527782013-02-21 03:58:00222} // namespace
223
tbansal0f56a39a2016-04-07 22:03:38224class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40225 public:
tbansal180587c2017-02-16 15:13:23226 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
227 bool* rtt_notification_received)
228 : should_notify_updated_rtt_(should_notify_updated_rtt),
229 rtt_notification_received_(rtt_notification_received) {}
Peter Boström293b1342021-09-22 17:31:43230
231 TestSocketPerformanceWatcher(const TestSocketPerformanceWatcher&) = delete;
232 TestSocketPerformanceWatcher& operator=(const TestSocketPerformanceWatcher&) =
233 delete;
234
Tsuyoshi Horo07c3f0e2022-06-16 07:30:47235 ~TestSocketPerformanceWatcher() override = default;
tbansalfdf5665b2015-09-21 22:46:40236
tbansal180587c2017-02-16 15:13:23237 bool ShouldNotifyUpdatedRTT() const override {
238 return *should_notify_updated_rtt_;
239 }
tbansalfdf5665b2015-09-21 22:46:40240
tbansal0f56a39a2016-04-07 22:03:38241 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
242 *rtt_notification_received_ = true;
243 }
244
245 void OnConnectionChanged() override {}
246
247 private:
Keishi Hattori0e45c022021-11-27 09:25:52248 raw_ptr<bool> should_notify_updated_rtt_;
249 raw_ptr<bool> rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38250};
251
252class TestSocketPerformanceWatcherFactory
253 : public SocketPerformanceWatcherFactory {
254 public:
Tsuyoshi Horo4478fd32022-06-09 01:41:25255 TestSocketPerformanceWatcherFactory() = default;
Peter Boström293b1342021-09-22 17:31:43256
257 TestSocketPerformanceWatcherFactory(
258 const TestSocketPerformanceWatcherFactory&) = delete;
259 TestSocketPerformanceWatcherFactory& operator=(
260 const TestSocketPerformanceWatcherFactory&) = delete;
261
Tsuyoshi Horo07c3f0e2022-06-16 07:30:47262 ~TestSocketPerformanceWatcherFactory() override = default;
tbansal0f56a39a2016-04-07 22:03:38263
264 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42265 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41266 const Protocol protocol,
267 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51268 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38269 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51270 }
271 ++watcher_count_;
Tsuyoshi Horof8861cb2022-07-05 23:50:20272 return std::make_unique<TestSocketPerformanceWatcher>(
273 &should_notify_updated_rtt_, &rtt_notification_received_);
tbansalfdf5665b2015-09-21 22:46:40274 }
275
tbansalc8a94ea2015-11-02 23:58:51276 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40277
tbansalc8a94ea2015-11-02 23:58:51278 bool rtt_notification_received() const { return rtt_notification_received_; }
279
tbansal180587c2017-02-16 15:13:23280 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
281 should_notify_updated_rtt_ = should_notify_updated_rtt;
282 }
283
tbansalc8a94ea2015-11-02 23:58:51284 private:
Tsuyoshi Horo4478fd32022-06-09 01:41:25285 size_t watcher_count_ = 0u;
286 bool should_notify_updated_rtt_ = true;
287 bool rtt_notification_received_ = false;
tbansalc8a94ea2015-11-02 23:58:51288};
289
Ryan Hamilton8d9ee76e2018-05-29 23:52:52290class QuicNetworkTransactionTest
291 : public PlatformTest,
David Schinazi09e9a6012019-10-03 17:37:57292 public ::testing::WithParamInterface<TestParams>,
Gabriel Charette694c3c332019-08-19 14:53:05293 public WithTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00294 protected:
[email protected]1c04f9522013-02-21 20:32:43295 QuicNetworkTransactionTest()
David Schinazi09e9a6012019-10-03 17:37:57296 : version_(GetParam().version),
297 client_headers_include_h2_stream_dependency_(
298 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:56299 supported_versions_(quic::test::SupportedVersions(version_)),
Tsuyoshi Horof8861cb2022-07-05 23:50:20300 client_maker_(std::make_unique<QuicTestPacketMaker>(
Zhongyi Shi1c022d22020-03-20 19:00:16301 version_,
302 quic::QuicUtils::CreateRandomConnectionId(
303 context_.random_generator()),
304 context_.clock(),
305 kDefaultServerHostName,
306 quic::Perspective::IS_CLIENT,
307 client_headers_include_h2_stream_dependency_)),
Victor Vasiliev7752898d2019-11-14 21:30:22308 server_maker_(version_,
309 quic::QuicUtils::CreateRandomConnectionId(
310 context_.random_generator()),
311 context_.clock(),
312 kDefaultServerHostName,
313 quic::Perspective::IS_SERVER,
314 false),
Tsuyoshi Horo2c0a5042022-07-06 05:53:07315 quic_task_runner_(
316 base::MakeRefCounted<TestTaskRunner>(context_.mock_clock())),
Tsuyoshi Horof8861cb2022-07-05 23:50:20317 ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()),
Nicolas Arciniegad2013f92020-02-07 23:00:56318 proxy_resolution_service_(
319 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11320 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke3233d8f22019-08-20 21:01:49321 http_server_properties_(std::make_unique<HttpServerProperties>()),
rchf114d982015-10-21 01:34:56322 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:19323 FLAGS_quic_enable_http3_grease_randomness = false;
[email protected]aa9b14d2013-05-10 23:45:19324 request_.method = "GET";
rchf114d982015-10-21 01:34:56325 std::string url("https://");
bncb07c05532015-05-14 19:07:20326 url.append(kDefaultServerHostName);
327 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19328 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10329 request_.traffic_annotation =
330 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Victor Vasiliev7752898d2019-11-14 21:30:22331 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56332
333 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29334 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56335 verify_details_.cert_verify_result.verified_cert = cert;
336 verify_details_.cert_verify_result.is_issued_by_known_root = true;
337 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43338 }
[email protected]61a527782013-02-21 03:58:00339
dcheng67be2b1f2014-10-27 21:47:29340 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00341 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55342 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00343 }
344
dcheng67be2b1f2014-10-27 21:47:29345 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00346 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
347 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55348 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00349 PlatformTest::TearDown();
350 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55351 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40352 session_.reset();
[email protected]61a527782013-02-21 03:58:00353 }
354
Ryan Hamilton8d9ee76e2018-05-29 23:52:52355 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23356 ConstructClientConnectionClosePacket(uint64_t num) {
Zhongyi Shi1c022d22020-03-20 19:00:16357 return client_maker_->MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52358 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30359 }
360
Ryan Hamilton8d9ee76e2018-05-29 23:52:52361 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23362 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03363 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52364 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58365 }
366
Ryan Hamilton8d9ee76e2018-05-29 23:52:52367 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23368 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52369 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20370 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58371 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20372 }
373
Ryan Hamilton8d9ee76e2018-05-29 23:52:52374 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23375 uint64_t packet_number,
376 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34377 uint64_t smallest_received) {
Zhongyi Shi1c022d22020-03-20 19:00:16378 return client_maker_->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34379 smallest_received);
fayang3bcb8b502016-12-07 21:44:37380 }
381
Ryan Hamilton8d9ee76e2018-05-29 23:52:52382 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23383 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52384 quic::QuicStreamId stream_id,
385 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23386 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34387 uint64_t smallest_received) {
388 return client_maker_->MakeAckAndRstPacket(
389 num, false, stream_id, error_code, largest_received, smallest_received);
zhongyi6b5a3892016-03-12 04:46:20390 }
391
Ryan Hamilton8d9ee76e2018-05-29 23:52:52392 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23393 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52394 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41395 quic::QuicRstStreamErrorCode error_code) {
Zhongyi Shi1c022d22020-03-20 19:00:16396 return client_maker_->MakeRstPacket(num, false, stream_id, error_code,
397 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56398 }
399
Ryan Hamilton8d9ee76e2018-05-29 23:52:52400 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58401 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23402 uint64_t num,
Fan Yangac867502019-01-28 21:10:23403 uint64_t largest_received,
404 uint64_t smallest_received,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52405 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29406 const std::string& quic_error_details,
407 uint64_t frame_type) {
Zhongyi Shi1c022d22020-03-20 19:00:16408 return client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:34409 num, false, largest_received, smallest_received, quic_error,
410 quic_error_details, frame_type);
zhongyica364fbb2015-12-12 03:39:12411 }
412
Ryan Hamilton8d9ee76e2018-05-29 23:52:52413 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23414 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12415 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52416 quic::QuicStreamId stream_id,
417 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58418 return server_maker_.MakeRstPacket(num, include_version, stream_id,
419 error_code);
zhongyica364fbb2015-12-12 03:39:12420 }
421
Ryan Hamilton8d9ee76e2018-05-29 23:52:52422 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02423 uint64_t packet_number) {
Zhongyi Shi1c022d22020-03-20 19:00:16424 return client_maker_->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37425 }
426
Ryan Hamilton8d9ee76e2018-05-29 23:52:52427 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23428 uint64_t packet_number,
429 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34430 uint64_t smallest_received) {
fayang3bcb8b502016-12-07 21:44:37431 return server_maker_.MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34432 smallest_received);
fayang3bcb8b502016-12-07 21:44:37433 }
434
Ryan Hamilton8d9ee76e2018-05-29 23:52:52435 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23436 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57437 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52438 quic::QuicStreamId id,
439 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02440 RequestPriority request_priority) {
Zhongyi Shi1c022d22020-03-20 19:00:16441 return client_maker_->MakePriorityPacket(
Yixin Wangb470bc882018-02-15 18:43:57442 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02443 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wang385652a2018-02-16 02:37:23444 }
445
Ryan Hamilton8d9ee76e2018-05-29 23:52:52446 std::unique_ptr<quic::QuicEncryptedPacket>
Haoyue Wang9d70d65c2020-05-29 22:45:34447 ConstructClientPriorityFramesPacket(
448 uint64_t packet_number,
449 bool should_include_version,
450 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
451 priority_frames) {
452 return client_maker_->MakeMultiplePriorityFramesPacket(
453 packet_number, should_include_version, priority_frames);
454 }
455
456 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25457 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23458 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23459 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23460 uint64_t largest_received,
461 uint64_t smallest_received,
Yixin Wange7ecc472018-03-06 19:00:25462 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
Ryan Hamilton0d65a8c2019-06-07 00:46:02463 priority_frames) {
Zhongyi Shi1c022d22020-03-20 19:00:16464 return client_maker_->MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23465 packet_number, should_include_version, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34466 smallest_received, priority_frames);
Yixin Wangb470bc882018-02-15 18:43:57467 }
468
Haoyue Wang9d70d65c2020-05-29 22:45:34469 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckAndPriorityPacket(
470 uint64_t packet_number,
471 bool should_include_version,
472 uint64_t largest_received,
473 uint64_t smallest_received,
474 quic::QuicStreamId id,
475 quic::QuicStreamId parent_stream_id,
476 RequestPriority request_priority) {
477 return client_maker_->MakeAckAndPriorityPacket(
478 packet_number, should_include_version, largest_received,
479 smallest_received, id, parent_stream_id,
480 ConvertRequestPriorityToQuicPriority(request_priority));
481 }
482
zhongyi32569c62016-01-08 02:54:30483 // Uses default QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01484 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
485 const std::string& scheme,
486 const std::string& path) {
Zhongyi Shi1c022d22020-03-20 19:00:16487 return GetRequestHeaders(method, scheme, path, client_maker_.get());
zhongyi32569c62016-01-08 02:54:30488 }
489
490 // Uses customized QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01491 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
492 const std::string& scheme,
493 const std::string& path,
494 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50495 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00496 }
497
Bence Béky4c325e52020-10-22 20:48:01498 spdy::Http2HeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Zhongyi Shi1c022d22020-03-20 19:00:16499 return client_maker_->ConnectRequestHeaders(host_port);
Yixin Wang46a273ec302018-01-23 17:59:56500 }
501
Bence Béky4c325e52020-10-22 20:48:01502 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58503 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00504 }
505
zhongyi32569c62016-01-08 02:54:30506 // Appends alt_svc headers in the response headers.
Bence Béky4c325e52020-10-22 20:48:01507 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status,
508 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58509 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30510 }
511
Ryan Hamilton8d9ee76e2018-05-29 23:52:52512 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23513 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52514 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05515 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00516 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10517 absl::string_view data) {
Ryan Hamilton7505eb92019-06-08 00:22:17518 return server_maker_.MakeDataPacket(packet_number, stream_id,
519 should_include_version, fin, data);
[email protected]61a527782013-02-21 03:58:00520 }
521
Ryan Hamilton8d9ee76e2018-05-29 23:52:52522 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23523 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52524 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36525 bool should_include_version,
526 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10527 absl::string_view data) {
Zhongyi Shi1c022d22020-03-20 19:00:16528 return client_maker_->MakeDataPacket(packet_number, stream_id,
529 should_include_version, fin, data);
ckrasicda193a82016-07-09 00:39:36530 }
531
Ryan Hamilton8d9ee76e2018-05-29 23:52:52532 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23533 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56534 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52535 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23536 uint64_t largest_received,
537 uint64_t smallest_received,
Yixin Wang46a273ec302018-01-23 17:59:56538 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10539 absl::string_view data) {
Renjie Tangcd594f32020-07-11 20:18:34540 return client_maker_->MakeAckAndDataPacket(packet_number, include_version,
541 stream_id, largest_received,
542 smallest_received, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56543 }
544
Kenichi Ishibashi10111e82021-03-23 02:19:06545 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckDataAndRst(
546 uint64_t packet_number,
547 bool include_version,
548 quic::QuicStreamId stream_id,
549 quic::QuicRstStreamErrorCode error_code,
550 uint64_t largest_received,
551 uint64_t smallest_received,
552 quic::QuicStreamId data_id,
553 bool fin,
554 absl::string_view data) {
555 return client_maker_->MakeAckDataAndRst(
556 packet_number, include_version, stream_id, error_code, largest_received,
557 smallest_received, data_id, fin, data);
558 }
559
Ryan Hamilton8d9ee76e2018-05-29 23:52:52560 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23561 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52562 quic::QuicStreamId stream_id,
563 bool should_include_version,
564 bool fin,
Bence Béky4c325e52020-10-22 20:48:01565 spdy::Http2HeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56566 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
567 should_include_version, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02568 std::move(headers), 0);
Yixin Wang46a273ec302018-01-23 17:59:56569 }
570
Ryan Hamilton8d9ee76e2018-05-29 23:52:52571 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23572 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52573 quic::QuicStreamId stream_id,
574 bool should_include_version,
575 bool fin,
Bence Béky4c325e52020-10-22 20:48:01576 spdy::Http2HeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02577 quic::QuicStreamId parent_stream_id) {
Yixin Wang46a273ec302018-01-23 17:59:56578 return ConstructClientRequestHeadersPacket(
579 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:02580 std::move(headers), parent_stream_id);
zhongyi32569c62016-01-08 02:54:30581 }
582
Ryan Hamilton8d9ee76e2018-05-29 23:52:52583 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23584 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52585 quic::QuicStreamId stream_id,
586 bool should_include_version,
587 bool fin,
588 RequestPriority request_priority,
Bence Béky4c325e52020-10-22 20:48:01589 spdy::Http2HeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02590 quic::QuicStreamId parent_stream_id) {
Ryan Hamilton0239aac2018-05-19 00:03:13591 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56592 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16593 return client_maker_->MakeRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56594 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02595 std::move(headers), parent_stream_id, nullptr);
[email protected]61a527782013-02-21 03:58:00596 }
597
Ryan Hamilton8d9ee76e2018-05-29 23:52:52598 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25599 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23600 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52601 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25602 bool should_include_version,
603 bool fin,
604 RequestPriority request_priority,
Bence Béky4c325e52020-10-22 20:48:01605 spdy::Http2HeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52606 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25607 size_t* spdy_headers_frame_length,
608 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13609 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25610 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16611 return client_maker_->MakeRequestHeadersAndMultipleDataFramesPacket(
Yixin Wange7ecc472018-03-06 19:00:25612 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02613 std::move(headers), parent_stream_id, spdy_headers_frame_length,
Yixin Wange7ecc472018-03-06 19:00:25614 data_writes);
615 }
616
Ryan Hamilton8d9ee76e2018-05-29 23:52:52617 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23618 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52619 quic::QuicStreamId stream_id,
620 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13621 bool should_include_version,
Bence Béky4c325e52020-10-22 20:48:01622 spdy::Http2HeaderBlock headers) {
Renjie Tangb7afea82020-07-15 23:35:47623 return server_maker_.MakePushPromisePacket(
ckrasic769733c2016-06-30 00:42:13624 packet_number, stream_id, promised_stream_id, should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02625 false, std::move(headers), nullptr);
ckrasic769733c2016-06-30 00:42:13626 }
627
Ryan Hamilton8d9ee76e2018-05-29 23:52:52628 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23629 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52630 quic::QuicStreamId stream_id,
631 bool should_include_version,
632 bool fin,
Bence Béky4c325e52020-10-22 20:48:01633 spdy::Http2HeaderBlock headers) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02634 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
635 should_include_version, fin,
636 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30637 }
638
Bence Béky319388a882020-09-23 18:42:52639 std::string ConstructDataFrame(base::StringPiece body) {
640 return ConstructDataFrameForVersion(body, version_);
Renjief49758b2019-01-11 23:32:41641 }
642
Nick Harper23290b82019-05-02 00:02:56643 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41644 session_params_.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:38645 context_.params()->supported_versions = supported_versions;
Victor Vasilieva1e66d72019-12-05 17:55:38646 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:05647 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00648
Victor Vasiliev7752898d2019-11-14 21:30:22649 session_context_.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:41650 session_context_.client_socket_factory = &socket_factory_;
651 session_context_.quic_crypto_client_stream_factory =
652 &crypto_client_stream_factory_;
653 session_context_.host_resolver = &host_resolver_;
654 session_context_.cert_verifier = &cert_verifier_;
655 session_context_.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:41656 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
657 session_context_.socket_performance_watcher_factory =
658 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59659 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41660 session_context_.ssl_config_service = ssl_config_service_.get();
661 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49662 session_context_.http_server_properties = http_server_properties_.get();
Matt Reichhoff0049a0b72021-10-20 20:44:26663 session_context_.net_log = NetLog::Get();
mmenke6ddfbea2017-05-31 21:48:41664
Renjie Tang6ff9a9b2021-02-03 22:11:09665 session_ =
666 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
Matt Menkeb566c392019-09-11 23:22:43667 session_->quic_stream_factory()
668 ->set_is_quic_known_to_work_on_current_network(true);
Yixin Wang46a273ec302018-01-23 17:59:56669 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
670 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00671 }
672
zhongyi86838d52017-06-30 01:19:44673 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21674
David Schinazif832cb82019-11-08 22:25:27675 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
Zhongyi Shi1c022d22020-03-20 19:00:16676 const std::string& status_line,
677 const quic::ParsedQuicVersion& version) {
[email protected]aa9b14d2013-05-10 23:45:19678 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42679 ASSERT_TRUE(response != nullptr);
680 ASSERT_TRUE(response->headers.get() != nullptr);
David Schinazif832cb82019-11-08 22:25:27681 EXPECT_EQ(status_line, response->headers->GetStatusLine());
[email protected]aa9b14d2013-05-10 23:45:19682 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52683 EXPECT_TRUE(response->was_alpn_negotiated);
Victor Vasiliev22dd3f212022-02-11 21:57:29684 auto connection_info =
685 QuicHttpStream::ConnectionInfoFromQuicVersion(version);
686 if (connection_info == response->connection_info) {
687 return;
688 }
689 // QUIC v1 and QUIC v2 are considered a match, because they have the same
690 // ALPN token.
691 if ((connection_info == HttpResponseInfo::CONNECTION_INFO_QUIC_RFC_V1 ||
692 connection_info == HttpResponseInfo::CONNECTION_INFO_QUIC_2_DRAFT_1) &&
693 (response->connection_info ==
694 HttpResponseInfo::CONNECTION_INFO_QUIC_RFC_V1 ||
695 response->connection_info ==
696 HttpResponseInfo::CONNECTION_INFO_QUIC_2_DRAFT_1)) {
697 return;
698 }
699
700 // They do not match. This EXPECT_EQ will fail and print useful
701 // information.
702 EXPECT_EQ(connection_info, response->connection_info);
[email protected]aa9b14d2013-05-10 23:45:19703 }
704
Zhongyi Shi1c022d22020-03-20 19:00:16705 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
706 const std::string& status_line) {
707 CheckWasQuicResponse(trans, status_line, version_);
708 }
709
David Schinazif832cb82019-11-08 22:25:27710 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
Kenichi Ishibashif8634ab2021-03-16 23:41:28711 CheckWasQuicResponse(trans, "HTTP/1.1 200", version_);
David Schinazif832cb82019-11-08 22:25:27712 }
713
bnc691fda62016-08-12 00:43:16714 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41715 const HttpResponseInfo* response = trans->GetResponseInfo();
716 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37717 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41718 }
719
bnc691fda62016-08-12 00:43:16720 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19721 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42722 ASSERT_TRUE(response != nullptr);
723 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19724 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
725 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52726 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52727 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19728 response->connection_info);
729 }
730
Yixin Wang46a273ec302018-01-23 17:59:56731 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
732 const HttpResponseInfo* response = trans->GetResponseInfo();
733 ASSERT_TRUE(response != nullptr);
734 ASSERT_TRUE(response->headers.get() != nullptr);
735 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
736 EXPECT_TRUE(response->was_fetched_via_spdy);
737 EXPECT_TRUE(response->was_alpn_negotiated);
738 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
739 response->connection_info);
740 }
741
bnc691fda62016-08-12 00:43:16742 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19743 const std::string& expected) {
744 std::string response_data;
bnc691fda62016-08-12 00:43:16745 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19746 EXPECT_EQ(expected, response_data);
747 }
748
bnc691fda62016-08-12 00:43:16749 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19750 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:26751 int rv = trans->Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:01752 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
753 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19754 }
755
756 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16757 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
758 RunTransaction(&trans);
759 CheckWasHttpResponse(&trans);
760 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19761 }
762
tbansalc3308d72016-08-27 10:25:04763 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
764 bool used_proxy,
765 uint16_t port) {
766 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalc3308d72016-08-27 10:25:04767 RunTransaction(&trans);
768 CheckWasHttpResponse(&trans);
769 CheckResponsePort(&trans, port);
770 CheckResponseData(&trans, expected);
tbansal2ecbbc72016-10-06 17:15:47771 if (used_proxy) {
772 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
773 } else {
774 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
775 }
tbansalc3308d72016-08-27 10:25:04776 }
David Schinazif832cb82019-11-08 22:25:27777 void SendRequestAndExpectQuicResponse(const std::string& expected,
778 const std::string& status_line) {
779 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443,
780 status_line);
781 }
tbansalc3308d72016-08-27 10:25:04782
[email protected]aa9b14d2013-05-10 23:45:19783 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56784 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12785 }
786
bnc62a44f022015-04-02 15:59:41787 void SendRequestAndExpectQuicResponseFromProxyOnPort(
788 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46789 uint16_t port) {
bnc62a44f022015-04-02 15:59:41790 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19791 }
792
793 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05794 MockCryptoClientStream::HandshakeMode handshake_mode,
795 const NetworkIsolationKey& network_isolation_key =
796 NetworkIsolationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19797 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46798 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21799 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
Peter Kastinge5a38ed2021-10-02 03:06:35800 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:49801 http_server_properties_->SetQuicAlternativeService(
Matt Menkeb32ba5122019-09-10 19:17:05802 server, network_isolation_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07803 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19804 }
805
rchbe69cb902016-02-11 01:10:48806 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27807 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48808 const HostPortPair& alternative) {
809 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46810 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21811 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48812 alternative.port());
Peter Kastinge5a38ed2021-10-02 03:06:35813 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:49814 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07815 server, NetworkIsolationKey(), alternative_service, expiration,
816 supported_versions_);
rchbe69cb902016-02-11 01:10:48817 }
818
Matt Menkeb32ba5122019-09-10 19:17:05819 void ExpectBrokenAlternateProtocolMapping(
820 const NetworkIsolationKey& network_isolation_key =
821 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46822 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34823 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49824 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05825 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34826 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49827 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05828 alternative_service_info_vector[0].alternative_service(),
829 network_isolation_key));
[email protected]aa9b14d2013-05-10 23:45:19830 }
831
Matt Menkeb32ba5122019-09-10 19:17:05832 void ExpectQuicAlternateProtocolMapping(
833 const NetworkIsolationKey& network_isolation_key =
834 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46835 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34836 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49837 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05838 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34839 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54840 EXPECT_EQ(
841 kProtoQUIC,
842 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49843 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05844 alternative_service_info_vector[0].alternative_service(),
845 network_isolation_key));
[email protected]4d590c9c2014-05-02 05:14:33846 }
847
[email protected]aa9b14d2013-05-10 23:45:19848 void AddHangingNonAlternateProtocolSocketData() {
Lei Zhange00db752021-04-17 00:48:46849 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
[email protected]dda75ab2013-06-22 22:43:30850 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30851 hanging_data->set_connect_data(hanging_connect);
852 hanging_data_.push_back(std::move(hanging_data));
853 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
[email protected]aa9b14d2013-05-10 23:45:19854 }
855
Zhongyi Shia6b68d112018-09-24 07:49:03856 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Victor Vasilieva1e66d72019-12-05 17:55:38857 context_.params()->migrate_sessions_on_network_change_v2 = true;
858 context_.params()->migrate_sessions_early_v2 = true;
859 context_.params()->retry_on_alternate_network_before_handshake = true;
Renjie Tang6ff9a9b2021-02-03 22:11:09860 scoped_mock_change_notifier_ =
861 std::make_unique<ScopedMockNetworkChangeNotifier>();
Zhongyi Shia6b68d112018-09-24 07:49:03862 MockNetworkChangeNotifier* mock_ncn =
863 scoped_mock_change_notifier_->mock_network_change_notifier();
864 mock_ncn->ForceNetworkHandlesSupported();
865 mock_ncn->SetConnectedNetworksList(
866 {kDefaultNetworkForTests, kNewNetworkForTests});
867 }
868
Matt Menkeb32ba5122019-09-10 19:17:05869 // Adds a new socket data provider for an HTTP request, and runs a request,
870 // expecting it to be used.
871 void AddHttpDataAndRunRequest() {
872 MockWrite http_writes[] = {
873 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
874 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
875 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
876
Ryan Hamiltona2dcbae2022-02-09 19:02:45877 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
878 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
879 MockRead(SYNCHRONOUS, 5, "http used"),
880 // Connection closed.
881 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:05882 SequencedSocketData http_data(http_reads, http_writes);
883 socket_factory_.AddSocketDataProvider(&http_data);
884 SSLSocketDataProvider ssl_data(ASYNC, OK);
885 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
886 SendRequestAndExpectHttpResponse("http used");
887 EXPECT_TRUE(http_data.AllWriteDataConsumed());
888 EXPECT_TRUE(http_data.AllReadDataConsumed());
889 }
890
891 // Adds a new socket data provider for a QUIC request, and runs a request,
892 // expecting it to be used. The new QUIC session is not closed.
893 void AddQuicDataAndRunRequest() {
894 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22895 version_,
896 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
897 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menkeb32ba5122019-09-10 19:17:05898 client_headers_include_h2_stream_dependency_);
899 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22900 version_,
901 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
902 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
903 false);
Matt Menkeb32ba5122019-09-10 19:17:05904 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56905 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05906 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:25907 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:56908 quic_data.AddWrite(
909 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_number++));
910 }
Matt Menkeb32ba5122019-09-10 19:17:05911 quic_data.AddWrite(
912 SYNCHRONOUS,
913 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56914 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
915 true, true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Matt Menkeb32ba5122019-09-10 19:17:05916 GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
917 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Fan Yang1ef6dfef2021-07-24 16:20:16918 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Matt Menkeb32ba5122019-09-10 19:17:05919 quic_data.AddRead(
920 ASYNC, server_maker.MakeResponseHeadersPacket(
921 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:28922 false, server_maker.GetResponseHeaders("200"), nullptr));
Matt Menkeb32ba5122019-09-10 19:17:05923 quic_data.AddRead(
924 ASYNC, server_maker.MakeDataPacket(
925 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:52926 true, ConstructDataFrame("quic used")));
Matt Menkeb32ba5122019-09-10 19:17:05927 // Don't care about the final ack.
928 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
929 // No more data to read.
930 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
931 quic_data.AddSocketDataToFactory(&socket_factory_);
Fan Yang1ef6dfef2021-07-24 16:20:16932
933 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
934 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:26935 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Fan Yang1ef6dfef2021-07-24 16:20:16936 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
937
938 // Pump the message loop to get the request started.
939 base::RunLoop().RunUntilIdle();
940 // Explicitly confirm the handshake.
941 crypto_client_stream_factory_.last_stream()
942 ->NotifySessionOneRttKeyAvailable();
943
944 ASSERT_FALSE(quic_data.AllReadDataConsumed());
945 quic_data.Resume();
946
947 // Run the QUIC session to completion.
948 base::RunLoop().RunUntilIdle();
Matt Menkeb32ba5122019-09-10 19:17:05949
950 EXPECT_TRUE(quic_data.AllReadDataConsumed());
951 }
952
Bence Béky6e243aa2019-12-13 19:01:07953 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56954 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
955 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36956 }
957
Bence Béky6e243aa2019-12-13 19:01:07958 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56959 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
960 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36961 }
962
Bence Béky6e243aa2019-12-13 19:01:07963 quic::QuicStreamId GetQpackDecoderStreamId() const {
964 return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
965 version_.transport_version, 1);
966 }
967
968 std::string StreamCancellationQpackDecoderInstruction(int n) const {
Ian Swettb70d9f8f2020-04-10 23:38:43969 return StreamCancellationQpackDecoderInstruction(n, true);
970 }
971
972 std::string StreamCancellationQpackDecoderInstruction(
973 int n,
974 bool create_stream) const {
Bence Béky6e243aa2019-12-13 19:01:07975 const quic::QuicStreamId cancelled_stream_id =
976 GetNthClientInitiatedBidirectionalStreamId(n);
977 EXPECT_LT(cancelled_stream_id, 63u);
978
Peter Kasting241e6d22021-06-09 17:24:58979 const char opcode = 0x40;
Ian Swettb70d9f8f2020-04-10 23:38:43980 if (create_stream) {
Peter Kasting241e6d22021-06-09 17:24:58981 return {0x03, static_cast<char>(opcode | cancelled_stream_id)};
Ian Swettb70d9f8f2020-04-10 23:38:43982 } else {
Peter Kasting241e6d22021-06-09 17:24:58983 return {static_cast<char>(opcode | cancelled_stream_id)};
Ian Swettb70d9f8f2020-04-10 23:38:43984 }
Bence Béky6e243aa2019-12-13 19:01:07985 }
986
Bence Béky230ac612017-08-30 19:17:08987 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49988 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08989 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49990 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08991 }
992
Zhongyi Shi1c022d22020-03-20 19:00:16993 void SendRequestAndExpectQuicResponseMaybeFromProxy(
994 const std::string& expected,
995 bool used_proxy,
996 uint16_t port,
997 const std::string& status_line,
998 const quic::ParsedQuicVersion& version) {
999 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Zhongyi Shi1c022d22020-03-20 19:00:161000 RunTransaction(&trans);
1001 CheckWasQuicResponse(&trans, status_line, version);
1002 CheckResponsePort(&trans, port);
1003 CheckResponseData(&trans, expected);
Zhongyi Shi1c022d22020-03-20 19:00:161004 if (used_proxy) {
1005 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
Cammie Smith Barnesbf91e2a2020-12-23 20:49:041006
1007 // DNS aliases should be empty when using a proxy.
1008 EXPECT_TRUE(trans.GetResponseInfo()->dns_aliases.empty());
Zhongyi Shi1c022d22020-03-20 19:00:161009 } else {
1010 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1011 }
1012 }
1013
Victor Vasiliev22dd3f212022-02-11 21:57:291014 // Verify that the set of QUIC protocols in `alt_svc_info_vector` and
1015 // `supported_versions` is the same. Since QUICv1 and QUICv2 have the same
1016 // ALPN token "h3", they cannot be distinguished when parsing ALPN, so
1017 // consider them equal. This is accomplished by comparing the set of ALPN
1018 // strings (instead of comparing the set of ParsedQuicVersion entities).
1019 static void VerifyQuicVersionsInAlternativeServices(
1020 const AlternativeServiceInfoVector& alt_svc_info_vector,
1021 const quic::ParsedQuicVersionVector& supported_versions) {
1022 // Process supported versions.
1023 std::set<std::string> supported_alpn;
1024 for (const auto& version : supported_versions) {
1025 if (version.AlpnDeferToRFCv1()) {
1026 // These versions currently do not support Alt-Svc.
1027 return;
1028 }
1029 supported_alpn.insert(quic::ParsedQuicVersionToString(version));
1030 }
1031
1032 // Versions that support the legacy Google-specific Alt-Svc format are sent
1033 // in a single Alt-Svc entry, therefore they are accumulated in a single
1034 // AlternativeServiceInfo, whereas more recent versions all have their own
1035 // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
1036 std::set<std::string> alt_svc_negotiated_alpn;
1037 for (const auto& alt_svc_info : alt_svc_info_vector) {
1038 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
1039 for (const auto& version : alt_svc_info.advertised_versions()) {
1040 alt_svc_negotiated_alpn.insert(
1041 quic::ParsedQuicVersionToString(version));
1042 }
1043 }
1044
1045 // Compare.
1046 EXPECT_EQ(alt_svc_negotiated_alpn, supported_alpn);
1047 }
1048
Nick Harper23290b82019-05-02 00:02:561049 const quic::ParsedQuicVersion version_;
Ryan Hamiltona2dcbae2022-02-09 19:02:451050 const std::string alt_svc_header_ =
1051 GenerateQuicAltSvcHeader({version_}) + "\r\n";
Yixin Wang079ad542018-01-11 04:06:051052 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:561053 quic::ParsedQuicVersionVector supported_versions_;
Patrick Meenan0041f332022-05-19 23:48:351054 quic::test::QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Victor Vasiliev7752898d2019-11-14 21:30:221055 MockQuicContext context_;
Zhongyi Shi1c022d22020-03-20 19:00:161056 std::unique_ptr<QuicTestPacketMaker> client_maker_;
alyssar2adf3ac2016-05-03 17:12:581057 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:091058 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:421059 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:001060 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:561061 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:051062 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Eric Orthbe86fee2021-10-28 22:31:111063 MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
1064 RuleResolver::GetLocalhostResult()};
[email protected]1c04f9522013-02-21 20:32:431065 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:111066 TransportSecurityState transport_security_state_;
Ryan Sleevi8a9c9c12018-05-09 02:36:231067 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:381068 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:071069 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:261070 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:421071 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:491072 std::unique_ptr<HttpServerProperties> http_server_properties_;
Matt Menke30a878c2021-07-20 22:25:091073 HttpNetworkSessionParams session_params_;
1074 HttpNetworkSessionContext session_context_;
[email protected]aa9b14d2013-05-10 23:45:191075 HttpRequestInfo request_;
Matt Reichhoff0049a0b72021-10-20 20:44:261076 NetLogWithSource net_log_with_source_{
1077 NetLogWithSource::Make(NetLogSourceType::NONE)};
1078 RecordingNetLogObserver net_log_observer_;
danakjad1777e2016-04-16 00:56:421079 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:561080 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:031081 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:121082
1083 private:
1084 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1085 const std::string& expected,
bnc62a44f022015-04-02 15:59:411086 bool used_proxy,
David Schinazif832cb82019-11-08 22:25:271087 uint16_t port,
1088 const std::string& status_line) {
Zhongyi Shi1c022d22020-03-20 19:00:161089 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
1090 status_line, version_);
tbansal7cec3812015-02-05 21:25:121091 }
David Schinazif832cb82019-11-08 22:25:271092
1093 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1094 const std::string& expected,
1095 bool used_proxy,
1096 uint16_t port) {
1097 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
Kenichi Ishibashif8634ab2021-03-16 23:41:281098 "HTTP/1.1 200", version_);
David Schinazif832cb82019-11-08 22:25:271099 }
[email protected]61a527782013-02-21 03:58:001100};
1101
David Schinazi09e9a6012019-10-03 17:37:571102INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1103 QuicNetworkTransactionTest,
1104 ::testing::ValuesIn(GetTestParams()),
1105 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201106
Ryan Hamiltona64a5bcf2017-11-30 07:35:281107TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:381108 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281109 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381110 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281111 HostPortPair::FromString("mail.example.org:443"));
1112 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271113 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281114
Ryan Hamiltonabad59e2019-06-06 04:02:591115 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251116 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231117 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281118 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1119 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211120 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281121
1122 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1123
1124 CreateSession();
1125
1126 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1127 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261128 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281129 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1130 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1131
1132 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1133 -ERR_INTERNET_DISCONNECTED, 1);
1134 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1135 -ERR_INTERNET_DISCONNECTED, 1);
1136}
1137
1138TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Victor Vasilieva1e66d72019-12-05 17:55:381139 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281140 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381141 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281142 HostPortPair::FromString("mail.example.org:443"));
1143 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271144 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281145
Ryan Hamiltonabad59e2019-06-06 04:02:591146 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251147 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231148 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281149 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1150 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211151 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281152
1153 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1154
1155 CreateSession();
1156
1157 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1158 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261159 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281160 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1161 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1162
1163 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1164 -ERR_INTERNET_DISCONNECTED, 1);
1165 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1166 -ERR_INTERNET_DISCONNECTED, 1);
1167}
1168
tbansal180587c2017-02-16 15:13:231169TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381170 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231171 HostPortPair::FromString("mail.example.org:443"));
1172
Ryan Hamiltonabad59e2019-06-06 04:02:591173 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231174 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251175 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231176 mock_quic_data.AddWrite(SYNCHRONOUS,
1177 ConstructInitialSettingsPacket(packet_num++));
1178 }
rch5cb522462017-04-25 20:18:361179 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231180 SYNCHRONOUS,
1181 ConstructClientRequestHeadersPacket(
1182 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1183 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431184 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331185 ASYNC, ConstructServerResponseHeadersPacket(
1186 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281187 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331188 mock_quic_data.AddRead(
1189 ASYNC, ConstructServerDataPacket(
1190 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521191 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231192 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341193 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231194 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1195
1196 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1197
1198 CreateSession();
1199 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1200
1201 EXPECT_FALSE(
1202 test_socket_performance_watcher_factory_.rtt_notification_received());
1203 SendRequestAndExpectQuicResponse("hello!");
1204 EXPECT_TRUE(
1205 test_socket_performance_watcher_factory_.rtt_notification_received());
1206}
1207
1208TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381209 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231210 HostPortPair::FromString("mail.example.org:443"));
1211
Ryan Hamiltonabad59e2019-06-06 04:02:591212 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231213 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251214 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231215 mock_quic_data.AddWrite(SYNCHRONOUS,
1216 ConstructInitialSettingsPacket(packet_num++));
1217 }
rch5cb522462017-04-25 20:18:361218 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231219 SYNCHRONOUS,
1220 ConstructClientRequestHeadersPacket(
1221 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1222 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431223 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331224 ASYNC, ConstructServerResponseHeadersPacket(
1225 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281226 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331227 mock_quic_data.AddRead(
1228 ASYNC, ConstructServerDataPacket(
1229 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521230 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231231 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341232 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231233 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1234
1235 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1236
1237 CreateSession();
1238 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1239
1240 EXPECT_FALSE(
1241 test_socket_performance_watcher_factory_.rtt_notification_received());
1242 SendRequestAndExpectQuicResponse("hello!");
1243 EXPECT_FALSE(
1244 test_socket_performance_watcher_factory_.rtt_notification_received());
1245}
1246
[email protected]1e960032013-12-20 19:00:201247TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:381248 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571249 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471250
Ryan Hamiltonabad59e2019-06-06 04:02:591251 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231252 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251253 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231254 mock_quic_data.AddWrite(SYNCHRONOUS,
1255 ConstructInitialSettingsPacket(packet_num++));
1256 }
rch5cb522462017-04-25 20:18:361257 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231258 SYNCHRONOUS,
1259 ConstructClientRequestHeadersPacket(
1260 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1261 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431262 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331263 ASYNC, ConstructServerResponseHeadersPacket(
1264 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281265 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331266 mock_quic_data.AddRead(
1267 ASYNC, ConstructServerDataPacket(
1268 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521269 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231270 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341271 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:591272 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471273
rcha5399e02015-04-21 19:32:041274 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471275
[email protected]4dca587c2013-03-07 16:54:471276 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471277
[email protected]aa9b14d2013-05-10 23:45:191278 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471279
[email protected]98b20ce2013-05-10 05:55:261280 // Check that the NetLog was filled reasonably.
Matt Reichhoff0049a0b72021-10-20 20:44:261281 auto entries = net_log_observer_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261282 EXPECT_LT(0u, entries.size());
1283
1284 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291285 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001286 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1287 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261288 EXPECT_LT(0, pos);
1289
David Schinazi24bfaa02020-10-22 19:54:381290 // ... and also a TYPE_QUIC_SESSION_PACKET_SENT.
1291 pos = ExpectLogContainsSomewhere(entries, 0,
1292 NetLogEventType::QUIC_SESSION_PACKET_SENT,
1293 NetLogEventPhase::NONE);
1294 EXPECT_LT(0, pos);
1295
rchfd527212015-08-25 00:41:261296 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291297 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261298 entries, 0,
mikecirone8b85c432016-09-08 19:11:001299 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1300 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261301 EXPECT_LT(0, pos);
1302
Eric Roman79cc7552019-07-19 02:17:541303 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261304
rchfd527212015-08-25 00:41:261305 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1306 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001307 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1308 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261309 EXPECT_LT(0, pos);
1310
[email protected]98b20ce2013-05-10 05:55:261311 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291312 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001313 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1314 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261315 EXPECT_LT(0, pos);
1316
Eric Roman79cc7552019-07-19 02:17:541317 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Victor Vasiliev7da08172019-10-14 06:04:251318 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451319 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1320 static_cast<quic::QuicStreamId>(log_stream_id));
1321 } else {
1322 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1323 static_cast<quic::QuicStreamId>(log_stream_id));
1324 }
[email protected]4dca587c2013-03-07 16:54:471325}
1326
Bence Békyb6300042020-01-28 21:18:201327// Regression test for https://crbug.com/1043531.
1328TEST_P(QuicNetworkTransactionTest, ResetOnEmptyResponseHeaders) {
1329 if (!quic::VersionUsesHttp3(version_.transport_version)) {
1330 return;
1331 }
1332
Kenichi Ishibashi10111e82021-03-23 02:19:061333 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Bence Békyb6300042020-01-28 21:18:201334 context_.params()->origins_to_force_quic_on.insert(
1335 HostPortPair::FromString("mail.example.org:443"));
1336
1337 MockQuicData mock_quic_data(version_);
1338 int write_packet_num = 1;
1339 mock_quic_data.AddWrite(SYNCHRONOUS,
1340 ConstructInitialSettingsPacket(write_packet_num++));
1341 mock_quic_data.AddWrite(
1342 SYNCHRONOUS,
1343 ConstructClientRequestHeadersPacket(
1344 write_packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1345 true, true, GetRequestHeaders("GET", "https", "/")));
1346
1347 const quic::QuicStreamId request_stream_id =
1348 GetNthClientInitiatedBidirectionalStreamId(0);
Bence Béky4c325e52020-10-22 20:48:011349 spdy::Http2HeaderBlock empty_response_headers;
Bence Békyb6300042020-01-28 21:18:201350 const std::string response_data = server_maker_.QpackEncodeHeaders(
1351 request_stream_id, std::move(empty_response_headers), nullptr);
1352 uint64_t read_packet_num = 1;
1353 mock_quic_data.AddRead(
1354 ASYNC, ConstructServerDataPacket(read_packet_num++, request_stream_id,
1355 false, false, response_data));
1356 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1357
1358 mock_quic_data.AddWrite(
Kenichi Ishibashi10111e82021-03-23 02:19:061359 ASYNC, ConstructClientAckDataAndRst(
1360 write_packet_num++, true, request_stream_id,
1361 quic::QUIC_STREAM_GENERAL_PROTOCOL_ERROR, 1, 1,
1362 GetQpackDecoderStreamId(), false,
1363 StreamCancellationQpackDecoderInstruction(request_stream_id)));
Bence Békyb6300042020-01-28 21:18:201364
1365 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1366
1367 CreateSession();
1368
1369 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1370 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261371 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Bence Békyb6300042020-01-28 21:18:201372 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Kenichi Ishibashi10111e82021-03-23 02:19:061373 EXPECT_THAT(callback.WaitForResult(), IsError(net::ERR_QUIC_PROTOCOL_ERROR));
1374 base::RunLoop().RunUntilIdle();
1375 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1376 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
Bence Békyb6300042020-01-28 21:18:201377}
1378
rchbd089ab2017-05-26 23:05:041379TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381380 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041381 HostPortPair::FromString("mail.example.org:443"));
1382
Ryan Hamiltonabad59e2019-06-06 04:02:591383 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231384 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251385 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231386 mock_quic_data.AddWrite(SYNCHRONOUS,
1387 ConstructInitialSettingsPacket(packet_num++));
1388 }
rchbd089ab2017-05-26 23:05:041389 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231390 SYNCHRONOUS,
1391 ConstructClientRequestHeadersPacket(
1392 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1393 true, GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashif8634ab2021-03-16 23:41:281394 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200");
rchbd089ab2017-05-26 23:05:041395 response_headers["key1"] = std::string(30000, 'A');
1396 response_headers["key2"] = std::string(30000, 'A');
1397 response_headers["key3"] = std::string(30000, 'A');
1398 response_headers["key4"] = std::string(30000, 'A');
1399 response_headers["key5"] = std::string(30000, 'A');
1400 response_headers["key6"] = std::string(30000, 'A');
1401 response_headers["key7"] = std::string(30000, 'A');
1402 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451403 quic::QuicStreamId stream_id;
1404 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251405 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451406 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281407 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451408 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451409 } else {
1410 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1411 spdy::SpdyHeadersIR headers_frame(
1412 GetNthClientInitiatedBidirectionalStreamId(0),
1413 std::move(response_headers));
1414 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1415 spdy::SpdySerializedFrame spdy_frame =
1416 response_framer.SerializeFrame(headers_frame);
1417 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1418 }
rchbd089ab2017-05-26 23:05:041419
Fan Yangac867502019-01-28 21:10:231420 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041421 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451422 for (size_t offset = 0; offset < response_data.length();
1423 offset += chunk_size) {
1424 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431425 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451426 ASYNC, ConstructServerDataPacket(
1427 packet_number++, stream_id, false, false,
Victor Vasiliev502ba582020-09-15 23:16:151428 absl::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041429 }
1430
1431 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331432 ASYNC, ConstructServerDataPacket(
1433 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Bence Béky319388a882020-09-23 18:42:521434 false, true, ConstructDataFrame("hello!")));
rchbd089ab2017-05-26 23:05:041435 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341436 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Renjie Tangaadb84b2019-08-31 01:00:231437 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341438 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3));
rchbd089ab2017-05-26 23:05:041439
1440 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1441
1442 CreateSession();
1443
1444 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421445 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1446 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041447}
1448
1449TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381450 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1451 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041452 HostPortPair::FromString("mail.example.org:443"));
1453
Ryan Hamiltonabad59e2019-06-06 04:02:591454 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231455 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251456 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231457 mock_quic_data.AddWrite(SYNCHRONOUS,
1458 ConstructInitialSettingsPacket(packet_num++));
1459 }
rchbd089ab2017-05-26 23:05:041460 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231461 SYNCHRONOUS,
1462 ConstructClientRequestHeadersPacket(
1463 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1464 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451465
Kenichi Ishibashif8634ab2021-03-16 23:41:281466 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200");
rchbd089ab2017-05-26 23:05:041467 response_headers["key1"] = std::string(30000, 'A');
1468 response_headers["key2"] = std::string(30000, 'A');
1469 response_headers["key3"] = std::string(30000, 'A');
1470 response_headers["key4"] = std::string(30000, 'A');
1471 response_headers["key5"] = std::string(30000, 'A');
1472 response_headers["key6"] = std::string(30000, 'A');
1473 response_headers["key7"] = std::string(30000, 'A');
1474 response_headers["key8"] = std::string(30000, 'A');
1475 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451476
1477 quic::QuicStreamId stream_id;
1478 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251479 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451480 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281481 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451482 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451483 } else {
1484 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1485 spdy::SpdyHeadersIR headers_frame(
1486 GetNthClientInitiatedBidirectionalStreamId(0),
1487 std::move(response_headers));
1488 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1489 spdy::SpdySerializedFrame spdy_frame =
1490 response_framer.SerializeFrame(headers_frame);
1491 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1492 }
rchbd089ab2017-05-26 23:05:041493
Fan Yangac867502019-01-28 21:10:231494 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041495 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451496 for (size_t offset = 0; offset < response_data.length();
1497 offset += chunk_size) {
1498 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431499 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451500 ASYNC, ConstructServerDataPacket(
1501 packet_number++, stream_id, false, false,
Victor Vasiliev502ba582020-09-15 23:16:151502 absl::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041503 }
1504
1505 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331506 ASYNC, ConstructServerDataPacket(
1507 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Bence Béky319388a882020-09-23 18:42:521508 false, true, ConstructDataFrame("hello!")));
rchbd089ab2017-05-26 23:05:041509 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341510 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431511 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331512 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231513 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:341514 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3));
rchbd089ab2017-05-26 23:05:041515
1516 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1517
1518 CreateSession();
1519
1520 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1521 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261522 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rchbd089ab2017-05-26 23:05:041523 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1524 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1525}
1526
Kenichi Ishibashifd2d3e62022-03-01 22:54:051527TEST_P(QuicNetworkTransactionTest, RedirectMultipleLocations) {
1528 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1529 context_.params()->origins_to_force_quic_on.insert(
1530 HostPortPair::FromString("mail.example.org:443"));
1531
1532 MockQuicData mock_quic_data(version_);
1533 int packet_num = 1;
1534 if (VersionUsesHttp3(version_.transport_version)) {
1535 mock_quic_data.AddWrite(SYNCHRONOUS,
1536 ConstructInitialSettingsPacket(packet_num++));
1537 }
1538 mock_quic_data.AddWrite(
1539 SYNCHRONOUS,
1540 ConstructClientRequestHeadersPacket(
1541 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1542 true, GetRequestHeaders("GET", "https", "/")));
1543
1544 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("301");
1545 response_headers.AppendValueOrAddHeader("location", "https://example1.test");
1546 response_headers.AppendValueOrAddHeader("location", "https://example2.test");
1547
1548 if (quic::VersionUsesHttp3(version_.transport_version)) {
1549 const quic::QuicStreamId stream_id =
1550 GetNthClientInitiatedBidirectionalStreamId(0);
1551 const std::string response_data = server_maker_.QpackEncodeHeaders(
1552 stream_id, std::move(response_headers), nullptr);
1553 ASSERT_LT(response_data.size(), 1200u);
1554 mock_quic_data.AddRead(
1555 ASYNC, ConstructServerDataPacket(/*packet_number=*/1, stream_id,
1556 /*should_include_version=*/false,
1557 /*fin=*/true, response_data));
1558 } else {
1559 const quic::QuicStreamId stream_id =
1560 quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1561 spdy::SpdyHeadersIR headers_frame(
1562 GetNthClientInitiatedBidirectionalStreamId(0),
1563 std::move(response_headers));
1564 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1565 spdy::SpdySerializedFrame spdy_frame =
1566 response_framer.SerializeFrame(headers_frame);
1567 const std::string response_data =
1568 std::string(spdy_frame.data(), spdy_frame.size());
1569 ASSERT_LT(response_data.size(), 1200u);
1570 mock_quic_data.AddRead(
1571 ASYNC, ConstructServerDataPacket(/*packet_number=*/1, stream_id,
1572 /*should_include_version=*/false,
1573 /*fin=*/false, response_data));
1574 }
1575 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1576
1577 mock_quic_data.AddWrite(
1578 ASYNC, ConstructClientAckAndRstPacket(
1579 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1580 quic::QUIC_STREAM_CANCELLED,
1581 /*largest_received=*/1, /*smallest_received=*/1));
1582
1583 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1584
1585 CreateSession();
1586
1587 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1588 TestCompletionCallback callback;
1589 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
1590 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1591 ASSERT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1592}
1593
rcha2bd44b2016-07-02 00:42:551594TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Victor Vasilieva1e66d72019-12-05 17:55:381595 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551596
Ryan Hamilton9835e662018-08-02 05:36:271597 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551598
Ryan Hamiltonabad59e2019-06-06 04:02:591599 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231600 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251601 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231602 mock_quic_data.AddWrite(SYNCHRONOUS,
1603 ConstructInitialSettingsPacket(packet_num++));
1604 }
rch5cb522462017-04-25 20:18:361605 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231606 SYNCHRONOUS,
1607 ConstructClientRequestHeadersPacket(
1608 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1609 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431610 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331611 ASYNC, ConstructServerResponseHeadersPacket(
1612 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281613 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331614 mock_quic_data.AddRead(
1615 ASYNC, ConstructServerDataPacket(
1616 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521617 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231618 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341619 ConstructClientAckPacket(packet_num++, 2, 1));
rcha2bd44b2016-07-02 00:42:551620 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1621
1622 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1623
1624 CreateSession();
1625
1626 SendRequestAndExpectQuicResponse("hello!");
1627 EXPECT_TRUE(
1628 test_socket_performance_watcher_factory_.rtt_notification_received());
1629}
1630
David Schinazif832cb82019-11-08 22:25:271631// Regression test for https://crbug.com/695225
1632TEST_P(QuicNetworkTransactionTest, 408Response) {
Victor Vasilieva1e66d72019-12-05 17:55:381633 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
David Schinazif832cb82019-11-08 22:25:271634
1635 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1636
1637 MockQuicData mock_quic_data(version_);
1638 int packet_num = 1;
1639 if (VersionUsesHttp3(version_.transport_version)) {
1640 mock_quic_data.AddWrite(SYNCHRONOUS,
1641 ConstructInitialSettingsPacket(packet_num++));
1642 }
1643 mock_quic_data.AddWrite(
1644 SYNCHRONOUS,
1645 ConstructClientRequestHeadersPacket(
1646 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1647 true, GetRequestHeaders("GET", "https", "/")));
1648 mock_quic_data.AddRead(
1649 ASYNC, ConstructServerResponseHeadersPacket(
1650 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281651 GetResponseHeaders("408")));
David Schinazif832cb82019-11-08 22:25:271652 mock_quic_data.AddRead(
1653 ASYNC, ConstructServerDataPacket(
1654 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521655 ConstructDataFrame("hello!")));
David Schinazif832cb82019-11-08 22:25:271656 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341657 ConstructClientAckPacket(packet_num++, 2, 1));
David Schinazif832cb82019-11-08 22:25:271658 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1659
1660 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1661
1662 CreateSession();
1663
Kenichi Ishibashif8634ab2021-03-16 23:41:281664 SendRequestAndExpectQuicResponse("hello!", "HTTP/1.1 408");
David Schinazif832cb82019-11-08 22:25:271665}
1666
[email protected]cf3e3cd62014-02-05 16:16:161667TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411668 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561669 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:271670 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:561671 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161672
Ryan Hamiltonabad59e2019-06-06 04:02:591673 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231674 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251675 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231676 mock_quic_data.AddWrite(SYNCHRONOUS,
1677 ConstructInitialSettingsPacket(packet_num++));
1678 }
rch5cb522462017-04-25 20:18:361679 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231680 SYNCHRONOUS,
1681 ConstructClientRequestHeadersPacket(
1682 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1683 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431684 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331685 ASYNC, ConstructServerResponseHeadersPacket(
1686 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281687 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331688 mock_quic_data.AddRead(
1689 ASYNC, ConstructServerDataPacket(
1690 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521691 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231692 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341693 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:501694 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211695 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
[email protected]cf3e3cd62014-02-05 16:16:161696
rcha5399e02015-04-21 19:32:041697 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161698
tbansal0f56a39a2016-04-07 22:03:381699 EXPECT_FALSE(
1700 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161701 // There is no need to set up an alternate protocol job, because
1702 // no attempt will be made to speak to the proxy over TCP.
1703
rch9ae5b3b2016-02-11 00:36:291704 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161705 CreateSession();
1706
bnc62a44f022015-04-02 15:59:411707 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381708 EXPECT_TRUE(
1709 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161710}
1711
bnc313ba9c2015-06-11 15:42:311712// Regression test for https://crbug.com/492458. Test that for an HTTP
1713// connection through a QUIC proxy, the certificate exhibited by the proxy is
1714// checked against the proxy hostname, not the origin hostname.
1715TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291716 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311717 const std::string proxy_host = "www.example.org";
1718
mmenke6ddfbea2017-05-31 21:48:411719 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561720 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:271721 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:561722 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311723
Zhongyi Shi1c022d22020-03-20 19:00:161724 client_maker_->set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591725 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231726 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251727 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231728 mock_quic_data.AddWrite(SYNCHRONOUS,
1729 ConstructInitialSettingsPacket(packet_num++));
1730 }
rch5cb522462017-04-25 20:18:361731 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231732 SYNCHRONOUS,
1733 ConstructClientRequestHeadersPacket(
1734 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1735 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431736 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331737 ASYNC, ConstructServerResponseHeadersPacket(
1738 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281739 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331740 mock_quic_data.AddRead(
1741 ASYNC, ConstructServerDataPacket(
1742 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521743 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231744 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341745 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:501746 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211747 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc313ba9c2015-06-11 15:42:311748 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1749
1750 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291751 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311752 ASSERT_TRUE(cert.get());
1753 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241754 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1755 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311756 ProofVerifyDetailsChromium verify_details;
1757 verify_details.cert_verify_result.verified_cert = cert;
1758 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561759 ProofVerifyDetailsChromium verify_details2;
1760 verify_details2.cert_verify_result.verified_cert = cert;
1761 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311762
1763 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091764 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321765 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271766 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311767 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1768}
1769
rchbe69cb902016-02-11 01:10:481770TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Victor Vasilieva1e66d72019-12-05 17:55:381771 context_.params()->allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481772 HostPortPair origin("www.example.org", 443);
1773 HostPortPair alternative("mail.example.org", 443);
1774
1775 base::FilePath certs_dir = GetTestCertsDirectory();
1776 scoped_refptr<X509Certificate> cert(
1777 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1778 ASSERT_TRUE(cert.get());
1779 // TODO(rch): the connection should be "to" the origin, so if the cert is
1780 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241781 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1782 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481783 ProofVerifyDetailsChromium verify_details;
1784 verify_details.cert_verify_result.verified_cert = cert;
1785 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1786
Zhongyi Shi1c022d22020-03-20 19:00:161787 client_maker_->set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591788 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021789
Renjie Tangaadb84b2019-08-31 01:00:231790 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251791 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231792 mock_quic_data.AddWrite(SYNCHRONOUS,
1793 ConstructInitialSettingsPacket(packet_num++));
1794 }
rch5cb522462017-04-25 20:18:361795 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231796 SYNCHRONOUS,
1797 ConstructClientRequestHeadersPacket(
1798 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1799 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431800 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331801 ASYNC, ConstructServerResponseHeadersPacket(
1802 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281803 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331804 mock_quic_data.AddRead(
1805 ASYNC, ConstructServerDataPacket(
1806 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521807 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231808 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341809 ConstructClientAckPacket(packet_num++, 2, 1));
rchbe69cb902016-02-11 01:10:481810 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211811 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rchbe69cb902016-02-11 01:10:481812 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1813
1814 request_.url = GURL("https://" + origin.host());
1815 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271816 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091817 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321818 CreateSession();
rchbe69cb902016-02-11 01:10:481819
1820 SendRequestAndExpectQuicResponse("hello!");
1821}
1822
zhongyief3f4ce52017-07-05 23:53:281823TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
David Schinazi84c58bb2020-06-04 20:14:331824 quic::ParsedQuicVersion unsupported_version =
1825 quic::ParsedQuicVersion::Unsupported();
Bence Békyb89104962020-01-24 00:05:171826 // Add support for another QUIC version besides |version_|. Also find an
zhongyief3f4ce52017-07-05 23:53:281827 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561828 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281829 if (version == version_)
1830 continue;
1831 if (supported_versions_.size() != 2) {
1832 supported_versions_.push_back(version);
1833 continue;
1834 }
1835 unsupported_version = version;
1836 break;
1837 }
Bence Békyb89104962020-01-24 00:05:171838 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:331839 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), unsupported_version);
zhongyief3f4ce52017-07-05 23:53:281840
1841 // Set up alternative service to use QUIC with a version that is not
1842 // supported.
1843 url::SchemeHostPort server(request_.url);
1844 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1845 443);
Peter Kastinge5a38ed2021-10-02 03:06:351846 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:491847 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071848 server, NetworkIsolationKey(), alternative_service, expiration,
1849 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281850
1851 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491852 http_server_properties_->GetAlternativeServiceInfos(
1853 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281854 EXPECT_EQ(1u, alt_svc_info_vector.size());
1855 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1856 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1857 EXPECT_EQ(unsupported_version,
1858 alt_svc_info_vector[0].advertised_versions()[0]);
1859
1860 // First request should still be sent via TCP as the QUIC version advertised
1861 // in the stored AlternativeService is not supported by the client. However,
1862 // the response from the server will advertise new Alt-Svc with supported
1863 // versions.
David Schinazifbd4c432020-04-07 19:23:551864 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyief3f4ce52017-07-05 23:53:281865 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:171866 MockRead("HTTP/1.1 200 OK\r\n"),
1867 MockRead(altsvc_header.c_str()),
1868 MockRead("\r\n"),
zhongyief3f4ce52017-07-05 23:53:281869 MockRead("hello world"),
1870 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1871 MockRead(ASYNC, OK)};
1872
Ryan Sleevib8d7ea02018-05-07 20:01:011873 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281874 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081875 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281876 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1877
1878 // Second request should be sent via QUIC as a new list of verions supported
1879 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591880 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231881 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251882 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231883 mock_quic_data.AddWrite(SYNCHRONOUS,
1884 ConstructInitialSettingsPacket(packet_num++));
1885 }
zhongyief3f4ce52017-07-05 23:53:281886 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231887 SYNCHRONOUS,
1888 ConstructClientRequestHeadersPacket(
1889 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1890 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431891 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331892 ASYNC, ConstructServerResponseHeadersPacket(
1893 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281894 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331895 mock_quic_data.AddRead(
1896 ASYNC, ConstructServerDataPacket(
1897 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521898 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231899 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341900 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyief3f4ce52017-07-05 23:53:281901 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211902 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyief3f4ce52017-07-05 23:53:281903
1904 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1905
1906 AddHangingNonAlternateProtocolSocketData();
1907
1908 CreateSession(supported_versions_);
1909
1910 SendRequestAndExpectHttpResponse("hello world");
1911 SendRequestAndExpectQuicResponse("hello!");
1912
1913 // Check alternative service list is updated with new versions.
1914 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491915 session_->http_server_properties()->GetAlternativeServiceInfos(
1916 server, NetworkIsolationKey());
Victor Vasiliev22dd3f212022-02-11 21:57:291917 VerifyQuicVersionsInAlternativeServices(alt_svc_info_vector,
1918 supported_versions_);
zhongyief3f4ce52017-07-05 23:53:281919}
1920
bncaccd4962017-04-06 21:00:261921// Regression test for https://crbug.com/546991.
1922// The server might not be able to serve a request on an alternative connection,
1923// and might send a 421 Misdirected Request response status to indicate this.
1924// HttpNetworkTransaction should reset the request and retry without using
1925// alternative services.
1926TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1927 // Set up alternative service to use QUIC.
1928 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1929 // that overrides |enable_alternative_services|.
1930 url::SchemeHostPort server(request_.url);
1931 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1932 443);
Peter Kastinge5a38ed2021-10-02 03:06:351933 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:491934 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071935 server, NetworkIsolationKey(), alternative_service, expiration,
1936 supported_versions_);
bncaccd4962017-04-06 21:00:261937
davidbena4449722017-05-05 23:30:531938 // First try: The alternative job uses QUIC and reports an HTTP 421
1939 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1940 // paused at Connect(), so it will never exit the socket pool. This ensures
1941 // that the alternate job always wins the race and keeps whether the
1942 // |http_data| exits the socket pool before the main job is aborted
1943 // deterministic. The first main job gets aborted without the socket pool ever
1944 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591945 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231946 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251947 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231948 mock_quic_data.AddWrite(SYNCHRONOUS,
1949 ConstructInitialSettingsPacket(packet_num++));
1950 }
rch5cb522462017-04-25 20:18:361951 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231952 SYNCHRONOUS,
1953 ConstructClientRequestHeadersPacket(
1954 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1955 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331956 mock_quic_data.AddRead(
1957 ASYNC, ConstructServerResponseHeadersPacket(
1958 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021959 GetResponseHeaders("421")));
David Schinazi395918c2021-02-05 18:56:211960 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncaccd4962017-04-06 21:00:261961 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1962
davidbena4449722017-05-05 23:30:531963 // Second try: The main job uses TCP, and there is no alternate job. Once the
1964 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1965 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261966 // Note that if there was an alternative QUIC Job created for the second try,
1967 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1968 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531969 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1970 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1971 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1972 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1973 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1974 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011975 reads, writes);
bncaccd4962017-04-06 21:00:261976 socket_factory_.AddSocketDataProvider(&http_data);
1977 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1978
bncaccd4962017-04-06 21:00:261979 CreateSession();
1980 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531981
1982 // Run until |mock_quic_data| has failed and |http_data| has paused.
1983 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261984 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
davidbena4449722017-05-05 23:30:531985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1986 base::RunLoop().RunUntilIdle();
1987
1988 // |mock_quic_data| must have run to completion.
1989 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1990 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1991
1992 // Now that the QUIC data has been consumed, unblock |http_data|.
1993 http_data.socket()->OnConnectComplete(MockConnect());
1994
1995 // The retry logic must hide the 421 status. The transaction succeeds on
1996 // |http_data|.
1997 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261998 CheckWasHttpResponse(&trans);
1999 CheckResponsePort(&trans, 443);
2000 CheckResponseData(&trans, "hello!");
2001}
2002
[email protected]1e960032013-12-20 19:00:202003TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Victor Vasilieva1e66d72019-12-05 17:55:382004 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:572005 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:302006
Ryan Hamiltonabad59e2019-06-06 04:02:592007 MockQuicData mock_quic_data1(version_);
Victor Vasiliev7da08172019-10-14 06:04:252008 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232009 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:402010 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Zhongyi Shi1c022d22020-03-20 19:00:162011 client_maker_->Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:592012 MockQuicData mock_quic_data2(version_);
Victor Vasiliev7da08172019-10-14 06:04:252013 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232014 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:302015 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:402016 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:432017 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:402018
2019 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
2020 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:302021
2022 CreateSession();
2023
tbansal0f56a39a2016-04-07 22:03:382024 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:402025 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:162026 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:402027 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262028 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:012029 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2030 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:382031 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:532032
2033 NetErrorDetails details;
2034 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522035 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:402036 }
[email protected]cebe3282013-05-22 23:49:302037}
2038
tbansalc8a94ea2015-11-02 23:58:512039TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
2040 // Attempt to "force" quic on 443, which will not be honored.
Victor Vasilieva1e66d72019-12-05 17:55:382041 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:572042 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:512043
2044 MockRead http_reads[] = {
2045 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
2046 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2047 MockRead(ASYNC, OK)};
2048
Ryan Sleevib8d7ea02018-05-07 20:01:012049 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:512050 socket_factory_.AddSocketDataProvider(&data);
2051 SSLSocketDataProvider ssl(ASYNC, OK);
2052 socket_factory_.AddSSLSocketDataProvider(&ssl);
2053
2054 CreateSession();
2055
2056 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:382057 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:512058}
2059
bncc958faa2015-07-31 18:14:522060TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:352061 if (version_.AlpnDeferToRFCv1()) {
2062 // These versions currently do not support Alt-Svc.
2063 return;
2064 }
bncc958faa2015-07-31 18:14:522065 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452066 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:562067 MockRead("hello world"),
bncc958faa2015-07-31 18:14:522068 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2069 MockRead(ASYNC, OK)};
2070
Ryan Sleevib8d7ea02018-05-07 20:01:012071 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:522072 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082073 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:562074 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:522075
Ryan Hamiltonabad59e2019-06-06 04:02:592076 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232077 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252078 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232079 mock_quic_data.AddWrite(SYNCHRONOUS,
2080 ConstructInitialSettingsPacket(packet_num++));
2081 }
rch5cb522462017-04-25 20:18:362082 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232083 SYNCHRONOUS,
2084 ConstructClientRequestHeadersPacket(
2085 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2086 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432087 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332088 ASYNC, ConstructServerResponseHeadersPacket(
2089 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282090 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332091 mock_quic_data.AddRead(
2092 ASYNC, ConstructServerDataPacket(
2093 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522094 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232095 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342096 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:522097 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212098 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:522099
2100 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2101
rtennetib8e80fb2016-05-16 00:12:092102 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322103 CreateSession();
bncc958faa2015-07-31 18:14:522104
2105 SendRequestAndExpectHttpResponse("hello world");
2106 SendRequestAndExpectQuicResponse("hello!");
2107}
2108
Ryan Hamilton64f21d52019-08-31 07:10:512109TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:352110 if (version_.AlpnDeferToRFCv1()) {
2111 // These versions currently do not support Alt-Svc.
2112 return;
2113 }
Ryan Hamilton64f21d52019-08-31 07:10:512114 std::string alt_svc_header =
2115 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
2116 MockRead http_reads[] = {
2117 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
2118 MockRead("hello world"),
2119 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2120 MockRead(ASYNC, OK)};
2121
2122 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2123 socket_factory_.AddSocketDataProvider(&http_data);
2124 AddCertificate(&ssl_data_);
2125 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2126
2127 MockQuicData mock_quic_data(version_);
2128 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252129 if (VersionUsesHttp3(version_.transport_version)) {
Ryan Hamilton64f21d52019-08-31 07:10:512130 mock_quic_data.AddWrite(SYNCHRONOUS,
2131 ConstructInitialSettingsPacket(packet_num++));
2132 }
2133 mock_quic_data.AddWrite(
2134 SYNCHRONOUS,
2135 ConstructClientRequestHeadersPacket(
2136 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2137 true, GetRequestHeaders("GET", "https", "/")));
2138 mock_quic_data.AddRead(
2139 ASYNC, ConstructServerResponseHeadersPacket(
2140 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282141 GetResponseHeaders("200")));
Ryan Hamilton64f21d52019-08-31 07:10:512142 mock_quic_data.AddRead(
2143 ASYNC, ConstructServerDataPacket(
2144 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522145 ConstructDataFrame("hello!")));
Ryan Hamilton64f21d52019-08-31 07:10:512146 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342147 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton64f21d52019-08-31 07:10:512148 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212149 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamilton64f21d52019-08-31 07:10:512150
2151 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2152
2153 AddHangingNonAlternateProtocolSocketData();
2154 CreateSession();
2155
2156 SendRequestAndExpectHttpResponse("hello world");
2157 SendRequestAndExpectQuicResponse("hello!");
2158}
2159
Matt Menke3233d8f22019-08-20 21:01:492160// Much like above, but makes sure NetworkIsolationKey is respected.
2161TEST_P(QuicNetworkTransactionTest,
2162 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:352163 if (version_.AlpnDeferToRFCv1()) {
2164 // These versions currently do not support Alt-Svc.
2165 return;
2166 }
Matt Menke3233d8f22019-08-20 21:01:492167 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:052168 feature_list.InitWithFeatures(
2169 // enabled_features
2170 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2171 features::kPartitionConnectionsByNetworkIsolationKey},
2172 // disabled_features
2173 {});
Matt Menke3233d8f22019-08-20 21:01:492174 // Since HttpServerProperties caches the feature value, have to create a new
2175 // one.
2176 http_server_properties_ = std::make_unique<HttpServerProperties>();
2177
Matt Menke4807a9a2020-11-21 00:14:412178 const SchemefulSite kSite1(GURL("https://foo.test/"));
2179 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
2180 const SchemefulSite kSite2(GURL("https://bar.test/"));
2181 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menke3233d8f22019-08-20 21:01:492182
2183 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452184 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Matt Menke3233d8f22019-08-20 21:01:492185 MockRead("hello world"),
2186 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2187 MockRead(ASYNC, OK)};
2188
2189 AddCertificate(&ssl_data_);
2190
2191 // Request with empty NetworkIsolationKey.
2192 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2193 socket_factory_.AddSocketDataProvider(&http_data1);
2194 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2195
2196 // First request with kNetworkIsolationKey1.
2197 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2198 socket_factory_.AddSocketDataProvider(&http_data2);
2199 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2200
2201 // Request with kNetworkIsolationKey2.
2202 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2203 socket_factory_.AddSocketDataProvider(&http_data3);
2204 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2205
2206 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2207 // alternative service infrmation has been received in this context before.
2208 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232209 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252210 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232211 mock_quic_data.AddWrite(SYNCHRONOUS,
2212 ConstructInitialSettingsPacket(packet_num++));
2213 }
Matt Menke3233d8f22019-08-20 21:01:492214 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232215 SYNCHRONOUS,
2216 ConstructClientRequestHeadersPacket(
2217 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2218 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492219 mock_quic_data.AddRead(
2220 ASYNC, ConstructServerResponseHeadersPacket(
2221 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282222 GetResponseHeaders("200")));
Matt Menke3233d8f22019-08-20 21:01:492223 mock_quic_data.AddRead(
2224 ASYNC, ConstructServerDataPacket(
2225 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522226 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232227 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342228 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menke3233d8f22019-08-20 21:01:492229 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212230 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Matt Menke3233d8f22019-08-20 21:01:492231
2232 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2233
2234 AddHangingNonAlternateProtocolSocketData();
2235 CreateSession();
2236
2237 // This is first so that the test fails if alternative service info is
2238 // written with the right NetworkIsolationKey, but always queried with an
2239 // empty one.
2240 request_.network_isolation_key = NetworkIsolationKey();
2241 SendRequestAndExpectHttpResponse("hello world");
2242 request_.network_isolation_key = kNetworkIsolationKey1;
2243 SendRequestAndExpectHttpResponse("hello world");
2244 request_.network_isolation_key = kNetworkIsolationKey2;
2245 SendRequestAndExpectHttpResponse("hello world");
2246
2247 // Only use QUIC when using a NetworkIsolationKey which has been used when
2248 // alternative service information was received.
2249 request_.network_isolation_key = kNetworkIsolationKey1;
2250 SendRequestAndExpectQuicResponse("hello!");
2251}
2252
zhongyia00ca012017-07-06 23:36:392253TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
Ryan Hamiltona51800a2022-02-12 19:34:352254 if (version_.AlpnDeferToRFCv1()) {
2255 // These versions currently do not support Alt-Svc.
2256 return;
2257 }
Victor Vasiliev22dd3f212022-02-11 21:57:292258 // Both client and server supports two QUIC versions:
2259 // Client supports |supported_versions_[0]| and |supported_versions_[1]|,
2260 // server supports |version_| and |advertised_version_2|.
2261 // Only |version_| (same as |supported_versions_[0]|) is supported by both.
zhongyia00ca012017-07-06 23:36:392262 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2263 // PacketMakers are using |version_|.
2264
Victor Vasiliev22dd3f212022-02-11 21:57:292265 // Compare ALPN strings instead of ParsedQuicVersions because QUIC v1 and v2
2266 // have the same ALPN string.
2267 ASSERT_EQ(1u, supported_versions_.size());
2268 ASSERT_EQ(supported_versions_[0], version_);
David Schinazi84c58bb2020-06-04 20:14:332269 quic::ParsedQuicVersion advertised_version_2 =
2270 quic::ParsedQuicVersion::Unsupported();
Nick Harper23290b82019-05-02 00:02:562271 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Victor Vasiliev22dd3f212022-02-11 21:57:292272 if (quic::AlpnForVersion(version) == quic::AlpnForVersion(version_)) {
zhongyia00ca012017-07-06 23:36:392273 continue;
Victor Vasiliev22dd3f212022-02-11 21:57:292274 }
zhongyia00ca012017-07-06 23:36:392275 if (supported_versions_.size() != 2) {
2276 supported_versions_.push_back(version);
2277 continue;
2278 }
Victor Vasiliev22dd3f212022-02-11 21:57:292279 if (supported_versions_.size() == 2 &&
2280 quic::AlpnForVersion(supported_versions_[1]) ==
2281 quic::AlpnForVersion(version)) {
2282 continue;
2283 }
zhongyia00ca012017-07-06 23:36:392284 advertised_version_2 = version;
2285 break;
2286 }
Bence Békyb89104962020-01-24 00:05:172287 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:332288 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), advertised_version_2);
zhongyia00ca012017-07-06 23:36:392289
Bence Békyb89104962020-01-24 00:05:172290 std::string QuicAltSvcWithVersionHeader =
2291 base::StringPrintf("Alt-Svc: %s=\":443\", %s=\":443\"\r\n\r\n",
2292 quic::AlpnForVersion(advertised_version_2).c_str(),
2293 quic::AlpnForVersion(version_).c_str());
zhongyia00ca012017-07-06 23:36:392294
2295 MockRead http_reads[] = {
2296 MockRead("HTTP/1.1 200 OK\r\n"),
2297 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2298 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2299 MockRead(ASYNC, OK)};
2300
Ryan Sleevib8d7ea02018-05-07 20:01:012301 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392302 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082303 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392304 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2305
Ryan Hamiltonabad59e2019-06-06 04:02:592306 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232307 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252308 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232309 mock_quic_data.AddWrite(SYNCHRONOUS,
2310 ConstructInitialSettingsPacket(packet_num++));
2311 }
zhongyia00ca012017-07-06 23:36:392312 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232313 SYNCHRONOUS,
2314 ConstructClientRequestHeadersPacket(
2315 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2316 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432317 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332318 ASYNC, ConstructServerResponseHeadersPacket(
2319 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282320 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332321 mock_quic_data.AddRead(
2322 ASYNC, ConstructServerDataPacket(
2323 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522324 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232325 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342326 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392327 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212328 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyia00ca012017-07-06 23:36:392329
2330 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2331
2332 AddHangingNonAlternateProtocolSocketData();
2333 CreateSession(supported_versions_);
2334
2335 SendRequestAndExpectHttpResponse("hello world");
2336 SendRequestAndExpectQuicResponse("hello!");
2337}
2338
Zhongyi Shi1c022d22020-03-20 19:00:162339TEST_P(QuicNetworkTransactionTest,
2340 PickQuicVersionWhenMultipleVersionsAreSupported) {
2341 // Client and server both support more than one QUIC_VERSION.
2342 // Client prefers |version_|, and then common_version_2.
2343 // Server prefers common_version_2, and then |version_|.
David Schinazifbd4c432020-04-07 19:23:552344 // We should honor the server's preference.
Zhongyi Shi1c022d22020-03-20 19:00:162345 // The picked version is verified via checking the version used by the
2346 // TestPacketMakers and the response.
Bence Békyb89104962020-01-24 00:05:172347
Zhongyi Shi1c022d22020-03-20 19:00:162348 // Find an alternative commonly supported version other than |version_|.
David Schinazi84c58bb2020-06-04 20:14:332349 quic::ParsedQuicVersion common_version_2 =
2350 quic::ParsedQuicVersion::Unsupported();
2351 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Ryan Hamiltona51800a2022-02-12 19:34:352352 if (version != version_ && !version.AlpnDeferToRFCv1()) {
Zhongyi Shi1c022d22020-03-20 19:00:162353 common_version_2 = version;
2354 break;
2355 }
zhongyia00ca012017-07-06 23:36:392356 }
David Schinazi84c58bb2020-06-04 20:14:332357 ASSERT_NE(common_version_2, quic::ParsedQuicVersion::Unsupported());
zhongyia00ca012017-07-06 23:36:392358
Zhongyi Shi1c022d22020-03-20 19:00:162359 // Setting up client's preference list: {|version_|, |common_version_2|}.
2360 supported_versions_.clear();
2361 supported_versions_.push_back(version_);
2362 supported_versions_.push_back(common_version_2);
zhongyia00ca012017-07-06 23:36:392363
Zhongyi Shi1c022d22020-03-20 19:00:162364 // Setting up server's Alt-Svc header in the following preference order:
2365 // |common_version_2|, |version_|.
2366 std::string QuicAltSvcWithVersionHeader;
David Schinazi84c58bb2020-06-04 20:14:332367 quic::ParsedQuicVersion picked_version =
2368 quic::ParsedQuicVersion::Unsupported();
2369 QuicAltSvcWithVersionHeader =
2370 "Alt-Svc: " + quic::AlpnForVersion(common_version_2) +
2371 "=\":443\"; ma=3600, " + quic::AlpnForVersion(version_) +
2372 "=\":443\"; ma=3600\r\n\r\n";
2373 picked_version = common_version_2; // Use server's preference.
zhongyia00ca012017-07-06 23:36:392374
2375 MockRead http_reads[] = {
2376 MockRead("HTTP/1.1 200 OK\r\n"),
2377 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2378 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2379 MockRead(ASYNC, OK)};
2380
Ryan Sleevib8d7ea02018-05-07 20:01:012381 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392382 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082383 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392384 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2385
Zhongyi Shi1c022d22020-03-20 19:00:162386 MockQuicData mock_quic_data(picked_version);
2387
2388 // Reset QuicTestPacket makers as the version picked may not be |version_|.
Renjie Tang6ff9a9b2021-02-03 22:11:092389 client_maker_ = std::make_unique<QuicTestPacketMaker>(
Zhongyi Shi1c022d22020-03-20 19:00:162390 picked_version,
2391 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2392 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Renjie Tang6ff9a9b2021-02-03 22:11:092393 client_headers_include_h2_stream_dependency_);
Zhongyi Shi1c022d22020-03-20 19:00:162394 QuicTestPacketMaker server_maker(
2395 picked_version,
2396 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2397 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
2398 false);
2399
Renjie Tangaadb84b2019-08-31 01:00:232400 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:162401 if (VersionUsesHttp3(picked_version.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232402 mock_quic_data.AddWrite(SYNCHRONOUS,
2403 ConstructInitialSettingsPacket(packet_num++));
2404 }
Zhongyi Shi1c022d22020-03-20 19:00:162405
2406 quic::QuicStreamId client_stream_0 =
2407 quic::test::GetNthClientInitiatedBidirectionalStreamId(
2408 picked_version.transport_version, 0);
2409 mock_quic_data.AddWrite(SYNCHRONOUS,
2410 ConstructClientRequestHeadersPacket(
2411 packet_num++, client_stream_0, true, true,
2412 GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashif8634ab2021-03-16 23:41:282413 mock_quic_data.AddRead(ASYNC,
2414 server_maker.MakeResponseHeadersPacket(
2415 1, client_stream_0, false, false,
2416 server_maker.GetResponseHeaders("200"), nullptr));
Fan Yang32c5a112018-12-10 20:06:332417 mock_quic_data.AddRead(
Bence Béky319388a882020-09-23 18:42:522418 ASYNC, server_maker.MakeDataPacket(
2419 2, client_stream_0, false, true,
2420 ConstructDataFrameForVersion("hello!", picked_version)));
Renjie Tangaadb84b2019-08-31 01:00:232421 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342422 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392423 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212424 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyia00ca012017-07-06 23:36:392425
2426 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2427
2428 AddHangingNonAlternateProtocolSocketData();
2429 CreateSession(supported_versions_);
2430
2431 SendRequestAndExpectHttpResponse("hello world");
Zhongyi Shi1c022d22020-03-20 19:00:162432 SendRequestAndExpectQuicResponseMaybeFromProxy(
Kenichi Ishibashif8634ab2021-03-16 23:41:282433 "hello!", false, 443, "HTTP/1.1 200", picked_version);
zhongyia00ca012017-07-06 23:36:392434}
2435
zhongyi3d4a55e72016-04-22 20:36:462436TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
Ryan Hamiltona51800a2022-02-12 19:34:352437 if (version_.AlpnDeferToRFCv1()) {
2438 // These versions currently do not support Alt-Svc.
2439 return;
2440 }
Ryan Hamiltona2dcbae2022-02-09 19:02:452441 std::string alt_svc_header = base::StrCat(
2442 {"Alt-Svc: ",
2443 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.com", 443), ",",
2444 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
zhongyi3d4a55e72016-04-22 20:36:462445 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452446 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
zhongyi3d4a55e72016-04-22 20:36:462447 MockRead("hello world"),
2448 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2449 MockRead(ASYNC, OK)};
2450
Ryan Sleevib8d7ea02018-05-07 20:01:012451 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462452 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082453 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462454 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2455
2456 CreateSession();
bncb26024382016-06-29 02:39:452457 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462458 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452459 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462460 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402461 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462462 session_->http_server_properties();
2463 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2464 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2465 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462466 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492467 2u, http_server_properties
2468 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2469 .size());
bncb26024382016-06-29 02:39:452470 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492471 http_server_properties
2472 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2473 .empty());
zhongyi3d4a55e72016-04-22 20:36:462474}
2475
2476TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
Ryan Hamiltona51800a2022-02-12 19:34:352477 if (version_.AlpnDeferToRFCv1()) {
2478 // These versions currently do not support Alt-Svc.
2479 return;
2480 }
Ryan Hamiltona2dcbae2022-02-09 19:02:452481 std::string alt_svc_header = base::StrCat(
2482 {"Alt-Svc: ",
2483 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.com", 443), ",",
2484 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
zhongyi3d4a55e72016-04-22 20:36:462485 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452486 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
zhongyi3d4a55e72016-04-22 20:36:462487 MockRead("hello world"),
2488 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2489 MockRead(ASYNC, OK)};
2490
Ryan Sleevib8d7ea02018-05-07 20:01:012491 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082492 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462493
2494 socket_factory_.AddSocketDataProvider(&http_data);
2495 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2496 socket_factory_.AddSocketDataProvider(&http_data);
2497 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2498
2499 CreateSession();
2500
2501 // Send https request and set alternative services if response header
2502 // advertises alternative service for mail.example.org.
2503 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402504 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462505 session_->http_server_properties();
2506
2507 const url::SchemeHostPort https_server(request_.url);
2508 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342509 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492510 2u, http_server_properties
2511 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2512 .size());
zhongyi3d4a55e72016-04-22 20:36:462513
2514 // Send http request to the same origin but with diffrent scheme, should not
2515 // use QUIC.
2516 request_.url = GURL("http://mail.example.org:443");
2517 SendRequestAndExpectHttpResponse("hello world");
2518}
2519
zhongyie537a002017-06-27 16:48:212520TEST_P(QuicNetworkTransactionTest,
2521 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442522 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562523 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Bence Békyb89104962020-01-24 00:05:172524 if (version != version_) {
2525 supported_versions_.push_back(version);
2526 break;
2527 }
zhongyi86838d52017-06-30 01:19:442528 }
2529
David Schinazifbd4c432020-04-07 19:23:552530 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyie537a002017-06-27 16:48:212531 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:172532 MockRead("HTTP/1.1 200 OK\r\n"),
2533 MockRead(altsvc_header.c_str()),
2534 MockRead("\r\n"),
zhongyie537a002017-06-27 16:48:212535 MockRead("hello world"),
2536 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2537 MockRead(ASYNC, OK)};
2538
Ryan Sleevib8d7ea02018-05-07 20:01:012539 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212540 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082541 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212542 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2543
Ryan Hamiltonabad59e2019-06-06 04:02:592544 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232545 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252546 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232547 mock_quic_data.AddWrite(SYNCHRONOUS,
2548 ConstructInitialSettingsPacket(packet_num++));
2549 }
zhongyie537a002017-06-27 16:48:212550 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232551 SYNCHRONOUS,
2552 ConstructClientRequestHeadersPacket(
2553 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2554 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432555 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332556 ASYNC, ConstructServerResponseHeadersPacket(
2557 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282558 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332559 mock_quic_data.AddRead(
2560 ASYNC, ConstructServerDataPacket(
2561 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522562 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232563 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342564 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyie537a002017-06-27 16:48:212565 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212566 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyie537a002017-06-27 16:48:212567
2568 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2569
2570 AddHangingNonAlternateProtocolSocketData();
2571
zhongyi86838d52017-06-30 01:19:442572 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212573
2574 SendRequestAndExpectHttpResponse("hello world");
2575 SendRequestAndExpectQuicResponse("hello!");
2576
Bence Békyb89104962020-01-24 00:05:172577 // Alt-Svc header contains all possible versions, so alternative services
2578 // should contain all of |supported_versions_|.
zhongyie537a002017-06-27 16:48:212579 const url::SchemeHostPort https_server(request_.url);
2580 const AlternativeServiceInfoVector alt_svc_info_vector =
2581 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492582 https_server, NetworkIsolationKey());
Victor Vasiliev22dd3f212022-02-11 21:57:292583 VerifyQuicVersionsInAlternativeServices(alt_svc_info_vector,
2584 supported_versions_);
zhongyie537a002017-06-27 16:48:212585}
2586
danzh3134c2562016-08-12 14:07:522587TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Ryan Hamiltona51800a2022-02-12 19:34:352588 if (version_.AlpnDeferToRFCv1()) {
2589 // These versions currently do not support Alt-Svc.
2590 return;
2591 }
Nick Harper23290b82019-05-02 00:02:562592 std::string altsvc_header = base::StringPrintf(
Bence Békyb89104962020-01-24 00:05:172593 "Alt-Svc: %s=\":443\"\r\n\r\n", quic::AlpnForVersion(version_).c_str());
bnc8be55ebb2015-10-30 14:12:072594 MockRead http_reads[] = {
2595 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2596 MockRead("hello world"),
2597 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2598 MockRead(ASYNC, OK)};
2599
Ryan Sleevib8d7ea02018-05-07 20:01:012600 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072601 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082602 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072603 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2604
Ryan Hamiltonabad59e2019-06-06 04:02:592605 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232606 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252607 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232608 mock_quic_data.AddWrite(SYNCHRONOUS,
2609 ConstructInitialSettingsPacket(packet_num++));
2610 }
rch5cb522462017-04-25 20:18:362611 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232612 SYNCHRONOUS,
2613 ConstructClientRequestHeadersPacket(
2614 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2615 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432616 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332617 ASYNC, ConstructServerResponseHeadersPacket(
2618 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282619 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332620 mock_quic_data.AddRead(
2621 ASYNC, ConstructServerDataPacket(
2622 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522623 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232624 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342625 ConstructClientAckPacket(packet_num++, 2, 1));
bnc8be55ebb2015-10-30 14:12:072626 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212627 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc8be55ebb2015-10-30 14:12:072628
2629 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2630
rtennetib8e80fb2016-05-16 00:12:092631 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322632 CreateSession();
bnc8be55ebb2015-10-30 14:12:072633
2634 SendRequestAndExpectHttpResponse("hello world");
2635 SendRequestAndExpectQuicResponse("hello!");
2636}
2637
zhongyi6b5a3892016-03-12 04:46:202638TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harperc6cb7a612020-02-24 20:03:322639 if (version_.HasIetfQuicFrames()) {
Renjie Tangba21e032019-09-27 21:52:282640 // GoAway is not available under version 99
Frank Kastenholz6e4c5382018-06-21 23:00:092641 return;
2642 }
Ryan Hamiltonabad59e2019-06-06 04:02:592643 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232644 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252645 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232646 mock_quic_data.AddWrite(SYNCHRONOUS,
2647 ConstructInitialSettingsPacket(packet_num++));
2648 }
rch5cb522462017-04-25 20:18:362649 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232650 SYNCHRONOUS,
2651 ConstructClientRequestHeadersPacket(
2652 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2653 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332654 mock_quic_data.AddRead(
2655 ASYNC, ConstructServerResponseHeadersPacket(
2656 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282657 GetResponseHeaders("200")));
zhongyi6b5a3892016-03-12 04:46:202658 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522659 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432660 mock_quic_data.AddRead(SYNCHRONOUS,
2661 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522662 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432663 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232664 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342665 ConstructClientAckPacket(packet_num++, 2, 1));
Fan Yang32c5a112018-12-10 20:06:332666 mock_quic_data.AddRead(
2667 SYNCHRONOUS, ConstructServerDataPacket(
2668 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:522669 true, ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232670 mock_quic_data.AddWrite(
2671 SYNCHRONOUS,
2672 ConstructClientAckAndRstPacket(
2673 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:342674 quic::QUIC_STREAM_CANCELLED, 3, 3));
zhongyi6b5a3892016-03-12 04:46:202675 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212676 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi6b5a3892016-03-12 04:46:202677
2678 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2679
2680 // The non-alternate protocol job needs to hang in order to guarantee that
2681 // the alternate-protocol job will "win".
2682 AddHangingNonAlternateProtocolSocketData();
2683
2684 // In order for a new QUIC session to be established via alternate-protocol
2685 // without racing an HTTP connection, we need the host resolution to happen
2686 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2687 // connection to the the server, in this test we require confirmation
2688 // before encrypting so the HTTP job will still start.
2689 host_resolver_.set_synchronous_mode(true);
2690 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2691 "");
zhongyi6b5a3892016-03-12 04:46:202692
2693 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432694 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2695 false);
Ryan Hamilton9835e662018-08-02 05:36:272696 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202697
bnc691fda62016-08-12 00:43:162698 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202699 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262700 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:012701 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202702
Fan Yang3673cc72020-02-07 14:49:282703 crypto_client_stream_factory_.last_stream()
2704 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:012705 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202706
2707 // Check whether this transaction is correctly marked as received a go-away
2708 // because of migrating port.
2709 NetErrorDetails details;
2710 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162711 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202712 EXPECT_TRUE(details.quic_port_migration_detected);
2713}
2714
Zhongyi Shia6b68d112018-09-24 07:49:032715// This test verifies that a new QUIC connection will be attempted on the
2716// alternate network if the original QUIC connection fails with idle timeout
2717// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2718// alternate network as well, QUIC is marked as broken and the brokenness will
2719// not expire when default network changes.
Renjie Tangb6fc5e02020-06-30 00:48:342720// TODO(fayang): Add time driven idle network detection test.
2721TEST_P(QuicNetworkTransactionTest,
2722 DISABLED_QuicFailsOnBothNetworksWhileTCPSucceeds) {
Ryan Hamiltona51800a2022-02-12 19:34:352723 if (version_.AlpnDeferToRFCv1()) {
2724 // These versions currently do not support Alt-Svc.
2725 return;
2726 }
Renjie Tangb6fc5e02020-06-30 00:48:342727 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432728 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2729 return;
2730 }
Zhongyi Shia6b68d112018-09-24 07:49:032731 SetUpTestForRetryConnectionOnAlternateNetwork();
2732
Zhongyi Shi1c022d22020-03-20 19:00:162733 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032734
2735 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592736 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032737 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2738 int packet_num = 1;
2739 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162740 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:592741 // Retransmit the handshake messages.
Zhongyi Shia6b68d112018-09-24 07:49:032742 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162743 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032744 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162745 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032746 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162747 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032748 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162749 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032750 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2751 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162752 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:032753 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522754 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:032755 quic_data.AddSocketDataToFactory(&socket_factory_);
2756
2757 // Add successful TCP data so that TCP job will succeed.
2758 MockWrite http_writes[] = {
2759 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2760 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2761 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2762
Ryan Hamiltona2dcbae2022-02-09 19:02:452763 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2764 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
2765 MockRead(SYNCHRONOUS, 5, "TCP succeeds"),
2766 MockRead(SYNCHRONOUS, OK, 6)};
Zhongyi Shia6b68d112018-09-24 07:49:032767 SequencedSocketData http_data(http_reads, http_writes);
2768 socket_factory_.AddSocketDataProvider(&http_data);
2769 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2770
2771 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592772 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032773 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2774 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2775 quic_data2.AddSocketDataToFactory(&socket_factory_);
2776
2777 // Resolve the host resolution synchronously.
2778 host_resolver_.set_synchronous_mode(true);
2779 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2780 "");
Zhongyi Shia6b68d112018-09-24 07:49:032781
2782 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432783 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2784 false);
Zhongyi Shia6b68d112018-09-24 07:49:032785 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032786 QuicStreamFactoryPeer::SetAlarmFactory(
2787 session_->quic_stream_factory(),
2788 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222789 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032790 // Add alternate protocol mapping to race QUIC and TCP.
2791 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2792 // peer.
2793 AddQuicAlternateProtocolMapping(
2794 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2795
2796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2797 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262798 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Zhongyi Shia6b68d112018-09-24 07:49:032799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2800
2801 // Pump the message loop to get the request started.
2802 // Request will be served with TCP job.
2803 base::RunLoop().RunUntilIdle();
2804 EXPECT_THAT(callback.WaitForResult(), IsOk());
2805 CheckResponseData(&trans, "TCP succeeds");
2806
Zhongyi Shia6b68d112018-09-24 07:49:032807 // Fast forward to idle timeout the original connection. A new connection will
2808 // be kicked off on the alternate network.
2809 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2810 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2811 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2812
2813 // Run the message loop to execute posted tasks, which will report job status.
2814 base::RunLoop().RunUntilIdle();
2815
2816 // Verify that QUIC is marked as broken.
2817 ExpectBrokenAlternateProtocolMapping();
2818
2819 // Deliver a message to notify the new network becomes default, the brokenness
2820 // will not expire as QUIC is broken on both networks.
2821 scoped_mock_change_notifier_->mock_network_change_notifier()
2822 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2823 ExpectBrokenAlternateProtocolMapping();
2824
2825 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2826 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2827}
2828
2829// This test verifies that a new QUIC connection will be attempted on the
2830// alternate network if the original QUIC connection fails with idle timeout
2831// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2832// alternate network, QUIC is marked as broken. The brokenness will expire when
2833// the default network changes.
Renjie Tangb6fc5e02020-06-30 00:48:342834// TODO(fayang): Add time driven idle network detection test.
2835TEST_P(QuicNetworkTransactionTest,
2836 DISABLED_RetryOnAlternateNetworkWhileTCPSucceeds) {
Ryan Hamiltona51800a2022-02-12 19:34:352837 if (version_.AlpnDeferToRFCv1()) {
2838 // These versions currently do not support Alt-Svc.
2839 return;
2840 }
Renjie Tangb6fc5e02020-06-30 00:48:342841 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432842 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2843 return;
2844 }
2845
Zhongyi Shia6b68d112018-09-24 07:49:032846 SetUpTestForRetryConnectionOnAlternateNetwork();
2847
Zhongyi Shi1c022d22020-03-20 19:00:162848 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032849
2850 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592851 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032852 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2853 int packet_num = 1;
2854 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162855 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:592856 // Retransmit the handshake messages.
Zhongyi Shia6b68d112018-09-24 07:49:032857 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162858 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032859 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162860 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032861 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162862 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032863 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162864 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032865 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2866 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162867 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:032868 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522869 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:032870 quic_data.AddSocketDataToFactory(&socket_factory_);
2871
2872 // Add successful TCP data so that TCP job will succeed.
2873 MockWrite http_writes[] = {
2874 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2875 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2876 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2877
Ryan Hamiltona2dcbae2022-02-09 19:02:452878 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2879 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
2880 MockRead(SYNCHRONOUS, 5, "TCP succeeds"),
2881 MockRead(SYNCHRONOUS, OK, 6)};
Zhongyi Shia6b68d112018-09-24 07:49:032882 SequencedSocketData http_data(http_reads, http_writes);
2883 socket_factory_.AddSocketDataProvider(&http_data);
2884 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2885
2886 // Quic connection will be retried on the alternate network after the initial
2887 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592888 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032889 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2890 quic_data2.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162891 client_maker_->MakeDummyCHLOPacket(1)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:032892
Zhongyi Shi1c022d22020-03-20 19:00:162893 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252894 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232895 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032896 quic_data2.AddSocketDataToFactory(&socket_factory_);
2897
2898 // Resolve the host resolution synchronously.
2899 host_resolver_.set_synchronous_mode(true);
2900 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2901 "");
Zhongyi Shia6b68d112018-09-24 07:49:032902
2903 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432904 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2905 false);
Zhongyi Shia6b68d112018-09-24 07:49:032906 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032907 QuicStreamFactoryPeer::SetAlarmFactory(
2908 session_->quic_stream_factory(),
2909 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222910 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032911 // Add alternate protocol mapping to race QUIC and TCP.
2912 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2913 // peer.
2914 AddQuicAlternateProtocolMapping(
2915 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2916
2917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2918 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262919 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Zhongyi Shia6b68d112018-09-24 07:49:032920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2921
2922 // Pump the message loop to get the request started.
2923 // Request will be served with TCP job.
2924 base::RunLoop().RunUntilIdle();
2925 EXPECT_THAT(callback.WaitForResult(), IsOk());
2926 CheckResponseData(&trans, "TCP succeeds");
2927
Zhongyi Shia6b68d112018-09-24 07:49:032928 // Fast forward to idle timeout the original connection. A new connection will
2929 // be kicked off on the alternate network.
2930 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2931 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2932 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2933
2934 // The second connection hasn't finish handshake, verify that QUIC is not
2935 // marked as broken.
2936 ExpectQuicAlternateProtocolMapping();
2937 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:282938 crypto_client_stream_factory_.last_stream()
2939 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia6b68d112018-09-24 07:49:032940 // Run message loop to execute posted tasks, which will notify JoController
2941 // about the orphaned job status.
2942 base::RunLoop().RunUntilIdle();
2943
2944 // Verify that QUIC is marked as broken.
2945 ExpectBrokenAlternateProtocolMapping();
2946
2947 // Deliver a message to notify the new network becomes default, the previous
2948 // brokenness will be clear as the brokenness is bond with old default
2949 // network.
2950 scoped_mock_change_notifier_->mock_network_change_notifier()
2951 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2952 ExpectQuicAlternateProtocolMapping();
2953
2954 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2955 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2956}
2957
Matt Menkeb32ba5122019-09-10 19:17:052958// Much like above test, but verifies NetworkIsolationKeys are respected.
Renjie Tangb6fc5e02020-06-30 00:48:342959// TODO(fayang): Add time driven idle network detection test.
2960TEST_P(
2961 QuicNetworkTransactionTest,
2962 DISABLED_RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:352963 if (version_.AlpnDeferToRFCv1()) {
2964 // These versions currently do not support Alt-Svc.
2965 return;
2966 }
Renjie Tangb6fc5e02020-06-30 00:48:342967 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432968 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2969 return;
2970 }
2971
Matt Menke4807a9a2020-11-21 00:14:412972 const SchemefulSite kSite1(GURL("https://foo.test/"));
2973 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
2974 const SchemefulSite kSite2(GURL("https://bar.test/"));
2975 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:052976
2977 base::test::ScopedFeatureList feature_list;
2978 feature_list.InitWithFeatures(
2979 // enabled_features
2980 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2981 // Need to partition connections by NetworkIsolationKey for
2982 // QuicSessionAliasKey to include NetworkIsolationKeys.
2983 features::kPartitionConnectionsByNetworkIsolationKey},
2984 // disabled_features
2985 {});
2986 // Since HttpServerProperties caches the feature value, have to create a new
2987 // one.
2988 http_server_properties_ = std::make_unique<HttpServerProperties>();
2989
2990 SetUpTestForRetryConnectionOnAlternateNetwork();
2991
Zhongyi Shi1c022d22020-03-20 19:00:162992 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Matt Menkeb32ba5122019-09-10 19:17:052993
2994 // The request will initially go out over QUIC.
2995 MockQuicData quic_data(version_);
2996 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2997 int packet_num = 1;
2998 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162999 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:593000 // Retransmit the handshake messages.
Matt Menkeb32ba5122019-09-10 19:17:053001 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163002 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:053003 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163004 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:053005 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163006 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:053007 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163008 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:053009 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
3010 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163011 client_maker_->MakeConnectionClosePacket(
Matt Menkeb32ba5122019-09-10 19:17:053012 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523013 "No recent network activity after 4s. Timeout:4s"));
Matt Menkeb32ba5122019-09-10 19:17:053014 quic_data.AddSocketDataToFactory(&socket_factory_);
3015
3016 // Add successful TCP data so that TCP job will succeed.
3017 MockWrite http_writes[] = {
3018 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3019 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3020 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3021
Ryan Hamiltona2dcbae2022-02-09 19:02:453022 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3023 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3024 MockRead(SYNCHRONOUS, 5, "TCP succeeds"),
3025 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:053026 SequencedSocketData http_data(http_reads, http_writes);
3027 socket_factory_.AddSocketDataProvider(&http_data);
3028 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3029
3030 // Quic connection will be retried on the alternate network after the initial
3031 // one fails on the default network.
3032 MockQuicData quic_data2(version_);
3033 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
3034 quic_data2.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163035 client_maker_->MakeDummyCHLOPacket(1)); // CHLO
Matt Menkeb32ba5122019-09-10 19:17:053036
Zhongyi Shi1c022d22020-03-20 19:00:163037 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253038 if (VersionUsesHttp3(version_.transport_version))
Matt Menkeb32ba5122019-09-10 19:17:053039 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
3040 quic_data2.AddSocketDataToFactory(&socket_factory_);
3041
3042 // Resolve the host resolution synchronously.
3043 host_resolver_.set_synchronous_mode(true);
3044 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3045 "");
3046
3047 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433048 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3049 false);
Matt Menkeb32ba5122019-09-10 19:17:053050 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
3051 QuicStreamFactoryPeer::SetAlarmFactory(
3052 session_->quic_stream_factory(),
3053 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223054 context_.clock()));
Matt Menkeb32ba5122019-09-10 19:17:053055 // Add alternate protocol mapping to race QUIC and TCP.
3056 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3057 // peer.
3058 AddQuicAlternateProtocolMapping(
3059 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
3060 AddQuicAlternateProtocolMapping(
3061 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
3062
3063 request_.network_isolation_key = kNetworkIsolationKey1;
3064 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3065 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263066 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeb32ba5122019-09-10 19:17:053067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3068
3069 // Pump the message loop to get the request started.
3070 // Request will be served with TCP job.
3071 base::RunLoop().RunUntilIdle();
3072 EXPECT_THAT(callback.WaitForResult(), IsOk());
3073 CheckResponseData(&trans, "TCP succeeds");
3074
3075 // Fast forward to idle timeout the original connection. A new connection will
3076 // be kicked off on the alternate network.
3077 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3078 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3079 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3080
3081 // The second connection hasn't finish handshake, verify that QUIC is not
3082 // marked as broken.
3083 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
3084 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3085 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:283086 crypto_client_stream_factory_.last_stream()
3087 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:053088 // Run message loop to execute posted tasks, which will notify JoController
3089 // about the orphaned job status.
3090 base::RunLoop().RunUntilIdle();
3091
3092 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
3093 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3094 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3095
3096 // Deliver a message to notify the new network becomes default, the previous
3097 // brokenness will be clear as the brokenness is bond with old default
3098 // network.
3099 scoped_mock_change_notifier_->mock_network_change_notifier()
3100 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3101 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
3102 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3103
3104 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3105 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3106}
3107
Zhongyi Shia6b68d112018-09-24 07:49:033108// This test verifies that a new QUIC connection will be attempted on the
3109// alternate network if the original QUIC connection fails with idle timeout
3110// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
3111// alternative network succeeds, QUIC is not marked as broken.
Renjie Tangb6fc5e02020-06-30 00:48:343112// TODO(fayang): Add time driven idle network detection test.
3113TEST_P(QuicNetworkTransactionTest,
3114 DISABLED_RetryOnAlternateNetworkWhileTCPHanging) {
3115 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433116 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3117 return;
3118 }
3119
Zhongyi Shia6b68d112018-09-24 07:49:033120 SetUpTestForRetryConnectionOnAlternateNetwork();
3121
Zhongyi Shi1c022d22020-03-20 19:00:163122 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:033123
3124 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593125 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:033126 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
3127 int packet_num = 1;
3128 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163129 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:593130 // Retransmit the handshake messages.
Zhongyi Shia6b68d112018-09-24 07:49:033131 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163132 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033133 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163134 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033135 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163136 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033137 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163138 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033139 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
3140 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163141 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:033142 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523143 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:033144 quic_data.AddSocketDataToFactory(&socket_factory_);
3145
3146 // Add hanging TCP data so that TCP job will never succeeded.
3147 AddHangingNonAlternateProtocolSocketData();
3148
3149 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:593150 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:233151 packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:163152 quic_data2.AddWrite(
3153 SYNCHRONOUS,
3154 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:033155
Victor Vasiliev076657c2019-03-12 02:46:433156 const std::string body = "hello!";
Renjief49758b2019-01-11 23:32:413157
Zhongyi Shi1c022d22020-03-20 19:00:163158 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253159 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233160 quic_data2.AddWrite(SYNCHRONOUS,
3161 ConstructInitialSettingsPacket(packet_num++));
3162 }
Zhongyi Shia6b68d112018-09-24 07:49:033163 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233164 SYNCHRONOUS,
3165 ConstructClientRequestHeadersPacket(
3166 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3167 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:033168 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333169 ASYNC, ConstructServerResponseHeadersPacket(
3170 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283171 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:333172 quic_data2.AddRead(
3173 ASYNC, ConstructServerDataPacket(
3174 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523175 ConstructDataFrame(body)));
Renjie Tangaadb84b2019-08-31 01:00:233176 quic_data2.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343177 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shia6b68d112018-09-24 07:49:033178 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
3179 quic_data2.AddSocketDataToFactory(&socket_factory_);
3180
3181 // Resolve the host resolution synchronously.
3182 host_resolver_.set_synchronous_mode(true);
3183 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3184 "");
Zhongyi Shia6b68d112018-09-24 07:49:033185
3186 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433187 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3188 false);
Zhongyi Shia6b68d112018-09-24 07:49:033189 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:033190 QuicStreamFactoryPeer::SetAlarmFactory(
3191 session_->quic_stream_factory(),
3192 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223193 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:033194 // Add alternate protocol mapping to race QUIC and TCP.
3195 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3196 // peer.
3197 AddQuicAlternateProtocolMapping(
3198 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3199
3200 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3201 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263202 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Zhongyi Shia6b68d112018-09-24 07:49:033203 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3204
3205 // Pump the message loop to get the request started.
3206 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:033207
3208 // Fast forward to idle timeout the original connection. A new connection will
3209 // be kicked off on the alternate network.
3210 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3211 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3212 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3213
3214 // Verify that QUIC is not marked as broken.
3215 ExpectQuicAlternateProtocolMapping();
3216 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:283217 crypto_client_stream_factory_.last_stream()
3218 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia6b68d112018-09-24 07:49:033219
3220 // Read the response.
3221 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:413222 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:033223 // Verify that QUIC is not marked as broken.
3224 ExpectQuicAlternateProtocolMapping();
3225
3226 // Deliver a message to notify the new network becomes default.
3227 scoped_mock_change_notifier_->mock_network_change_notifier()
3228 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3229 ExpectQuicAlternateProtocolMapping();
3230 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3231 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3232}
3233
rch9ecde09b2017-04-08 00:18:233234// Verify that if a QUIC connection times out, the QuicHttpStream will
3235// return QUIC_PROTOCOL_ERROR.
3236TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:383237 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Peter Kastinge5a38ed2021-10-02 03:06:353238 context_.params()->idle_connection_timeout = base::Seconds(5);
Renjie Tangd05389fe2022-07-13 23:46:233239 // Turn off port migration to avoid dealing with unnecessary complexity in
3240 // this test.
3241 context_.params()->allow_port_migration = false;
rch9ecde09b2017-04-08 00:18:233242
3243 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593244 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133245 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233246 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3247
Zhongyi Shi1c022d22020-03-20 19:00:163248 client_maker_->set_save_packet_frames(true);
3249 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493250 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253251 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493252 quic_data.AddWrite(SYNCHRONOUS,
3253 ConstructInitialSettingsPacket(packet_num++));
3254 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023255 quic_data.AddWrite(
3256 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163257 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493258 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3259 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453260
Zhongyi Shi1c022d22020-03-20 19:00:163261 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233262
Victor Vasiliev7da08172019-10-14 06:04:253263 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper0b214c132020-10-26 20:10:233264 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3265 // sending PTO packets.
3266 packet_num++;
3267 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163268 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493269 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233270 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3271 // sending PTO packets.
3272 packet_num++;
3273 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163274 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493275 2, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233276 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3277 // sending PTO packets.
3278 packet_num++;
3279 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163280 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493281 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233282
3283 quic_data.AddWrite(SYNCHRONOUS,
3284 client_maker_->MakeConnectionClosePacket(
3285 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3286 "No recent network activity after 4s. Timeout:4s"));
Yutaka Hiranobba79bc2022-05-09 03:11:473287 } else {
Nick Harper0b214c132020-10-26 20:10:233288 // Settings were sent in the request packet so there is only 1 packet to
3289 // retransmit.
3290 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3291 // sending PTO packets.
3292 packet_num++;
3293 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163294 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493295 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233296 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3297 // sending PTO packets.
3298 packet_num++;
3299 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163300 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493301 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233302 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3303 // sending PTO packets.
3304 packet_num++;
3305 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163306 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper0b214c132020-10-26 20:10:233307 1, packet_num++, true));
Ryan Hamilton3cc2c152019-07-09 19:36:013308
Findit2403b85d2019-11-19 05:06:373309 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163310 client_maker_->MakeConnectionClosePacket(
Findit2403b85d2019-11-19 05:06:373311 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523312 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493313 }
Fan Yang928f1632017-12-14 18:55:223314
rch9ecde09b2017-04-08 00:18:233315 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3316 quic_data.AddRead(ASYNC, OK);
3317 quic_data.AddSocketDataToFactory(&socket_factory_);
3318
3319 // In order for a new QUIC session to be established via alternate-protocol
3320 // without racing an HTTP connection, we need the host resolution to happen
3321 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3322 // connection to the the server, in this test we require confirmation
3323 // before encrypting so the HTTP job will still start.
3324 host_resolver_.set_synchronous_mode(true);
3325 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3326 "");
rch9ecde09b2017-04-08 00:18:233327
3328 CreateSession();
3329 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233330 QuicStreamFactoryPeer::SetAlarmFactory(
3331 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193332 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223333 context_.clock()));
rch9ecde09b2017-04-08 00:18:233334
Ryan Hamilton9835e662018-08-02 05:36:273335 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233336
3337 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3338 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263339 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch9ecde09b2017-04-08 00:18:233340 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3341
3342 // Pump the message loop to get the request started.
3343 base::RunLoop().RunUntilIdle();
3344 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283345 crypto_client_stream_factory_.last_stream()
3346 ->NotifySessionOneRttKeyAvailable();
rch9ecde09b2017-04-08 00:18:233347
3348 // Run the QUIC session to completion.
3349 quic_task_runner_->RunUntilIdle();
3350
3351 ExpectQuicAlternateProtocolMapping();
3352 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3353 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3354}
3355
David Schinazi7e980ab2020-05-13 20:26:553356// TODO(fayang): Add time driven TOO_MANY_RTOS test.
rch9ecde09b2017-04-08 00:18:233357
rch2f2991c2017-04-13 19:28:173358// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3359// the request fails with QUIC_PROTOCOL_ERROR.
3360TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:383361 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173362 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593363 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:163364 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493365 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253366 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493367 quic_data.AddWrite(SYNCHRONOUS,
3368 ConstructInitialSettingsPacket(packet_num++));
3369 }
3370 quic_data.AddWrite(
3371 SYNCHRONOUS,
3372 ConstructClientRequestHeadersPacket(
3373 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3374 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163375 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553376 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173377 // Peer sending data from an non-existing stream causes this end to raise
3378 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333379 quic_data.AddRead(
3380 ASYNC, ConstructServerRstPacket(
3381 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3382 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173383 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:343384 quic_data.AddWrite(
3385 SYNCHRONOUS,
3386 ConstructClientAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:343387 packet_num++, 1, 1,
Renjie Tang248e36ea2020-06-26 00:12:343388 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
3389 : quic::QUIC_INVALID_STREAM_ID,
Renjie Tanga35322a2020-12-02 20:12:273390 quic_error_details,
3391 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
3392 : quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173393 quic_data.AddSocketDataToFactory(&socket_factory_);
3394
3395 // In order for a new QUIC session to be established via alternate-protocol
3396 // without racing an HTTP connection, we need the host resolution to happen
3397 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3398 // connection to the the server, in this test we require confirmation
3399 // before encrypting so the HTTP job will still start.
3400 host_resolver_.set_synchronous_mode(true);
3401 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3402 "");
rch2f2991c2017-04-13 19:28:173403
3404 CreateSession();
3405
Ryan Hamilton9835e662018-08-02 05:36:273406 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173407
3408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3409 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263410 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:173411 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3412
3413 // Pump the message loop to get the request started.
3414 base::RunLoop().RunUntilIdle();
3415 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283416 crypto_client_stream_factory_.last_stream()
3417 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:173418
3419 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553420 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173421
3422 // Run the QUIC session to completion.
3423 base::RunLoop().RunUntilIdle();
3424 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3425 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3426
3427 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3428 ExpectQuicAlternateProtocolMapping();
3429 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3430}
3431
rch2f2991c2017-04-13 19:28:173432// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3433// connection times out, then QUIC will be marked as broken and the request
3434// retried over TCP.
3435TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Ryan Hamiltona51800a2022-02-12 19:34:353436 if (version_.AlpnDeferToRFCv1()) {
3437 // These versions currently do not support Alt-Svc.
3438 return;
3439 }
Peter Kastinge5a38ed2021-10-02 03:06:353440 context_.params()->idle_connection_timeout = base::Seconds(5);
Renjie Tangd05389fe2022-07-13 23:46:233441 // Turn off port migration to avoid dealing with unnecessary complexity in
3442 // this test.
3443 context_.params()->allow_port_migration = false;
rch2f2991c2017-04-13 19:28:173444
3445 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593446 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133447 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173448 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3449
Zhongyi Shi1c022d22020-03-20 19:00:163450 client_maker_->set_save_packet_frames(true);
3451 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493452 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253453 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493454 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163455 client_maker_->MakeInitialSettingsPacket(packet_num++));
Nick Harper057264a82019-09-12 23:33:493456 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023457 quic_data.AddWrite(
3458 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163459 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493460 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3461 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453462
Zhongyi Shi1c022d22020-03-20 19:00:163463 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253464 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper0b214c132020-10-26 20:10:233465 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3466 // sending PTO packets.
3467 packet_num++;
3468 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163469 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493470 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233471
3472 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3473 // sending PTO packets.
3474 packet_num++;
3475 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163476 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493477 2, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233478
3479 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3480 // sending PTO packets.
3481 packet_num++;
3482 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163483 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493484 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233485
3486 quic_data.AddWrite(SYNCHRONOUS,
3487 client_maker_->MakeConnectionClosePacket(
3488 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3489 "No recent network activity after 4s. Timeout:4s"));
Yutaka Hiranobba79bc2022-05-09 03:11:473490 } else {
Nick Harper0b214c132020-10-26 20:10:233491 // Settings were sent in the request packet so there is only 1 packet to
3492 // retransmit.
3493 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3494 // sending PTO packets.
3495 packet_num++;
3496 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163497 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493498 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233499 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3500 // sending PTO packets.
3501 packet_num++;
3502 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163503 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493504 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233505 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3506 // sending PTO packets.
3507 packet_num++;
3508 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163509 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper0b214c132020-10-26 20:10:233510 1, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373511
3512 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163513 client_maker_->MakeConnectionClosePacket(
Findit2403b85d2019-11-19 05:06:373514 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523515 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493516 }
Fan Yang928f1632017-12-14 18:55:223517
rch2f2991c2017-04-13 19:28:173518 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3519 quic_data.AddRead(ASYNC, OK);
3520 quic_data.AddSocketDataToFactory(&socket_factory_);
3521
3522 // After that fails, it will be resent via TCP.
3523 MockWrite http_writes[] = {
3524 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3525 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3526 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3527
Ryan Hamiltona2dcbae2022-02-09 19:02:453528 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3529 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3530 MockRead(SYNCHRONOUS, 5, "hello world"),
3531 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013532 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173533 socket_factory_.AddSocketDataProvider(&http_data);
3534 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3535
3536 // In order for a new QUIC session to be established via alternate-protocol
3537 // without racing an HTTP connection, we need the host resolution to happen
3538 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3539 // connection to the the server, in this test we require confirmation
3540 // before encrypting so the HTTP job will still start.
3541 host_resolver_.set_synchronous_mode(true);
3542 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3543 "");
rch2f2991c2017-04-13 19:28:173544
3545 CreateSession();
3546 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173547 QuicStreamFactoryPeer::SetAlarmFactory(
3548 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193549 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223550 context_.clock()));
rch2f2991c2017-04-13 19:28:173551
Ryan Hamilton9835e662018-08-02 05:36:273552 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173553
3554 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3555 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263556 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:173557 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3558
3559 // Pump the message loop to get the request started.
3560 base::RunLoop().RunUntilIdle();
3561 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283562 crypto_client_stream_factory_.last_stream()
3563 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:173564
3565 // Run the QUIC session to completion.
3566 quic_task_runner_->RunUntilIdle();
3567 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3568
3569 ExpectQuicAlternateProtocolMapping();
3570
3571 // Let the transaction proceed which will result in QUIC being marked
3572 // as broken and the request falling back to TCP.
3573 EXPECT_THAT(callback.WaitForResult(), IsOk());
3574
3575 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3576 ASSERT_FALSE(http_data.AllReadDataConsumed());
3577
3578 // Read the response body over TCP.
3579 CheckResponseData(&trans, "hello world");
3580 ExpectBrokenAlternateProtocolMapping();
3581 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3582 ASSERT_TRUE(http_data.AllReadDataConsumed());
3583}
3584
rch2f2991c2017-04-13 19:28:173585// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3586// protocol error occurs after the handshake is confirmed, the request
3587// retried over TCP and the QUIC will be marked as broken.
3588TEST_P(QuicNetworkTransactionTest,
3589 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:353590 if (version_.AlpnDeferToRFCv1()) {
3591 // These versions currently do not support Alt-Svc.
3592 return;
3593 }
Peter Kastinge5a38ed2021-10-02 03:06:353594 context_.params()->idle_connection_timeout = base::Seconds(5);
rch2f2991c2017-04-13 19:28:173595
3596 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593597 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:163598 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493599 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253600 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493601 quic_data.AddWrite(SYNCHRONOUS,
3602 ConstructInitialSettingsPacket(packet_num++));
3603 }
3604 quic_data.AddWrite(
3605 SYNCHRONOUS,
3606 ConstructClientRequestHeadersPacket(
3607 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3608 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163609 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553610 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3611
rch2f2991c2017-04-13 19:28:173612 // Peer sending data from an non-existing stream causes this end to raise
3613 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333614 quic_data.AddRead(
3615 ASYNC, ConstructServerRstPacket(
3616 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3617 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173618 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:343619 quic_data.AddWrite(
3620 SYNCHRONOUS,
3621 ConstructClientAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:343622 packet_num++, 1, 1,
Renjie Tang248e36ea2020-06-26 00:12:343623 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
3624 : quic::QUIC_INVALID_STREAM_ID,
Renjie Tanga35322a2020-12-02 20:12:273625 quic_error_details,
3626 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
3627 : quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173628 quic_data.AddSocketDataToFactory(&socket_factory_);
3629
3630 // After that fails, it will be resent via TCP.
3631 MockWrite http_writes[] = {
3632 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3633 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3634 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3635
Ryan Hamiltona2dcbae2022-02-09 19:02:453636 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3637 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3638 MockRead(SYNCHRONOUS, 5, "hello world"),
3639 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013640 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173641 socket_factory_.AddSocketDataProvider(&http_data);
3642 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3643
3644 // In order for a new QUIC session to be established via alternate-protocol
3645 // without racing an HTTP connection, we need the host resolution to happen
3646 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3647 // connection to the the server, in this test we require confirmation
3648 // before encrypting so the HTTP job will still start.
3649 host_resolver_.set_synchronous_mode(true);
3650 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3651 "");
rch2f2991c2017-04-13 19:28:173652
3653 CreateSession();
3654
Ryan Hamilton9835e662018-08-02 05:36:273655 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173656
3657 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3658 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263659 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:173660 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3661
3662 // Pump the message loop to get the request started.
3663 base::RunLoop().RunUntilIdle();
3664 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283665 crypto_client_stream_factory_.last_stream()
3666 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553667 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173668
3669 // Run the QUIC session to completion.
3670 base::RunLoop().RunUntilIdle();
3671 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3672
3673 ExpectQuicAlternateProtocolMapping();
3674
3675 // Let the transaction proceed which will result in QUIC being marked
3676 // as broken and the request falling back to TCP.
3677 EXPECT_THAT(callback.WaitForResult(), IsOk());
3678
3679 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3680 ASSERT_FALSE(http_data.AllReadDataConsumed());
3681
3682 // Read the response body over TCP.
3683 CheckResponseData(&trans, "hello world");
3684 ExpectBrokenAlternateProtocolMapping();
3685 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3686 ASSERT_TRUE(http_data.AllReadDataConsumed());
3687}
3688
Matt Menkeb32ba5122019-09-10 19:17:053689// Much like above test, but verifies that NetworkIsolationKey is respected.
3690TEST_P(QuicNetworkTransactionTest,
3691 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:353692 if (version_.AlpnDeferToRFCv1()) {
3693 // These versions currently do not support Alt-Svc.
3694 return;
3695 }
Matt Menke4807a9a2020-11-21 00:14:413696 const SchemefulSite kSite1(GURL("https://foo.test/"));
3697 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
3698 const SchemefulSite kSite2(GURL("https://bar.test/"));
3699 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:053700
3701 base::test::ScopedFeatureList feature_list;
3702 feature_list.InitWithFeatures(
3703 // enabled_features
3704 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3705 features::kPartitionConnectionsByNetworkIsolationKey},
3706 // disabled_features
3707 {});
3708 // Since HttpServerProperties caches the feature value, have to create a new
3709 // one.
3710 http_server_properties_ = std::make_unique<HttpServerProperties>();
3711
Peter Kastinge5a38ed2021-10-02 03:06:353712 context_.params()->idle_connection_timeout = base::Seconds(5);
Matt Menkeb32ba5122019-09-10 19:17:053713
3714 // The request will initially go out over QUIC.
3715 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:563716 uint64_t packet_number = 1;
Zhongyi Shi1c022d22020-03-20 19:00:163717 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:253718 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:563719 quic_data.AddWrite(SYNCHRONOUS,
3720 ConstructInitialSettingsPacket(packet_number++));
3721 }
3722 quic_data.AddWrite(
3723 SYNCHRONOUS,
3724 ConstructClientRequestHeadersPacket(
3725 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3726 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163727 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:053728 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3729
3730 // Peer sending data from an non-existing stream causes this end to raise
3731 // error and close connection.
3732 quic_data.AddRead(
3733 ASYNC, ConstructServerRstPacket(
3734 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3735 quic::QUIC_STREAM_LAST_ERROR));
3736 std::string quic_error_details = "Data for nonexistent stream";
Nick Harper1ccb0ce2020-10-07 00:28:583737 quic::QuicErrorCode quic_error_code = quic::QUIC_INVALID_STREAM_ID;
3738 if (version_.HasIetfQuicFrames()) {
3739 quic_error_code = quic::QUIC_HTTP_STREAM_WRONG_DIRECTION;
3740 }
Renjie Tanga35322a2020-12-02 20:12:273741 quic_data.AddWrite(
3742 SYNCHRONOUS,
3743 ConstructClientAckAndConnectionClosePacket(
3744 packet_number++, 1, 1, quic_error_code, quic_error_details,
3745 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
3746 : quic::IETF_RST_STREAM));
Matt Menkeb32ba5122019-09-10 19:17:053747 quic_data.AddSocketDataToFactory(&socket_factory_);
3748
3749 // After that fails, it will be resent via TCP.
3750 MockWrite http_writes[] = {
3751 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3752 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3753 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3754
Ryan Hamiltona2dcbae2022-02-09 19:02:453755 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3756 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3757 MockRead(SYNCHRONOUS, 5, "hello world"),
3758 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:053759 SequencedSocketData http_data(http_reads, http_writes);
3760 socket_factory_.AddSocketDataProvider(&http_data);
3761 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3762
3763 // In order for a new QUIC session to be established via alternate-protocol
3764 // without racing an HTTP connection, we need the host resolution to happen
3765 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3766 // connection to the the server, in this test we require confirmation
3767 // before encrypting so the HTTP job will still start.
3768 host_resolver_.set_synchronous_mode(true);
3769 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3770 "");
3771
3772 CreateSession();
3773
3774 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3775 kNetworkIsolationKey1);
3776 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3777 kNetworkIsolationKey2);
3778
3779 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3780 TestCompletionCallback callback;
3781 request_.network_isolation_key = kNetworkIsolationKey1;
Matt Reichhoff0049a0b72021-10-20 20:44:263782 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeb32ba5122019-09-10 19:17:053783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3784
3785 // Pump the message loop to get the request started.
3786 base::RunLoop().RunUntilIdle();
3787 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283788 crypto_client_stream_factory_.last_stream()
3789 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:053790 quic_data.Resume();
3791
3792 // Run the QUIC session to completion.
3793 base::RunLoop().RunUntilIdle();
3794 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3795
3796 // Let the transaction proceed which will result in QUIC being marked
3797 // as broken and the request falling back to TCP.
3798 EXPECT_THAT(callback.WaitForResult(), IsOk());
3799 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3800 ASSERT_FALSE(http_data.AllReadDataConsumed());
3801
3802 // Read the response body over TCP.
3803 CheckResponseData(&trans, "hello world");
3804 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3805 ASSERT_TRUE(http_data.AllReadDataConsumed());
3806
3807 // The alternative service shouldhave been marked as broken under
3808 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3809 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3810 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3811
3812 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3813 AddHttpDataAndRunRequest();
3814 // Requests using other NetworkIsolationKeys can still use QUIC.
3815 request_.network_isolation_key = kNetworkIsolationKey2;
3816 AddQuicDataAndRunRequest();
3817
3818 // The last two requests should not have changed the alternative service
3819 // mappings.
3820 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3821 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3822}
3823
rch30943ee2017-06-12 21:28:443824// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3825// request is reset from, then QUIC will be marked as broken and the request
3826// retried over TCP.
3827TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:353828 if (version_.AlpnDeferToRFCv1()) {
3829 // These versions currently do not support Alt-Svc.
3830 return;
3831 }
rch30943ee2017-06-12 21:28:443832 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593833 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133834 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443835 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3836
Zhongyi Shi1c022d22020-03-20 19:00:163837 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493838 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253839 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493840 quic_data.AddWrite(SYNCHRONOUS,
3841 ConstructInitialSettingsPacket(packet_num++));
3842 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023843 quic_data.AddWrite(
3844 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163845 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493846 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3847 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453848
Zhongyi Shi1c022d22020-03-20 19:00:163849 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553850 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443851
Fan Yang32c5a112018-12-10 20:06:333852 quic_data.AddRead(ASYNC,
3853 ConstructServerRstPacket(
3854 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3855 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443856
Bence Béky6e243aa2019-12-13 19:01:073857 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang248e36ea2020-06-26 00:12:343858 quic_data.AddWrite(
Renjie Tanga35322a2020-12-02 20:12:273859 SYNCHRONOUS,
Fan Yang8d4177792021-07-16 17:48:533860 client_maker_->MakeAckRstAndDataPacket(
Renjie Tanga35322a2020-12-02 20:12:273861 packet_num++, true, GetNthClientInitiatedBidirectionalStreamId(0),
3862 quic::QUIC_HEADERS_TOO_LARGE, 1, 1, GetQpackDecoderStreamId(),
3863 false, StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:073864 }
3865
rch30943ee2017-06-12 21:28:443866 quic_data.AddRead(ASYNC, OK);
3867 quic_data.AddSocketDataToFactory(&socket_factory_);
3868
3869 // After that fails, it will be resent via TCP.
3870 MockWrite http_writes[] = {
3871 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3872 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3873 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3874
Ryan Hamiltona2dcbae2022-02-09 19:02:453875 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3876 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3877 MockRead(SYNCHRONOUS, 5, "hello world"),
3878 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013879 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443880 socket_factory_.AddSocketDataProvider(&http_data);
3881 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3882
3883 // In order for a new QUIC session to be established via alternate-protocol
3884 // without racing an HTTP connection, we need the host resolution to happen
3885 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3886 // connection to the the server, in this test we require confirmation
3887 // before encrypting so the HTTP job will still start.
3888 host_resolver_.set_synchronous_mode(true);
3889 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3890 "");
rch30943ee2017-06-12 21:28:443891
3892 CreateSession();
3893
Ryan Hamilton9835e662018-08-02 05:36:273894 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443895
3896 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3897 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263898 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch30943ee2017-06-12 21:28:443899 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3900
3901 // Pump the message loop to get the request started.
3902 base::RunLoop().RunUntilIdle();
3903 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283904 crypto_client_stream_factory_.last_stream()
3905 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553906 quic_data.Resume();
rch30943ee2017-06-12 21:28:443907
3908 // Run the QUIC session to completion.
3909 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3910
3911 ExpectQuicAlternateProtocolMapping();
3912
3913 // Let the transaction proceed which will result in QUIC being marked
3914 // as broken and the request falling back to TCP.
3915 EXPECT_THAT(callback.WaitForResult(), IsOk());
3916
3917 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3918 ASSERT_FALSE(http_data.AllReadDataConsumed());
3919
3920 // Read the response body over TCP.
3921 CheckResponseData(&trans, "hello world");
3922 ExpectBrokenAlternateProtocolMapping();
3923 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3924 ASSERT_TRUE(http_data.AllReadDataConsumed());
3925}
3926
Ryan Hamilton6c2a2a82017-12-15 02:06:283927// Verify that when an origin has two alt-svc advertisements, one local and one
3928// remote, that when the local is broken the request will go over QUIC via
3929// the remote Alt-Svc.
3930// This is a regression test for crbug/825646.
3931TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:383932 context_.params()->allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:283933
3934 GURL origin1 = request_.url; // mail.example.org
3935 GURL origin2("https://www.example.org/");
3936 ASSERT_NE(origin1.host(), origin2.host());
3937
3938 scoped_refptr<X509Certificate> cert(
3939 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243940 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3941 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283942
3943 ProofVerifyDetailsChromium verify_details;
3944 verify_details.cert_verify_result.verified_cert = cert;
3945 verify_details.cert_verify_result.is_issued_by_known_root = true;
3946 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3947
Ryan Hamiltonabad59e2019-06-06 04:02:593948 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233949 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253950 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233951 mock_quic_data.AddWrite(SYNCHRONOUS,
3952 ConstructInitialSettingsPacket(packet_num++));
3953 }
Ryan Hamilton6c2a2a82017-12-15 02:06:283954 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233955 SYNCHRONOUS,
3956 ConstructClientRequestHeadersPacket(
3957 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3958 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433959 mock_quic_data.AddRead(
3960 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333961 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283962 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433963 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333964 ASYNC, ConstructServerDataPacket(
3965 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523966 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233967 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343968 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283969 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213970 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamilton6c2a2a82017-12-15 02:06:283971
3972 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:593973 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:283974 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3975 AddHangingNonAlternateProtocolSocketData();
3976
3977 CreateSession();
3978
3979 // Set up alternative service for |origin1|.
3980 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3981 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
Peter Kastinge5a38ed2021-10-02 03:06:353982 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamilton6c2a2a82017-12-15 02:06:283983 AlternativeServiceInfoVector alternative_services;
3984 alternative_services.push_back(
3985 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3986 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383987 context_.params()->supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:283988 alternative_services.push_back(
3989 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3990 remote_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383991 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:493992 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
3993 NetworkIsolationKey(),
3994 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:283995
Matt Menkeb32ba5122019-09-10 19:17:053996 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
3997 NetworkIsolationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:283998
3999 SendRequestAndExpectQuicResponse("hello!");
4000}
4001
Ryan Hamilton899c2e082019-11-14 01:22:024002// Verify that when multiple alternatives are broken,
4003// ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
4004// This is a regression test for crbug/1024613.
4005TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
Ryan Hamiltona51800a2022-02-12 19:34:354006 if (version_.AlpnDeferToRFCv1()) {
4007 // These versions currently do not support Alt-Svc.
4008 return;
4009 }
Ryan Hamilton899c2e082019-11-14 01:22:024010 base::HistogramTester histogram_tester;
4011
4012 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454013 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Ryan Hamilton899c2e082019-11-14 01:22:024014 MockRead("hello world"),
4015 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4016 MockRead(ASYNC, OK)};
4017
4018 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4019 socket_factory_.AddSocketDataProvider(&http_data);
4020 AddCertificate(&ssl_data_);
4021 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4022
4023 GURL origin1 = request_.url; // mail.example.org
4024
4025 scoped_refptr<X509Certificate> cert(
4026 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
4027 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
4028
4029 ProofVerifyDetailsChromium verify_details;
4030 verify_details.cert_verify_result.verified_cert = cert;
4031 verify_details.cert_verify_result.is_issued_by_known_root = true;
4032 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4033
4034 CreateSession();
4035
4036 // Set up alternative service for |origin1|.
4037 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
Peter Kastinge5a38ed2021-10-02 03:06:354038 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamilton899c2e082019-11-14 01:22:024039 AlternativeServiceInfoVector alternative_services;
4040 alternative_services.push_back(
4041 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4042 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384043 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024044 alternative_services.push_back(
4045 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4046 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384047 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024048 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4049 NetworkIsolationKey(),
4050 alternative_services);
4051
4052 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4053 NetworkIsolationKey());
4054
4055 SendRequestAndExpectHttpResponse("hello world");
4056
4057 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
4058 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
4059}
4060
rch30943ee2017-06-12 21:28:444061// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4062// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:054063// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:444064// connection instead of going back to the broken QUIC connection.
4065// This is a regression tests for crbug/731303.
4066TEST_P(QuicNetworkTransactionTest,
4067 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:354068 if (version_.AlpnDeferToRFCv1()) {
4069 // These versions currently do not support Alt-Svc.
4070 return;
4071 }
Victor Vasilieva1e66d72019-12-05 17:55:384072 context_.params()->allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444073
4074 GURL origin1 = request_.url;
4075 GURL origin2("https://www.example.org/");
4076 ASSERT_NE(origin1.host(), origin2.host());
4077
Ryan Hamiltonabad59e2019-06-06 04:02:594078 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:444079
4080 scoped_refptr<X509Certificate> cert(
4081 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244082 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4083 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444084
4085 ProofVerifyDetailsChromium verify_details;
4086 verify_details.cert_verify_result.verified_cert = cert;
4087 verify_details.cert_verify_result.is_issued_by_known_root = true;
4088 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4089
Renjie Tangaadb84b2019-08-31 01:00:234090 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254091 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234092 mock_quic_data.AddWrite(SYNCHRONOUS,
4093 ConstructInitialSettingsPacket(packet_num++));
4094 }
rch30943ee2017-06-12 21:28:444095 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434096 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234097 SYNCHRONOUS,
4098 ConstructClientRequestHeadersPacket(
4099 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4100 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434101 mock_quic_data.AddRead(
4102 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334103 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284104 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434105 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334106 ASYNC, ConstructServerDataPacket(
4107 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524108 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234109 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344110 ConstructClientAckPacket(packet_num++, 2, 1));
rch30943ee2017-06-12 21:28:444111
4112 // Second request will go over the pooled QUIC connection, but will be
4113 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054114 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224115 version_,
4116 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4117 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054118 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174119 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224120 version_,
4121 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4122 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434123 mock_quic_data.AddWrite(
4124 SYNCHRONOUS,
4125 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234126 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4127 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024128 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334129 mock_quic_data.AddRead(
4130 ASYNC, ConstructServerRstPacket(
4131 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4132 quic::QUIC_HEADERS_TOO_LARGE));
Bence Béky6e243aa2019-12-13 19:01:074133
4134 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangcd594f32020-07-11 20:18:344135 mock_quic_data.AddWrite(
4136 SYNCHRONOUS,
Fan Yang8d4177792021-07-16 17:48:534137 client_maker_->MakeAckRstAndDataPacket(
Renjie Tanga35322a2020-12-02 20:12:274138 packet_num++, /*include_version=*/true,
4139 GetNthClientInitiatedBidirectionalStreamId(1),
4140 quic::QUIC_HEADERS_TOO_LARGE, 3, 2, GetQpackDecoderStreamId(),
Renjie Tangcd594f32020-07-11 20:18:344141 /*fin=*/false, StreamCancellationQpackDecoderInstruction(1)));
Bence Béky6e243aa2019-12-13 19:01:074142 }
4143
rch30943ee2017-06-12 21:28:444144 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214145 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rch30943ee2017-06-12 21:28:444146
4147 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4148
4149 // After that fails, it will be resent via TCP.
4150 MockWrite http_writes[] = {
4151 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4152 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4153 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4154
Ryan Hamiltona2dcbae2022-02-09 19:02:454155 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4156 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
4157 MockRead(SYNCHRONOUS, 5, "hello world"),
4158 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014159 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444160 socket_factory_.AddSocketDataProvider(&http_data);
4161 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4162
Ryan Hamilton6c2a2a82017-12-15 02:06:284163 // Then the next request to the second origin will be sent over TCP.
4164 socket_factory_.AddSocketDataProvider(&http_data);
4165 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444166
4167 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564168 QuicStreamFactoryPeer::SetAlarmFactory(
4169 session_->quic_stream_factory(),
4170 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224171 context_.clock()));
rch30943ee2017-06-12 21:28:444172
4173 // Set up alternative service for |origin1|.
Peter Kastinge5a38ed2021-10-02 03:06:354174 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244175 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494176 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074177 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4178 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:444179
4180 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244181 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494182 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074183 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4184 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344185
rch30943ee2017-06-12 21:28:444186 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524187 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444188 SendRequestAndExpectQuicResponse("hello!");
4189
4190 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524191 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:054192 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:444193 request_.url = origin2;
4194 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:054195 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
4196 alternative1, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244197 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:054198 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
4199 alternative2, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244200 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444201
Matt Menkeb32ba5122019-09-10 19:17:054202 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:444203 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284204 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444205}
4206
bnc8be55ebb2015-10-30 14:12:074207TEST_P(QuicNetworkTransactionTest,
4208 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Ryan Hamiltona51800a2022-02-12 19:34:354209 if (version_.AlpnDeferToRFCv1()) {
4210 // These versions currently do not support Alt-Svc.
4211 return;
4212 }
Nick Harper23290b82019-05-02 00:02:564213 std::string altsvc_header =
4214 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4215 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074216 MockRead http_reads[] = {
4217 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4218 MockRead("hello world"),
4219 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4220 MockRead(ASYNC, OK)};
4221
Ryan Sleevib8d7ea02018-05-07 20:01:014222 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074223 socket_factory_.AddSocketDataProvider(&http_data);
4224 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4225 socket_factory_.AddSocketDataProvider(&http_data);
4226 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4227
rch3f4b8452016-02-23 16:59:324228 CreateSession();
bnc8be55ebb2015-10-30 14:12:074229
4230 SendRequestAndExpectHttpResponse("hello world");
4231 SendRequestAndExpectHttpResponse("hello world");
4232}
4233
Xida Chen9bfe0b62018-04-24 19:52:214234// When multiple alternative services are advertised, HttpStreamFactory should
4235// select the alternative service which uses existing QUIC session if available.
4236// If no existing QUIC session can be used, use the first alternative service
4237// from the list.
zhongyi32569c62016-01-08 02:54:304238TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:354239 if (version_.AlpnDeferToRFCv1()) {
4240 // These versions currently do not support Alt-Svc.
4241 return;
4242 }
Victor Vasilieva1e66d72019-12-05 17:55:384243 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltona2dcbae2022-02-09 19:02:454244 std::string alt_svc_header = base::StrCat(
4245 {"Alt-Svc: ",
4246 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.org", 443), ",",
4247 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
bncc958faa2015-07-31 18:14:524248 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454249 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
bncc958faa2015-07-31 18:14:524250 MockRead("hello world"),
4251 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4252 MockRead(ASYNC, OK)};
4253
Ryan Sleevib8d7ea02018-05-07 20:01:014254 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524255 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084256 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564257 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524258
zhongyi32569c62016-01-08 02:54:304259 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294260 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304261 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594262 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234263 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254264 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234265 mock_quic_data.AddWrite(SYNCHRONOUS,
4266 ConstructInitialSettingsPacket(packet_num++));
4267 }
rch5cb522462017-04-25 20:18:364268 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234269 SYNCHRONOUS,
4270 ConstructClientRequestHeadersPacket(
4271 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4272 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304273
Ryan Hamiltona2dcbae2022-02-09 19:02:454274 std::string alt_svc_list = base::StrCat(
4275 {GenerateQuicAltSvcHeaderValue({version_}, "mail.example.org", 444), ",",
4276 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.org", 443), ",",
4277 GenerateQuicAltSvcHeaderValue({version_}, "bar.example.org", 445)});
Zhongyi Shi32f2fd02018-04-16 18:23:434278 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024279 ASYNC, ConstructServerResponseHeadersPacket(
4280 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284281 GetResponseHeaders("200", alt_svc_list)));
Zhongyi Shi32f2fd02018-04-16 18:23:434282 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334283 ASYNC, ConstructServerDataPacket(
4284 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524285 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234286 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344287 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:304288
4289 // Second QUIC request data.
4290 // Connection pooling, using existing session, no need to include version
4291 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584292 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234293 SYNCHRONOUS,
4294 ConstructClientRequestHeadersPacket(
4295 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4296 true, GetRequestHeaders("GET", "https", "/"),
4297 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434298 mock_quic_data.AddRead(
4299 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334300 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284301 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434302 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334303 ASYNC, ConstructServerDataPacket(
4304 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524305 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474306 mock_quic_data.AddWrite(SYNCHRONOUS,
4307 ConstructClientAckPacket(packet_num++, 4, 3));
bncc958faa2015-07-31 18:14:524308 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214309 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:524310
4311 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4312
rtennetib8e80fb2016-05-16 00:12:094313 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324314 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564315 QuicStreamFactoryPeer::SetAlarmFactory(
4316 session_->quic_stream_factory(),
4317 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224318 context_.clock()));
bncc958faa2015-07-31 18:14:524319
4320 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304321
bnc359ed2a2016-04-29 20:43:454322 SendRequestAndExpectQuicResponse("hello!");
4323 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304324}
4325
Ryan Hamilton8d9ee76e2018-05-29 23:52:524326// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454327// even if alternative service destination is different.
4328TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Victor Vasilieva1e66d72019-12-05 17:55:384329 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594330 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454331
Renjie Tangaadb84b2019-08-31 01:00:234332 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254333 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234334 mock_quic_data.AddWrite(SYNCHRONOUS,
4335 ConstructInitialSettingsPacket(packet_num++));
4336 }
bnc359ed2a2016-04-29 20:43:454337 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434338 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234339 SYNCHRONOUS,
4340 ConstructClientRequestHeadersPacket(
4341 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4342 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434343 mock_quic_data.AddRead(
4344 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334345 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284346 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434347 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334348 ASYNC, ConstructServerDataPacket(
4349 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524350 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234351 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344352 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:304353
bnc359ed2a2016-04-29 20:43:454354 // Second request.
alyssar2adf3ac2016-05-03 17:12:584355 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234356 SYNCHRONOUS,
4357 ConstructClientRequestHeadersPacket(
4358 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4359 true, GetRequestHeaders("GET", "https", "/"),
4360 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434361 mock_quic_data.AddRead(
4362 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334363 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284364 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434365 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334366 ASYNC, ConstructServerDataPacket(
4367 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524368 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474369 mock_quic_data.AddWrite(SYNCHRONOUS,
4370 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:304371 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214372 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi32569c62016-01-08 02:54:304373
4374 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454375
4376 AddHangingNonAlternateProtocolSocketData();
4377 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304378
rch3f4b8452016-02-23 16:59:324379 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564380 QuicStreamFactoryPeer::SetAlarmFactory(
4381 session_->quic_stream_factory(),
4382 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224383 context_.clock()));
zhongyi32569c62016-01-08 02:54:304384
bnc359ed2a2016-04-29 20:43:454385 const char destination1[] = "first.example.com";
4386 const char destination2[] = "second.example.com";
4387
4388 // Set up alternative service entry to destination1.
4389 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214390 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
Peter Kastinge5a38ed2021-10-02 03:06:354391 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:494392 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074393 server, NetworkIsolationKey(), alternative_service, expiration,
4394 supported_versions_);
bnc359ed2a2016-04-29 20:43:454395 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524396 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454397 SendRequestAndExpectQuicResponse("hello!");
4398
4399 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214400 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494401 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074402 server, NetworkIsolationKey(), alternative_service, expiration,
4403 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524404 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454405 // even though alternative service destination is different.
4406 SendRequestAndExpectQuicResponse("hello!");
4407}
4408
4409// Pool to existing session with matching destination and matching certificate
4410// even if origin is different, and even if the alternative service with
4411// matching destination is not the first one on the list.
4412TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Victor Vasilieva1e66d72019-12-05 17:55:384413 context_.params()->allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454414 GURL origin1 = request_.url;
4415 GURL origin2("https://www.example.org/");
4416 ASSERT_NE(origin1.host(), origin2.host());
4417
Ryan Hamiltonabad59e2019-06-06 04:02:594418 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454419
Renjie Tangaadb84b2019-08-31 01:00:234420 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254421 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234422 mock_quic_data.AddWrite(SYNCHRONOUS,
4423 ConstructInitialSettingsPacket(packet_num++));
4424 }
bnc359ed2a2016-04-29 20:43:454425 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434426 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234427 SYNCHRONOUS,
4428 ConstructClientRequestHeadersPacket(
4429 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4430 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434431 mock_quic_data.AddRead(
4432 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334433 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284434 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434435 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334436 ASYNC, ConstructServerDataPacket(
4437 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524438 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234439 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344440 ConstructClientAckPacket(packet_num++, 2, 1));
bnc359ed2a2016-04-29 20:43:454441
4442 // Second request.
Yixin Wang079ad542018-01-11 04:06:054443 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224444 version_,
4445 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4446 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054447 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174448 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224449 version_,
4450 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4451 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584452 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434453 SYNCHRONOUS,
4454 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234455 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4456 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024457 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434458 mock_quic_data.AddRead(
4459 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334460 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284461 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434462 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334463 ASYNC, ConstructServerDataPacket(
4464 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524465 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474466 mock_quic_data.AddWrite(SYNCHRONOUS,
4467 ConstructClientAckPacket(packet_num++, 4, 3));
bnc359ed2a2016-04-29 20:43:454468 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214469 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:454470
4471 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4472
4473 AddHangingNonAlternateProtocolSocketData();
4474 AddHangingNonAlternateProtocolSocketData();
4475
4476 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564477 QuicStreamFactoryPeer::SetAlarmFactory(
4478 session_->quic_stream_factory(),
4479 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224480 context_.clock()));
bnc359ed2a2016-04-29 20:43:454481
4482 const char destination1[] = "first.example.com";
4483 const char destination2[] = "second.example.com";
4484
4485 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214486 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
Peter Kastinge5a38ed2021-10-02 03:06:354487 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:494488 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074489 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4490 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454491
4492 // Set up multiple alternative service entries for |origin2|,
4493 // the first one with a different destination as for |origin1|,
4494 // the second one with the same. The second one should be used,
4495 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214496 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454497 AlternativeServiceInfoVector alternative_services;
4498 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214499 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4500 alternative_service2, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384501 context_.params()->supported_versions));
bnc359ed2a2016-04-29 20:43:454502 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214503 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4504 alternative_service1, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384505 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494506 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4507 NetworkIsolationKey(),
4508 alternative_services);
bnc359ed2a2016-04-29 20:43:454509 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524510 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454511 SendRequestAndExpectQuicResponse("hello!");
4512
4513 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524514 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454515 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584516
bnc359ed2a2016-04-29 20:43:454517 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304518}
4519
4520// Multiple origins have listed the same alternative services. When there's a
4521// existing QUIC session opened by a request to other origin,
4522// if the cert is valid, should select this QUIC session to make the request
4523// if this is also the first existing QUIC session.
4524TEST_P(QuicNetworkTransactionTest,
4525 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltona51800a2022-02-12 19:34:354526 if (version_.AlpnDeferToRFCv1()) {
4527 // These versions currently do not support Alt-Svc.
4528 return;
4529 }
Victor Vasilieva1e66d72019-12-05 17:55:384530 context_.params()->allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294531 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304532
rch9ae5b3b2016-02-11 00:36:294533 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304534 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454535 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rch9ae5b3b2016-02-11 00:36:294536 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304537 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4538 MockRead(ASYNC, OK)};
4539
Ryan Sleevib8d7ea02018-05-07 20:01:014540 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304541 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084542 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304543 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4544
4545 // HTTP data for request to mail.example.org.
Ryan Hamiltona2dcbae2022-02-09 19:02:454546 std::string alt_svc_header2 = base::StrCat(
4547 {"Alt-Svc: ", GenerateQuicAltSvcHeaderValue({version_}, 444), ",",
4548 GenerateQuicAltSvcHeaderValue({version_}, "www.example.org", 443),
4549 "\r\n\r\n"});
zhongyi32569c62016-01-08 02:54:304550 MockRead http_reads2[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454551 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header2.data()),
zhongyi32569c62016-01-08 02:54:304552 MockRead("hello world from mail.example.org"),
4553 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4554 MockRead(ASYNC, OK)};
4555
Ryan Sleevib8d7ea02018-05-07 20:01:014556 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304557 socket_factory_.AddSocketDataProvider(&http_data2);
4558 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4559
Yixin Wang079ad542018-01-11 04:06:054560 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:224561 version_,
4562 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4563 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054564 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584565 server_maker_.set_hostname("www.example.org");
Zhongyi Shi1c022d22020-03-20 19:00:164566 client_maker_->set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594567 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234568 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254569 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234570 mock_quic_data.AddWrite(SYNCHRONOUS,
4571 ConstructInitialSettingsPacket(packet_num++));
4572 }
zhongyi32569c62016-01-08 02:54:304573 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584574 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234575 SYNCHRONOUS,
4576 ConstructClientRequestHeadersPacket(
4577 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4578 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434579
4580 mock_quic_data.AddRead(
4581 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334582 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284583 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334584 mock_quic_data.AddRead(
4585 ASYNC, ConstructServerDataPacket(
4586 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524587 ConstructDataFrame("hello from mail QUIC!")));
Renjie Tangaadb84b2019-08-31 01:00:234588 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344589 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434590 // Second QUIC request data.
4591 mock_quic_data.AddWrite(
4592 SYNCHRONOUS,
4593 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234594 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4595 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024596 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434597 mock_quic_data.AddRead(
4598 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334599 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284600 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334601 mock_quic_data.AddRead(
4602 ASYNC, ConstructServerDataPacket(
4603 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524604 ConstructDataFrame("hello from mail QUIC!")));
Renjie Tangb7afea82020-07-15 23:35:474605 mock_quic_data.AddWrite(SYNCHRONOUS,
4606 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:304607 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214608 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi32569c62016-01-08 02:54:304609
4610 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304611
rtennetib8e80fb2016-05-16 00:12:094612 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324613 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564614 QuicStreamFactoryPeer::SetAlarmFactory(
4615 session_->quic_stream_factory(),
4616 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224617 context_.clock()));
zhongyi32569c62016-01-08 02:54:304618
4619 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294620 request_.url = GURL("https://www.example.org/");
4621 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304622 request_.url = GURL("https://mail.example.org/");
4623 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4624
rch9ae5b3b2016-02-11 00:36:294625 // Open a QUIC session to mail.example.org:443 when making request
4626 // to mail.example.org.
4627 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454628 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304629
rch9ae5b3b2016-02-11 00:36:294630 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304631 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454632 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524633}
4634
4635TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
Ryan Hamiltona51800a2022-02-12 19:34:354636 if (version_.AlpnDeferToRFCv1()) {
4637 // These versions currently do not support Alt-Svc.
4638 return;
4639 }
Ryan Hamiltona2dcbae2022-02-09 19:02:454640 std::string alt_svc_header =
4641 base::StrCat({"Alt-Svc: ", GenerateQuicAltSvcHeaderValue({version_}, 137),
4642 "\r\n\r\n"});
bncc958faa2015-07-31 18:14:524643 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454644 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
bncc958faa2015-07-31 18:14:524645 MockRead("hello world"),
4646 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4647 MockRead(ASYNC, OK)};
4648
Ryan Sleevib8d7ea02018-05-07 20:01:014649 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524650 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084651 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564652 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524653
rtennetib8e80fb2016-05-16 00:12:094654 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324655 CreateSession();
bncc958faa2015-07-31 18:14:524656
4657 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454658
4659 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344660 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494661 http_server_properties_->GetAlternativeServiceInfos(
4662 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344663 ASSERT_EQ(1u, alternative_service_info_vector.size());
4664 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544665 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344666 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4667 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4668 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524669}
4670
4671TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
Ryan Hamiltona51800a2022-02-12 19:34:354672 if (version_.AlpnDeferToRFCv1()) {
4673 // These versions currently do not support Alt-Svc.
4674 return;
4675 }
bncc958faa2015-07-31 18:14:524676 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454677 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:564678 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524679 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4680 MockRead(ASYNC, OK)};
4681
Ryan Sleevib8d7ea02018-05-07 20:01:014682 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524683 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084684 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564685 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524686
Ryan Hamiltonabad59e2019-06-06 04:02:594687 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234688 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254689 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234690 mock_quic_data.AddWrite(SYNCHRONOUS,
4691 ConstructInitialSettingsPacket(packet_num++));
4692 }
rch5cb522462017-04-25 20:18:364693 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234694 SYNCHRONOUS,
4695 ConstructClientRequestHeadersPacket(
4696 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4697 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434698 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334699 ASYNC, ConstructServerResponseHeadersPacket(
4700 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284701 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334702 mock_quic_data.AddRead(
4703 ASYNC, ConstructServerDataPacket(
4704 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524705 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234706 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344707 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:524708 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214709 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:524710
4711 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4712
rtennetib8e80fb2016-05-16 00:12:094713 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324714 CreateSession();
bncc958faa2015-07-31 18:14:524715
bnc3472afd2016-11-17 15:27:214716 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524717 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494718 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054719 alternative_service, NetworkIsolationKey());
Matt Menke3233d8f22019-08-20 21:01:494720 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054721 alternative_service, NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524722
4723 SendRequestAndExpectHttpResponse("hello world");
4724 SendRequestAndExpectQuicResponse("hello!");
4725
mmenkee24011922015-12-17 22:12:594726 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524727
Matt Menke3233d8f22019-08-20 21:01:494728 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054729 alternative_service, NetworkIsolationKey()));
Matt Menke19475f72019-08-21 18:57:444730 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4731 url::SchemeHostPort("https", request_.url.host(), 443),
4732 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524733}
4734
Matt Menkeb32ba5122019-09-10 19:17:054735TEST_P(QuicNetworkTransactionTest,
4736 ConfirmAlternativeServiceWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:354737 if (version_.AlpnDeferToRFCv1()) {
4738 // These versions currently do not support Alt-Svc.
4739 return;
4740 }
Matt Menke4807a9a2020-11-21 00:14:414741 const SchemefulSite kSite1(GURL("https://foo.test/"));
4742 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
4743 const SchemefulSite kSite2(GURL("https://bar.test/"));
4744 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:054745
4746 base::test::ScopedFeatureList feature_list;
4747 feature_list.InitWithFeatures(
4748 // enabled_features
4749 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4750 features::kPartitionConnectionsByNetworkIsolationKey},
4751 // disabled_features
4752 {});
4753 // Since HttpServerProperties caches the feature value, have to create a new
4754 // one.
4755 http_server_properties_ = std::make_unique<HttpServerProperties>();
4756
4757 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454758 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Matt Menkeb32ba5122019-09-10 19:17:054759 MockRead("hello world"),
4760 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4761 MockRead(ASYNC, OK)};
4762
4763 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4764 socket_factory_.AddSocketDataProvider(&http_data);
4765 AddCertificate(&ssl_data_);
4766 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4767
4768 MockQuicData mock_quic_data(version_);
4769 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254770 if (VersionUsesHttp3(version_.transport_version)) {
Matt Menkeb32ba5122019-09-10 19:17:054771 mock_quic_data.AddWrite(SYNCHRONOUS,
4772 ConstructInitialSettingsPacket(packet_num++));
4773 }
4774 mock_quic_data.AddWrite(
4775 SYNCHRONOUS,
4776 ConstructClientRequestHeadersPacket(
4777 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4778 true, GetRequestHeaders("GET", "https", "/")));
4779 mock_quic_data.AddRead(
4780 ASYNC, ConstructServerResponseHeadersPacket(
4781 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284782 GetResponseHeaders("200")));
Matt Menkeb32ba5122019-09-10 19:17:054783 mock_quic_data.AddRead(
4784 ASYNC, ConstructServerDataPacket(
4785 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524786 ConstructDataFrame("hello!")));
Matt Menkeb32ba5122019-09-10 19:17:054787 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344788 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menkeb32ba5122019-09-10 19:17:054789 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214790 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Matt Menkeb32ba5122019-09-10 19:17:054791
4792 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4793
4794 CreateSession();
4795
4796 AlternativeService alternative_service(kProtoQUIC,
4797 HostPortPair::FromURL(request_.url));
4798 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4799 alternative_service, kNetworkIsolationKey1);
4800 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4801 alternative_service, kNetworkIsolationKey2);
4802 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4803 alternative_service, kNetworkIsolationKey1));
4804 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4805 alternative_service, kNetworkIsolationKey2));
4806
4807 request_.network_isolation_key = kNetworkIsolationKey1;
4808 SendRequestAndExpectHttpResponse("hello world");
4809 SendRequestAndExpectQuicResponse("hello!");
4810
4811 mock_quic_data.Resume();
4812
4813 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4814 alternative_service, kNetworkIsolationKey1));
4815 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4816 url::SchemeHostPort("https", request_.url.host(), 443),
4817 kNetworkIsolationKey1));
4818 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4819 alternative_service, kNetworkIsolationKey2));
4820 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4821 url::SchemeHostPort("https", request_.url.host(), 443),
4822 kNetworkIsolationKey2));
4823}
4824
bncc958faa2015-07-31 18:14:524825TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
Ryan Hamiltona51800a2022-02-12 19:34:354826 if (version_.AlpnDeferToRFCv1()) {
4827 // These versions currently do not support Alt-Svc.
4828 return;
4829 }
bncc958faa2015-07-31 18:14:524830 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454831 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:564832 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524833 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4834 MockRead(ASYNC, OK)};
4835
Ryan Sleevib8d7ea02018-05-07 20:01:014836 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524837 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564838 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524839
Ryan Hamiltonabad59e2019-06-06 04:02:594840 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234841 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254842 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234843 mock_quic_data.AddWrite(SYNCHRONOUS,
4844 ConstructInitialSettingsPacket(packet_num++));
4845 }
rch5cb522462017-04-25 20:18:364846 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234847 SYNCHRONOUS,
4848 ConstructClientRequestHeadersPacket(
4849 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4850 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434851 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334852 ASYNC, ConstructServerResponseHeadersPacket(
4853 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284854 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334855 mock_quic_data.AddRead(
4856 ASYNC, ConstructServerDataPacket(
4857 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524858 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234859 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344860 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:524861 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4862
4863 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4864
4865 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324866 CreateSession();
bncc958faa2015-07-31 18:14:524867
4868 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4869 SendRequestAndExpectHttpResponse("hello world");
4870}
4871
bnc1c196c6e2016-05-28 13:51:484872TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
Ryan Hamiltona51800a2022-02-12 19:34:354873 if (version_.AlpnDeferToRFCv1()) {
4874 // These versions currently do not support Alt-Svc.
4875 return;
4876 }
[email protected]dda75ab2013-06-22 22:43:304877 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274878 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304879
4880 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564881 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294882 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564883 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304884
Ryan Hamiltona2dcbae2022-02-09 19:02:454885 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4886 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
4887 MockRead(SYNCHRONOUS, 5, "hello world"),
4888 MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304889
Ryan Sleevib8d7ea02018-05-07 20:01:014890 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504891 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084892 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504893 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304894
4895 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454896 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304897 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454898 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304899 };
Ryan Sleevib8d7ea02018-05-07 20:01:014900 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504901 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304902
4903 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014904 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504905 socket_factory_.AddSocketDataProvider(&http_data2);
4906 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304907
bnc912a04b2016-04-20 14:19:504908 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304909
4910 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304911 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174912 ASSERT_TRUE(http_data.AllReadDataConsumed());
4913 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304914
4915 // Now run the second request in which the QUIC socket hangs,
4916 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304917 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454918 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304919
rch37de576c2015-05-17 20:28:174920 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4921 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454922 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304923}
4924
[email protected]1e960032013-12-20 19:00:204925TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594926 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164927 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494928 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254929 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:494930 mock_quic_data.AddWrite(SYNCHRONOUS,
4931 ConstructInitialSettingsPacket(packet_num++));
4932 }
Zhongyi Shi32f2fd02018-04-16 18:23:434933 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494934 SYNCHRONOUS,
4935 ConstructClientRequestHeadersPacket(
4936 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4937 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:164938 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4939 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Zhongyi Shi32f2fd02018-04-16 18:23:434940 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334941 ASYNC, ConstructServerResponseHeadersPacket(
4942 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284943 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334944 mock_quic_data.AddRead(
4945 ASYNC, ConstructServerDataPacket(
4946 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524947 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:494948 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344949 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:504950 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214951 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
[email protected]8ba81212013-05-03 13:11:484952
rcha5399e02015-04-21 19:32:044953 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484954
rtennetib8e80fb2016-05-16 00:12:094955 // The non-alternate protocol job needs to hang in order to guarantee that
4956 // the alternate-protocol job will "win".
4957 AddHangingNonAlternateProtocolSocketData();
4958
rch3f4b8452016-02-23 16:59:324959 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274960 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yang1ef6dfef2021-07-24 16:20:164961 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4962 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264963 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Fan Yang1ef6dfef2021-07-24 16:20:164964 IsError(ERR_IO_PENDING));
4965 // Complete host resolution in next message loop so that QUIC job could
4966 // proceed.
4967 base::RunLoop().RunUntilIdle();
4968 // Explicitly confirm the handshake.
4969 crypto_client_stream_factory_.last_stream()
4970 ->NotifySessionOneRttKeyAvailable();
4971
4972 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
4973 mock_quic_data.Resume();
4974
4975 // Run the QUIC session to completion.
4976 base::RunLoop().RunUntilIdle();
4977
4978 EXPECT_THAT(callback.WaitForResult(), IsOk());
4979
4980 CheckWasQuicResponse(&trans);
4981 CheckResponseData(&trans, "hello!");
rchac7f35e2017-03-15 20:42:304982
Matt Menke19475f72019-08-21 18:57:444983 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4984 url::SchemeHostPort("https", request_.url.host(), 443),
4985 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:484986}
4987
[email protected]1e960032013-12-20 19:00:204988TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594989 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164990 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494991 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:254992 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:494993 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:164994 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:494995 }
Fan Yang32c5a112018-12-10 20:06:334996 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494997 SYNCHRONOUS,
4998 ConstructClientRequestHeadersPacket(
4999 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5000 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:165001 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5002 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Zhongyi Shi32f2fd02018-04-16 18:23:435003 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335004 ASYNC, ConstructServerResponseHeadersPacket(
5005 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285006 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335007 mock_quic_data.AddRead(
5008 ASYNC, ConstructServerDataPacket(
5009 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525010 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:495011 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345012 ConstructClientAckPacket(packet_number++, 2, 1));
rchb27683c2015-07-29 23:53:505013 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215014 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rcha5399e02015-04-21 19:32:045015 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275016
5017 // In order for a new QUIC session to be established via alternate-protocol
5018 // without racing an HTTP connection, we need the host resolution to happen
5019 // synchronously.
5020 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295021 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565022 "");
[email protected]3a120a6b2013-06-25 01:08:275023
rtennetib8e80fb2016-05-16 00:12:095024 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325025 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275026 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yang1ef6dfef2021-07-24 16:20:165027 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5028 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265029 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Fan Yang1ef6dfef2021-07-24 16:20:165030 IsError(ERR_IO_PENDING));
5031 // Complete host resolution in next message loop so that QUIC job could
5032 // proceed.
5033 base::RunLoop().RunUntilIdle();
5034 // Explicitly confirm the handshake.
5035 crypto_client_stream_factory_.last_stream()
5036 ->NotifySessionOneRttKeyAvailable();
5037
5038 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
5039 mock_quic_data.Resume();
5040
5041 // Run the QUIC session to completion.
5042 base::RunLoop().RunUntilIdle();
5043
5044 EXPECT_THAT(callback.WaitForResult(), IsOk());
5045
5046 CheckWasQuicResponse(&trans);
5047 CheckResponseData(&trans, "hello!");
[email protected]3a120a6b2013-06-25 01:08:275048}
5049
[email protected]0fc924b2014-03-31 04:34:155050TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ryan Hamiltona51800a2022-02-12 19:34:355051 if (version_.AlpnDeferToRFCv1()) {
5052 // These versions currently do not support Alt-Svc.
5053 return;
5054 }
Nicolas Arciniegad2013f92020-02-07 23:00:565055 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:275056 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:565057 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155058
5059 // Since we are using a proxy, the QUIC job will not succeed.
5060 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295061 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5062 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565063 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155064
Ryan Hamiltona2dcbae2022-02-09 19:02:455065 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
5066 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
5067 MockRead(SYNCHRONOUS, 5, "hello world"),
5068 MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155069
Ryan Sleevib8d7ea02018-05-07 20:01:015070 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155071 socket_factory_.AddSocketDataProvider(&http_data);
5072
5073 // In order for a new QUIC session to be established via alternate-protocol
5074 // without racing an HTTP connection, we need the host resolution to happen
5075 // synchronously.
5076 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295077 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565078 "");
[email protected]0fc924b2014-03-31 04:34:155079
rch9ae5b3b2016-02-11 00:36:295080 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325081 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275082 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155083 SendRequestAndExpectHttpResponse("hello world");
5084}
5085
[email protected]1e960032013-12-20 19:00:205086TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:595087 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235088 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165089 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255090 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235091 mock_quic_data.AddWrite(SYNCHRONOUS,
5092 ConstructInitialSettingsPacket(packet_num++));
5093 }
Zhongyi Shi1c022d22020-03-20 19:00:165094 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365095 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235096 SYNCHRONOUS,
5097 ConstructClientRequestHeadersPacket(
5098 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5099 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435100 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335101 ASYNC, ConstructServerResponseHeadersPacket(
5102 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285103 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335104 mock_quic_data.AddRead(
5105 ASYNC, ConstructServerDataPacket(
5106 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525107 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235108 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345109 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:595110 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045111 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125112
rtennetib8e80fb2016-05-16 00:12:095113 // The non-alternate protocol job needs to hang in order to guarantee that
5114 // the alternate-protocol job will "win".
5115 AddHangingNonAlternateProtocolSocketData();
5116
[email protected]11c05872013-08-20 02:04:125117 // In order for a new QUIC session to be established via alternate-protocol
5118 // without racing an HTTP connection, we need the host resolution to happen
5119 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5120 // connection to the the server, in this test we require confirmation
5121 // before encrypting so the HTTP job will still start.
5122 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295123 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565124 "");
[email protected]11c05872013-08-20 02:04:125125
rch3f4b8452016-02-23 16:59:325126 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435127 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5128 false);
Ryan Hamilton9835e662018-08-02 05:36:275129 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125130
bnc691fda62016-08-12 00:43:165131 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125132 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265133 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125135
Fan Yang3673cc72020-02-07 14:49:285136 crypto_client_stream_factory_.last_stream()
5137 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015138 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505139
bnc691fda62016-08-12 00:43:165140 CheckWasQuicResponse(&trans);
5141 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125142}
5143
Steven Valdez58097ec32018-07-16 18:29:045144TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015145 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595146 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165147 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255148 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495149 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:165150 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:495151 }
Steven Valdez58097ec32018-07-16 18:29:045152 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015153 SYNCHRONOUS,
5154 ConstructClientRequestHeadersPacket(
5155 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5156 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335157 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025158 ASYNC, ConstructServerResponseHeadersPacket(
5159 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285160 GetResponseHeaders("425")));
Bence Béky6e243aa2019-12-13 19:01:075161 if (VersionUsesHttp3(version_.transport_version)) {
5162 mock_quic_data.AddWrite(
5163 SYNCHRONOUS,
5164 ConstructClientAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:345165 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, false,
Bence Béky6e243aa2019-12-13 19:01:075166 StreamCancellationQpackDecoderInstruction(0)));
5167 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165168 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075169 packet_number++, false,
5170 GetNthClientInitiatedBidirectionalStreamId(0),
5171 quic::QUIC_STREAM_CANCELLED));
5172 } else {
5173 mock_quic_data.AddWrite(
5174 SYNCHRONOUS,
5175 ConstructClientAckAndRstPacket(
5176 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:345177 quic::QUIC_STREAM_CANCELLED, 1, 1));
Bence Béky6e243aa2019-12-13 19:01:075178 }
Steven Valdez58097ec32018-07-16 18:29:045179
Zhongyi Shi1c022d22020-03-20 19:00:165180 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:045181
Steven Valdez58097ec32018-07-16 18:29:045182 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015183 SYNCHRONOUS,
5184 ConstructClientRequestHeadersPacket(
5185 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5186 true, GetRequestHeaders("GET", "https", "/"),
5187 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045188 mock_quic_data.AddRead(
5189 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335190 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285191 GetResponseHeaders("200")));
Steven Valdez58097ec32018-07-16 18:29:045192 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335193 ASYNC, ConstructServerDataPacket(
5194 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:525195 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:475196 mock_quic_data.AddWrite(SYNCHRONOUS,
5197 ConstructClientAckPacket(packet_number++, 3, 1));
Steven Valdez58097ec32018-07-16 18:29:045198 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215199 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Steven Valdez58097ec32018-07-16 18:29:045200
5201 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5202
5203 // In order for a new QUIC session to be established via alternate-protocol
5204 // without racing an HTTP connection, we need the host resolution to happen
5205 // synchronously.
5206 host_resolver_.set_synchronous_mode(true);
5207 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5208 "");
Steven Valdez58097ec32018-07-16 18:29:045209
5210 AddHangingNonAlternateProtocolSocketData();
5211 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275212 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565213 QuicStreamFactoryPeer::SetAlarmFactory(
5214 session_->quic_stream_factory(),
5215 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225216 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045217
5218 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5219 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265220 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Steven Valdez58097ec32018-07-16 18:29:045221 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5222
5223 // Confirm the handshake after the 425 Too Early.
5224 base::RunLoop().RunUntilIdle();
5225
5226 // The handshake hasn't been confirmed yet, so the retry should not have
5227 // succeeded.
5228 EXPECT_FALSE(callback.have_result());
5229
Fan Yang3673cc72020-02-07 14:49:285230 crypto_client_stream_factory_.last_stream()
5231 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:045232
5233 EXPECT_THAT(callback.WaitForResult(), IsOk());
5234 CheckWasQuicResponse(&trans);
5235 CheckResponseData(&trans, "hello!");
5236}
5237
5238TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015239 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595240 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165241 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255242 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495243 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:165244 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:495245 }
Steven Valdez58097ec32018-07-16 18:29:045246 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015247 SYNCHRONOUS,
5248 ConstructClientRequestHeadersPacket(
5249 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5250 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335251 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025252 ASYNC, ConstructServerResponseHeadersPacket(
5253 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285254 GetResponseHeaders("425")));
Bence Béky6e243aa2019-12-13 19:01:075255 if (VersionUsesHttp3(version_.transport_version)) {
5256 mock_quic_data.AddWrite(
5257 SYNCHRONOUS,
5258 ConstructClientAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:345259 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, false,
Bence Béky6e243aa2019-12-13 19:01:075260 StreamCancellationQpackDecoderInstruction(0)));
5261 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165262 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075263 packet_number++, false,
5264 GetNthClientInitiatedBidirectionalStreamId(0),
5265 quic::QUIC_STREAM_CANCELLED));
5266 } else {
5267 mock_quic_data.AddWrite(
5268 SYNCHRONOUS,
5269 ConstructClientAckAndRstPacket(
5270 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:345271 quic::QUIC_STREAM_CANCELLED, 1, 1));
Bence Béky6e243aa2019-12-13 19:01:075272 }
Steven Valdez58097ec32018-07-16 18:29:045273
Zhongyi Shi1c022d22020-03-20 19:00:165274 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:045275
Steven Valdez58097ec32018-07-16 18:29:045276 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015277 SYNCHRONOUS,
5278 ConstructClientRequestHeadersPacket(
5279 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5280 true, GetRequestHeaders("GET", "https", "/"),
5281 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335282 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025283 ASYNC, ConstructServerResponseHeadersPacket(
5284 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285285 GetResponseHeaders("425")));
Bence Béky6e243aa2019-12-13 19:01:075286 if (VersionUsesHttp3(version_.transport_version)) {
5287 mock_quic_data.AddWrite(
5288 SYNCHRONOUS,
5289 ConstructClientAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:345290 packet_number++, false, GetQpackDecoderStreamId(), 2, 1, false,
Renjie Tang248e36ea2020-06-26 00:12:345291 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:075292 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165293 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075294 packet_number++, false,
5295 GetNthClientInitiatedBidirectionalStreamId(1),
5296 quic::QUIC_STREAM_CANCELLED));
5297 } else {
5298 mock_quic_data.AddWrite(
5299 SYNCHRONOUS,
5300 ConstructClientAckAndRstPacket(
5301 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
Renjie Tangcd594f32020-07-11 20:18:345302 quic::QUIC_STREAM_CANCELLED, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:075303 }
Steven Valdez58097ec32018-07-16 18:29:045304 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215305 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Steven Valdez58097ec32018-07-16 18:29:045306
5307 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5308
5309 // In order for a new QUIC session to be established via alternate-protocol
5310 // without racing an HTTP connection, we need the host resolution to happen
5311 // synchronously.
5312 host_resolver_.set_synchronous_mode(true);
5313 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5314 "");
Steven Valdez58097ec32018-07-16 18:29:045315
5316 AddHangingNonAlternateProtocolSocketData();
5317 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275318 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565319 QuicStreamFactoryPeer::SetAlarmFactory(
5320 session_->quic_stream_factory(),
5321 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225322 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045323
5324 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5325 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265326 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Steven Valdez58097ec32018-07-16 18:29:045327 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5328
5329 // Confirm the handshake after the 425 Too Early.
5330 base::RunLoop().RunUntilIdle();
5331
5332 // The handshake hasn't been confirmed yet, so the retry should not have
5333 // succeeded.
5334 EXPECT_FALSE(callback.have_result());
5335
Fan Yang3673cc72020-02-07 14:49:285336 crypto_client_stream_factory_.last_stream()
5337 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:045338
5339 EXPECT_THAT(callback.WaitForResult(), IsOk());
5340 const HttpResponseInfo* response = trans.GetResponseInfo();
5341 ASSERT_TRUE(response != nullptr);
5342 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:285343 EXPECT_EQ("HTTP/1.1 425", response->headers->GetStatusLine());
Steven Valdez58097ec32018-07-16 18:29:045344 EXPECT_TRUE(response->was_fetched_via_spdy);
5345 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085346 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5347 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045348}
5349
zhongyica364fbb2015-12-12 03:39:125350TEST_P(QuicNetworkTransactionTest,
5351 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Victor Vasilieva1e66d72019-12-05 17:55:385352 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595353 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235354 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165355 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255356 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235357 mock_quic_data.AddWrite(SYNCHRONOUS,
5358 ConstructInitialSettingsPacket(packet_num++));
5359 }
Zhongyi Shi1c022d22020-03-20 19:00:165360 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365361 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235362 SYNCHRONOUS,
5363 ConstructClientRequestHeadersPacket(
5364 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5365 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125366 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525367 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435368 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125369 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5370
5371 // The non-alternate protocol job needs to hang in order to guarantee that
5372 // the alternate-protocol job will "win".
5373 AddHangingNonAlternateProtocolSocketData();
5374
5375 // In order for a new QUIC session to be established via alternate-protocol
5376 // without racing an HTTP connection, we need the host resolution to happen
5377 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5378 // connection to the the server, in this test we require confirmation
5379 // before encrypting so the HTTP job will still start.
5380 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295381 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125382 "");
zhongyica364fbb2015-12-12 03:39:125383
rch3f4b8452016-02-23 16:59:325384 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435385 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5386 false);
Ryan Hamilton9835e662018-08-02 05:36:275387 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125388
bnc691fda62016-08-12 00:43:165389 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125390 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265391 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015392 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125393
Fan Yang3673cc72020-02-07 14:49:285394 crypto_client_stream_factory_.last_stream()
5395 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015396 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125397
5398 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525399 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125400
bnc691fda62016-08-12 00:43:165401 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125402 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525403 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5404 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125405}
5406
5407TEST_P(QuicNetworkTransactionTest,
5408 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Victor Vasilieva1e66d72019-12-05 17:55:385409 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595410 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235411 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165412 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255413 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235414 mock_quic_data.AddWrite(SYNCHRONOUS,
5415 ConstructInitialSettingsPacket(packet_num++));
5416 }
Zhongyi Shi1c022d22020-03-20 19:00:165417 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365418 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235419 SYNCHRONOUS,
5420 ConstructClientRequestHeadersPacket(
5421 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5422 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215423 // Peer sending data from an non-existing stream causes this end to raise
5424 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335425 mock_quic_data.AddRead(
5426 ASYNC, ConstructServerRstPacket(
5427 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5428 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215429 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:375430 mock_quic_data.AddWrite(
Renjie Tang248e36ea2020-06-26 00:12:345431 SYNCHRONOUS,
5432 ConstructClientAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:345433 packet_num++, 1, 1,
Renjie Tang248e36ea2020-06-26 00:12:345434 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
5435 : quic::QUIC_INVALID_STREAM_ID,
Renjie Tanga35322a2020-12-02 20:12:275436 quic_error_details,
5437 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
5438 : quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125439 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5440
5441 // The non-alternate protocol job needs to hang in order to guarantee that
5442 // the alternate-protocol job will "win".
5443 AddHangingNonAlternateProtocolSocketData();
5444
5445 // In order for a new QUIC session to be established via alternate-protocol
5446 // without racing an HTTP connection, we need the host resolution to happen
5447 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5448 // connection to the the server, in this test we require confirmation
5449 // before encrypting so the HTTP job will still start.
5450 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295451 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125452 "");
zhongyica364fbb2015-12-12 03:39:125453
rch3f4b8452016-02-23 16:59:325454 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435455 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5456 false);
Ryan Hamilton9835e662018-08-02 05:36:275457 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125458
bnc691fda62016-08-12 00:43:165459 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125460 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265461 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015462 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125463
Fan Yang3673cc72020-02-07 14:49:285464 crypto_client_stream_factory_.last_stream()
5465 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015466 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125467 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525468 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125469
bnc691fda62016-08-12 00:43:165470 trans.PopulateNetErrorDetails(&details);
Renjie Tang248e36ea2020-06-26 00:12:345471 EXPECT_EQ(version_.HasIetfQuicFrames()
5472 ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
5473 : quic::QUIC_INVALID_STREAM_ID,
5474 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125475}
5476
Nick Harper057264a82019-09-12 23:33:495477TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:595478 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235479 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165480 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255481 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235482 mock_quic_data.AddWrite(SYNCHRONOUS,
5483 ConstructInitialSettingsPacket(packet_num++));
5484 }
Zhongyi Shi1c022d22020-03-20 19:00:165485 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365486 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235487 SYNCHRONOUS,
5488 ConstructClientRequestHeadersPacket(
5489 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5490 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485491 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335492 mock_quic_data.AddRead(
5493 ASYNC, ConstructServerResponseHeadersPacket(
5494 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285495 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335496 mock_quic_data.AddRead(
5497 ASYNC, ConstructServerRstPacket(
5498 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5499 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075500
5501 if (VersionUsesHttp3(version_.transport_version)) {
5502 mock_quic_data.AddWrite(
Renjie Tanga35322a2020-12-02 20:12:275503 SYNCHRONOUS,
5504 client_maker_->MakeAckRstAndDataPacket(
5505 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5506 quic::QUIC_STREAM_CANCELLED, 2, 1, GetQpackDecoderStreamId(), false,
5507 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:075508 } else {
5509 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345510 ConstructClientAckPacket(packet_num++, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:075511 }
rchcd5f1c62016-06-23 02:43:485512 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5513 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5514
5515 // The non-alternate protocol job needs to hang in order to guarantee that
5516 // the alternate-protocol job will "win".
5517 AddHangingNonAlternateProtocolSocketData();
5518
5519 // In order for a new QUIC session to be established via alternate-protocol
5520 // without racing an HTTP connection, we need the host resolution to happen
5521 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5522 // connection to the the server, in this test we require confirmation
5523 // before encrypting so the HTTP job will still start.
5524 host_resolver_.set_synchronous_mode(true);
5525 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5526 "");
rchcd5f1c62016-06-23 02:43:485527
5528 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435529 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5530 false);
Ryan Hamilton9835e662018-08-02 05:36:275531 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485532
bnc691fda62016-08-12 00:43:165533 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485534 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265535 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015536 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485537
Fan Yang3673cc72020-02-07 14:49:285538 crypto_client_stream_factory_.last_stream()
5539 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:485540 // Read the headers.
robpercival214763f2016-07-01 23:27:015541 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485542
bnc691fda62016-08-12 00:43:165543 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485544 ASSERT_TRUE(response != nullptr);
5545 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:285546 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
rchcd5f1c62016-06-23 02:43:485547 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525548 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085549 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5550 response->connection_info);
rchcd5f1c62016-06-23 02:43:485551
5552 std::string response_data;
bnc691fda62016-08-12 00:43:165553 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485554}
5555
Nick Harper057264a82019-09-12 23:33:495556TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:385557 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595558 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235559 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165560 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255561 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235562 mock_quic_data.AddWrite(SYNCHRONOUS,
5563 ConstructInitialSettingsPacket(packet_num++));
5564 }
Zhongyi Shi1c022d22020-03-20 19:00:165565 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365566 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235567 SYNCHRONOUS,
5568 ConstructClientRequestHeadersPacket(
5569 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5570 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335571 mock_quic_data.AddRead(
5572 ASYNC, ConstructServerRstPacket(
5573 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5574 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075575
5576 if (VersionUsesHttp3(version_.transport_version)) {
5577 mock_quic_data.AddWrite(
Renjie Tanga35322a2020-12-02 20:12:275578 SYNCHRONOUS,
Fan Yang8d4177792021-07-16 17:48:535579 client_maker_->MakeAckRstAndDataPacket(
Renjie Tanga35322a2020-12-02 20:12:275580 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5581 quic::QUIC_STREAM_CANCELLED, 1, 1, GetQpackDecoderStreamId(), false,
5582 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:075583 }
5584
rchcd5f1c62016-06-23 02:43:485585 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5586 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5587
5588 // The non-alternate protocol job needs to hang in order to guarantee that
5589 // the alternate-protocol job will "win".
5590 AddHangingNonAlternateProtocolSocketData();
5591
5592 // In order for a new QUIC session to be established via alternate-protocol
5593 // without racing an HTTP connection, we need the host resolution to happen
5594 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5595 // connection to the the server, in this test we require confirmation
5596 // before encrypting so the HTTP job will still start.
5597 host_resolver_.set_synchronous_mode(true);
5598 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5599 "");
rchcd5f1c62016-06-23 02:43:485600
5601 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435602 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5603 false);
Ryan Hamilton9835e662018-08-02 05:36:275604 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485605
bnc691fda62016-08-12 00:43:165606 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485607 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265608 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015609 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485610
Fan Yang3673cc72020-02-07 14:49:285611 crypto_client_stream_factory_.last_stream()
5612 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:485613 // Read the headers.
robpercival214763f2016-07-01 23:27:015614 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485615}
5616
[email protected]1e960032013-12-20 19:00:205617TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305618 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525619 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585620 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305621 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505622 MockRead(ASYNC, close->data(), close->length()),
5623 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5624 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305625 };
Ryan Sleevib8d7ea02018-05-07 20:01:015626 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305627 socket_factory_.AddSocketDataProvider(&quic_data);
5628
5629 // Main job which will succeed even though the alternate job fails.
5630 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025631 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5632 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5633 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305634
Ryan Sleevib8d7ea02018-05-07 20:01:015635 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305636 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565637 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305638
rch3f4b8452016-02-23 16:59:325639 CreateSession();
David Schinazic8281052019-01-24 06:14:175640 AddQuicAlternateProtocolMapping(
5641 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195642 SendRequestAndExpectHttpResponse("hello from http");
5643 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305644}
5645
Matt Menkeb32ba5122019-09-10 19:17:055646TEST_P(QuicNetworkTransactionTest,
5647 BrokenAlternateProtocolWithNetworkIsolationKey) {
Matt Menke4807a9a2020-11-21 00:14:415648 const SchemefulSite kSite1(GURL("https://foo.test/"));
5649 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
5650 const SchemefulSite kSite2(GURL("https://bar.test/"));
5651 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:055652
5653 base::test::ScopedFeatureList feature_list;
5654 feature_list.InitWithFeatures(
5655 // enabled_features
5656 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5657 features::kPartitionConnectionsByNetworkIsolationKey},
5658 // disabled_features
5659 {});
5660 // Since HttpServerProperties caches the feature value, have to create a new
5661 // one.
5662 http_server_properties_ = std::make_unique<HttpServerProperties>();
5663
5664 // Alternate-protocol job
5665 std::unique_ptr<quic::QuicEncryptedPacket> close(
5666 ConstructServerConnectionClosePacket(1));
5667 MockRead quic_reads[] = {
5668 MockRead(ASYNC, close->data(), close->length()),
5669 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5670 MockRead(ASYNC, OK), // EOF
5671 };
5672 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5673 socket_factory_.AddSocketDataProvider(&quic_data);
5674
5675 // Main job which will succeed even though the alternate job fails.
5676 MockRead http_reads[] = {
5677 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5678 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5679 MockRead(ASYNC, OK)};
5680
5681 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5682 socket_factory_.AddSocketDataProvider(&http_data);
5683 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5684
5685 CreateSession();
5686 AddQuicAlternateProtocolMapping(
5687 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5688 AddQuicAlternateProtocolMapping(
5689 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5690 request_.network_isolation_key = kNetworkIsolationKey1;
5691 SendRequestAndExpectHttpResponse("hello from http");
5692
5693 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5694 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5695}
5696
[email protected]1e960032013-12-20 19:00:205697TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595698 // Alternate-protocol job
5699 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025700 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595701 };
Ryan Sleevib8d7ea02018-05-07 20:01:015702 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595703 socket_factory_.AddSocketDataProvider(&quic_data);
5704
5705 // Main job which will succeed even though the alternate job fails.
5706 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025707 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5708 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5709 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595710
Ryan Sleevib8d7ea02018-05-07 20:01:015711 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595712 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565713 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595714
rch3f4b8452016-02-23 16:59:325715 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595716
Ryan Hamilton9835e662018-08-02 05:36:275717 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195718 SendRequestAndExpectHttpResponse("hello from http");
5719 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595720}
5721
[email protected]00c159f2014-05-21 22:38:165722TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535723 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165724 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025725 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165726 };
Ryan Sleevib8d7ea02018-05-07 20:01:015727 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165728 socket_factory_.AddSocketDataProvider(&quic_data);
5729
[email protected]eb71ab62014-05-23 07:57:535730 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165731 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025732 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165733 };
5734
Ryan Sleevib8d7ea02018-05-07 20:01:015735 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165736 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5737 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565738 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165739
rtennetib8e80fb2016-05-16 00:12:095740 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325741 CreateSession();
[email protected]00c159f2014-05-21 22:38:165742
Ryan Hamilton9835e662018-08-02 05:36:275743 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165744 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165745 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265746 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5748 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165749 ExpectQuicAlternateProtocolMapping();
5750}
5751
Zhongyi Shia0cef1082017-08-25 01:49:505752TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5753 // Tests that TCP job is delayed and QUIC job does not require confirmation
5754 // if QUIC was recently supported on the same IP on start.
5755
5756 // Set QUIC support on the last IP address, which is same with the local IP
5757 // address. Require confirmation mode will be turned off immediately when
5758 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435759 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5760 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:505761
Ryan Hamiltonabad59e2019-06-06 04:02:595762 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165763 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495764 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255765 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495766 mock_quic_data.AddWrite(SYNCHRONOUS,
5767 ConstructInitialSettingsPacket(packet_number++));
5768 }
Zhongyi Shi32f2fd02018-04-16 18:23:435769 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495770 SYNCHRONOUS,
5771 ConstructClientRequestHeadersPacket(
5772 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5773 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:165774 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5775 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
Zhongyi Shi32f2fd02018-04-16 18:23:435776 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335777 ASYNC, ConstructServerResponseHeadersPacket(
5778 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285779 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335780 mock_quic_data.AddRead(
5781 ASYNC, ConstructServerDataPacket(
5782 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525783 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:495784 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345785 ConstructClientAckPacket(packet_number++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505786 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215787 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Zhongyi Shia0cef1082017-08-25 01:49:505788
5789 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5790 // No HTTP data is mocked as TCP job never starts in this case.
5791
5792 CreateSession();
5793 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:435794 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5795 false);
Zhongyi Shia0cef1082017-08-25 01:49:505796
Ryan Hamilton9835e662018-08-02 05:36:275797 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505798
5799 // Stall host resolution so that QUIC job will not succeed synchronously.
5800 // Socket will not be configured immediately and QUIC support is not sorted
5801 // out, TCP job will still be delayed as server properties indicates QUIC
5802 // support on last IP address.
5803 host_resolver_.set_synchronous_mode(false);
5804
5805 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5806 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265807 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Zhongyi Shia0cef1082017-08-25 01:49:505808 IsError(ERR_IO_PENDING));
5809 // Complete host resolution in next message loop so that QUIC job could
5810 // proceed.
5811 base::RunLoop().RunUntilIdle();
Fan Yang1ef6dfef2021-07-24 16:20:165812 // Explicitly confirm the handshake.
5813 crypto_client_stream_factory_.last_stream()
5814 ->NotifySessionOneRttKeyAvailable();
5815
5816 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
5817 mock_quic_data.Resume();
5818
5819 // Run the QUIC session to completion.
5820 base::RunLoop().RunUntilIdle();
Zhongyi Shia0cef1082017-08-25 01:49:505821 EXPECT_THAT(callback.WaitForResult(), IsOk());
5822
5823 CheckWasQuicResponse(&trans);
5824 CheckResponseData(&trans, "hello!");
5825}
5826
5827TEST_P(QuicNetworkTransactionTest,
5828 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5829 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5830 // was recently supported on a different IP address on start.
5831
5832 // Set QUIC support on the last IP address, which is different with the local
5833 // IP address. Require confirmation mode will remain when local IP address is
5834 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435835 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5836 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:505837
Ryan Hamiltonabad59e2019-06-06 04:02:595838 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235839 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165840 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255841 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235842 mock_quic_data.AddWrite(SYNCHRONOUS,
5843 ConstructInitialSettingsPacket(packet_num++));
5844 }
Zhongyi Shi1c022d22020-03-20 19:00:165845 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:505846 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235847 SYNCHRONOUS,
5848 ConstructClientRequestHeadersPacket(
5849 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5850 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435851 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335852 ASYNC, ConstructServerResponseHeadersPacket(
5853 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285854 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335855 mock_quic_data.AddRead(
5856 ASYNC, ConstructServerDataPacket(
5857 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525858 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235859 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345860 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505861 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5862 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5863 // No HTTP data is mocked as TCP job will be delayed and never starts.
5864
5865 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435866 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5867 false);
Ryan Hamilton9835e662018-08-02 05:36:275868 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505869
5870 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5871 // Socket will not be configured immediately and QUIC support is not sorted
5872 // out, TCP job will still be delayed as server properties indicates QUIC
5873 // support on last IP address.
5874 host_resolver_.set_synchronous_mode(false);
5875
5876 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5877 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265878 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Zhongyi Shia0cef1082017-08-25 01:49:505879 IsError(ERR_IO_PENDING));
5880
5881 // Complete host resolution in next message loop so that QUIC job could
5882 // proceed.
5883 base::RunLoop().RunUntilIdle();
5884 // Explicitly confirm the handshake so that QUIC job could succeed.
Fan Yang3673cc72020-02-07 14:49:285885 crypto_client_stream_factory_.last_stream()
5886 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia0cef1082017-08-25 01:49:505887 EXPECT_THAT(callback.WaitForResult(), IsOk());
5888
5889 CheckWasQuicResponse(&trans);
5890 CheckResponseData(&trans, "hello!");
5891}
5892
Ryan Hamilton75f197262017-08-17 14:00:075893TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5894 // Test that NetErrorDetails is correctly populated, even if the
5895 // handshake has not yet been confirmed and no stream has been created.
5896
5897 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595898 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075899 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5900 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5901 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5902
5903 // Main job will also fail.
5904 MockRead http_reads[] = {
5905 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5906 };
5907
Ryan Sleevib8d7ea02018-05-07 20:01:015908 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075909 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5910 socket_factory_.AddSocketDataProvider(&http_data);
5911 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5912
5913 AddHangingNonAlternateProtocolSocketData();
5914 CreateSession();
5915 // Require handshake confirmation to ensure that no QUIC streams are
5916 // created, and to ensure that the TCP job does not wait for the QUIC
5917 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:435918 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5919 false);
Ryan Hamilton75f197262017-08-17 14:00:075920
Ryan Hamilton9835e662018-08-02 05:36:275921 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075922 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5923 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265924 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton75f197262017-08-17 14:00:075925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5926 // Allow the TCP job to fail.
5927 base::RunLoop().RunUntilIdle();
5928 // Now let the QUIC job fail.
5929 mock_quic_data.Resume();
5930 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5931 ExpectQuicAlternateProtocolMapping();
5932 NetErrorDetails details;
5933 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525934 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075935}
5936
[email protected]1e960032013-12-20 19:00:205937TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455938 // Alternate-protocol job
5939 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025940 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455941 };
Ryan Sleevib8d7ea02018-05-07 20:01:015942 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455943 socket_factory_.AddSocketDataProvider(&quic_data);
5944
[email protected]c92c1b52014-05-31 04:16:065945 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015946 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065947 socket_factory_.AddSocketDataProvider(&quic_data2);
5948
[email protected]4d283b32013-10-17 12:57:275949 // Final job that will proceed when the QUIC job fails.
5950 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025951 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5952 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5953 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275954
Ryan Sleevib8d7ea02018-05-07 20:01:015955 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275956 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565957 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275958
rch3f4b8452016-02-23 16:59:325959 CreateSession();
[email protected]77c6c162013-08-17 02:57:455960
Ryan Hamilton9835e662018-08-02 05:36:275961 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455962
[email protected]4d283b32013-10-17 12:57:275963 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455964
5965 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275966
rch37de576c2015-05-17 20:28:175967 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5968 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455969}
5970
Matt Menkeb32ba5122019-09-10 19:17:055971TEST_P(QuicNetworkTransactionTest,
5972 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
5973 base::test::ScopedFeatureList feature_list;
5974 feature_list.InitWithFeatures(
5975 // enabled_features
5976 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5977 features::kPartitionConnectionsByNetworkIsolationKey},
5978 // disabled_features
5979 {});
5980 // Since HttpServerProperties caches the feature value, have to create a new
5981 // one.
5982 http_server_properties_ = std::make_unique<HttpServerProperties>();
5983
Matt Menke4807a9a2020-11-21 00:14:415984 const SchemefulSite kSite1(GURL("https://foo.test/"));
5985 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
5986 const SchemefulSite kSite2(GURL("https://bar.test/"));
5987 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:055988
5989 // Alternate-protocol job
5990 MockRead quic_reads[] = {
5991 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5992 };
5993 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5994 socket_factory_.AddSocketDataProvider(&quic_data);
5995
5996 // Second Alternate-protocol job which will race with the TCP job.
5997 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
5998 socket_factory_.AddSocketDataProvider(&quic_data2);
5999
6000 // Final job that will proceed when the QUIC job fails.
6001 MockRead http_reads[] = {
6002 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6003 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6004 MockRead(ASYNC, OK)};
6005
6006 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
6007 socket_factory_.AddSocketDataProvider(&http_data);
6008 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6009
6010 CreateSession();
6011
6012 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6013 kNetworkIsolationKey1);
6014 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6015 kNetworkIsolationKey2);
6016
6017 request_.network_isolation_key = kNetworkIsolationKey1;
6018 SendRequestAndExpectHttpResponse("hello from http");
6019 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6020 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
6021
6022 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6023 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6024
6025 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
6026 AddHttpDataAndRunRequest();
6027 // Requests using other NetworkIsolationKeys can still use QUIC.
6028 request_.network_isolation_key = kNetworkIsolationKey2;
6029 AddQuicDataAndRunRequest();
6030
6031 // The last two requests should not have changed the alternative service
6032 // mappings.
6033 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6034 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6035}
6036
[email protected]eb71ab62014-05-23 07:57:536037TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:336038 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:016039 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:496040 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:336041 socket_factory_.AddSocketDataProvider(&quic_data);
6042
6043 // Main job which will succeed even though the alternate job fails.
6044 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026045 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6046 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6047 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:336048
Ryan Sleevib8d7ea02018-05-07 20:01:016049 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:336050 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566051 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:336052
rch3f4b8452016-02-23 16:59:326053 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276054 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:336055 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:536056
6057 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:336058}
6059
Nidhi Jaju391105a2022-07-28 02:09:516060// TODO(crbug.com/1347664): This test is failing on various platforms.
6061TEST_P(QuicNetworkTransactionTest, DISABLED_ConnectionCloseDuringConnect) {
Ryan Hamiltona51800a2022-02-12 19:34:356062 if (version_.AlpnDeferToRFCv1()) {
6063 // These versions currently do not support Alt-Svc.
6064 return;
6065 }
Ryan Hamiltonabad59e2019-06-06 04:02:596066 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:166067 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:176068 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:046069 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:156070
6071 // When the QUIC connection fails, we will try the request again over HTTP.
6072 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:456073 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:566074 MockRead("hello world"),
6075 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6076 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:156077
Ryan Sleevib8d7ea02018-05-07 20:01:016078 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:156079 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566080 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:156081
6082 // In order for a new QUIC session to be established via alternate-protocol
6083 // without racing an HTTP connection, we need the host resolution to happen
6084 // synchronously.
6085 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:296086 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:566087 "");
[email protected]4fee9672014-01-08 14:47:156088
rch3f4b8452016-02-23 16:59:326089 CreateSession();
David Schinazic8281052019-01-24 06:14:176090 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
6091 AddQuicAlternateProtocolMapping(
6092 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:156093 SendRequestAndExpectHttpResponse("hello world");
6094}
6095
tbansalc3308d72016-08-27 10:25:046096TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltona51800a2022-02-12 19:34:356097 if (version_.AlpnDeferToRFCv1()) {
6098 // These versions currently do not support Alt-Svc.
6099 return;
6100 }
Ryan Hamiltonabad59e2019-06-06 04:02:596101 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:166102 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:176103 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:336104 mock_quic_data.AddWrite(
6105 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6106 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
6107 true, GetRequestHeaders("GET", "https", "/")));
Renjie Tangcd594f32020-07-11 20:18:346108 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1));
tbansalc3308d72016-08-27 10:25:046109 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6110
6111 // When the QUIC connection fails, we will try the request again over HTTP.
6112 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:456113 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
tbansalc3308d72016-08-27 10:25:046114 MockRead("hello world"),
6115 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6116 MockRead(ASYNC, OK)};
6117
Ryan Sleevib8d7ea02018-05-07 20:01:016118 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:046119 socket_factory_.AddSocketDataProvider(&http_data);
6120 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6121
6122 TestProxyDelegate test_proxy_delegate;
6123 const HostPortPair host_port_pair("myproxy.org", 443);
tbansalc3308d72016-08-27 10:25:046124
Nicolas Arciniegad2013f92020-02-07 23:00:566125 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276126 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Matt Menke7bc4def2020-07-29 20:54:516127 "QUIC myproxy.org:443; HTTPS myproxy.org:443",
6128 TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526129 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046130 request_.url = GURL("http://mail.example.org/");
6131
6132 // In order for a new QUIC session to be established via alternate-protocol
6133 // without racing an HTTP connection, we need the host resolution to happen
6134 // synchronously.
6135 host_resolver_.set_synchronous_mode(true);
6136 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:046137
6138 CreateSession();
David Schinazic8281052019-01-24 06:14:176139 crypto_client_stream_factory_.set_handshake_mode(
6140 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:046141 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596142 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166143 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046144}
6145
bnc508835902015-05-12 20:10:296146TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
Zhongyi Shi1c022d22020-03-20 19:00:166147 client_maker_->set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386148 EXPECT_FALSE(
6149 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:596150 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236151 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256152 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236153 mock_quic_data.AddWrite(SYNCHRONOUS,
6154 ConstructInitialSettingsPacket(packet_num++));
6155 }
rch5cb522462017-04-25 20:18:366156 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236157 SYNCHRONOUS,
6158 ConstructClientRequestHeadersPacket(
6159 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6160 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436161 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336162 ASYNC, ConstructServerResponseHeadersPacket(
6163 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286164 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336165 mock_quic_data.AddRead(
6166 ASYNC, ConstructServerDataPacket(
6167 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526168 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:236169 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346170 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:506171 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296172 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6173
bncb07c05532015-05-14 19:07:206174 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096175 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326176 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276177 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296178 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386179 EXPECT_TRUE(
6180 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296181}
6182
rtenneti56977812016-01-15 19:26:566183TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Victor Vasilieva1e66d72019-12-05 17:55:386184 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576185 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566186
Renjie Tangaadb84b2019-08-31 01:00:236187 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:256188 if (!VersionUsesHttp3(version_.transport_version))
David Schinazi395918c2021-02-05 18:56:216189 mock_quic_data.AddRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED);
Renjie Tangaadb84b2019-08-31 01:00:236190 else
6191 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6192 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6193 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6194
6195 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6196 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
6197 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:016198 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:236199 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:566200
rtennetib8e80fb2016-05-16 00:12:096201 // The non-alternate protocol job needs to hang in order to guarantee that
6202 // the alternate-protocol job will "win".
6203 AddHangingNonAlternateProtocolSocketData();
6204
rtenneti56977812016-01-15 19:26:566205 CreateSession();
6206 request_.method = "POST";
6207 ChunkedUploadDataStream upload_data(0);
6208 upload_data.AppendData("1", 1, true);
6209
6210 request_.upload_data_stream = &upload_data;
6211
bnc691fda62016-08-12 00:43:166212 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566213 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266214 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:016215 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566216 EXPECT_NE(OK, callback.WaitForResult());
6217}
6218
rche11300ef2016-09-02 01:44:286219TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Victor Vasilieva1e66d72019-12-05 17:55:386220 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286221 ScopedMockNetworkChangeNotifier network_change_notifier;
6222 MockNetworkChangeNotifier* mock_ncn =
6223 network_change_notifier.mock_network_change_notifier();
6224 mock_ncn->ForceNetworkHandlesSupported();
6225 mock_ncn->SetConnectedNetworksList(
6226 {kDefaultNetworkForTests, kNewNetworkForTests});
6227
Victor Vasilieva1e66d72019-12-05 17:55:386228 context_.params()->origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286229 HostPortPair::FromString("mail.example.org:443"));
Victor Vasilieva1e66d72019-12-05 17:55:386230 context_.params()->migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286231
Ryan Hamiltonabad59e2019-06-06 04:02:596232 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286233 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236234 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256235 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236236 socket_data.AddWrite(SYNCHRONOUS,
6237 ConstructInitialSettingsPacket(packet_num++));
6238 }
Fan Yang32c5a112018-12-10 20:06:336239 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236240 SYNCHRONOUS,
6241 ConstructClientRequestHeadersPacket(
6242 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6243 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:286244 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6245 socket_data.AddSocketDataToFactory(&socket_factory_);
6246
Ryan Hamiltonabad59e2019-06-06 04:02:596247 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286248 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6249 socket_data2.AddSocketDataToFactory(&socket_factory_);
6250
6251 // The non-alternate protocol job needs to hang in order to guarantee that
6252 // the alternate-protocol job will "win".
6253 AddHangingNonAlternateProtocolSocketData();
6254
6255 CreateSession();
6256 request_.method = "POST";
6257 ChunkedUploadDataStream upload_data(0);
6258
6259 request_.upload_data_stream = &upload_data;
6260
Tsuyoshi Horof8861cb2022-07-05 23:50:206261 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
6262 session_.get());
rche11300ef2016-09-02 01:44:286263 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266264 int rv = trans->Start(&request_, callback.callback(), net_log_with_source_);
rche11300ef2016-09-02 01:44:286265 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6266
6267 base::RunLoop().RunUntilIdle();
6268 upload_data.AppendData("1", 1, true);
6269 base::RunLoop().RunUntilIdle();
6270
6271 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506272 trans.reset();
rche11300ef2016-09-02 01:44:286273 session_.reset();
6274}
6275
Ryan Hamilton4b3574532017-10-30 20:17:256276TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386277 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256278 HostPortPair::FromString("mail.example.org:443"));
6279
Ryan Hamiltonabad59e2019-06-06 04:02:596280 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236281 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256282 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236283 socket_data.AddWrite(SYNCHRONOUS,
6284 ConstructInitialSettingsPacket(packet_num++));
6285 }
Ryan Hamilton4b3574532017-10-30 20:17:256286 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336287 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236288 SYNCHRONOUS,
6289 ConstructClientRequestHeadersPacket(
6290 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6291 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436292 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336293 ASYNC, ConstructServerResponseHeadersPacket(
6294 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286295 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336296 socket_data.AddRead(
6297 ASYNC, ConstructServerDataPacket(
6298 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526299 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:236300 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346301 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256302 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi1c022d22020-03-20 19:00:166303 socket_data.AddWrite(SYNCHRONOUS,
6304 client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:346305 packet_num++, false, 2, 1,
Zhongyi Shi1c022d22020-03-20 19:00:166306 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256307
6308 socket_data.AddSocketDataToFactory(&socket_factory_);
6309
6310 CreateSession();
6311
6312 SendRequestAndExpectQuicResponse("hello!");
6313 session_.reset();
6314}
6315
6316TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386317 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256318 HostPortPair::FromString("mail.example.org:443"));
6319
Ryan Hamiltonabad59e2019-06-06 04:02:596320 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236321 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256322 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236323 socket_data.AddWrite(SYNCHRONOUS,
6324 ConstructInitialSettingsPacket(packet_num++));
6325 }
Ryan Hamilton4b3574532017-10-30 20:17:256326 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336327 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236328 SYNCHRONOUS,
6329 ConstructClientRequestHeadersPacket(
6330 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6331 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436332 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336333 ASYNC, ConstructServerResponseHeadersPacket(
6334 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286335 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336336 socket_data.AddRead(
6337 ASYNC, ConstructServerDataPacket(
6338 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526339 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:236340 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346341 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256342 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi1c022d22020-03-20 19:00:166343 socket_data.AddWrite(SYNCHRONOUS,
6344 client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:346345 packet_num++, false, 2, 1,
Zhongyi Shi1c022d22020-03-20 19:00:166346 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256347
6348 socket_data.AddSocketDataToFactory(&socket_factory_);
6349
6350 CreateSession();
6351
6352 SendRequestAndExpectQuicResponse("hello!");
6353 session_.reset();
6354}
6355
Ryan Hamilton9edcf1a2017-11-22 05:55:176356TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386357 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6358 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256359 HostPortPair::FromString("mail.example.org:443"));
6360
Ryan Hamiltonabad59e2019-06-06 04:02:596361 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256362 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256363 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236364 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176365 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256366 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6367 }
6368 socket_data.AddSocketDataToFactory(&socket_factory_);
6369
6370 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176371 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176372 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6373 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256374
Victor Vasiliev7752898d2019-11-14 21:30:226375 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6377 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266378 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton4b3574532017-10-30 20:17:256379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176380 while (!callback.have_result()) {
6381 base::RunLoop().RunUntilIdle();
6382 quic_task_runner_->RunUntilIdle();
6383 }
6384 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256385 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176386 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6387 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6388 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226389 EXPECT_TRUE(context_.clock()->Now() - start >
6390 quic::QuicTime::Delta::FromSeconds(4));
6391 EXPECT_TRUE(context_.clock()->Now() - start <
6392 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256393}
6394
Ryan Hamilton9edcf1a2017-11-22 05:55:176395TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386396 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6397 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256398 HostPortPair::FromString("mail.example.org:443"));
6399
Ryan Hamiltonabad59e2019-06-06 04:02:596400 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256401 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256402 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236403 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176404 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256405 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6406 }
6407 socket_data.AddSocketDataToFactory(&socket_factory_);
6408
6409 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176410 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176411 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6412 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256413
Victor Vasiliev7752898d2019-11-14 21:30:226414 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256415 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6416 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266417 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton4b3574532017-10-30 20:17:256418 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176419 while (!callback.have_result()) {
6420 base::RunLoop().RunUntilIdle();
6421 quic_task_runner_->RunUntilIdle();
6422 }
6423 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256424 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176425 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6426 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6427 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226428 EXPECT_TRUE(context_.clock()->Now() - start >
6429 quic::QuicTime::Delta::FromSeconds(4));
6430 EXPECT_TRUE(context_.clock()->Now() - start <
6431 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256432}
6433
Cherie Shi7596de632018-02-22 07:28:186434TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Victor Vasilieva1e66d72019-12-05 17:55:386435 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6436 context_.params()->origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186437 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev62c09dc2020-11-06 18:18:296438 const std::string error_details = base::StrCat(
6439 {"Write failed with error: ", base::NumberToString(ERR_MSG_TOO_BIG), " (",
6440 strerror(ERR_MSG_TOO_BIG), ")"});
Cherie Shi7596de632018-02-22 07:28:186441
Ryan Hamiltonabad59e2019-06-06 04:02:596442 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186443 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236444 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256445 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236446 socket_data.AddWrite(SYNCHRONOUS,
6447 ConstructInitialSettingsPacket(packet_num++));
6448 }
Cherie Shi7596de632018-02-22 07:28:186449 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6450 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526451 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236452 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:166453 client_maker_->MakeConnectionClosePacket(
Renjie Tangaadb84b2019-08-31 01:00:236454 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186455 socket_data.AddSocketDataToFactory(&socket_factory_);
6456
6457 CreateSession();
6458
6459 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6460 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266461 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Cherie Shi7596de632018-02-22 07:28:186462 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6463 base::RunLoop().RunUntilIdle();
6464 ASSERT_TRUE(callback.have_result());
6465 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6466 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6467 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6468}
6469
ckrasic769733c2016-06-30 00:42:136470// Adds coverage to catch regression such as https://crbug.com/622043
6471TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Victor Vasiliev638956df2021-04-05 16:41:406472 if (VersionUsesHttp3(version_.transport_version)) {
6473 return;
6474 }
Victor Vasilieva1e66d72019-12-05 17:55:386475 context_.params()->origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136476 HostPortPair::FromString("mail.example.org:443"));
6477
Ryan Hamiltonabad59e2019-06-06 04:02:596478 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236479 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436480 mock_quic_data.AddWrite(
6481 SYNCHRONOUS,
6482 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336483 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026484 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436485 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:476486 ASYNC, ConstructServerPushPromisePacket(
6487 1, GetNthClientInitiatedBidirectionalStreamId(0),
6488 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6489 GetRequestHeaders("GET", "https", "/pushed.jpg")));
Haoyue Wang9d70d65c2020-05-29 22:45:346490 const bool should_send_priority_packet =
6491 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:346492 !VersionUsesHttp3(version_.transport_version);
6493 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346494 mock_quic_data.AddWrite(
6495 SYNCHRONOUS,
6496 ConstructClientAckAndPriorityPacket(
6497 client_packet_number++, false,
6498 /*largest_received=*/1, /*smallest_received=*/1,
6499 GetNthServerInitiatedUnidirectionalStreamId(0),
6500 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576501 }
Zhongyi Shi32f2fd02018-04-16 18:23:436502 mock_quic_data.AddRead(
6503 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336504 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286505 GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:006506 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346507 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346508 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346509 }
Zhongyi Shi32f2fd02018-04-16 18:23:436510 mock_quic_data.AddRead(
6511 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336512 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286513 false, GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:006514 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346515 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346516 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346517 }
Zhongyi Shi32f2fd02018-04-16 18:23:436518 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336519 ASYNC, ConstructServerDataPacket(
6520 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526521 ConstructDataFrame("hello!")));
Fan Yang32d79502020-06-24 22:36:006522 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346523 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346524 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:346525 }
Zhongyi Shi32f2fd02018-04-16 18:23:436526 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336527 ASYNC, ConstructServerDataPacket(
6528 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526529 ConstructDataFrame("and hello!")));
Fan Yang32d79502020-06-24 22:36:006530 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346531 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346532 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:346533 }
Renjie Tangee921d12020-02-06 00:41:496534 if (!VersionUsesHttp3(version_.transport_version)) {
6535 mock_quic_data.AddWrite(SYNCHRONOUS,
6536 ConstructClientAckAndRstPacket(
6537 client_packet_number++,
6538 GetNthServerInitiatedUnidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:346539 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
Renjie Tangee921d12020-02-06 00:41:496540 } else {
6541 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:166542 SYNCHRONOUS, client_maker_->MakeAckAndPriorityUpdatePacket(
Renjie Tangcd594f32020-07-11 20:18:346543 client_packet_number++, true, 5, 5, 3,
Renjie Tangee921d12020-02-06 00:41:496544 GetNthServerInitiatedUnidirectionalStreamId(0)));
6545 }
ckrasic769733c2016-06-30 00:42:136546 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216547 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
ckrasic769733c2016-06-30 00:42:136548 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6549
6550 // The non-alternate protocol job needs to hang in order to guarantee that
6551 // the alternate-protocol job will "win".
6552 AddHangingNonAlternateProtocolSocketData();
6553
6554 CreateSession();
6555
6556 // PUSH_PROMISE handling in the http layer gets exercised here.
6557 SendRequestAndExpectQuicResponse("hello!");
6558
6559 request_.url = GURL("https://mail.example.org/pushed.jpg");
6560 SendRequestAndExpectQuicResponse("and hello!");
6561
6562 // Check that the NetLog was filled reasonably.
Matt Reichhoff0049a0b72021-10-20 20:44:266563 auto entries = net_log_observer_.GetEntries();
ckrasic769733c2016-06-30 00:42:136564 EXPECT_LT(0u, entries.size());
6565
6566 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6567 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006568 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6569 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136570 EXPECT_LT(0, pos);
6571}
6572
Matt Menked804aaf2020-07-21 21:25:486573// Checks that if the same resource is pushed using two different
6574// NetworkIsolationKeys, both pushed resources are tracked independently, and
6575// NetworkIsolationKeys are respected.
6576TEST_P(QuicNetworkTransactionTest, QuicServerPushRespectsNetworkIsolationKey) {
Victor Vasiliev638956df2021-04-05 16:41:406577 if (VersionUsesHttp3(version_.transport_version)) {
6578 return;
6579 }
Matt Menked804aaf2020-07-21 21:25:486580 base::test::ScopedFeatureList feature_list;
6581 feature_list.InitAndEnableFeature(
6582 features::kPartitionConnectionsByNetworkIsolationKey);
Matt Menked804aaf2020-07-21 21:25:486583 context_.params()->origins_to_force_quic_on.insert(
6584 HostPortPair::FromString("mail.example.org:443"));
6585
6586 MockQuicData mock_quic_data1(version_);
6587 uint64_t client_packet_number1 = 1;
Matt Menked804aaf2020-07-21 21:25:486588 mock_quic_data1.AddWrite(
6589 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6590 client_packet_number1++,
6591 GetNthClientInitiatedBidirectionalStreamId(0), true,
6592 true, GetRequestHeaders("GET", "https", "/")));
6593 mock_quic_data1.AddRead(
6594 ASYNC, ConstructServerPushPromisePacket(
6595 1, GetNthClientInitiatedBidirectionalStreamId(0),
6596 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6597 GetRequestHeaders("GET", "https", "/pushed.jpg")));
6598 const bool should_send_priority_packet =
6599 client_headers_include_h2_stream_dependency_ &&
6600 !VersionUsesHttp3(version_.transport_version);
6601 if (should_send_priority_packet) {
6602 mock_quic_data1.AddWrite(
6603 SYNCHRONOUS,
6604 ConstructClientAckAndPriorityPacket(
6605 client_packet_number1++, false,
6606 /*largest_received=*/1, /*smallest_received=*/1,
6607 GetNthServerInitiatedUnidirectionalStreamId(0),
6608 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
6609 }
6610 mock_quic_data1.AddRead(
6611 ASYNC, ConstructServerResponseHeadersPacket(
6612 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286613 GetResponseHeaders("200")));
Matt Menked804aaf2020-07-21 21:25:486614 if (!should_send_priority_packet) {
6615 mock_quic_data1.AddWrite(
6616 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 2, 1));
6617 }
6618 mock_quic_data1.AddRead(
6619 ASYNC, ConstructServerResponseHeadersPacket(
6620 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286621 false, GetResponseHeaders("200")));
Matt Menked804aaf2020-07-21 21:25:486622 if (should_send_priority_packet) {
6623 mock_quic_data1.AddWrite(
6624 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 3, 1));
6625 }
Matt Menked804aaf2020-07-21 21:25:486626 mock_quic_data1.AddRead(
6627 ASYNC, ConstructServerDataPacket(
6628 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526629 ConstructDataFrame("hello1")));
Matt Menked804aaf2020-07-21 21:25:486630 if (!should_send_priority_packet) {
6631 mock_quic_data1.AddWrite(
6632 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 4, 3));
6633 }
Matt Menked804aaf2020-07-21 21:25:486634 mock_quic_data1.AddRead(
6635 ASYNC, ConstructServerDataPacket(
6636 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526637 ConstructDataFrame("and hello1")));
Matt Menked804aaf2020-07-21 21:25:486638 if (should_send_priority_packet) {
6639 mock_quic_data1.AddWrite(
6640 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 5, 3));
6641 }
6642 if (!VersionUsesHttp3(version_.transport_version)) {
6643 mock_quic_data1.AddWrite(SYNCHRONOUS,
6644 ConstructClientAckAndRstPacket(
6645 client_packet_number1++,
6646 GetNthServerInitiatedUnidirectionalStreamId(0),
6647 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
6648 } else {
6649 mock_quic_data1.AddWrite(
6650 SYNCHRONOUS, client_maker_->MakeAckAndPriorityUpdatePacket(
6651 client_packet_number1++, true, 5, 5, 3,
6652 GetNthServerInitiatedUnidirectionalStreamId(0)));
6653 }
6654 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6655 mock_quic_data1.AddRead(ASYNC, 0); // EOF
6656 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
6657
6658 QuicTestPacketMaker client_maker2(
6659 version_,
6660 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
6661 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
6662 client_headers_include_h2_stream_dependency_);
Matt Menked804aaf2020-07-21 21:25:486663 QuicTestPacketMaker server_maker2(
6664 version_,
6665 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
6666 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
6667 false);
6668 MockQuicData mock_quic_data2(version_);
6669 uint64_t client_packet_number2 = 1;
6670 if (VersionUsesHttp3(version_.transport_version)) {
6671 mock_quic_data2.AddWrite(
6672 SYNCHRONOUS,
6673 client_maker2.MakeInitialSettingsPacket(client_packet_number2++));
6674 }
6675 mock_quic_data2.AddWrite(
6676 SYNCHRONOUS,
6677 client_maker2.MakeRequestHeadersPacket(
6678 client_packet_number2++,
6679 GetNthClientInitiatedBidirectionalStreamId(0), true, true,
6680 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
6681 GetRequestHeaders("GET", "https", "/"), 0, nullptr));
6682 mock_quic_data2.AddRead(
6683 ASYNC, server_maker2.MakePushPromisePacket(
6684 1, GetNthClientInitiatedBidirectionalStreamId(0),
6685 GetNthServerInitiatedUnidirectionalStreamId(0), false, false,
6686 GetRequestHeaders("GET", "https", "/pushed.jpg"), nullptr));
6687 if (should_send_priority_packet) {
6688 mock_quic_data2.AddWrite(
6689 SYNCHRONOUS,
6690 client_maker2.MakeAckAndPriorityPacket(
6691 client_packet_number2++, false,
6692 /*largest_received=*/1, /*smallest_received=*/1,
6693 GetNthServerInitiatedUnidirectionalStreamId(0),
6694 GetNthClientInitiatedBidirectionalStreamId(0),
6695 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)));
6696 }
6697 mock_quic_data2.AddRead(
6698 ASYNC, server_maker2.MakeResponseHeadersPacket(
6699 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286700 GetResponseHeaders("200"), nullptr));
Matt Menked804aaf2020-07-21 21:25:486701 if (!should_send_priority_packet) {
6702 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6703 client_packet_number2++, 2, 1));
6704 }
6705 mock_quic_data2.AddRead(
6706 ASYNC, server_maker2.MakeResponseHeadersPacket(
6707 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286708 false, GetResponseHeaders("200"), nullptr));
Matt Menked804aaf2020-07-21 21:25:486709 if (should_send_priority_packet) {
6710 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6711 client_packet_number2++, 3, 1));
6712 }
Matt Menked804aaf2020-07-21 21:25:486713 mock_quic_data2.AddRead(
6714 ASYNC, server_maker2.MakeDataPacket(
6715 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526716 ConstructDataFrame("hello2")));
Matt Menked804aaf2020-07-21 21:25:486717 if (!should_send_priority_packet) {
6718 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6719 client_packet_number2++, 4, 3));
6720 }
Matt Menked804aaf2020-07-21 21:25:486721 mock_quic_data2.AddRead(
6722 ASYNC, server_maker2.MakeDataPacket(
6723 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526724 ConstructDataFrame("and hello2")));
Matt Menked804aaf2020-07-21 21:25:486725 if (should_send_priority_packet) {
6726 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6727 client_packet_number2++, 5, 3));
6728 }
6729 if (!VersionUsesHttp3(version_.transport_version)) {
6730 mock_quic_data2.AddWrite(SYNCHRONOUS,
6731 client_maker2.MakeAckAndRstPacket(
6732 client_packet_number2++, false,
6733 GetNthServerInitiatedUnidirectionalStreamId(0),
6734 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
6735 } else {
6736 mock_quic_data2.AddWrite(
6737 SYNCHRONOUS, client_maker2.MakeAckAndPriorityUpdatePacket(
6738 client_packet_number2++, true, 5, 5, 3,
6739 GetNthServerInitiatedUnidirectionalStreamId(0)));
6740 }
6741 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6742 mock_quic_data2.AddRead(ASYNC, 0); // EOF
6743 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
6744
6745 scoped_refptr<X509Certificate> cert(
6746 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
6747 verify_details_.cert_verify_result.verified_cert = cert;
6748 verify_details_.cert_verify_result.is_issued_by_known_root = true;
6749 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
6750
6751 // The non-alternate protocol jobs need to hang in order to guarantee that
6752 // the alternate-protocol job will "win". Use "AddTcpSocketDataProvider()", as
6753 // the connection requests may or may not actually make it to the socket
6754 // factory, there may or may not be a TCP connection made in between the two
6755 // QUIC connection attempts.
6756 StaticSocketDataProvider hanging_data1;
6757 hanging_data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
6758 socket_factory_.AddTcpSocketDataProvider(&hanging_data1);
6759 StaticSocketDataProvider hanging_data2;
6760 hanging_data2.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
6761 socket_factory_.AddTcpSocketDataProvider(&hanging_data2);
6762
6763 CreateSession();
6764
6765 NetworkIsolationKey network_isolation_key1 =
6766 NetworkIsolationKey::CreateTransient();
6767 NetworkIsolationKey network_isolation_key2 =
6768 NetworkIsolationKey::CreateTransient();
6769
6770 // Creates the first QUIC session, and triggers the first push.
6771 request_.network_isolation_key = network_isolation_key1;
6772 SendRequestAndExpectQuicResponse("hello1");
6773
6774 // Use a different NIK, which creates another QUIC session, triggering a
6775 // second push,
6776 request_.network_isolation_key = network_isolation_key2;
6777 SendRequestAndExpectQuicResponse("hello2");
6778
6779 // Use the second NIK again, should receive the push body from the second
6780 // session.
6781 request_.url = GURL("https://mail.example.org/pushed.jpg");
6782 SendRequestAndExpectQuicResponse("and hello2");
6783
6784 // Use the first NIK again, should receive the push body from the first
6785 // session.
6786 request_.network_isolation_key = network_isolation_key1;
6787 SendRequestAndExpectQuicResponse("and hello1");
6788}
6789
rch56ec40a2017-06-23 14:48:446790// Regression test for http://crbug.com/719461 in which a promised stream
6791// is closed before the pushed headers arrive, but after the connection
6792// is closed and before the callbacks are executed.
6793TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Victor Vasiliev638956df2021-04-05 16:41:406794 if (VersionUsesHttp3(version_.transport_version)) {
6795 return;
6796 }
Victor Vasilieva1e66d72019-12-05 17:55:386797 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6798 context_.params()->origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446799 HostPortPair::FromString("mail.example.org:443"));
6800
Ryan Hamiltonabad59e2019-06-06 04:02:596801 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236802 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446803 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436804 mock_quic_data.AddWrite(
6805 SYNCHRONOUS,
6806 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336807 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026808 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446809 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436810 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:476811 ASYNC, ConstructServerPushPromisePacket(
6812 1, GetNthClientInitiatedBidirectionalStreamId(0),
6813 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6814 GetRequestHeaders("GET", "https", "/pushed.jpg")));
Haoyue Wang9d70d65c2020-05-29 22:45:346815 const bool should_send_priority_packet =
6816 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:346817 !VersionUsesHttp3(version_.transport_version);
6818 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346819 mock_quic_data.AddWrite(
6820 SYNCHRONOUS,
6821 ConstructClientAckAndPriorityPacket(
6822 client_packet_number++, false,
6823 /*largest_received=*/1, /*smallest_received=*/1,
6824 GetNthServerInitiatedUnidirectionalStreamId(0),
6825 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576826 }
rch56ec40a2017-06-23 14:48:446827 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436828 mock_quic_data.AddRead(
6829 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336830 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286831 GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:006832 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346833 // Client ACKs the response headers.
6834 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346835 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346836 }
rch56ec40a2017-06-23 14:48:446837 // Response body for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436838 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336839 ASYNC, ConstructServerDataPacket(
6840 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526841 ConstructDataFrame("hello!")));
Fan Yang32d79502020-06-24 22:36:006842 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346843 // Client ACKs the response headers.
6844 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346845 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346846 }
rch56ec40a2017-06-23 14:48:446847 // Write error for the third request.
6848 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6849 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216850 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rch56ec40a2017-06-23 14:48:446851 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6852
6853 CreateSession();
6854
6855 // Send a request which triggers a push promise from the server.
6856 SendRequestAndExpectQuicResponse("hello!");
6857
6858 // Start a push transaction that will be cancelled after the connection
6859 // is closed, but before the callback is executed.
6860 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196861 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446862 session_.get());
6863 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:266864 int rv = trans2->Start(&request_, callback2.callback(), net_log_with_source_);
rch56ec40a2017-06-23 14:48:446865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6866 base::RunLoop().RunUntilIdle();
6867
6868 // Cause the connection to close on a write error.
6869 HttpRequestInfo request3;
6870 request3.method = "GET";
6871 request3.url = GURL("https://mail.example.org/");
6872 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106873 request3.traffic_annotation =
6874 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446875 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6876 TestCompletionCallback callback3;
Matt Reichhoff0049a0b72021-10-20 20:44:266877 EXPECT_THAT(
6878 trans3.Start(&request3, callback3.callback(), net_log_with_source_),
6879 IsError(ERR_IO_PENDING));
rch56ec40a2017-06-23 14:48:446880
6881 base::RunLoop().RunUntilIdle();
6882
6883 // When |trans2| is destroyed, the underlying stream will be closed.
6884 EXPECT_FALSE(callback2.have_result());
6885 trans2 = nullptr;
6886
6887 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6888}
6889
ckrasicda193a82016-07-09 00:39:366890TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Victor Vasilieva1e66d72019-12-05 17:55:386891 context_.params()->origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366892 HostPortPair::FromString("mail.example.org:443"));
6893
Ryan Hamiltonabad59e2019-06-06 04:02:596894 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:366895
Renjief49758b2019-01-11 23:32:416896 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:256897 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236898 mock_quic_data.AddWrite(
6899 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
6900 }
ckrasicda193a82016-07-09 00:39:366901
Bence Béky319388a882020-09-23 18:42:526902 mock_quic_data.AddWrite(
6903 SYNCHRONOUS,
6904 ConstructClientRequestHeadersAndDataFramesPacket(
6905 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6906 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
6907 0, nullptr, {ConstructDataFrame("1")}));
ckrasicda193a82016-07-09 00:39:366908
Zhongyi Shi32f2fd02018-04-16 18:23:436909 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336910 ASYNC, ConstructServerResponseHeadersPacket(
6911 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286912 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336913
6914 mock_quic_data.AddRead(
6915 ASYNC, ConstructServerDataPacket(
6916 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526917 ConstructDataFrame("hello!")));
ckrasicda193a82016-07-09 00:39:366918
Renjie Tangcd594f32020-07-11 20:18:346919 mock_quic_data.AddWrite(SYNCHRONOUS,
6920 ConstructClientAckPacket(write_packet_index++, 2, 1));
ckrasicda193a82016-07-09 00:39:366921
6922 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216923 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
ckrasicda193a82016-07-09 00:39:366924 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6925
6926 // The non-alternate protocol job needs to hang in order to guarantee that
6927 // the alternate-protocol job will "win".
6928 AddHangingNonAlternateProtocolSocketData();
6929
6930 CreateSession();
6931 request_.method = "POST";
6932 ChunkedUploadDataStream upload_data(0);
6933 upload_data.AppendData("1", 1, true);
6934
6935 request_.upload_data_stream = &upload_data;
6936
6937 SendRequestAndExpectQuicResponse("hello!");
6938}
6939
Ryan Sleevia9d6aa62019-07-26 13:32:186940TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
Ryan Hamiltona51800a2022-02-12 19:34:356941 if (version_.AlpnDeferToRFCv1()) {
6942 // These versions currently do not support Alt-Svc.
6943 return;
6944 }
Ryan Sleevia9d6aa62019-07-26 13:32:186945 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:206946
6947 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:456948 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yixin Wang10f477ed2017-11-21 04:20:206949 MockRead("hello world"),
6950 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6951 MockRead(ASYNC, OK)};
6952
Ryan Sleevib8d7ea02018-05-07 20:01:016953 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206954 socket_factory_.AddSocketDataProvider(&http_data);
6955 AddCertificate(&ssl_data_);
6956 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6957
Ryan Hamiltonabad59e2019-06-06 04:02:596958 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236959 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256960 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236961 mock_quic_data.AddWrite(SYNCHRONOUS,
6962 ConstructInitialSettingsPacket(packet_num++));
6963 }
Yixin Wang10f477ed2017-11-21 04:20:206964 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236965 SYNCHRONOUS,
6966 ConstructClientRequestHeadersPacket(
6967 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6968 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436969 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336970 ASYNC, ConstructServerResponseHeadersPacket(
6971 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286972 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336973 mock_quic_data.AddRead(
6974 ASYNC, ConstructServerDataPacket(
6975 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526976 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:236977 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346978 ConstructClientAckPacket(packet_num++, 2, 1));
Yixin Wang10f477ed2017-11-21 04:20:206979 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216980 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang10f477ed2017-11-21 04:20:206981
6982 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6983
6984 AddHangingNonAlternateProtocolSocketData();
6985 CreateSession();
6986
6987 SendRequestAndExpectHttpResponse("hello world");
6988 SendRequestAndExpectQuicResponse("hello!");
6989}
6990
Ryan Sleevia9d6aa62019-07-26 13:32:186991TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
Ryan Hamiltona51800a2022-02-12 19:34:356992 if (version_.AlpnDeferToRFCv1()) {
6993 // These versions currently do not support Alt-Svc.
6994 return;
6995 }
Ryan Sleevia9d6aa62019-07-26 13:32:186996 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:206997
6998 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:456999 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yixin Wang10f477ed2017-11-21 04:20:207000 MockRead("hello world"),
7001 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7002 MockRead(ASYNC, OK)};
7003
Ryan Sleevib8d7ea02018-05-07 20:01:017004 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207005 socket_factory_.AddSocketDataProvider(&http_data);
7006 AddCertificate(&ssl_data_);
7007 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7008 socket_factory_.AddSocketDataProvider(&http_data);
7009 AddCertificate(&ssl_data_);
7010 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7011
7012 AddHangingNonAlternateProtocolSocketData();
7013 CreateSession();
7014
7015 SendRequestAndExpectHttpResponse("hello world");
7016 SendRequestAndExpectHttpResponse("hello world");
7017}
7018
bnc359ed2a2016-04-29 20:43:457019class QuicNetworkTransactionWithDestinationTest
7020 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:017021 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:057022 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:457023 protected:
7024 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:557025 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:057026 client_headers_include_h2_stream_dependency_(
7027 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:567028 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:457029 destination_type_(GetParam().destination_type),
Tsuyoshi Horof8861cb2022-07-05 23:50:207030 ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()),
Nicolas Arciniegad2013f92020-02-07 23:00:567031 proxy_resolution_service_(
7032 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:117033 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Ryan Hamiltonf9a421f2020-01-31 21:09:527034 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:197035 FLAGS_quic_enable_http3_grease_randomness = false;
Ryan Hamiltonf9a421f2020-01-31 21:09:527036 }
bnc359ed2a2016-04-29 20:43:457037
7038 void SetUp() override {
7039 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557040 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457041
Matt Menke30a878c2021-07-20 22:25:097042 HttpNetworkSessionParams session_params;
mmenke6ddfbea2017-05-31 21:48:417043 session_params.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:387044 context_.params()->allow_remote_alt_svc = true;
7045 context_.params()->supported_versions = supported_versions_;
7046 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:057047 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:417048
Matt Menke30a878c2021-07-20 22:25:097049 HttpNetworkSessionContext session_context;
bnc359ed2a2016-04-29 20:43:457050
Victor Vasiliev7752898d2019-11-14 21:30:227051 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
bnc359ed2a2016-04-29 20:43:457052
7053 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277054 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:417055 session_context.quic_crypto_client_stream_factory =
7056 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:457057
Victor Vasiliev7752898d2019-11-14 21:30:227058 session_context.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:417059 session_context.client_socket_factory = &socket_factory_;
7060 session_context.host_resolver = &host_resolver_;
7061 session_context.cert_verifier = &cert_verifier_;
7062 session_context.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:417063 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
7064 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:457065 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:417066 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:597067 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:417068 session_context.http_auth_handler_factory = auth_handler_factory_.get();
7069 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:457070
Renjie Tang6ff9a9b2021-02-03 22:11:097071 session_ =
7072 std::make_unique<HttpNetworkSession>(session_params, session_context);
Matt Menkeb566c392019-09-11 23:22:437073 session_->quic_stream_factory()
7074 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:457075 }
7076
7077 void TearDown() override {
7078 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7079 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557080 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457081 PlatformTest::TearDown();
7082 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557083 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:407084 session_.reset();
bnc359ed2a2016-04-29 20:43:457085 }
7086
zhongyie537a002017-06-27 16:48:217087 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:457088 HostPortPair destination;
7089 switch (destination_type_) {
7090 case SAME_AS_FIRST:
7091 destination = HostPortPair(origin1_, 443);
7092 break;
7093 case SAME_AS_SECOND:
7094 destination = HostPortPair(origin2_, 443);
7095 break;
7096 case DIFFERENT:
7097 destination = HostPortPair(kDifferentHostname, 443);
7098 break;
7099 }
bnc3472afd2016-11-17 15:27:217100 AlternativeService alternative_service(kProtoQUIC, destination);
Peter Kastinge5a38ed2021-10-02 03:06:357101 base::Time expiration = base::Time::Now() + base::Days(1);
zhongyie537a002017-06-27 16:48:217102 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:077103 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
7104 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:457105 }
7106
Ryan Hamilton8d9ee76e2018-05-29 23:52:527107 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237108 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527109 quic::QuicStreamId stream_id,
7110 bool should_include_version,
7111 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527112 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137113 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457114 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Bence Béky4c325e52020-10-22 20:48:017115 spdy::Http2HeaderBlock headers(
Ryan Hamilton0239aac2018-05-19 00:03:137116 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027117 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457118 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027119 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:457120 }
7121
Ryan Hamilton8d9ee76e2018-05-29 23:52:527122 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237123 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527124 quic::QuicStreamId stream_id,
7125 bool should_include_version,
7126 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587127 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:027128 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:457129 }
7130
Ryan Hamilton8d9ee76e2018-05-29 23:52:527131 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237132 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527133 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527134 QuicTestPacketMaker* maker) {
Kenichi Ishibashif8634ab2021-03-16 23:41:287135 spdy::Http2HeaderBlock headers(maker->GetResponseHeaders("200"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027136 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
7137 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:457138 }
7139
Ryan Hamilton8d9ee76e2018-05-29 23:52:527140 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237141 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527142 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457143 QuicTestPacketMaker* maker) {
Bence Béky319388a882020-09-23 18:42:527144 return maker->MakeDataPacket(
7145 packet_number, stream_id, false, true,
7146 ConstructDataFrameForVersion("hello", version_));
bnc359ed2a2016-04-29 20:43:457147 }
7148
Ryan Hamilton8d9ee76e2018-05-29 23:52:527149 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237150 uint64_t packet_number,
7151 uint64_t largest_received,
7152 uint64_t smallest_received,
bnc359ed2a2016-04-29 20:43:457153 QuicTestPacketMaker* maker) {
7154 return maker->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:347155 smallest_received);
bnc359ed2a2016-04-29 20:43:457156 }
7157
Ryan Hamilton8d9ee76e2018-05-29 23:52:527158 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237159 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:377160 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027161 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:377162 }
7163
bnc359ed2a2016-04-29 20:43:457164 void AddRefusedSocketData() {
Tsuyoshi Horof8861cb2022-07-05 23:50:207165 auto refused_data = std::make_unique<StaticSocketDataProvider>();
bnc359ed2a2016-04-29 20:43:457166 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7167 refused_data->set_connect_data(refused_connect);
7168 socket_factory_.AddSocketDataProvider(refused_data.get());
7169 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7170 }
7171
7172 void AddHangingSocketData() {
Tsuyoshi Horof8861cb2022-07-05 23:50:207173 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
bnc359ed2a2016-04-29 20:43:457174 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7175 hanging_data->set_connect_data(hanging_connect);
7176 socket_factory_.AddSocketDataProvider(hanging_data.get());
7177 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7178 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7179 }
7180
7181 bool AllDataConsumed() {
7182 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7183 if (!socket_data_ptr->AllReadDataConsumed() ||
7184 !socket_data_ptr->AllWriteDataConsumed()) {
7185 return false;
7186 }
7187 }
7188 return true;
7189 }
7190
7191 void SendRequestAndExpectQuicResponse(const std::string& host) {
7192 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7193 HttpRequestInfo request;
7194 std::string url("https://");
7195 url.append(host);
7196 request.url = GURL(url);
7197 request.load_flags = 0;
7198 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107199 request.traffic_annotation =
7200 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457201 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267202 int rv = trans.Start(&request, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:017203 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457204
7205 std::string response_data;
robpercival214763f2016-07-01 23:27:017206 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457207 EXPECT_EQ("hello", response_data);
7208
7209 const HttpResponseInfo* response = trans.GetResponseInfo();
7210 ASSERT_TRUE(response != nullptr);
7211 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:287212 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
bnc359ed2a2016-04-29 20:43:457213 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527214 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:087215 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457216 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377217 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457218 }
7219
Fan Yang32c5a112018-12-10 20:06:337220 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567221 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7222 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367223 }
7224
Patrick Meenan0041f332022-05-19 23:48:357225 quic::test::QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Nick Harper23290b82019-05-02 00:02:567226 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057227 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567228 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457229 DestinationType destination_type_;
7230 std::string origin1_;
7231 std::string origin2_;
Victor Vasiliev7752898d2019-11-14 21:30:227232 MockQuicContext context_;
bnc359ed2a2016-04-29 20:43:457233 std::unique_ptr<HttpNetworkSession> session_;
7234 MockClientSocketFactory socket_factory_;
Eric Orthbe86fee2021-10-28 22:31:117235 MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
7236 RuleResolver::GetLocalhostResult()};
bnc359ed2a2016-04-29 20:43:457237 MockCertVerifier cert_verifier_;
7238 TransportSecurityState transport_security_state_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237239 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457240 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077241 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:267242 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457243 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:267244 HttpServerProperties http_server_properties_;
Matt Reichhoff0049a0b72021-10-20 20:44:267245 NetLogWithSource net_log_with_source_{
7246 NetLogWithSource::Make(NetLogSourceType::NONE)};
bnc359ed2a2016-04-29 20:43:457247 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7248 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7249 static_socket_data_provider_vector_;
7250 SSLSocketDataProvider ssl_data_;
7251};
7252
Victor Costane635086f2019-01-27 05:20:307253INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7254 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:577255 ::testing::ValuesIn(GetPoolingTestParams()),
7256 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:457257
7258// A single QUIC request fails because the certificate does not match the origin
7259// hostname, regardless of whether it matches the alternative service hostname.
7260TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7261 if (destination_type_ == DIFFERENT)
7262 return;
7263
7264 GURL url("https://mail.example.com/");
7265 origin1_ = url.host();
7266
7267 // Not used for requests, but this provides a test case where the certificate
7268 // is valid for the hostname of the alternative service.
7269 origin2_ = "mail.example.org";
7270
zhongyie537a002017-06-27 16:48:217271 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457272
7273 scoped_refptr<X509Certificate> cert(
7274 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247275 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7276 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457277
7278 ProofVerifyDetailsChromium verify_details;
7279 verify_details.cert_verify_result.verified_cert = cert;
7280 verify_details.cert_verify_result.is_issued_by_known_root = true;
7281 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7282
Ryan Hamiltonabad59e2019-06-06 04:02:597283 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457284 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
David Schinazi395918c2021-02-05 18:56:217285 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:457286
7287 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7288
7289 AddRefusedSocketData();
7290
7291 HttpRequestInfo request;
7292 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107293 request.traffic_annotation =
7294 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457295
7296 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7297 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267298 int rv = trans.Start(&request, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:017299 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457300
7301 EXPECT_TRUE(AllDataConsumed());
7302}
7303
7304// First request opens QUIC session to alternative service. Second request
7305// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527306// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457307TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7308 origin1_ = "mail.example.org";
7309 origin2_ = "news.example.org";
7310
zhongyie537a002017-06-27 16:48:217311 SetQuicAlternativeService(origin1_);
7312 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457313
7314 scoped_refptr<X509Certificate> cert(
7315 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247316 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7317 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7318 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457319
7320 ProofVerifyDetailsChromium verify_details;
7321 verify_details.cert_verify_result.verified_cert = cert;
7322 verify_details.cert_verify_result.is_issued_by_known_root = true;
7323 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7324
Yixin Wang079ad542018-01-11 04:06:057325 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227326 version_,
7327 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7328 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057329 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177330 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227331 version_,
7332 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7333 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457334
Ryan Hamiltonabad59e2019-06-06 04:02:597335 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237336 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257337 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237338 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7339 packet_num++, &client_maker));
7340 }
Fan Yang32c5a112018-12-10 20:06:337341 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237342 SYNCHRONOUS,
7343 ConstructClientRequestHeadersPacket(
7344 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7345 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:027346 mock_quic_data.AddRead(
7347 ASYNC,
7348 ConstructServerResponseHeadersPacket(
7349 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437350 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337351 ASYNC,
7352 ConstructServerDataPacket(
7353 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237354 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347355 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457356
Yixin Wang079ad542018-01-11 04:06:057357 client_maker.set_hostname(origin2_);
7358 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457359
Zhongyi Shi32f2fd02018-04-16 18:23:437360 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027361 SYNCHRONOUS,
7362 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237363 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027364 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7365 mock_quic_data.AddRead(
7366 ASYNC,
7367 ConstructServerResponseHeadersPacket(
7368 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437369 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337370 ASYNC,
7371 ConstructServerDataPacket(
7372 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237373 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347374 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3, &client_maker));
bnc359ed2a2016-04-29 20:43:457375 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:217376 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:457377
7378 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7379
7380 AddHangingSocketData();
7381 AddHangingSocketData();
7382
Tsuyoshi Horo2c0a5042022-07-06 05:53:077383 auto quic_task_runner =
7384 base::MakeRefCounted<TestTaskRunner>(context_.mock_clock());
Fan Yangc9e00dc2018-10-09 14:17:567385 QuicStreamFactoryPeer::SetAlarmFactory(
7386 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097387 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Victor Vasiliev7752898d2019-11-14 21:30:227388 context_.clock()));
Fan Yangc9e00dc2018-10-09 14:17:567389
bnc359ed2a2016-04-29 20:43:457390 SendRequestAndExpectQuicResponse(origin1_);
7391 SendRequestAndExpectQuicResponse(origin2_);
7392
7393 EXPECT_TRUE(AllDataConsumed());
7394}
7395
7396// First request opens QUIC session to alternative service. Second request does
7397// not pool to it, even though destination matches, because certificate is not
7398// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527399// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457400TEST_P(QuicNetworkTransactionWithDestinationTest,
7401 DoNotPoolIfCertificateInvalid) {
7402 origin1_ = "news.example.org";
7403 origin2_ = "mail.example.com";
7404
zhongyie537a002017-06-27 16:48:217405 SetQuicAlternativeService(origin1_);
7406 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457407
7408 scoped_refptr<X509Certificate> cert1(
7409 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247410 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7411 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7412 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457413
7414 scoped_refptr<X509Certificate> cert2(
7415 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247416 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7417 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457418
7419 ProofVerifyDetailsChromium verify_details1;
7420 verify_details1.cert_verify_result.verified_cert = cert1;
7421 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7422 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7423
7424 ProofVerifyDetailsChromium verify_details2;
7425 verify_details2.cert_verify_result.verified_cert = cert2;
7426 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7427 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7428
Yixin Wang079ad542018-01-11 04:06:057429 QuicTestPacketMaker client_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227430 version_,
7431 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7432 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057433 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177434 QuicTestPacketMaker server_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227435 version_,
7436 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7437 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457438
Ryan Hamiltonabad59e2019-06-06 04:02:597439 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:237440 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257441 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237442 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7443 packet_num++, &client_maker1));
7444 }
Fan Yang32c5a112018-12-10 20:06:337445 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237446 SYNCHRONOUS,
7447 ConstructClientRequestHeadersPacket(
7448 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7449 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437450 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337451 ASYNC,
7452 ConstructServerResponseHeadersPacket(
7453 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437454 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337455 ASYNC,
7456 ConstructServerDataPacket(
7457 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437458 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237459 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347460 ConstructClientAckPacket(packet_num++, 2, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457461 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7462 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7463
7464 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7465
Yixin Wang079ad542018-01-11 04:06:057466 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227467 version_,
7468 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7469 context_.clock(), origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057470 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177471 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227472 version_,
7473 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7474 context_.clock(), origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457475
Ryan Hamiltonabad59e2019-06-06 04:02:597476 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:237477 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:257478 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237479 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7480 packet_num2++, &client_maker2));
7481 }
Fan Yang32c5a112018-12-10 20:06:337482 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237483 SYNCHRONOUS,
7484 ConstructClientRequestHeadersPacket(
7485 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7486 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437487 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337488 ASYNC,
7489 ConstructServerResponseHeadersPacket(
7490 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437491 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337492 ASYNC,
7493 ConstructServerDataPacket(
7494 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437495 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237496 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347497 ConstructClientAckPacket(packet_num2++, 2, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457498 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7499 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7500
7501 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7502
bnc359ed2a2016-04-29 20:43:457503 SendRequestAndExpectQuicResponse(origin1_);
7504 SendRequestAndExpectQuicResponse(origin2_);
7505
7506 EXPECT_TRUE(AllDataConsumed());
7507}
7508
ckrasicdee37572017-04-06 22:42:277509// crbug.com/705109 - this confirms that matching request with a body
7510// triggers a crash (pre-fix).
7511TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Victor Vasiliev638956df2021-04-05 16:41:407512 if (VersionUsesHttp3(version_.transport_version)) {
7513 return;
7514 }
Victor Vasilieva1e66d72019-12-05 17:55:387515 context_.params()->origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277516 HostPortPair::FromString("mail.example.org:443"));
7517
Ryan Hamiltonabad59e2019-06-06 04:02:597518 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237519 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437520 mock_quic_data.AddWrite(
7521 SYNCHRONOUS,
7522 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337523 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027524 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437525 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:477526 ASYNC, ConstructServerPushPromisePacket(
7527 1, GetNthClientInitiatedBidirectionalStreamId(0),
7528 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7529 GetRequestHeaders("GET", "https", "/pushed.jpg")));
Renjie Tang703fea92019-07-23 21:08:317530
Haoyue Wang9d70d65c2020-05-29 22:45:347531 const bool should_send_priority_packet =
7532 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:347533 !VersionUsesHttp3(version_.transport_version);
7534 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347535 mock_quic_data.AddWrite(
7536 SYNCHRONOUS,
7537 ConstructClientAckAndPriorityPacket(
7538 client_packet_number++, false,
7539 /*largest_received=*/1, /*smallest_received=*/1,
7540 GetNthServerInitiatedUnidirectionalStreamId(0),
7541 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577542 }
Zhongyi Shi32f2fd02018-04-16 18:23:437543 mock_quic_data.AddRead(
7544 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337545 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287546 GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:007547 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347548 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347549 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:347550 }
Zhongyi Shi32f2fd02018-04-16 18:23:437551 mock_quic_data.AddRead(
7552 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337553 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287554 false, GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:007555 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347556 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347557 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:347558 }
Zhongyi Shi32f2fd02018-04-16 18:23:437559 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337560 ASYNC, ConstructServerDataPacket(
7561 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527562 ConstructDataFrame("hello!")));
Fan Yang32d79502020-06-24 22:36:007563 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347564 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347565 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:347566 }
Renjief49758b2019-01-11 23:32:417567
Zhongyi Shi32f2fd02018-04-16 18:23:437568 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337569 ASYNC, ConstructServerDataPacket(
7570 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527571 ConstructDataFrame("and hello!")));
Fan Yang32d79502020-06-24 22:36:007572 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347573 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347574 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:347575 }
ckrasicdee37572017-04-06 22:42:277576
7577 // Because the matching request has a body, we will see the push
7578 // stream get cancelled, and the matching request go out on the
7579 // wire.
Fan Yang32d79502020-06-24 22:36:007580 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347581 mock_quic_data.AddWrite(
7582 SYNCHRONOUS,
7583 ConstructClientRstPacket(client_packet_number++,
7584 GetNthServerInitiatedUnidirectionalStreamId(0),
7585 quic::QUIC_STREAM_CANCELLED));
7586 } else {
7587 mock_quic_data.AddWrite(SYNCHRONOUS,
7588 ConstructClientAckAndRstPacket(
7589 client_packet_number++,
7590 GetNthServerInitiatedUnidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:347591 quic::QUIC_STREAM_CANCELLED, 5, 5));
Haoyue Wang9d70d65c2020-05-29 22:45:347592 }
Bence Béky319388a882020-09-23 18:42:527593 mock_quic_data.AddWrite(
7594 SYNCHRONOUS,
7595 ConstructClientRequestHeadersAndDataFramesPacket(
7596 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
7597 false, true, DEFAULT_PRIORITY,
7598 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7599 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7600 {ConstructDataFrame("1")}));
ckrasicdee37572017-04-06 22:42:277601
7602 // We see the same response as for the earlier pushed and cancelled
7603 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437604 mock_quic_data.AddRead(
7605 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337606 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287607 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:437608 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337609 ASYNC, ConstructServerDataPacket(
7610 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:527611 ConstructDataFrame("and hello!")));
ckrasicdee37572017-04-06 22:42:277612
Yixin Wangb470bc882018-02-15 18:43:577613 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347614 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6));
ckrasicdee37572017-04-06 22:42:277615 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:217616 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
ckrasicdee37572017-04-06 22:42:277617 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7618
7619 // The non-alternate protocol job needs to hang in order to guarantee that
7620 // the alternate-protocol job will "win".
7621 AddHangingNonAlternateProtocolSocketData();
7622
7623 CreateSession();
7624
7625 // PUSH_PROMISE handling in the http layer gets exercised here.
7626 SendRequestAndExpectQuicResponse("hello!");
7627
7628 request_.url = GURL("https://mail.example.org/pushed.jpg");
7629 ChunkedUploadDataStream upload_data(0);
7630 upload_data.AppendData("1", 1, true);
7631 request_.upload_data_stream = &upload_data;
7632 SendRequestAndExpectQuicResponse("and hello!");
7633}
7634
Bence Béky7538a952018-02-01 16:59:527635// Regression test for https://crbug.com/797825: If pushed headers describe a
7636// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7637// not be called (otherwise a DCHECK fails).
7638TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Victor Vasiliev638956df2021-04-05 16:41:407639 if (VersionUsesHttp3(version_.transport_version)) {
7640 return;
7641 }
Bence Béky4c325e52020-10-22 20:48:017642 spdy::Http2HeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527643 pushed_request_headers[":authority"] = "";
7644 pushed_request_headers[":method"] = "GET";
7645 pushed_request_headers[":path"] = "/";
7646 pushed_request_headers[":scheme"] = "nosuchscheme";
7647
Victor Vasilieva1e66d72019-12-05 17:55:387648 context_.params()->origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:527649 HostPortPair::FromString("mail.example.org:443"));
7650
Ryan Hamiltonabad59e2019-06-06 04:02:597651 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:527652
Renjie Tangaadb84b2019-08-31 01:00:237653 int packet_num = 1;
Bence Béky7538a952018-02-01 16:59:527654 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237655 SYNCHRONOUS,
7656 ConstructClientRequestHeadersPacket(
7657 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7658 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:527659
Fan Yang32c5a112018-12-10 20:06:337660 mock_quic_data.AddRead(
7661 ASYNC, ConstructServerPushPromisePacket(
7662 1, GetNthClientInitiatedBidirectionalStreamId(0),
7663 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Renjie Tangb7afea82020-07-15 23:35:477664 std::move(pushed_request_headers)));
Renjie Tangcd594f32020-07-11 20:18:347665 mock_quic_data.AddWrite(
7666 SYNCHRONOUS,
7667 ConstructClientAckAndRstPacket(
7668 packet_num++, GetNthServerInitiatedUnidirectionalStreamId(0),
7669 quic::QUIC_INVALID_PROMISE_URL, 1, 1));
Bence Béky7538a952018-02-01 16:59:527670
Zhongyi Shi32f2fd02018-04-16 18:23:437671 mock_quic_data.AddRead(
7672 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337673 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287674 GetResponseHeaders("200")));
Bence Béky7538a952018-02-01 16:59:527675
Zhongyi Shi32f2fd02018-04-16 18:23:437676 mock_quic_data.AddRead(
7677 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337678 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287679 false, GetResponseHeaders("200")));
Renjie Tangcd594f32020-07-11 20:18:347680 mock_quic_data.AddWrite(SYNCHRONOUS,
7681 ConstructClientAckPacket(packet_num++, 3, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:437682 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337683 ASYNC, ConstructServerDataPacket(
7684 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527685 ConstructDataFrame("hello!")));
Bence Béky7538a952018-02-01 16:59:527686
David Schinazi395918c2021-02-05 18:56:217687 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Bence Béky7538a952018-02-01 16:59:527688 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7689
7690 // The non-alternate protocol job needs to hang in order to guarantee that
7691 // the alternate-protocol job will "win".
7692 AddHangingNonAlternateProtocolSocketData();
7693
7694 CreateSession();
7695
7696 // PUSH_PROMISE handling in the http layer gets exercised here.
7697 SendRequestAndExpectQuicResponse("hello!");
7698
7699 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7700 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7701}
7702
Yixin Wang46a273ec302018-01-23 17:59:567703// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147704TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567705 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147706 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567707 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:277708 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:567709 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567710
Ryan Hamiltonabad59e2019-06-06 04:02:597711 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237712 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257713 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237714 mock_quic_data.AddWrite(SYNCHRONOUS,
7715 ConstructInitialSettingsPacket(packet_num++));
7716 }
Fan Yang32c5a112018-12-10 20:06:337717 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237718 SYNCHRONOUS,
7719 ConstructClientRequestHeadersPacket(
7720 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:497721 false,
7722 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:577723 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:497724 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:237725 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337726 mock_quic_data.AddRead(
7727 ASYNC, ConstructServerResponseHeadersPacket(
7728 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287729 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:567730
7731 const char get_request[] =
7732 "GET / HTTP/1.1\r\n"
7733 "Host: mail.example.org\r\n"
7734 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:527735 mock_quic_data.AddWrite(
7736 SYNCHRONOUS,
7737 ConstructClientAckAndDataPacket(
7738 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
7739 1, false, ConstructDataFrame(get_request)));
Renjief49758b2019-01-11 23:32:417740
Yixin Wang46a273ec302018-01-23 17:59:567741 const char get_response[] =
7742 "HTTP/1.1 200 OK\r\n"
7743 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437744 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337745 ASYNC, ConstructServerDataPacket(
7746 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527747 ConstructDataFrame(get_response)));
Fan Yang32c5a112018-12-10 20:06:337748 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417749 SYNCHRONOUS, ConstructServerDataPacket(
7750 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527751 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:237752 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347753 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:567754 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7755
Bence Béky6e243aa2019-12-13 19:01:077756 if (VersionUsesHttp3(version_.transport_version)) {
7757 mock_quic_data.AddWrite(
7758 SYNCHRONOUS, ConstructClientDataPacket(
7759 packet_num++, GetQpackDecoderStreamId(), true, false,
7760 StreamCancellationQpackDecoderInstruction(0)));
7761 }
7762
Yixin Wang46a273ec302018-01-23 17:59:567763 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417764 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237765 ConstructClientRstPacket(packet_num++,
7766 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417767 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567768
7769 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7770
7771 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7772
7773 CreateSession();
7774
7775 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097776 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567777 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567778 RunTransaction(&trans);
7779 CheckWasHttpResponse(&trans);
7780 CheckResponsePort(&trans, 70);
7781 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:567782 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7783
Cammie Smith Barnesbf91e2a2020-12-23 20:49:047784 // DNS aliases should be empty when using a proxy.
7785 EXPECT_TRUE(trans.GetResponseInfo()->dns_aliases.empty());
7786
Yixin Wang46a273ec302018-01-23 17:59:567787 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7788 // proxy socket to disconnect.
7789 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7790
7791 base::RunLoop().RunUntilIdle();
7792 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7793 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7794}
7795
7796// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147797TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567798 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147799 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567800 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:277801 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:567802 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567803
Ryan Hamiltonabad59e2019-06-06 04:02:597804 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237805 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257806 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237807 mock_quic_data.AddWrite(SYNCHRONOUS,
7808 ConstructInitialSettingsPacket(packet_num++));
7809 }
Fan Yang32c5a112018-12-10 20:06:337810 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237811 SYNCHRONOUS,
7812 ConstructClientRequestHeadersPacket(
7813 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:497814 false,
7815 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:577816 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:497817 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:237818 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337819 mock_quic_data.AddRead(
7820 ASYNC, ConstructServerResponseHeadersPacket(
7821 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287822 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:567823
7824 SpdyTestUtil spdy_util;
7825
Ryan Hamilton0239aac2018-05-19 00:03:137826 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567827 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:527828 mock_quic_data.AddWrite(
7829 SYNCHRONOUS,
7830 ConstructClientAckAndDataPacket(
7831 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
7832 1, false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Ryan Hamilton0239aac2018-05-19 00:03:137833 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567834 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:437835 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177836 ASYNC, ConstructServerDataPacket(
7837 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527838 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:567839
Ryan Hamilton0239aac2018-05-19 00:03:137840 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197841 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Zhongyi Shi32f2fd02018-04-16 18:23:437842 mock_quic_data.AddRead(
7843 SYNCHRONOUS,
7844 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337845 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527846 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Renjie Tangaadb84b2019-08-31 01:00:237847 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347848 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:567849 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7850
Bence Béky6e243aa2019-12-13 19:01:077851 if (VersionUsesHttp3(version_.transport_version)) {
7852 mock_quic_data.AddWrite(
7853 SYNCHRONOUS, ConstructClientDataPacket(
7854 packet_num++, GetQpackDecoderStreamId(), true, false,
7855 StreamCancellationQpackDecoderInstruction(0)));
7856 }
7857
Yixin Wang46a273ec302018-01-23 17:59:567858 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437859 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237860 ConstructClientRstPacket(packet_num++,
7861 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417862 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567863
7864 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7865
7866 SSLSocketDataProvider ssl_data(ASYNC, OK);
7867 ssl_data.next_proto = kProtoHTTP2;
7868 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7869
7870 CreateSession();
7871
7872 request_.url = GURL("https://mail.example.org/");
7873 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567874 RunTransaction(&trans);
7875 CheckWasSpdyResponse(&trans);
7876 CheckResponsePort(&trans, 70);
7877 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:567878 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7879
Wez0e717112018-06-18 23:09:227880 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7881 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567882 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7883
7884 base::RunLoop().RunUntilIdle();
7885 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7886 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7887}
7888
7889// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7890// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147891TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567892 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147893 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567894 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:277895 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:567896 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567897
Ryan Hamiltonabad59e2019-06-06 04:02:597898 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:417899 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:257900 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237901 mock_quic_data.AddWrite(
7902 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7903 }
Fan Yang32c5a112018-12-10 20:06:337904 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417905 SYNCHRONOUS,
7906 ConstructClientRequestHeadersPacket(
7907 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangee921d12020-02-06 00:41:497908 true, false,
7909 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:577910 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:497911 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027912 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337913 mock_quic_data.AddRead(
7914 ASYNC, ConstructServerResponseHeadersPacket(
7915 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287916 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:567917
Yixin Wang46a273ec302018-01-23 17:59:567918 const char get_request_1[] =
7919 "GET / HTTP/1.1\r\n"
7920 "Host: mail.example.org\r\n"
7921 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:527922 mock_quic_data.AddWrite(
7923 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7924 write_packet_index++, false,
7925 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
7926 false, ConstructDataFrame(get_request_1)));
Renjief49758b2019-01-11 23:32:417927
Yixin Wang46a273ec302018-01-23 17:59:567928 const char get_response_1[] =
7929 "HTTP/1.1 200 OK\r\n"
7930 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437931 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437932 ASYNC, ConstructServerDataPacket(
7933 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527934 ConstructDataFrame(get_response_1)));
Yixin Wang46a273ec302018-01-23 17:59:567935
Fan Yang32c5a112018-12-10 20:06:337936 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177937 SYNCHRONOUS, ConstructServerDataPacket(
7938 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527939 false, ConstructDataFrame("0123456789")));
Yixin Wang46a273ec302018-01-23 17:59:567940
Renjie Tangcd594f32020-07-11 20:18:347941 mock_quic_data.AddWrite(SYNCHRONOUS,
7942 ConstructClientAckPacket(write_packet_index++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:567943
7944 const char get_request_2[] =
7945 "GET /2 HTTP/1.1\r\n"
7946 "Host: mail.example.org\r\n"
7947 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:527948 mock_quic_data.AddWrite(
7949 SYNCHRONOUS,
7950 ConstructClientDataPacket(
7951 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7952 false, false, ConstructDataFrame(get_request_2)));
Yixin Wang46a273ec302018-01-23 17:59:567953
7954 const char get_response_2[] =
7955 "HTTP/1.1 200 OK\r\n"
7956 "Content-Length: 7\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437957 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437958 ASYNC, ConstructServerDataPacket(
7959 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527960 ConstructDataFrame(get_response_2)));
Yixin Wang46a273ec302018-01-23 17:59:567961
Ryan Hamilton8d9ee76e2018-05-29 23:52:527962 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177963 SYNCHRONOUS, ConstructServerDataPacket(
7964 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527965 false, ConstructDataFrame("0123456")));
Yixin Wang46a273ec302018-01-23 17:59:567966
Renjie Tangcd594f32020-07-11 20:18:347967 mock_quic_data.AddWrite(SYNCHRONOUS,
7968 ConstructClientAckPacket(write_packet_index++, 5, 4));
Yixin Wang46a273ec302018-01-23 17:59:567969 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7970
Bence Béky6e243aa2019-12-13 19:01:077971 if (VersionUsesHttp3(version_.transport_version)) {
7972 mock_quic_data.AddWrite(
7973 SYNCHRONOUS, ConstructClientDataPacket(
7974 write_packet_index++, GetQpackDecoderStreamId(), true,
7975 false, StreamCancellationQpackDecoderInstruction(0)));
7976 }
7977
Renjief49758b2019-01-11 23:32:417978 mock_quic_data.AddWrite(
7979 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417980 ConstructClientRstPacket(write_packet_index++,
7981 GetNthClientInitiatedBidirectionalStreamId(0),
7982 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567983
7984 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7985
7986 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7987
7988 CreateSession();
7989
7990 request_.url = GURL("https://mail.example.org/");
7991 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567992 RunTransaction(&trans_1);
7993 CheckWasHttpResponse(&trans_1);
7994 CheckResponsePort(&trans_1, 70);
7995 CheckResponseData(&trans_1, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:567996 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7997
7998 request_.url = GURL("https://mail.example.org/2");
7999 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568000 RunTransaction(&trans_2);
8001 CheckWasHttpResponse(&trans_2);
8002 CheckResponsePort(&trans_2, 70);
8003 CheckResponseData(&trans_2, "0123456");
Yixin Wang46a273ec302018-01-23 17:59:568004 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8005
8006 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8007 // proxy socket to disconnect.
8008 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8009
8010 base::RunLoop().RunUntilIdle();
8011 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8012 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8013}
8014
8015// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
8016// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
8017// server is reused for the second request.
Bence Békyf6bb6b22020-04-17 20:22:118018TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:568019 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148020 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568021 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:278022 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:568023 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568024
Ryan Hamiltonabad59e2019-06-06 04:02:598025 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238026 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258027 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238028 mock_quic_data.AddWrite(SYNCHRONOUS,
8029 ConstructInitialSettingsPacket(packet_num++));
8030 }
Yixin Wang46a273ec302018-01-23 17:59:568031
8032 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:338033 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238034 SYNCHRONOUS,
8035 ConstructClientRequestHeadersPacket(
8036 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498037 false,
8038 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578039 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498040 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238041 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438042 mock_quic_data.AddRead(
8043 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338044 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288045 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:568046
8047 // GET request, response, and data over QUIC tunnel for first request
8048 const char get_request[] =
8049 "GET / HTTP/1.1\r\n"
8050 "Host: mail.example.org\r\n"
8051 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:528052 mock_quic_data.AddWrite(
8053 SYNCHRONOUS,
8054 ConstructClientAckAndDataPacket(
8055 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
8056 1, false, ConstructDataFrame(get_request)));
Renjief49758b2019-01-11 23:32:418057
Yixin Wang46a273ec302018-01-23 17:59:568058 const char get_response[] =
8059 "HTTP/1.1 200 OK\r\n"
8060 "Content-Length: 10\r\n\r\n";
8061 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338062 ASYNC, ConstructServerDataPacket(
8063 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:528064 ConstructDataFrame(get_response)));
Fan Yang32c5a112018-12-10 20:06:338065 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418066 SYNCHRONOUS, ConstructServerDataPacket(
8067 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:528068 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238069 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348070 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:568071
8072 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438073 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238074 SYNCHRONOUS,
8075 ConstructClientRequestHeadersPacket(
8076 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Renjie Tangee921d12020-02-06 00:41:498077 false,
8078 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578079 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498080 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238081 ConnectRequestHeaders("different.example.org:443"),
8082 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438083 mock_quic_data.AddRead(
8084 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338085 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288086 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:568087
8088 // GET request, response, and data over QUIC tunnel for second request
8089 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138090 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568091 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:528092 mock_quic_data.AddWrite(
8093 SYNCHRONOUS,
8094 ConstructClientAckAndDataPacket(
8095 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 4,
8096 4, false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:568097
Ryan Hamilton0239aac2018-05-19 00:03:138098 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568099 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:438100 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178101 ASYNC, ConstructServerDataPacket(
8102 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:528103 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:568104
Ryan Hamilton0239aac2018-05-19 00:03:138105 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198106 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Zhongyi Shi32f2fd02018-04-16 18:23:438107 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438108 ASYNC, ConstructServerDataPacket(
8109 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:528110 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:568111
Renjie Tangaadb84b2019-08-31 01:00:238112 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348113 ConstructClientAckPacket(packet_num++, 6, 5));
Yixin Wang46a273ec302018-01-23 17:59:568114 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8115
Bence Béky6e243aa2019-12-13 19:01:078116 if (VersionUsesHttp3(version_.transport_version)) {
8117 mock_quic_data.AddWrite(
8118 SYNCHRONOUS, ConstructClientDataPacket(
8119 packet_num++, GetQpackDecoderStreamId(), true, false,
8120 StreamCancellationQpackDecoderInstruction(0)));
8121 }
8122
Yixin Wang46a273ec302018-01-23 17:59:568123 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418124 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238125 ConstructClientRstPacket(packet_num++,
8126 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418127 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:078128
8129 if (VersionUsesHttp3(version_.transport_version)) {
8130 mock_quic_data.AddWrite(
8131 SYNCHRONOUS, ConstructClientDataPacket(
8132 packet_num++, GetQpackDecoderStreamId(), true, false,
Bence Békyf6bb6b22020-04-17 20:22:118133 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078134 }
8135
Yixin Wang46a273ec302018-01-23 17:59:568136 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438137 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238138 ConstructClientRstPacket(packet_num++,
8139 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418140 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568141
8142 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8143
8144 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8145
8146 SSLSocketDataProvider ssl_data(ASYNC, OK);
8147 ssl_data.next_proto = kProtoHTTP2;
8148 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8149
8150 CreateSession();
8151
8152 request_.url = GURL("https://mail.example.org/");
8153 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568154 RunTransaction(&trans_1);
8155 CheckWasHttpResponse(&trans_1);
8156 CheckResponsePort(&trans_1, 70);
8157 CheckResponseData(&trans_1, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568158 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8159
8160 request_.url = GURL("https://different.example.org/");
8161 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568162 RunTransaction(&trans_2);
8163 CheckWasSpdyResponse(&trans_2);
8164 CheckResponsePort(&trans_2, 70);
8165 CheckResponseData(&trans_2, "0123456");
Yixin Wang46a273ec302018-01-23 17:59:568166 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8167
8168 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8169 // proxy socket to disconnect.
8170 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8171
8172 base::RunLoop().RunUntilIdle();
8173 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8174 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8175}
8176
8177// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148178TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568179 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148180 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568181 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:278182 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:568183 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568184
Ryan Hamiltonabad59e2019-06-06 04:02:598185 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238186 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258187 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238188 mock_quic_data.AddWrite(SYNCHRONOUS,
8189 ConstructInitialSettingsPacket(packet_num++));
8190 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:528191 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238192 SYNCHRONOUS,
8193 ConstructClientRequestHeadersPacket(
8194 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498195 false,
8196 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578197 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498198 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238199 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338200 mock_quic_data.AddRead(
8201 ASYNC, ConstructServerResponseHeadersPacket(
8202 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8203 GetResponseHeaders("500")));
8204 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:238205 mock_quic_data.AddWrite(
8206 SYNCHRONOUS,
8207 ConstructClientAckAndRstPacket(
8208 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:348209 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568210
8211 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8212
8213 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8214
8215 CreateSession();
8216
8217 request_.url = GURL("https://mail.example.org/");
8218 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568219 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268220 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:568221 EXPECT_EQ(ERR_IO_PENDING, rv);
8222 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
Yixin Wang46a273ec302018-01-23 17:59:568223
8224 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8225 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8226}
8227
8228// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148229TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568230 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148231 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568232 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:278233 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:568234 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568235
Ryan Hamiltonabad59e2019-06-06 04:02:598236 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238237 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258238 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238239 mock_quic_data.AddWrite(SYNCHRONOUS,
8240 ConstructInitialSettingsPacket(packet_num++));
8241 }
Fan Yang32c5a112018-12-10 20:06:338242 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238243 SYNCHRONOUS,
8244 ConstructClientRequestHeadersPacket(
8245 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498246 false,
8247 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578248 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498249 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238250 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:568251 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8252
8253 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8254
8255 CreateSession();
8256
8257 request_.url = GURL("https://mail.example.org/");
8258 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568259 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268260 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:568261 EXPECT_EQ(ERR_IO_PENDING, rv);
8262 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8263
8264 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8265 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8266}
8267
8268// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8269// host. Retries request and succeeds.
Bence Békyf6bb6b22020-04-17 20:22:118270TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568271 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148272 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568273 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:278274 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:568275 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568276
Ryan Hamiltonabad59e2019-06-06 04:02:598277 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238278 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258279 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238280 mock_quic_data.AddWrite(SYNCHRONOUS,
8281 ConstructInitialSettingsPacket(packet_num++));
8282 }
Fan Yang32c5a112018-12-10 20:06:338283 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238284 SYNCHRONOUS,
8285 ConstructClientRequestHeadersPacket(
8286 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498287 false,
8288 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578289 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498290 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238291 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438292 mock_quic_data.AddRead(
8293 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338294 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288295 GetResponseHeaders("200")));
Bence Béky6e243aa2019-12-13 19:01:078296 if (VersionUsesHttp3(version_.transport_version)) {
8297 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:348298 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8299 packet_num++, false, GetQpackDecoderStreamId(), 1, 1,
8300 false, StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:078301 mock_quic_data.AddWrite(
8302 SYNCHRONOUS,
8303 ConstructClientRstPacket(packet_num++,
8304 GetNthClientInitiatedBidirectionalStreamId(0),
8305 quic::QUIC_STREAM_CANCELLED));
8306 } else {
8307 mock_quic_data.AddWrite(
8308 SYNCHRONOUS,
8309 ConstructClientAckAndRstPacket(
8310 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:348311 quic::QUIC_STREAM_CANCELLED, 1, 1));
Bence Béky6e243aa2019-12-13 19:01:078312 }
Yixin Wang46a273ec302018-01-23 17:59:568313
Zhongyi Shi32f2fd02018-04-16 18:23:438314 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238315 SYNCHRONOUS,
8316 ConstructClientRequestHeadersPacket(
8317 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Renjie Tangee921d12020-02-06 00:41:498318 false,
8319 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578320 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498321 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238322 ConnectRequestHeaders("mail.example.org:443"),
8323 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438324 mock_quic_data.AddRead(
8325 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338326 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288327 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:568328
8329 const char get_request[] =
8330 "GET / HTTP/1.1\r\n"
8331 "Host: mail.example.org\r\n"
8332 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:528333 mock_quic_data.AddWrite(
8334 SYNCHRONOUS,
8335 ConstructClientAckAndDataPacket(
8336 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 2,
8337 2, false, ConstructDataFrame(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:568338 const char get_response[] =
8339 "HTTP/1.1 200 OK\r\n"
8340 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:438341 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338342 ASYNC, ConstructServerDataPacket(
8343 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:528344 ConstructDataFrame(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528345
Fan Yang32c5a112018-12-10 20:06:338346 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418347 SYNCHRONOUS, ConstructServerDataPacket(
8348 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:528349 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238350 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348351 ConstructClientAckPacket(packet_num++, 4, 3));
Yixin Wang46a273ec302018-01-23 17:59:568352 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8353
Bence Béky6e243aa2019-12-13 19:01:078354 if (VersionUsesHttp3(version_.transport_version)) {
8355 mock_quic_data.AddWrite(
8356 SYNCHRONOUS, ConstructClientDataPacket(
8357 packet_num++, GetQpackDecoderStreamId(), true, false,
Bence Békyf6bb6b22020-04-17 20:22:118358 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078359 }
Yixin Wang46a273ec302018-01-23 17:59:568360 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418361 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238362 ConstructClientRstPacket(packet_num++,
8363 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418364 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568365
8366 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8367
8368 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8369 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8370
8371 SSLSocketDataProvider ssl_data(ASYNC, OK);
8372 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8373
8374 CreateSession();
8375
8376 request_.url = GURL("https://mail.example.org/");
8377 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568378 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268379 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:568380 EXPECT_EQ(ERR_IO_PENDING, rv);
8381 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8382
8383 rv = trans.RestartIgnoringLastError(callback.callback());
8384 EXPECT_EQ(ERR_IO_PENDING, rv);
8385 EXPECT_EQ(OK, callback.WaitForResult());
8386
8387 CheckWasHttpResponse(&trans);
8388 CheckResponsePort(&trans, 70);
8389 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568390 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8391
8392 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8393 // proxy socket to disconnect.
8394 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8395
8396 base::RunLoop().RunUntilIdle();
8397 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8398 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8399}
8400
8401// Checks if a request's specified "user-agent" header shows up correctly in the
8402// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148403TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008404 const char kConfiguredUserAgent[] = "Configured User-Agent";
8405 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568406 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148407 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568408 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:278409 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:568410 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568411
Ryan Hamiltonabad59e2019-06-06 04:02:598412 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238413 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258414 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238415 mock_quic_data.AddWrite(SYNCHRONOUS,
8416 ConstructInitialSettingsPacket(packet_num++));
8417 }
Yixin Wang46a273ec302018-01-23 17:59:568418
Bence Béky4c325e52020-10-22 20:48:018419 spdy::Http2HeaderBlock headers =
8420 ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008421 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338422 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028423 SYNCHRONOUS,
8424 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238425 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498426 false,
8427 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578428 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498429 : HttpProxyConnectJob::kH2QuicTunnelPriority,
8430 std::move(headers), 0));
Yixin Wang46a273ec302018-01-23 17:59:568431 // Return an error, so the transaction stops here (this test isn't interested
8432 // in the rest).
8433 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8434
8435 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8436
Matt Menked732ea42019-03-08 12:05:008437 StaticHttpUserAgentSettings http_user_agent_settings(
8438 std::string() /* accept_language */, kConfiguredUserAgent);
8439 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568440 CreateSession();
8441
8442 request_.url = GURL("https://mail.example.org/");
8443 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008444 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568445 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568446 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268447 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:568448 EXPECT_EQ(ERR_IO_PENDING, rv);
8449 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8450
8451 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8452 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8453}
8454
Yixin Wang00fc44c2018-01-23 21:12:208455// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8456// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148457TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208458 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148459 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568460 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:278461 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:568462 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208463
8464 const RequestPriority request_priority = MEDIUM;
8465
Ryan Hamiltonabad59e2019-06-06 04:02:598466 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238467 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258468 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238469 mock_quic_data.AddWrite(SYNCHRONOUS,
8470 ConstructInitialSettingsPacket(packet_num++));
8471 }
Zhongyi Shi32f2fd02018-04-16 18:23:438472 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238473 SYNCHRONOUS,
8474 ConstructClientRequestHeadersPacket(
8475 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498476 false,
8477 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578478 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498479 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238480 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:208481 // Return an error, so the transaction stops here (this test isn't interested
8482 // in the rest).
8483 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8484
8485 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8486
8487 CreateSession();
8488
8489 request_.url = GURL("https://mail.example.org/");
8490 HttpNetworkTransaction trans(request_priority, session_.get());
8491 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268492 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang00fc44c2018-01-23 21:12:208493 EXPECT_EQ(ERR_IO_PENDING, rv);
8494 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8495
8496 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8497 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8498}
8499
Matt Menkeedaf3b82019-03-14 21:39:448500// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8501// HTTP/2 stream dependency and weights given the request priority.
8502TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8503 session_params_.enable_quic = true;
8504 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568505 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:278506 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:568507 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeedaf3b82019-03-14 21:39:448508
8509 const RequestPriority kRequestPriority = MEDIUM;
8510 const RequestPriority kRequestPriority2 = LOWEST;
8511
Ryan Hamiltonabad59e2019-06-06 04:02:598512 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:258513 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238514 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
8515 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8516 } else {
8517 mock_quic_data.AddWrite(
8518 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8519 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
8520 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8521 ConnectRequestHeaders("mail.example.org:443"), 0));
8522 }
Matt Menkeedaf3b82019-03-14 21:39:448523 // This should never be reached.
8524 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8525 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8526
8527 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:598528 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:448529 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8530 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8531
8532 int original_max_sockets_per_group =
8533 ClientSocketPoolManager::max_sockets_per_group(
8534 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8535 ClientSocketPoolManager::set_max_sockets_per_group(
8536 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8537 int original_max_sockets_per_pool =
8538 ClientSocketPoolManager::max_sockets_per_pool(
8539 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8540 ClientSocketPoolManager::set_max_sockets_per_pool(
8541 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8542 CreateSession();
8543
8544 request_.url = GURL("https://mail.example.org/");
8545 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8546 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268547 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeedaf3b82019-03-14 21:39:448548 EXPECT_EQ(ERR_IO_PENDING, rv);
8549
8550 HttpRequestInfo request2;
8551 request2.url = GURL("https://mail.example.org/some/other/path/");
8552 request2.traffic_annotation =
8553 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8554
8555 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8556 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:268557 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
Matt Menkeedaf3b82019-03-14 21:39:448558 EXPECT_EQ(ERR_IO_PENDING, rv2);
8559
8560 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8561 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8562
8563 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8564
8565 ClientSocketPoolManager::set_max_sockets_per_pool(
8566 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8567 original_max_sockets_per_pool);
8568 ClientSocketPoolManager::set_max_sockets_per_group(
8569 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8570 original_max_sockets_per_group);
8571}
8572
Yixin Wang46a273ec302018-01-23 17:59:568573// Test the request-challenge-retry sequence for basic auth, over a QUIC
8574// connection when setting up a QUIC proxy tunnel.
Bence Békyf6bb6b22020-04-17 20:22:118575TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Jan Wilken Dörriec92a6d7242021-03-23 17:43:488576 const std::u16string kBaz(u"baz");
8577 const std::u16string kFoo(u"foo");
Yixin Wang46a273ec302018-01-23 17:59:568578
Yixin Wang46a273ec302018-01-23 17:59:568579 // On the second pass, the body read of the auth challenge is synchronous, so
8580 // IsConnectedAndIdle returns false. The socket should still be drained and
8581 // reused. See http://crbug.com/544255.
8582 for (int i = 0; i < 2; ++i) {
Bence Béky6e243aa2019-12-13 19:01:078583 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:228584 version_,
8585 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8586 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky6e243aa2019-12-13 19:01:078587 client_headers_include_h2_stream_dependency_);
8588 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:228589 version_,
8590 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8591 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Bence Béky6e243aa2019-12-13 19:01:078592 false);
Yixin Wang46a273ec302018-01-23 17:59:568593
8594 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148595 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568596 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:278597 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Ramin Halavatica8d5252018-03-12 05:33:498598 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568599
Ryan Hamiltonabad59e2019-06-06 04:02:598600 MockQuicData mock_quic_data(version_);
Yixin Wang46a273ec302018-01-23 17:59:568601
Renjie Tangaadb84b2019-08-31 01:00:238602 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258603 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238604 mock_quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:078605 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Renjie Tangaadb84b2019-08-31 01:00:238606 }
Yixin Wang46a273ec302018-01-23 17:59:568607
8608 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438609 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:078610 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238611 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8612 false,
Renjie Tangee921d12020-02-06 00:41:498613 VersionUsesHttp3(version_.transport_version)
Dan Zhangfc4c085b2020-11-10 16:33:168614 ? quic::QuicStream::kDefaultUrgency
Renjie Tangee921d12020-02-06 00:41:498615 : ConvertRequestPriorityToQuicPriority(
8616 HttpProxyConnectJob::kH2QuicTunnelPriority),
Bence Béky6e243aa2019-12-13 19:01:078617 client_maker.ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028618 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568619
Kenichi Ishibashif8634ab2021-03-16 23:41:288620 spdy::Http2HeaderBlock headers = server_maker.GetResponseHeaders("407");
Yixin Wang46a273ec302018-01-23 17:59:568621 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8622 headers["content-length"] = "10";
8623 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078624 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338625 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028626 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568627
8628 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438629 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078630 ASYNC, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338631 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178632 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568633 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438634 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078635 SYNCHRONOUS, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338636 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:178637 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568638 }
Yixin Wang46a273ec302018-01-23 17:59:568639
Bence Béky7a45d4d2020-05-08 01:59:238640 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348641 client_maker.MakeAckPacket(packet_num++, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:078642
8643 if (VersionUsesHttp3(version_.transport_version)) {
8644 mock_quic_data.AddWrite(
8645 SYNCHRONOUS,
8646 client_maker.MakeDataPacket(
8647 packet_num++, GetQpackDecoderStreamId(),
8648 /* should_include_version = */ true,
8649 /* fin = */ false, StreamCancellationQpackDecoderInstruction(0)));
8650 }
Yixin Wang46a273ec302018-01-23 17:59:568651
8652 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338653 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:078654 client_maker.MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:238655 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418656 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:188657 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568658
Bence Béky6e243aa2019-12-13 19:01:078659 headers = client_maker.ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:568660 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8661 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048662 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:078663 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238664 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8665 false,
Renjie Tangee921d12020-02-06 00:41:498666 VersionUsesHttp3(version_.transport_version)
Dan Zhangfc4c085b2020-11-10 16:33:168667 ? quic::QuicStream::kDefaultUrgency
Renjie Tangee921d12020-02-06 00:41:498668 : ConvertRequestPriorityToQuicPriority(
8669 HttpProxyConnectJob::kH2QuicTunnelPriority),
Matt Menke6e879bd2019-03-18 17:26:048670 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:028671 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568672
8673 // Response to wrong password
Kenichi Ishibashif8634ab2021-03-16 23:41:288674 headers = server_maker.GetResponseHeaders("407");
Yixin Wang46a273ec302018-01-23 17:59:568675 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8676 headers["content-length"] = "10";
8677 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078678 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338679 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028680 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568681 mock_quic_data.AddRead(SYNCHRONOUS,
8682 ERR_IO_PENDING); // No more data to read
8683
Bence Béky6e243aa2019-12-13 19:01:078684 if (VersionUsesHttp3(version_.transport_version)) {
8685 mock_quic_data.AddWrite(
8686 SYNCHRONOUS,
8687 client_maker.MakeAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:348688 packet_num++, false, GetQpackDecoderStreamId(), 3, 3, false,
Bence Békyf6bb6b22020-04-17 20:22:118689 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078690 mock_quic_data.AddWrite(SYNCHRONOUS,
8691 client_maker.MakeRstPacket(
8692 packet_num++, false,
8693 GetNthClientInitiatedBidirectionalStreamId(1),
8694 quic::QUIC_STREAM_CANCELLED));
8695 } else {
8696 mock_quic_data.AddWrite(SYNCHRONOUS,
8697 client_maker.MakeAckAndRstPacket(
8698 packet_num++, false,
8699 GetNthClientInitiatedBidirectionalStreamId(1),
Renjie Tangcd594f32020-07-11 20:18:348700 quic::QUIC_STREAM_CANCELLED, 3, 3));
Bence Béky6e243aa2019-12-13 19:01:078701 }
Yixin Wang46a273ec302018-01-23 17:59:568702
8703 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8704 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8705
8706 CreateSession();
8707
8708 request_.url = GURL("https://mail.example.org/");
8709 // Ensure that proxy authentication is attempted even
Matt Menke25eaa432020-08-25 00:10:008710 // when privacy mode is enabled.
8711 request_.privacy_mode = PRIVACY_MODE_ENABLED;
Yixin Wang46a273ec302018-01-23 17:59:568712 {
8713 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568714 RunTransaction(&trans);
8715
8716 const HttpResponseInfo* response = trans.GetResponseInfo();
8717 ASSERT_TRUE(response != nullptr);
8718 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:288719 EXPECT_EQ("HTTP/1.1 407", response->headers->GetStatusLine());
Yixin Wang46a273ec302018-01-23 17:59:568720 EXPECT_TRUE(response->headers->IsKeepAlive());
8721 EXPECT_EQ(407, response->headers->response_code());
8722 EXPECT_EQ(10, response->headers->GetContentLength());
8723 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Anton Bikineev068d2912021-05-15 20:43:528724 absl::optional<AuthChallengeInfo> auth_challenge =
Emily Starkf2c9bbd2019-04-09 17:08:588725 response->auth_challenge;
8726 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568727 EXPECT_TRUE(auth_challenge->is_proxy);
8728 EXPECT_EQ("https://proxy.example.org:70",
8729 auth_challenge->challenger.Serialize());
8730 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8731 EXPECT_EQ("basic", auth_challenge->scheme);
8732
8733 TestCompletionCallback callback;
8734 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8735 callback.callback());
8736 EXPECT_EQ(ERR_IO_PENDING, rv);
8737 EXPECT_EQ(OK, callback.WaitForResult());
8738
8739 response = trans.GetResponseInfo();
8740 ASSERT_TRUE(response != nullptr);
8741 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:288742 EXPECT_EQ("HTTP/1.1 407", response->headers->GetStatusLine());
Yixin Wang46a273ec302018-01-23 17:59:568743 EXPECT_TRUE(response->headers->IsKeepAlive());
8744 EXPECT_EQ(407, response->headers->response_code());
8745 EXPECT_EQ(10, response->headers->GetContentLength());
8746 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588747 auth_challenge = response->auth_challenge;
8748 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568749 EXPECT_TRUE(auth_challenge->is_proxy);
8750 EXPECT_EQ("https://proxy.example.org:70",
8751 auth_challenge->challenger.Serialize());
8752 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8753 EXPECT_EQ("basic", auth_challenge->scheme);
8754 }
8755 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8756 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8757 // reused because it's not connected).
8758 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8759 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8760 }
8761}
8762
Yixin Wang385652a2018-02-16 02:37:238763TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8764 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8765 // in HEADERS frames for requests and PRIORITY frames).
David Schinazi84c58bb2020-06-04 20:14:338766 if (!client_headers_include_h2_stream_dependency_) {
Yixin Wang385652a2018-02-16 02:37:238767 return;
8768 }
8769
Victor Vasiliev7da08172019-10-14 06:04:258770 if (quic::VersionUsesHttp3(version_.transport_version)) {
Renjie Tangba21e032019-09-27 21:52:288771 // HTTP/3 currently doesn't support PRIORITY.
Ryan Hamiltone940bd12019-06-30 02:46:458772 return;
8773 }
8774
Victor Vasilieva1e66d72019-12-05 17:55:388775 context_.params()->origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:238776 HostPortPair::FromString("mail.example.org:443"));
8777
Fan Yang32c5a112018-12-10 20:06:338778 const quic::QuicStreamId client_stream_0 =
8779 GetNthClientInitiatedBidirectionalStreamId(0);
8780 const quic::QuicStreamId client_stream_1 =
8781 GetNthClientInitiatedBidirectionalStreamId(1);
8782 const quic::QuicStreamId client_stream_2 =
8783 GetNthClientInitiatedBidirectionalStreamId(2);
8784 const quic::QuicStreamId push_stream_0 =
8785 GetNthServerInitiatedUnidirectionalStreamId(0);
8786 const quic::QuicStreamId push_stream_1 =
8787 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238788
Ryan Hamiltonabad59e2019-06-06 04:02:598789 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238790 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258791 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238792 mock_quic_data.AddWrite(SYNCHRONOUS,
8793 ConstructInitialSettingsPacket(packet_num++));
8794 }
Yixin Wang385652a2018-02-16 02:37:238795
8796 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:238797 mock_quic_data.AddWrite(
8798 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8799 packet_num++, client_stream_0, true, true, HIGHEST,
8800 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:028801 mock_quic_data.AddWrite(
8802 SYNCHRONOUS,
8803 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238804 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028805 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
8806 mock_quic_data.AddWrite(
8807 SYNCHRONOUS,
8808 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238809 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028810 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:238811
8812 // Server replies "OK" for the three requests.
Kenichi Ishibashif8634ab2021-03-16 23:41:288813 mock_quic_data.AddRead(
8814 ASYNC, ConstructServerResponseHeadersPacket(
8815 1, client_stream_0, false, false, GetResponseHeaders("200")));
8816 mock_quic_data.AddRead(
8817 ASYNC, ConstructServerResponseHeadersPacket(
8818 2, client_stream_1, false, false, GetResponseHeaders("200")));
Renjie Tangaadb84b2019-08-31 01:00:238819 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348820 ConstructClientAckPacket(packet_num++, 2, 1));
Kenichi Ishibashif8634ab2021-03-16 23:41:288821 mock_quic_data.AddRead(
8822 ASYNC, ConstructServerResponseHeadersPacket(
8823 3, client_stream_2, false, false, GetResponseHeaders("200")));
Yixin Wang385652a2018-02-16 02:37:238824
8825 // Server sends two push promises associated with |client_stream_0|; client
8826 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8827 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:028828 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:478829 ASYNC, ConstructServerPushPromisePacket(
8830 4, client_stream_0, push_stream_0, false,
8831 GetRequestHeaders("GET", "https", "/pushed_0.jpg")));
Yixin Wang385652a2018-02-16 02:37:238832 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438833 SYNCHRONOUS,
8834 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangcd594f32020-07-11 20:18:348835 packet_num++, false, 4, 3,
Zhongyi Shi32f2fd02018-04-16 18:23:438836 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:028837 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
8838 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:478839 ASYNC, ConstructServerPushPromisePacket(
8840 5, client_stream_0, push_stream_1, false,
8841 GetRequestHeaders("GET", "https", "/pushed_1.jpg")));
8842 mock_quic_data.AddWrite(SYNCHRONOUS,
8843 ConstructClientAckAndPriorityPacket(
8844 packet_num++, false,
8845 /*largest_received=*/5, /*smallest_received=*/4,
8846 push_stream_1, push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:238847
8848 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438849 mock_quic_data.AddRead(
8850 ASYNC, ConstructServerResponseHeadersPacket(
Kenichi Ishibashif8634ab2021-03-16 23:41:288851 6, push_stream_0, false, false, GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:438852 mock_quic_data.AddRead(
8853 ASYNC, ConstructServerResponseHeadersPacket(
Kenichi Ishibashif8634ab2021-03-16 23:41:288854 7, push_stream_1, false, false, GetResponseHeaders("200")));
Renjie Tangcd594f32020-07-11 20:18:348855 mock_quic_data.AddWrite(SYNCHRONOUS,
8856 ConstructClientAckPacket(packet_num++, 7, 5));
Yixin Wang385652a2018-02-16 02:37:238857
8858 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8859 // priority updates to match the request's priority. Client sends PRIORITY
8860 // frames to inform server of new HTTP/2 stream dependencies.
Bence Béky319388a882020-09-23 18:42:528861 mock_quic_data.AddWrite(
8862 SYNCHRONOUS,
8863 ConstructClientPriorityFramesPacket(
8864 packet_num++, false,
8865 {{push_stream_1, client_stream_2,
8866 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8867 {push_stream_0, client_stream_0,
8868 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:238869
8870 // Server sends data for the three requests and the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438871 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178872 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Bence Béky319388a882020-09-23 18:42:528873 ConstructDataFrame("hello 0!")));
Zhongyi Shi32f2fd02018-04-16 18:23:438874 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178875 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Bence Béky319388a882020-09-23 18:42:528876 ConstructDataFrame("hello 1!")));
Renjie Tangaadb84b2019-08-31 01:00:238877 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348878 ConstructClientAckPacket(packet_num++, 9, 8));
Zhongyi Shi32f2fd02018-04-16 18:23:438879 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178880 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Bence Béky319388a882020-09-23 18:42:528881 ConstructDataFrame("hello 2!")));
8882 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
8883 11, push_stream_0, false, true,
8884 ConstructDataFrame("and hello 0!")));
Renjie Tangaadb84b2019-08-31 01:00:238885 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348886 ConstructClientAckPacket(packet_num++, 11, 10));
Zhongyi Shi32f2fd02018-04-16 18:23:438887 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178888 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Bence Béky319388a882020-09-23 18:42:528889 ConstructDataFrame("and hello 1!")));
Yixin Wang385652a2018-02-16 02:37:238890
Yixin Wang385652a2018-02-16 02:37:238891 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:218892 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang385652a2018-02-16 02:37:238893 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8894
8895 // The non-alternate protocol job needs to hang in order to guarantee that
8896 // the alternate-protocol job will "win".
8897 AddHangingNonAlternateProtocolSocketData();
8898
8899 CreateSession();
8900
8901 request_.url = GURL("https://mail.example.org/0.jpg");
8902 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8903 TestCompletionCallback callback_0;
Matt Reichhoff0049a0b72021-10-20 20:44:268904 EXPECT_EQ(ERR_IO_PENDING, trans_0.Start(&request_, callback_0.callback(),
8905 net_log_with_source_));
Yixin Wang385652a2018-02-16 02:37:238906 base::RunLoop().RunUntilIdle();
8907
8908 request_.url = GURL("https://mail.example.org/1.jpg");
8909 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8910 TestCompletionCallback callback_1;
Matt Reichhoff0049a0b72021-10-20 20:44:268911 EXPECT_EQ(ERR_IO_PENDING, trans_1.Start(&request_, callback_1.callback(),
8912 net_log_with_source_));
Yixin Wang385652a2018-02-16 02:37:238913 base::RunLoop().RunUntilIdle();
8914
8915 request_.url = GURL("https://mail.example.org/2.jpg");
8916 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8917 TestCompletionCallback callback_2;
Matt Reichhoff0049a0b72021-10-20 20:44:268918 EXPECT_EQ(ERR_IO_PENDING, trans_2.Start(&request_, callback_2.callback(),
8919 net_log_with_source_));
Yixin Wang385652a2018-02-16 02:37:238920 base::RunLoop().RunUntilIdle();
8921
8922 // Client makes request that matches resource pushed in |pushed_stream_0|.
8923 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8924 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8925 TestCompletionCallback callback_3;
Matt Reichhoff0049a0b72021-10-20 20:44:268926 EXPECT_EQ(ERR_IO_PENDING, trans_3.Start(&request_, callback_3.callback(),
8927 net_log_with_source_));
Yixin Wang385652a2018-02-16 02:37:238928 base::RunLoop().RunUntilIdle();
8929
8930 EXPECT_TRUE(callback_0.have_result());
8931 EXPECT_EQ(OK, callback_0.WaitForResult());
8932 EXPECT_TRUE(callback_1.have_result());
8933 EXPECT_EQ(OK, callback_1.WaitForResult());
8934 EXPECT_TRUE(callback_2.have_result());
8935 EXPECT_EQ(OK, callback_2.WaitForResult());
8936
8937 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8938 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8939 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8940 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8941
8942 mock_quic_data.Resume();
8943 base::RunLoop().RunUntilIdle();
8944 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8945 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8946}
8947
Matt Menke26e41542019-06-05 01:09:518948// Test that NetworkIsolationKey is respected by QUIC connections, when
8949// kPartitionConnectionsByNetworkIsolationKey is enabled.
8950TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Matt Menke4807a9a2020-11-21 00:14:418951 const SchemefulSite kSite1(GURL("http://origin1/"));
8952 const SchemefulSite kSite2(GURL("http://origin2/"));
8953 NetworkIsolationKey network_isolation_key1(kSite1, kSite1);
8954 NetworkIsolationKey network_isolation_key2(kSite2, kSite2);
Matt Menke26e41542019-06-05 01:09:518955
Victor Vasilieva1e66d72019-12-05 17:55:388956 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:518957 HostPortPair::FromString("mail.example.org:443"));
8958
8959 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
8960 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
8961 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
8962 // the same way as the HTTP over H2 proxy case.
8963 for (bool use_proxy : {false, true}) {
8964 SCOPED_TRACE(use_proxy);
8965
8966 if (use_proxy) {
8967 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:278968 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Matt Menke26e41542019-06-05 01:09:518969 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
8970 } else {
Nicolas Arciniegad2013f92020-02-07 23:00:568971 proxy_resolution_service_ =
8972 ConfiguredProxyResolutionService::CreateDirect();
Matt Menke26e41542019-06-05 01:09:518973 }
8974
8975 GURL url1;
8976 GURL url2;
8977 GURL url3;
8978 if (use_proxy) {
8979 url1 = GURL("http://mail.example.org/1");
8980 url2 = GURL("http://mail.example.org/2");
8981 url3 = GURL("http://mail.example.org/3");
8982 } else {
8983 url1 = GURL("https://mail.example.org/1");
8984 url2 = GURL("https://mail.example.org/2");
8985 url3 = GURL("https://mail.example.org/3");
8986 }
8987
8988 for (bool partition_connections : {false, true}) {
8989 SCOPED_TRACE(partition_connections);
8990
8991 base::test::ScopedFeatureList feature_list;
8992 if (partition_connections) {
8993 feature_list.InitAndEnableFeature(
8994 features::kPartitionConnectionsByNetworkIsolationKey);
8995 } else {
8996 feature_list.InitAndDisableFeature(
8997 features::kPartitionConnectionsByNetworkIsolationKey);
8998 }
8999
9000 // Reads and writes for the unpartitioned case, where only one socket is
9001 // used.
9002
Victor Vasilieva1e66d72019-12-05 17:55:389003 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519004 HostPortPair::FromString("mail.example.org:443"));
9005
Ryan Hamiltonabad59e2019-06-06 04:02:599006 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:519007 QuicTestPacketMaker client_maker1(
9008 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229009 quic::QuicUtils::CreateRandomConnectionId(
9010 context_.random_generator()),
9011 context_.clock(), kDefaultServerHostName,
9012 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519013 client_headers_include_h2_stream_dependency_);
9014 QuicTestPacketMaker server_maker1(
9015 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229016 quic::QuicUtils::CreateRandomConnectionId(
9017 context_.random_generator()),
9018 context_.clock(), kDefaultServerHostName,
9019 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519020
Renjie Tangaadb84b2019-08-31 01:00:239021 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259022 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239023 unpartitioned_mock_quic_data.AddWrite(
9024 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
9025 }
Matt Menke26e41542019-06-05 01:09:519026
9027 unpartitioned_mock_quic_data.AddWrite(
9028 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029029 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239030 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9031 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029032 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519033 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029034 ASYNC, server_maker1.MakeResponseHeadersPacket(
9035 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289036 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519037 unpartitioned_mock_quic_data.AddRead(
9038 ASYNC, server_maker1.MakeDataPacket(
9039 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529040 true, ConstructDataFrame("1")));
Matt Menke26e41542019-06-05 01:09:519041 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349042 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menke26e41542019-06-05 01:09:519043
9044 unpartitioned_mock_quic_data.AddWrite(
9045 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029046 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239047 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
9048 false, true,
Matt Menke26e41542019-06-05 01:09:519049 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029050 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519051 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029052 ASYNC, server_maker1.MakeResponseHeadersPacket(
9053 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289054 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519055 unpartitioned_mock_quic_data.AddRead(
9056 ASYNC, server_maker1.MakeDataPacket(
9057 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:529058 true, ConstructDataFrame("2")));
Matt Menke26e41542019-06-05 01:09:519059 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangb7afea82020-07-15 23:35:479060 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3));
Matt Menke26e41542019-06-05 01:09:519061
9062 unpartitioned_mock_quic_data.AddWrite(
9063 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029064 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239065 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
9066 false, true,
Matt Menke26e41542019-06-05 01:09:519067 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029068 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519069 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029070 ASYNC, server_maker1.MakeResponseHeadersPacket(
9071 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289072 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519073 unpartitioned_mock_quic_data.AddRead(
9074 ASYNC, server_maker1.MakeDataPacket(
9075 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Bence Béky319388a882020-09-23 18:42:529076 true, ConstructDataFrame("3")));
Matt Menke26e41542019-06-05 01:09:519077 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangb7afea82020-07-15 23:35:479078 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 6, 5));
Matt Menke26e41542019-06-05 01:09:519079
9080 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9081
9082 // Reads and writes for the partitioned case, where two sockets are used.
9083
Ryan Hamiltonabad59e2019-06-06 04:02:599084 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:519085 QuicTestPacketMaker client_maker2(
9086 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229087 quic::QuicUtils::CreateRandomConnectionId(
9088 context_.random_generator()),
9089 context_.clock(), kDefaultServerHostName,
9090 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519091 client_headers_include_h2_stream_dependency_);
9092 QuicTestPacketMaker server_maker2(
9093 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229094 quic::QuicUtils::CreateRandomConnectionId(
9095 context_.random_generator()),
9096 context_.clock(), kDefaultServerHostName,
9097 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519098
Renjie Tangaadb84b2019-08-31 01:00:239099 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259100 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239101 partitioned_mock_quic_data1.AddWrite(
9102 SYNCHRONOUS,
9103 client_maker2.MakeInitialSettingsPacket(packet_num2++));
9104 }
Matt Menke26e41542019-06-05 01:09:519105
9106 partitioned_mock_quic_data1.AddWrite(
9107 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029108 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239109 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
9110 true, true,
Matt Menke26e41542019-06-05 01:09:519111 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029112 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519113 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029114 ASYNC, server_maker2.MakeResponseHeadersPacket(
9115 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289116 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519117 partitioned_mock_quic_data1.AddRead(
9118 ASYNC, server_maker2.MakeDataPacket(
9119 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529120 true, ConstructDataFrame("1")));
Matt Menke26e41542019-06-05 01:09:519121 partitioned_mock_quic_data1.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349122 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 2, 1));
Matt Menke26e41542019-06-05 01:09:519123
9124 partitioned_mock_quic_data1.AddWrite(
9125 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029126 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239127 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
9128 false, true,
Matt Menke26e41542019-06-05 01:09:519129 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029130 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519131 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029132 ASYNC, server_maker2.MakeResponseHeadersPacket(
9133 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289134 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519135 partitioned_mock_quic_data1.AddRead(
9136 ASYNC, server_maker2.MakeDataPacket(
9137 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:529138 true, ConstructDataFrame("3")));
Matt Menke26e41542019-06-05 01:09:519139 partitioned_mock_quic_data1.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349140 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 4, 3));
Matt Menke26e41542019-06-05 01:09:519141
9142 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9143
Ryan Hamiltonabad59e2019-06-06 04:02:599144 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:519145 QuicTestPacketMaker client_maker3(
9146 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229147 quic::QuicUtils::CreateRandomConnectionId(
9148 context_.random_generator()),
9149 context_.clock(), kDefaultServerHostName,
9150 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519151 client_headers_include_h2_stream_dependency_);
9152 QuicTestPacketMaker server_maker3(
9153 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229154 quic::QuicUtils::CreateRandomConnectionId(
9155 context_.random_generator()),
9156 context_.clock(), kDefaultServerHostName,
9157 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519158
Renjie Tangaadb84b2019-08-31 01:00:239159 int packet_num3 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259160 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239161 partitioned_mock_quic_data2.AddWrite(
9162 SYNCHRONOUS,
9163 client_maker3.MakeInitialSettingsPacket(packet_num3++));
9164 }
Matt Menke26e41542019-06-05 01:09:519165
9166 partitioned_mock_quic_data2.AddWrite(
9167 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029168 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239169 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9170 true, true,
Matt Menke26e41542019-06-05 01:09:519171 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029172 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519173 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029174 ASYNC, server_maker3.MakeResponseHeadersPacket(
9175 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289176 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519177 partitioned_mock_quic_data2.AddRead(
9178 ASYNC, server_maker3.MakeDataPacket(
9179 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529180 true, ConstructDataFrame("2")));
Matt Menke26e41542019-06-05 01:09:519181 partitioned_mock_quic_data2.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349182 SYNCHRONOUS, client_maker3.MakeAckPacket(packet_num3++, 2, 1));
Matt Menke26e41542019-06-05 01:09:519183
9184 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9185
9186 if (partition_connections) {
9187 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9188 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9189 } else {
9190 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9191 }
9192
9193 CreateSession();
9194
9195 TestCompletionCallback callback;
9196 HttpRequestInfo request1;
9197 request1.method = "GET";
9198 request1.url = GURL(url1);
9199 request1.traffic_annotation =
9200 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9201 request1.network_isolation_key = network_isolation_key1;
9202 HttpNetworkTransaction trans1(LOWEST, session_.get());
9203 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9204 EXPECT_THAT(callback.GetResult(rv), IsOk());
9205 std::string response_data1;
9206 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9207 EXPECT_EQ("1", response_data1);
9208
9209 HttpRequestInfo request2;
9210 request2.method = "GET";
9211 request2.url = GURL(url2);
9212 request2.traffic_annotation =
9213 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9214 request2.network_isolation_key = network_isolation_key2;
9215 HttpNetworkTransaction trans2(LOWEST, session_.get());
9216 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9217 EXPECT_THAT(callback.GetResult(rv), IsOk());
9218 std::string response_data2;
9219 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9220 EXPECT_EQ("2", response_data2);
9221
9222 HttpRequestInfo request3;
9223 request3.method = "GET";
9224 request3.url = GURL(url3);
9225 request3.traffic_annotation =
9226 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9227 request3.network_isolation_key = network_isolation_key1;
9228 HttpNetworkTransaction trans3(LOWEST, session_.get());
9229 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9230 EXPECT_THAT(callback.GetResult(rv), IsOk());
9231 std::string response_data3;
9232 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9233 EXPECT_EQ("3", response_data3);
9234
9235 if (partition_connections) {
9236 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9237 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9238 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9239 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9240 } else {
9241 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9242 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9243 }
9244 }
9245 }
9246}
9247
9248// Test that two requests to the same origin over QUIC tunnels use different
9249// QUIC sessions if their NetworkIsolationKeys don't match, and
9250// kPartitionConnectionsByNetworkIsolationKey is enabled.
9251TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9252 base::test::ScopedFeatureList feature_list;
9253 feature_list.InitAndEnableFeature(
9254 features::kPartitionConnectionsByNetworkIsolationKey);
9255
9256 session_params_.enable_quic = true;
9257 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:569258 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:279259 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:569260 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menke26e41542019-06-05 01:09:519261
9262 const char kGetRequest[] =
9263 "GET / HTTP/1.1\r\n"
9264 "Host: mail.example.org\r\n"
9265 "Connection: keep-alive\r\n\r\n";
9266 const char kGetResponse[] =
9267 "HTTP/1.1 200 OK\r\n"
9268 "Content-Length: 10\r\n\r\n";
9269
Ryan Hamiltonabad59e2019-06-06 04:02:599270 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9271 std::make_unique<MockQuicData>(version_),
9272 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519273
9274 for (int index : {0, 1}) {
9275 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229276 version_,
9277 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9278 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519279 client_headers_include_h2_stream_dependency_);
9280 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229281 version_,
9282 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9283 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9284 false);
Matt Menke26e41542019-06-05 01:09:519285
Renjie Tangaadb84b2019-08-31 01:00:239286 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259287 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239288 mock_quic_data[index]->AddWrite(
9289 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
9290 }
Matt Menke26e41542019-06-05 01:09:519291
Ryan Hamiltonabad59e2019-06-06 04:02:599292 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519293 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029294 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239295 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9296 false,
Renjie Tangee921d12020-02-06 00:41:499297 VersionUsesHttp3(version_.transport_version)
Dan Zhangfc4c085b2020-11-10 16:33:169298 ? quic::QuicStream::kDefaultUrgency
Renjie Tangee921d12020-02-06 00:41:499299 : ConvertRequestPriorityToQuicPriority(
9300 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:029301 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:599302 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029303 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:519304 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289305 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519306
Bence Béky319388a882020-09-23 18:42:529307 mock_quic_data[index]->AddWrite(
9308 SYNCHRONOUS,
9309 client_maker.MakeAckAndDataPacket(
9310 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
9311 1, 1, false, ConstructDataFrame(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:519312
Ryan Hamiltonabad59e2019-06-06 04:02:599313 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519314 ASYNC, server_maker.MakeDataPacket(
9315 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529316 false, ConstructDataFrame(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599317 mock_quic_data[index]->AddRead(
Bence Béky319388a882020-09-23 18:42:529318 SYNCHRONOUS, server_maker.MakeDataPacket(
9319 3, GetNthClientInitiatedBidirectionalStreamId(0),
9320 false, false, ConstructDataFrame("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599321 mock_quic_data[index]->AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349322 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2));
Ryan Hamiltonabad59e2019-06-06 04:02:599323 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9324 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:519325
Ryan Hamiltonabad59e2019-06-06 04:02:599326 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:519327 }
9328
9329 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9330 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9331 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9332
9333 CreateSession();
9334
9335 request_.url = GURL("https://mail.example.org/");
9336 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9337 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9338 RunTransaction(&trans);
9339 CheckResponseData(&trans, "0123456789");
9340
9341 HttpRequestInfo request2;
Matt Menke4807a9a2020-11-21 00:14:419342 const SchemefulSite kSite1(GURL("http://origin1/"));
9343 request_.network_isolation_key = NetworkIsolationKey(kSite1, kSite1);
Matt Menke26e41542019-06-05 01:09:519344 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9345 RunTransaction(&trans2);
9346 CheckResponseData(&trans2, "0123456789");
9347
Ryan Hamiltonabad59e2019-06-06 04:02:599348 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9349 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9350 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9351 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:519352}
9353
Yoichi Osato4c75c0c2020-06-24 08:03:579354TEST_P(QuicNetworkTransactionTest, AllowHTTP1FalseProhibitsH1) {
9355 MockRead http_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING),
9356 MockRead(ASYNC, OK)};
9357 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
9358 socket_factory_.AddSocketDataProvider(&http_data);
9359 AddCertificate(&ssl_data_);
9360 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9361
9362 CreateSession();
9363
9364 request_.method = "POST";
9365 UploadDataStreamNotAllowHTTP1 upload_data("");
9366 request_.upload_data_stream = &upload_data;
9367
9368 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9369 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:269370 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:579371 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9372 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_H2_OR_QUIC_REQUIRED));
9373}
9374
9375// Confirm mock class UploadDataStreamNotAllowHTTP1 can upload content over
9376// QUIC.
9377TEST_P(QuicNetworkTransactionTest, AllowHTTP1MockTest) {
9378 context_.params()->origins_to_force_quic_on.insert(
9379 HostPortPair::FromString("mail.example.org:443"));
9380
9381 MockQuicData mock_quic_data(version_);
9382 int write_packet_index = 1;
9383 if (VersionUsesHttp3(version_.transport_version)) {
9384 mock_quic_data.AddWrite(
9385 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9386 }
9387 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:529388 mock_quic_data.AddWrite(
9389 SYNCHRONOUS,
9390 ConstructClientRequestHeadersAndDataFramesPacket(
9391 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9392 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9393 0, nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:579394 mock_quic_data.AddRead(
9395 ASYNC, ConstructServerResponseHeadersPacket(
9396 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289397 GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:579398
Yoichi Osato4c75c0c2020-06-24 08:03:579399 mock_quic_data.AddRead(
9400 ASYNC, ConstructServerDataPacket(
9401 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:529402 ConstructDataFrame("hello!")));
Yoichi Osato4c75c0c2020-06-24 08:03:579403
Renjie Tangcd594f32020-07-11 20:18:349404 mock_quic_data.AddWrite(SYNCHRONOUS,
9405 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:579406
9407 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:219408 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:579409 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9410
9411 // The non-alternate protocol job needs to hang in order to guarantee that
9412 // the alternate-protocol job will "win".
9413 AddHangingNonAlternateProtocolSocketData();
9414
9415 CreateSession();
9416 request_.method = "POST";
9417 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9418 request_.upload_data_stream = &upload_data;
9419
9420 SendRequestAndExpectQuicResponse("hello!");
9421}
9422
Nidhi Jaju391105a2022-07-28 02:09:519423// TODO(crbug.com/1347664): This test is failing on various platforms.
9424TEST_P(QuicNetworkTransactionTest, DISABLED_AllowHTTP1UploadPauseAndResume) {
Yoichi Osato4c75c0c2020-06-24 08:03:579425 context_.params()->origins_to_force_quic_on.insert(
9426 HostPortPair::FromString("mail.example.org:443"));
9427
9428 MockQuicData mock_quic_data(version_);
9429 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
9430 int write_packet_index = 1;
9431 mock_quic_data.AddWrite(
9432 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
9433 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
9434 if (VersionUsesHttp3(version_.transport_version)) {
9435 mock_quic_data.AddWrite(
9436 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9437 }
9438 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:529439 mock_quic_data.AddWrite(
9440 SYNCHRONOUS,
9441 ConstructClientRequestHeadersAndDataFramesPacket(
9442 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9443 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9444 0, nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:579445 mock_quic_data.AddRead(
9446 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
9447 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289448 false, GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:579449 mock_quic_data.AddRead(
9450 SYNCHRONOUS, ConstructServerDataPacket(
9451 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529452 true, ConstructDataFrame("hello!")));
Yoichi Osato4c75c0c2020-06-24 08:03:579453
Renjie Tangcd594f32020-07-11 20:18:349454 mock_quic_data.AddWrite(SYNCHRONOUS,
9455 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:579456 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:219457 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:579458 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9459 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
9460
9461 CreateSession();
9462
9463 AddQuicAlternateProtocolMapping(
9464 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
9465
9466 // Set up request.
9467 request_.method = "POST";
9468 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9469 request_.upload_data_stream = &upload_data;
9470
9471 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9472 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:269473 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:579474 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9475 base::RunLoop().RunUntilIdle();
9476 // Resume QUIC job
9477 crypto_client_stream_factory_.last_stream()
9478 ->NotifySessionOneRttKeyAvailable();
9479 socket_data->Resume();
9480
9481 base::RunLoop().RunUntilIdle();
9482 CheckResponseData(&trans, "hello!");
9483}
9484
Nidhi Jaju391105a2022-07-28 02:09:519485// TODO(crbug.com/1347664): This test is failing on various platforms.
9486TEST_P(QuicNetworkTransactionTest,
9487 DISABLED_AllowHTTP1UploadFailH1AndResumeQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:359488 if (version_.AlpnDeferToRFCv1()) {
9489 // These versions currently do not support Alt-Svc.
9490 return;
9491 }
Yoichi Osato4c75c0c2020-06-24 08:03:579492 // This test confirms failed main job should not bother quic job.
9493 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:459494 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yoichi Osato4c75c0c2020-06-24 08:03:579495 MockRead("1.1 Body"),
9496 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9497 MockRead(ASYNC, OK)};
9498 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
9499 socket_factory_.AddSocketDataProvider(&http_data);
9500 AddCertificate(&ssl_data_);
9501 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9502
9503 MockQuicData mock_quic_data(version_);
9504 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
9505 int write_packet_index = 1;
9506 mock_quic_data.AddWrite(
9507 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
9508 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
9509 if (VersionUsesHttp3(version_.transport_version)) {
9510 mock_quic_data.AddWrite(
9511 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9512 }
9513 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:529514 mock_quic_data.AddWrite(
9515 SYNCHRONOUS,
9516 ConstructClientRequestHeadersAndDataFramesPacket(
9517 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9518 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9519 0, nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:579520 mock_quic_data.AddRead(
9521 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
9522 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289523 false, GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:579524 mock_quic_data.AddRead(
9525 SYNCHRONOUS, ConstructServerDataPacket(
9526 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529527 true, ConstructDataFrame("hello!")));
Renjie Tangcd594f32020-07-11 20:18:349528 mock_quic_data.AddWrite(SYNCHRONOUS,
9529 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:579530 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:219531 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:579532 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9533 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
9534
9535 // This packet won't be read because AllowHTTP1:false doesn't allow H/1
9536 // connection.
9537 MockRead http_reads2[] = {MockRead("HTTP/1.1 200 OK\r\n")};
9538 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
9539 socket_factory_.AddSocketDataProvider(&http_data2);
9540 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9541
9542 CreateSession();
9543
9544 // Send the first request via TCP and set up alternative service (QUIC) for
9545 // the origin.
9546 SendRequestAndExpectHttpResponse("1.1 Body");
9547
9548 // Settings to resume main H/1 job quickly while pausing quic job.
9549 AddQuicAlternateProtocolMapping(
9550 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
9551 ServerNetworkStats stats1;
Peter Kastinge5a38ed2021-10-02 03:06:359552 stats1.srtt = base::Microseconds(10);
Yoichi Osato4c75c0c2020-06-24 08:03:579553 http_server_properties_->SetServerNetworkStats(
9554 url::SchemeHostPort(request_.url), NetworkIsolationKey(), stats1);
9555
9556 // Set up request.
9557 request_.method = "POST";
9558 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9559 request_.upload_data_stream = &upload_data;
9560
9561 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9562 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:269563 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:579564 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9565 // Confirm TCP job was resumed.
9566 // We can not check its failure because HttpStreamFactory::JobController.
9567 // main_job_net_error is not exposed.
9568 while (socket_factory_.mock_data().next_index() < 3u)
9569 base::RunLoop().RunUntilIdle();
9570 // Resume QUIC job.
9571 crypto_client_stream_factory_.last_stream()
9572 ->NotifySessionOneRttKeyAvailable();
9573 socket_data->Resume();
9574 base::RunLoop().RunUntilIdle();
9575 CheckResponseData(&trans, "hello!");
9576}
9577
Bence Békyc164e0d22020-09-22 20:08:599578TEST_P(QuicNetworkTransactionTest, IncorrectHttp3GoAway) {
9579 if (!version_.HasIetfQuicFrames()) {
9580 return;
9581 }
9582
9583 context_.params()->retry_without_alt_svc_on_quic_errors = false;
9584
9585 MockQuicData mock_quic_data(version_);
9586 int write_packet_number = 1;
9587 mock_quic_data.AddWrite(
9588 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number++));
9589 mock_quic_data.AddWrite(
9590 SYNCHRONOUS,
9591 ConstructClientRequestHeadersPacket(
9592 write_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
9593 true, true, GetRequestHeaders("GET", "https", "/")));
9594
9595 int read_packet_number = 1;
9596 mock_quic_data.AddRead(
9597 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number++));
9598 // The GOAWAY frame sent by the server MUST have a stream ID corresponding to
9599 // a client-initiated bidirectional stream. Any other kind of stream ID
9600 // should cause the client to close the connection.
9601 quic::GoAwayFrame goaway{3};
Nidhi Jaju391105a2022-07-28 02:09:519602 auto goaway_buffer = quic::HttpEncoder::SerializeGoAwayFrame(goaway);
Bence Békyc164e0d22020-09-22 20:08:599603 const quic::QuicStreamId control_stream_id =
9604 quic::QuicUtils::GetFirstUnidirectionalStreamId(
9605 version_.transport_version, quic::Perspective::IS_SERVER);
9606 mock_quic_data.AddRead(
Nidhi Jaju391105a2022-07-28 02:09:519607 ASYNC, ConstructServerDataPacket(read_packet_number++, control_stream_id,
9608 false, false, goaway_buffer));
Bence Békyc164e0d22020-09-22 20:08:599609 mock_quic_data.AddWrite(
9610 SYNCHRONOUS,
9611 ConstructClientAckAndConnectionClosePacket(
9612 write_packet_number++, 2, 4, quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
9613 "GOAWAY with invalid stream ID", 0));
9614 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9615
9616 // In order for a new QUIC session to be established via alternate-protocol
9617 // without racing an HTTP connection, we need the host resolution to happen
9618 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
9619 // connection to the the server, in this test we require confirmation
9620 // before encrypting so the HTTP job will still start.
9621 host_resolver_.set_synchronous_mode(true);
9622 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
9623 "");
9624
9625 CreateSession();
9626 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9627
9628 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9629 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:269630 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Bence Békyc164e0d22020-09-22 20:08:599631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9632
9633 crypto_client_stream_factory_.last_stream()
9634 ->NotifySessionOneRttKeyAvailable();
9635 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
9636
9637 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9638 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9639
9640 NetErrorDetails details;
9641 trans.PopulateNetErrorDetails(&details);
9642 EXPECT_THAT(details.quic_connection_error,
9643 quic::test::IsError(quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID));
9644}
9645
Bence Béky2ee18922020-09-25 12:11:329646TEST_P(QuicNetworkTransactionTest, RetryOnHttp3GoAway) {
9647 if (!version_.HasIetfQuicFrames()) {
9648 return;
9649 }
9650
9651 MockQuicData mock_quic_data1(version_);
9652 int write_packet_number1 = 1;
9653 mock_quic_data1.AddWrite(
9654 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number1++));
9655 const quic::QuicStreamId stream_id1 =
9656 GetNthClientInitiatedBidirectionalStreamId(0);
9657 mock_quic_data1.AddWrite(SYNCHRONOUS,
9658 ConstructClientRequestHeadersPacket(
9659 write_packet_number1++, stream_id1, true, true,
9660 GetRequestHeaders("GET", "https", "/")));
9661 const quic::QuicStreamId stream_id2 =
9662 GetNthClientInitiatedBidirectionalStreamId(1);
9663 mock_quic_data1.AddWrite(SYNCHRONOUS,
9664 ConstructClientRequestHeadersPacket(
9665 write_packet_number1++, stream_id2, true, true,
9666 GetRequestHeaders("GET", "https", "/foo")));
9667
9668 int read_packet_number1 = 1;
9669 mock_quic_data1.AddRead(
9670 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number1++));
9671
9672 // GOAWAY with stream_id2 informs the client that stream_id2 (and streams with
9673 // larger IDs) have not been processed and can safely be retried.
9674 quic::GoAwayFrame goaway{stream_id2};
Nidhi Jaju391105a2022-07-28 02:09:519675 auto goaway_buffer = quic::HttpEncoder::SerializeGoAwayFrame(goaway);
Bence Béky2ee18922020-09-25 12:11:329676 const quic::QuicStreamId control_stream_id =
9677 quic::QuicUtils::GetFirstUnidirectionalStreamId(
9678 version_.transport_version, quic::Perspective::IS_SERVER);
9679 mock_quic_data1.AddRead(
Nidhi Jaju391105a2022-07-28 02:09:519680 ASYNC, ConstructServerDataPacket(read_packet_number1++, control_stream_id,
9681 false, false, goaway_buffer));
Bence Béky2ee18922020-09-25 12:11:329682 mock_quic_data1.AddWrite(
9683 ASYNC, ConstructClientAckPacket(write_packet_number1++, 2, 1));
9684
9685 // Response to first request is accepted after GOAWAY.
9686 mock_quic_data1.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9687 read_packet_number1++, stream_id1, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289688 false, GetResponseHeaders("200")));
Bence Béky2ee18922020-09-25 12:11:329689 mock_quic_data1.AddRead(
9690 ASYNC, ConstructServerDataPacket(
9691 read_packet_number1++, stream_id1, false, true,
9692 ConstructDataFrame("response on the first connection")));
9693 mock_quic_data1.AddWrite(
9694 ASYNC, ConstructClientAckPacket(write_packet_number1++, 4, 1));
Bence Békye7426ec2021-02-02 18:18:199695 // Make socket hang to make sure connection stays in connection pool.
9696 // This should not prevent the retry from opening a new connection.
9697 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING);
David Schinazi395918c2021-02-05 18:56:219698 mock_quic_data1.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Bence Béky2ee18922020-09-25 12:11:329699 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9700
9701 // Second request is retried on a new connection.
9702 MockQuicData mock_quic_data2(version_);
9703 QuicTestPacketMaker client_maker2(
9704 version_,
9705 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9706 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9707 client_headers_include_h2_stream_dependency_);
9708 int write_packet_number2 = 1;
9709 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(
9710 write_packet_number2++));
9711 spdy::SpdyPriority priority =
9712 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
9713 mock_quic_data2.AddWrite(
9714 SYNCHRONOUS, client_maker2.MakeRequestHeadersPacket(
9715 write_packet_number2++, stream_id1, true, true, priority,
9716 GetRequestHeaders("GET", "https", "/foo"), 0, nullptr));
9717
9718 QuicTestPacketMaker server_maker2(
9719 version_,
9720 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9721 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9722 false);
9723 int read_packet_number2 = 1;
9724 mock_quic_data2.AddRead(ASYNC,
9725 server_maker2.MakeResponseHeadersPacket(
9726 read_packet_number2++, stream_id1, false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289727 GetResponseHeaders("200"), nullptr));
Bence Béky2ee18922020-09-25 12:11:329728 mock_quic_data2.AddRead(
9729 ASYNC, server_maker2.MakeDataPacket(
9730 read_packet_number2++, stream_id1, false, true,
9731 ConstructDataFrame("response on the second connection")));
9732 mock_quic_data2.AddWrite(
9733 ASYNC, client_maker2.MakeAckPacket(write_packet_number2++, 2, 1));
9734 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9735 mock_quic_data2.AddRead(ASYNC, 0); // EOF
9736 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9737
9738 AddHangingNonAlternateProtocolSocketData();
9739 CreateSession();
9740 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9741
9742 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
9743 TestCompletionCallback callback1;
Matt Reichhoff0049a0b72021-10-20 20:44:269744 int rv = trans1.Start(&request_, callback1.callback(), net_log_with_source_);
Bence Béky2ee18922020-09-25 12:11:329745 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9746 base::RunLoop().RunUntilIdle();
9747
9748 HttpRequestInfo request2;
9749 request2.method = "GET";
9750 std::string url("https://");
9751 url.append(kDefaultServerHostName);
9752 url.append("/foo");
9753 request2.url = GURL(url);
9754 request2.load_flags = 0;
9755 request2.traffic_annotation =
9756 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9757 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9758 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:269759 rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
Bence Béky2ee18922020-09-25 12:11:329760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9761
9762 EXPECT_THAT(callback1.WaitForResult(), IsOk());
9763 CheckResponseData(&trans1, "response on the first connection");
9764
9765 EXPECT_THAT(callback2.WaitForResult(), IsOk());
9766 CheckResponseData(&trans2, "response on the second connection");
9767
Bence Békye7426ec2021-02-02 18:18:199768 mock_quic_data1.Resume();
Bence Béky2ee18922020-09-25 12:11:329769 mock_quic_data2.Resume();
9770 EXPECT_TRUE(mock_quic_data1.AllWriteDataConsumed());
9771 EXPECT_TRUE(mock_quic_data1.AllReadDataConsumed());
9772 EXPECT_TRUE(mock_quic_data2.AllWriteDataConsumed());
9773 EXPECT_TRUE(mock_quic_data2.AllReadDataConsumed());
9774}
9775
Yoichi Osato4c75c0c2020-06-24 08:03:579776// TODO(yoichio): Add the TCP job reuse case. See crrev.com/c/2174099.
9777
Tsuyoshi Horo4f516be2022-06-14 11:53:139778} // namespace net::test