blob: 076eb9536640746c06db18b78a6dd8293c51c276 [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;
David Schinazif492e4318a2021-09-09 16:41:19324 FLAGS_quic_enable_chaos_protection = false;
[email protected]aa9b14d2013-05-10 23:45:19325 request_.method = "GET";
rchf114d982015-10-21 01:34:56326 std::string url("https://");
bncb07c05532015-05-14 19:07:20327 url.append(kDefaultServerHostName);
328 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19329 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10330 request_.traffic_annotation =
331 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Victor Vasiliev7752898d2019-11-14 21:30:22332 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56333
334 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29335 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56336 verify_details_.cert_verify_result.verified_cert = cert;
337 verify_details_.cert_verify_result.is_issued_by_known_root = true;
338 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43339 }
[email protected]61a527782013-02-21 03:58:00340
dcheng67be2b1f2014-10-27 21:47:29341 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00342 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55343 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00344 }
345
dcheng67be2b1f2014-10-27 21:47:29346 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00347 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
348 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55349 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00350 PlatformTest::TearDown();
351 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55352 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40353 session_.reset();
[email protected]61a527782013-02-21 03:58:00354 }
355
Ryan Hamilton8d9ee76e2018-05-29 23:52:52356 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23357 ConstructClientConnectionClosePacket(uint64_t num) {
Zhongyi Shi1c022d22020-03-20 19:00:16358 return client_maker_->MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52359 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30360 }
361
Ryan Hamilton8d9ee76e2018-05-29 23:52:52362 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23363 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03364 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52365 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58366 }
367
Ryan Hamilton8d9ee76e2018-05-29 23:52:52368 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23369 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52370 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20371 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58372 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20373 }
374
Ryan Hamilton8d9ee76e2018-05-29 23:52:52375 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23376 uint64_t packet_number,
377 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34378 uint64_t smallest_received) {
Zhongyi Shi1c022d22020-03-20 19:00:16379 return client_maker_->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34380 smallest_received);
fayang3bcb8b502016-12-07 21:44:37381 }
382
Ryan Hamilton8d9ee76e2018-05-29 23:52:52383 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23384 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52385 quic::QuicStreamId stream_id,
386 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23387 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34388 uint64_t smallest_received) {
389 return client_maker_->MakeAckAndRstPacket(
390 num, false, stream_id, error_code, largest_received, smallest_received);
zhongyi6b5a3892016-03-12 04:46:20391 }
392
Ryan Hamilton8d9ee76e2018-05-29 23:52:52393 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23394 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52395 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41396 quic::QuicRstStreamErrorCode error_code) {
Zhongyi Shi1c022d22020-03-20 19:00:16397 return client_maker_->MakeRstPacket(num, false, stream_id, error_code,
398 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56399 }
400
Ryan Hamilton8d9ee76e2018-05-29 23:52:52401 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58402 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23403 uint64_t num,
Fan Yangac867502019-01-28 21:10:23404 uint64_t largest_received,
405 uint64_t smallest_received,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52406 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29407 const std::string& quic_error_details,
408 uint64_t frame_type) {
Zhongyi Shi1c022d22020-03-20 19:00:16409 return client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:34410 num, false, largest_received, smallest_received, quic_error,
411 quic_error_details, frame_type);
zhongyica364fbb2015-12-12 03:39:12412 }
413
Ryan Hamilton8d9ee76e2018-05-29 23:52:52414 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23415 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12416 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52417 quic::QuicStreamId stream_id,
418 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58419 return server_maker_.MakeRstPacket(num, include_version, stream_id,
420 error_code);
zhongyica364fbb2015-12-12 03:39:12421 }
422
Ryan Hamilton8d9ee76e2018-05-29 23:52:52423 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02424 uint64_t packet_number) {
Zhongyi Shi1c022d22020-03-20 19:00:16425 return client_maker_->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37426 }
427
Ryan Hamilton8d9ee76e2018-05-29 23:52:52428 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23429 uint64_t packet_number,
430 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34431 uint64_t smallest_received) {
fayang3bcb8b502016-12-07 21:44:37432 return server_maker_.MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34433 smallest_received);
fayang3bcb8b502016-12-07 21:44:37434 }
435
Ryan Hamilton8d9ee76e2018-05-29 23:52:52436 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23437 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57438 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52439 quic::QuicStreamId id,
440 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02441 RequestPriority request_priority) {
Zhongyi Shi1c022d22020-03-20 19:00:16442 return client_maker_->MakePriorityPacket(
Yixin Wangb470bc882018-02-15 18:43:57443 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02444 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wang385652a2018-02-16 02:37:23445 }
446
Ryan Hamilton8d9ee76e2018-05-29 23:52:52447 std::unique_ptr<quic::QuicEncryptedPacket>
Haoyue Wang9d70d65c2020-05-29 22:45:34448 ConstructClientPriorityFramesPacket(
449 uint64_t packet_number,
450 bool should_include_version,
451 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
452 priority_frames) {
453 return client_maker_->MakeMultiplePriorityFramesPacket(
454 packet_number, should_include_version, priority_frames);
455 }
456
457 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25458 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23459 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23460 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23461 uint64_t largest_received,
462 uint64_t smallest_received,
Yixin Wange7ecc472018-03-06 19:00:25463 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
Ryan Hamilton0d65a8c2019-06-07 00:46:02464 priority_frames) {
Zhongyi Shi1c022d22020-03-20 19:00:16465 return client_maker_->MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23466 packet_number, should_include_version, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34467 smallest_received, priority_frames);
Yixin Wangb470bc882018-02-15 18:43:57468 }
469
Haoyue Wang9d70d65c2020-05-29 22:45:34470 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckAndPriorityPacket(
471 uint64_t packet_number,
472 bool should_include_version,
473 uint64_t largest_received,
474 uint64_t smallest_received,
475 quic::QuicStreamId id,
476 quic::QuicStreamId parent_stream_id,
477 RequestPriority request_priority) {
478 return client_maker_->MakeAckAndPriorityPacket(
479 packet_number, should_include_version, largest_received,
480 smallest_received, id, parent_stream_id,
481 ConvertRequestPriorityToQuicPriority(request_priority));
482 }
483
zhongyi32569c62016-01-08 02:54:30484 // Uses default QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01485 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
486 const std::string& scheme,
487 const std::string& path) {
Zhongyi Shi1c022d22020-03-20 19:00:16488 return GetRequestHeaders(method, scheme, path, client_maker_.get());
zhongyi32569c62016-01-08 02:54:30489 }
490
491 // Uses customized QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01492 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
493 const std::string& scheme,
494 const std::string& path,
495 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50496 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00497 }
498
Bence Béky4c325e52020-10-22 20:48:01499 spdy::Http2HeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Zhongyi Shi1c022d22020-03-20 19:00:16500 return client_maker_->ConnectRequestHeaders(host_port);
Yixin Wang46a273ec302018-01-23 17:59:56501 }
502
Bence Béky4c325e52020-10-22 20:48:01503 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58504 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00505 }
506
zhongyi32569c62016-01-08 02:54:30507 // Appends alt_svc headers in the response headers.
Bence Béky4c325e52020-10-22 20:48:01508 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status,
509 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58510 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30511 }
512
Ryan Hamilton8d9ee76e2018-05-29 23:52:52513 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23514 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52515 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05516 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00517 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10518 absl::string_view data) {
Ryan Hamilton7505eb92019-06-08 00:22:17519 return server_maker_.MakeDataPacket(packet_number, stream_id,
520 should_include_version, fin, data);
[email protected]61a527782013-02-21 03:58:00521 }
522
Ryan Hamilton8d9ee76e2018-05-29 23:52:52523 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23524 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52525 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36526 bool should_include_version,
527 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10528 absl::string_view data) {
Zhongyi Shi1c022d22020-03-20 19:00:16529 return client_maker_->MakeDataPacket(packet_number, stream_id,
530 should_include_version, fin, data);
ckrasicda193a82016-07-09 00:39:36531 }
532
Ryan Hamilton8d9ee76e2018-05-29 23:52:52533 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23534 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56535 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52536 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23537 uint64_t largest_received,
538 uint64_t smallest_received,
Yixin Wang46a273ec302018-01-23 17:59:56539 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10540 absl::string_view data) {
Renjie Tangcd594f32020-07-11 20:18:34541 return client_maker_->MakeAckAndDataPacket(packet_number, include_version,
542 stream_id, largest_received,
543 smallest_received, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56544 }
545
Kenichi Ishibashi10111e82021-03-23 02:19:06546 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckDataAndRst(
547 uint64_t packet_number,
548 bool include_version,
549 quic::QuicStreamId stream_id,
550 quic::QuicRstStreamErrorCode error_code,
551 uint64_t largest_received,
552 uint64_t smallest_received,
553 quic::QuicStreamId data_id,
554 bool fin,
555 absl::string_view data) {
556 return client_maker_->MakeAckDataAndRst(
557 packet_number, include_version, stream_id, error_code, largest_received,
558 smallest_received, data_id, fin, data);
559 }
560
Ryan Hamilton8d9ee76e2018-05-29 23:52:52561 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23562 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52563 quic::QuicStreamId stream_id,
564 bool should_include_version,
565 bool fin,
Bence Béky4c325e52020-10-22 20:48:01566 spdy::Http2HeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56567 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
568 should_include_version, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02569 std::move(headers), 0);
Yixin Wang46a273ec302018-01-23 17:59:56570 }
571
Ryan Hamilton8d9ee76e2018-05-29 23:52:52572 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23573 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52574 quic::QuicStreamId stream_id,
575 bool should_include_version,
576 bool fin,
Bence Béky4c325e52020-10-22 20:48:01577 spdy::Http2HeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02578 quic::QuicStreamId parent_stream_id) {
Yixin Wang46a273ec302018-01-23 17:59:56579 return ConstructClientRequestHeadersPacket(
580 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:02581 std::move(headers), parent_stream_id);
zhongyi32569c62016-01-08 02:54:30582 }
583
Ryan Hamilton8d9ee76e2018-05-29 23:52:52584 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23585 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52586 quic::QuicStreamId stream_id,
587 bool should_include_version,
588 bool fin,
589 RequestPriority request_priority,
Bence Béky4c325e52020-10-22 20:48:01590 spdy::Http2HeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02591 quic::QuicStreamId parent_stream_id) {
Ryan Hamilton0239aac2018-05-19 00:03:13592 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56593 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16594 return client_maker_->MakeRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56595 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02596 std::move(headers), parent_stream_id, nullptr);
[email protected]61a527782013-02-21 03:58:00597 }
598
Ryan Hamilton8d9ee76e2018-05-29 23:52:52599 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25600 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23601 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52602 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25603 bool should_include_version,
604 bool fin,
605 RequestPriority request_priority,
Bence Béky4c325e52020-10-22 20:48:01606 spdy::Http2HeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52607 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25608 size_t* spdy_headers_frame_length,
609 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13610 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25611 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16612 return client_maker_->MakeRequestHeadersAndMultipleDataFramesPacket(
Yixin Wange7ecc472018-03-06 19:00:25613 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02614 std::move(headers), parent_stream_id, spdy_headers_frame_length,
Yixin Wange7ecc472018-03-06 19:00:25615 data_writes);
616 }
617
Ryan Hamilton8d9ee76e2018-05-29 23:52:52618 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23619 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52620 quic::QuicStreamId stream_id,
621 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13622 bool should_include_version,
Bence Béky4c325e52020-10-22 20:48:01623 spdy::Http2HeaderBlock headers) {
Renjie Tangb7afea82020-07-15 23:35:47624 return server_maker_.MakePushPromisePacket(
ckrasic769733c2016-06-30 00:42:13625 packet_number, stream_id, promised_stream_id, should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02626 false, std::move(headers), nullptr);
ckrasic769733c2016-06-30 00:42:13627 }
628
Ryan Hamilton8d9ee76e2018-05-29 23:52:52629 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23630 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52631 quic::QuicStreamId stream_id,
632 bool should_include_version,
633 bool fin,
Bence Béky4c325e52020-10-22 20:48:01634 spdy::Http2HeaderBlock headers) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02635 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
636 should_include_version, fin,
637 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30638 }
639
Bence Béky319388a882020-09-23 18:42:52640 std::string ConstructDataFrame(base::StringPiece body) {
641 return ConstructDataFrameForVersion(body, version_);
Renjief49758b2019-01-11 23:32:41642 }
643
Nick Harper23290b82019-05-02 00:02:56644 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41645 session_params_.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:38646 context_.params()->supported_versions = supported_versions;
Victor Vasilieva1e66d72019-12-05 17:55:38647 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:05648 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00649
Victor Vasiliev7752898d2019-11-14 21:30:22650 session_context_.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:41651 session_context_.client_socket_factory = &socket_factory_;
652 session_context_.quic_crypto_client_stream_factory =
653 &crypto_client_stream_factory_;
654 session_context_.host_resolver = &host_resolver_;
655 session_context_.cert_verifier = &cert_verifier_;
656 session_context_.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:41657 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
658 session_context_.socket_performance_watcher_factory =
659 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59660 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41661 session_context_.ssl_config_service = ssl_config_service_.get();
662 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49663 session_context_.http_server_properties = http_server_properties_.get();
Matt Reichhoff0049a0b72021-10-20 20:44:26664 session_context_.net_log = NetLog::Get();
mmenke6ddfbea2017-05-31 21:48:41665
Renjie Tang6ff9a9b2021-02-03 22:11:09666 session_ =
667 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
Matt Menkeb566c392019-09-11 23:22:43668 session_->quic_stream_factory()
669 ->set_is_quic_known_to_work_on_current_network(true);
Yixin Wang46a273ec302018-01-23 17:59:56670 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
671 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00672 }
673
zhongyi86838d52017-06-30 01:19:44674 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21675
David Schinazif832cb82019-11-08 22:25:27676 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
Zhongyi Shi1c022d22020-03-20 19:00:16677 const std::string& status_line,
678 const quic::ParsedQuicVersion& version) {
[email protected]aa9b14d2013-05-10 23:45:19679 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42680 ASSERT_TRUE(response != nullptr);
681 ASSERT_TRUE(response->headers.get() != nullptr);
David Schinazif832cb82019-11-08 22:25:27682 EXPECT_EQ(status_line, response->headers->GetStatusLine());
[email protected]aa9b14d2013-05-10 23:45:19683 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52684 EXPECT_TRUE(response->was_alpn_negotiated);
Victor Vasiliev22dd3f212022-02-11 21:57:29685 auto connection_info =
686 QuicHttpStream::ConnectionInfoFromQuicVersion(version);
687 if (connection_info == response->connection_info) {
688 return;
689 }
690 // QUIC v1 and QUIC v2 are considered a match, because they have the same
691 // ALPN token.
692 if ((connection_info == HttpResponseInfo::CONNECTION_INFO_QUIC_RFC_V1 ||
693 connection_info == HttpResponseInfo::CONNECTION_INFO_QUIC_2_DRAFT_1) &&
694 (response->connection_info ==
695 HttpResponseInfo::CONNECTION_INFO_QUIC_RFC_V1 ||
696 response->connection_info ==
697 HttpResponseInfo::CONNECTION_INFO_QUIC_2_DRAFT_1)) {
698 return;
699 }
700
701 // They do not match. This EXPECT_EQ will fail and print useful
702 // information.
703 EXPECT_EQ(connection_info, response->connection_info);
[email protected]aa9b14d2013-05-10 23:45:19704 }
705
Zhongyi Shi1c022d22020-03-20 19:00:16706 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
707 const std::string& status_line) {
708 CheckWasQuicResponse(trans, status_line, version_);
709 }
710
David Schinazif832cb82019-11-08 22:25:27711 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
Kenichi Ishibashif8634ab2021-03-16 23:41:28712 CheckWasQuicResponse(trans, "HTTP/1.1 200", version_);
David Schinazif832cb82019-11-08 22:25:27713 }
714
bnc691fda62016-08-12 00:43:16715 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41716 const HttpResponseInfo* response = trans->GetResponseInfo();
717 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37718 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41719 }
720
bnc691fda62016-08-12 00:43:16721 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19722 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42723 ASSERT_TRUE(response != nullptr);
724 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19725 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
726 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52727 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52728 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19729 response->connection_info);
730 }
731
Yixin Wang46a273ec302018-01-23 17:59:56732 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
733 const HttpResponseInfo* response = trans->GetResponseInfo();
734 ASSERT_TRUE(response != nullptr);
735 ASSERT_TRUE(response->headers.get() != nullptr);
736 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
737 EXPECT_TRUE(response->was_fetched_via_spdy);
738 EXPECT_TRUE(response->was_alpn_negotiated);
739 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
740 response->connection_info);
741 }
742
bnc691fda62016-08-12 00:43:16743 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19744 const std::string& expected) {
745 std::string response_data;
bnc691fda62016-08-12 00:43:16746 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19747 EXPECT_EQ(expected, response_data);
748 }
749
bnc691fda62016-08-12 00:43:16750 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19751 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:26752 int rv = trans->Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:01753 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
754 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19755 }
756
757 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16758 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
759 RunTransaction(&trans);
760 CheckWasHttpResponse(&trans);
761 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19762 }
763
tbansalc3308d72016-08-27 10:25:04764 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
765 bool used_proxy,
766 uint16_t port) {
767 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalc3308d72016-08-27 10:25:04768 RunTransaction(&trans);
769 CheckWasHttpResponse(&trans);
770 CheckResponsePort(&trans, port);
771 CheckResponseData(&trans, expected);
tbansal2ecbbc72016-10-06 17:15:47772 if (used_proxy) {
773 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
774 } else {
775 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
776 }
tbansalc3308d72016-08-27 10:25:04777 }
David Schinazif832cb82019-11-08 22:25:27778 void SendRequestAndExpectQuicResponse(const std::string& expected,
779 const std::string& status_line) {
780 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443,
781 status_line);
782 }
tbansalc3308d72016-08-27 10:25:04783
[email protected]aa9b14d2013-05-10 23:45:19784 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56785 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12786 }
787
bnc62a44f022015-04-02 15:59:41788 void SendRequestAndExpectQuicResponseFromProxyOnPort(
789 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46790 uint16_t port) {
bnc62a44f022015-04-02 15:59:41791 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19792 }
793
794 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05795 MockCryptoClientStream::HandshakeMode handshake_mode,
796 const NetworkIsolationKey& network_isolation_key =
797 NetworkIsolationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19798 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46799 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21800 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
Peter Kastinge5a38ed2021-10-02 03:06:35801 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:49802 http_server_properties_->SetQuicAlternativeService(
Matt Menkeb32ba5122019-09-10 19:17:05803 server, network_isolation_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07804 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19805 }
806
rchbe69cb902016-02-11 01:10:48807 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27808 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48809 const HostPortPair& alternative) {
810 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46811 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21812 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48813 alternative.port());
Peter Kastinge5a38ed2021-10-02 03:06:35814 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:49815 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07816 server, NetworkIsolationKey(), alternative_service, expiration,
817 supported_versions_);
rchbe69cb902016-02-11 01:10:48818 }
819
Matt Menkeb32ba5122019-09-10 19:17:05820 void ExpectBrokenAlternateProtocolMapping(
821 const NetworkIsolationKey& network_isolation_key =
822 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46823 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34824 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49825 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05826 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34827 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49828 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05829 alternative_service_info_vector[0].alternative_service(),
830 network_isolation_key));
[email protected]aa9b14d2013-05-10 23:45:19831 }
832
Matt Menkeb32ba5122019-09-10 19:17:05833 void ExpectQuicAlternateProtocolMapping(
834 const NetworkIsolationKey& network_isolation_key =
835 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46836 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34837 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49838 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05839 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34840 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54841 EXPECT_EQ(
842 kProtoQUIC,
843 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49844 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05845 alternative_service_info_vector[0].alternative_service(),
846 network_isolation_key));
[email protected]4d590c9c2014-05-02 05:14:33847 }
848
[email protected]aa9b14d2013-05-10 23:45:19849 void AddHangingNonAlternateProtocolSocketData() {
Lei Zhange00db752021-04-17 00:48:46850 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
[email protected]dda75ab2013-06-22 22:43:30851 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30852 hanging_data->set_connect_data(hanging_connect);
853 hanging_data_.push_back(std::move(hanging_data));
854 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
[email protected]aa9b14d2013-05-10 23:45:19855 }
856
Zhongyi Shia6b68d112018-09-24 07:49:03857 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Victor Vasilieva1e66d72019-12-05 17:55:38858 context_.params()->migrate_sessions_on_network_change_v2 = true;
859 context_.params()->migrate_sessions_early_v2 = true;
860 context_.params()->retry_on_alternate_network_before_handshake = true;
Renjie Tang6ff9a9b2021-02-03 22:11:09861 scoped_mock_change_notifier_ =
862 std::make_unique<ScopedMockNetworkChangeNotifier>();
Zhongyi Shia6b68d112018-09-24 07:49:03863 MockNetworkChangeNotifier* mock_ncn =
864 scoped_mock_change_notifier_->mock_network_change_notifier();
865 mock_ncn->ForceNetworkHandlesSupported();
866 mock_ncn->SetConnectedNetworksList(
867 {kDefaultNetworkForTests, kNewNetworkForTests});
868 }
869
Matt Menkeb32ba5122019-09-10 19:17:05870 // Adds a new socket data provider for an HTTP request, and runs a request,
871 // expecting it to be used.
872 void AddHttpDataAndRunRequest() {
873 MockWrite http_writes[] = {
874 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
875 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
876 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
877
Ryan Hamiltona2dcbae2022-02-09 19:02:45878 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
879 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
880 MockRead(SYNCHRONOUS, 5, "http used"),
881 // Connection closed.
882 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:05883 SequencedSocketData http_data(http_reads, http_writes);
884 socket_factory_.AddSocketDataProvider(&http_data);
885 SSLSocketDataProvider ssl_data(ASYNC, OK);
886 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
887 SendRequestAndExpectHttpResponse("http used");
888 EXPECT_TRUE(http_data.AllWriteDataConsumed());
889 EXPECT_TRUE(http_data.AllReadDataConsumed());
890 }
891
892 // Adds a new socket data provider for a QUIC request, and runs a request,
893 // expecting it to be used. The new QUIC session is not closed.
894 void AddQuicDataAndRunRequest() {
895 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22896 version_,
897 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
898 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menkeb32ba5122019-09-10 19:17:05899 client_headers_include_h2_stream_dependency_);
900 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22901 version_,
902 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
903 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
904 false);
Matt Menkeb32ba5122019-09-10 19:17:05905 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56906 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05907 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:25908 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:56909 quic_data.AddWrite(
910 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_number++));
911 }
Matt Menkeb32ba5122019-09-10 19:17:05912 quic_data.AddWrite(
913 SYNCHRONOUS,
914 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56915 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
916 true, true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Matt Menkeb32ba5122019-09-10 19:17:05917 GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
918 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Fan Yang1ef6dfef2021-07-24 16:20:16919 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Matt Menkeb32ba5122019-09-10 19:17:05920 quic_data.AddRead(
921 ASYNC, server_maker.MakeResponseHeadersPacket(
922 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:28923 false, server_maker.GetResponseHeaders("200"), nullptr));
Matt Menkeb32ba5122019-09-10 19:17:05924 quic_data.AddRead(
925 ASYNC, server_maker.MakeDataPacket(
926 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:52927 true, ConstructDataFrame("quic used")));
Matt Menkeb32ba5122019-09-10 19:17:05928 // Don't care about the final ack.
929 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
930 // No more data to read.
931 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
932 quic_data.AddSocketDataToFactory(&socket_factory_);
Fan Yang1ef6dfef2021-07-24 16:20:16933
934 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
935 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:26936 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Fan Yang1ef6dfef2021-07-24 16:20:16937 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
938
939 // Pump the message loop to get the request started.
940 base::RunLoop().RunUntilIdle();
941 // Explicitly confirm the handshake.
942 crypto_client_stream_factory_.last_stream()
943 ->NotifySessionOneRttKeyAvailable();
944
945 ASSERT_FALSE(quic_data.AllReadDataConsumed());
946 quic_data.Resume();
947
948 // Run the QUIC session to completion.
949 base::RunLoop().RunUntilIdle();
Matt Menkeb32ba5122019-09-10 19:17:05950
951 EXPECT_TRUE(quic_data.AllReadDataConsumed());
952 }
953
Bence Béky6e243aa2019-12-13 19:01:07954 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56955 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
956 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36957 }
958
Bence Béky6e243aa2019-12-13 19:01:07959 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56960 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
961 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36962 }
963
Bence Béky6e243aa2019-12-13 19:01:07964 quic::QuicStreamId GetQpackDecoderStreamId() const {
965 return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
966 version_.transport_version, 1);
967 }
968
969 std::string StreamCancellationQpackDecoderInstruction(int n) const {
Ian Swettb70d9f8f2020-04-10 23:38:43970 return StreamCancellationQpackDecoderInstruction(n, true);
971 }
972
973 std::string StreamCancellationQpackDecoderInstruction(
974 int n,
975 bool create_stream) const {
Bence Béky6e243aa2019-12-13 19:01:07976 const quic::QuicStreamId cancelled_stream_id =
977 GetNthClientInitiatedBidirectionalStreamId(n);
978 EXPECT_LT(cancelled_stream_id, 63u);
979
Peter Kasting241e6d22021-06-09 17:24:58980 const char opcode = 0x40;
Ian Swettb70d9f8f2020-04-10 23:38:43981 if (create_stream) {
Peter Kasting241e6d22021-06-09 17:24:58982 return {0x03, static_cast<char>(opcode | cancelled_stream_id)};
Ian Swettb70d9f8f2020-04-10 23:38:43983 } else {
Peter Kasting241e6d22021-06-09 17:24:58984 return {static_cast<char>(opcode | cancelled_stream_id)};
Ian Swettb70d9f8f2020-04-10 23:38:43985 }
Bence Béky6e243aa2019-12-13 19:01:07986 }
987
Bence Béky230ac612017-08-30 19:17:08988 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49989 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08990 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49991 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08992 }
993
Zhongyi Shi1c022d22020-03-20 19:00:16994 void SendRequestAndExpectQuicResponseMaybeFromProxy(
995 const std::string& expected,
996 bool used_proxy,
997 uint16_t port,
998 const std::string& status_line,
999 const quic::ParsedQuicVersion& version) {
1000 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Zhongyi Shi1c022d22020-03-20 19:00:161001 RunTransaction(&trans);
1002 CheckWasQuicResponse(&trans, status_line, version);
1003 CheckResponsePort(&trans, port);
1004 CheckResponseData(&trans, expected);
Zhongyi Shi1c022d22020-03-20 19:00:161005 if (used_proxy) {
1006 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
Cammie Smith Barnesbf91e2a2020-12-23 20:49:041007
1008 // DNS aliases should be empty when using a proxy.
1009 EXPECT_TRUE(trans.GetResponseInfo()->dns_aliases.empty());
Zhongyi Shi1c022d22020-03-20 19:00:161010 } else {
1011 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1012 }
1013 }
1014
Victor Vasiliev22dd3f212022-02-11 21:57:291015 // Verify that the set of QUIC protocols in `alt_svc_info_vector` and
1016 // `supported_versions` is the same. Since QUICv1 and QUICv2 have the same
1017 // ALPN token "h3", they cannot be distinguished when parsing ALPN, so
1018 // consider them equal. This is accomplished by comparing the set of ALPN
1019 // strings (instead of comparing the set of ParsedQuicVersion entities).
1020 static void VerifyQuicVersionsInAlternativeServices(
1021 const AlternativeServiceInfoVector& alt_svc_info_vector,
1022 const quic::ParsedQuicVersionVector& supported_versions) {
1023 // Process supported versions.
1024 std::set<std::string> supported_alpn;
1025 for (const auto& version : supported_versions) {
1026 if (version.AlpnDeferToRFCv1()) {
1027 // These versions currently do not support Alt-Svc.
1028 return;
1029 }
1030 supported_alpn.insert(quic::ParsedQuicVersionToString(version));
1031 }
1032
1033 // Versions that support the legacy Google-specific Alt-Svc format are sent
1034 // in a single Alt-Svc entry, therefore they are accumulated in a single
1035 // AlternativeServiceInfo, whereas more recent versions all have their own
1036 // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
1037 std::set<std::string> alt_svc_negotiated_alpn;
1038 for (const auto& alt_svc_info : alt_svc_info_vector) {
1039 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
1040 for (const auto& version : alt_svc_info.advertised_versions()) {
1041 alt_svc_negotiated_alpn.insert(
1042 quic::ParsedQuicVersionToString(version));
1043 }
1044 }
1045
1046 // Compare.
1047 EXPECT_EQ(alt_svc_negotiated_alpn, supported_alpn);
1048 }
1049
Nick Harper23290b82019-05-02 00:02:561050 const quic::ParsedQuicVersion version_;
Ryan Hamiltona2dcbae2022-02-09 19:02:451051 const std::string alt_svc_header_ =
1052 GenerateQuicAltSvcHeader({version_}) + "\r\n";
Yixin Wang079ad542018-01-11 04:06:051053 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:561054 quic::ParsedQuicVersionVector supported_versions_;
Patrick Meenan0041f332022-05-19 23:48:351055 quic::test::QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Victor Vasiliev7752898d2019-11-14 21:30:221056 MockQuicContext context_;
Zhongyi Shi1c022d22020-03-20 19:00:161057 std::unique_ptr<QuicTestPacketMaker> client_maker_;
alyssar2adf3ac2016-05-03 17:12:581058 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:091059 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:421060 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:001061 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:561062 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:051063 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Eric Orthbe86fee2021-10-28 22:31:111064 MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
1065 RuleResolver::GetLocalhostResult()};
[email protected]1c04f9522013-02-21 20:32:431066 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:111067 TransportSecurityState transport_security_state_;
Ryan Sleevi8a9c9c12018-05-09 02:36:231068 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:381069 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:071070 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:261071 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:421072 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:491073 std::unique_ptr<HttpServerProperties> http_server_properties_;
Matt Menke30a878c2021-07-20 22:25:091074 HttpNetworkSessionParams session_params_;
1075 HttpNetworkSessionContext session_context_;
[email protected]aa9b14d2013-05-10 23:45:191076 HttpRequestInfo request_;
Matt Reichhoff0049a0b72021-10-20 20:44:261077 NetLogWithSource net_log_with_source_{
1078 NetLogWithSource::Make(NetLogSourceType::NONE)};
1079 RecordingNetLogObserver net_log_observer_;
danakjad1777e2016-04-16 00:56:421080 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:561081 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:031082 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:121083
1084 private:
1085 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1086 const std::string& expected,
bnc62a44f022015-04-02 15:59:411087 bool used_proxy,
David Schinazif832cb82019-11-08 22:25:271088 uint16_t port,
1089 const std::string& status_line) {
Zhongyi Shi1c022d22020-03-20 19:00:161090 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
1091 status_line, version_);
tbansal7cec3812015-02-05 21:25:121092 }
David Schinazif832cb82019-11-08 22:25:271093
1094 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1095 const std::string& expected,
1096 bool used_proxy,
1097 uint16_t port) {
1098 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
Kenichi Ishibashif8634ab2021-03-16 23:41:281099 "HTTP/1.1 200", version_);
David Schinazif832cb82019-11-08 22:25:271100 }
[email protected]61a527782013-02-21 03:58:001101};
1102
David Schinazi09e9a6012019-10-03 17:37:571103INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1104 QuicNetworkTransactionTest,
1105 ::testing::ValuesIn(GetTestParams()),
1106 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201107
Ryan Hamiltona64a5bcf2017-11-30 07:35:281108TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:381109 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281110 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381111 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281112 HostPortPair::FromString("mail.example.org:443"));
1113 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271114 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281115
Ryan Hamiltonabad59e2019-06-06 04:02:591116 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251117 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231118 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281119 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1120 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211121 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281122
1123 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1124
1125 CreateSession();
1126
1127 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1128 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261129 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281130 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1131 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1132
1133 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1134 -ERR_INTERNET_DISCONNECTED, 1);
1135 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1136 -ERR_INTERNET_DISCONNECTED, 1);
1137}
1138
1139TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Victor Vasilieva1e66d72019-12-05 17:55:381140 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281141 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381142 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281143 HostPortPair::FromString("mail.example.org:443"));
1144 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271145 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281146
Ryan Hamiltonabad59e2019-06-06 04:02:591147 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251148 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231149 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281150 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1151 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211152 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281153
1154 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1155
1156 CreateSession();
1157
1158 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1159 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261160 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281161 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1162 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1163
1164 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1165 -ERR_INTERNET_DISCONNECTED, 1);
1166 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1167 -ERR_INTERNET_DISCONNECTED, 1);
1168}
1169
tbansal180587c2017-02-16 15:13:231170TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381171 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231172 HostPortPair::FromString("mail.example.org:443"));
1173
Ryan Hamiltonabad59e2019-06-06 04:02:591174 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231175 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251176 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231177 mock_quic_data.AddWrite(SYNCHRONOUS,
1178 ConstructInitialSettingsPacket(packet_num++));
1179 }
rch5cb522462017-04-25 20:18:361180 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231181 SYNCHRONOUS,
1182 ConstructClientRequestHeadersPacket(
1183 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1184 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431185 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331186 ASYNC, ConstructServerResponseHeadersPacket(
1187 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281188 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331189 mock_quic_data.AddRead(
1190 ASYNC, ConstructServerDataPacket(
1191 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521192 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231193 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341194 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231195 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1196
1197 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1198
1199 CreateSession();
1200 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1201
1202 EXPECT_FALSE(
1203 test_socket_performance_watcher_factory_.rtt_notification_received());
1204 SendRequestAndExpectQuicResponse("hello!");
1205 EXPECT_TRUE(
1206 test_socket_performance_watcher_factory_.rtt_notification_received());
1207}
1208
1209TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381210 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231211 HostPortPair::FromString("mail.example.org:443"));
1212
Ryan Hamiltonabad59e2019-06-06 04:02:591213 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231214 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251215 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231216 mock_quic_data.AddWrite(SYNCHRONOUS,
1217 ConstructInitialSettingsPacket(packet_num++));
1218 }
rch5cb522462017-04-25 20:18:361219 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231220 SYNCHRONOUS,
1221 ConstructClientRequestHeadersPacket(
1222 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1223 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431224 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331225 ASYNC, ConstructServerResponseHeadersPacket(
1226 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281227 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331228 mock_quic_data.AddRead(
1229 ASYNC, ConstructServerDataPacket(
1230 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521231 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231232 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341233 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231234 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1235
1236 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1237
1238 CreateSession();
1239 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1240
1241 EXPECT_FALSE(
1242 test_socket_performance_watcher_factory_.rtt_notification_received());
1243 SendRequestAndExpectQuicResponse("hello!");
1244 EXPECT_FALSE(
1245 test_socket_performance_watcher_factory_.rtt_notification_received());
1246}
1247
[email protected]1e960032013-12-20 19:00:201248TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:381249 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571250 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471251
Ryan Hamiltonabad59e2019-06-06 04:02:591252 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231253 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251254 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231255 mock_quic_data.AddWrite(SYNCHRONOUS,
1256 ConstructInitialSettingsPacket(packet_num++));
1257 }
rch5cb522462017-04-25 20:18:361258 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231259 SYNCHRONOUS,
1260 ConstructClientRequestHeadersPacket(
1261 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1262 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431263 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331264 ASYNC, ConstructServerResponseHeadersPacket(
1265 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281266 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331267 mock_quic_data.AddRead(
1268 ASYNC, ConstructServerDataPacket(
1269 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521270 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231271 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341272 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:591273 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471274
rcha5399e02015-04-21 19:32:041275 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471276
[email protected]4dca587c2013-03-07 16:54:471277 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471278
[email protected]aa9b14d2013-05-10 23:45:191279 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471280
[email protected]98b20ce2013-05-10 05:55:261281 // Check that the NetLog was filled reasonably.
Matt Reichhoff0049a0b72021-10-20 20:44:261282 auto entries = net_log_observer_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261283 EXPECT_LT(0u, entries.size());
1284
1285 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291286 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001287 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1288 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261289 EXPECT_LT(0, pos);
1290
David Schinazi24bfaa02020-10-22 19:54:381291 // ... and also a TYPE_QUIC_SESSION_PACKET_SENT.
1292 pos = ExpectLogContainsSomewhere(entries, 0,
1293 NetLogEventType::QUIC_SESSION_PACKET_SENT,
1294 NetLogEventPhase::NONE);
1295 EXPECT_LT(0, pos);
1296
rchfd527212015-08-25 00:41:261297 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291298 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261299 entries, 0,
mikecirone8b85c432016-09-08 19:11:001300 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1301 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261302 EXPECT_LT(0, pos);
1303
Eric Roman79cc7552019-07-19 02:17:541304 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261305
rchfd527212015-08-25 00:41:261306 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1307 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001308 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1309 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261310 EXPECT_LT(0, pos);
1311
[email protected]98b20ce2013-05-10 05:55:261312 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291313 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001314 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1315 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261316 EXPECT_LT(0, pos);
1317
Eric Roman79cc7552019-07-19 02:17:541318 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Victor Vasiliev7da08172019-10-14 06:04:251319 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451320 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1321 static_cast<quic::QuicStreamId>(log_stream_id));
1322 } else {
1323 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1324 static_cast<quic::QuicStreamId>(log_stream_id));
1325 }
[email protected]4dca587c2013-03-07 16:54:471326}
1327
Bence Békyb6300042020-01-28 21:18:201328// Regression test for https://crbug.com/1043531.
1329TEST_P(QuicNetworkTransactionTest, ResetOnEmptyResponseHeaders) {
1330 if (!quic::VersionUsesHttp3(version_.transport_version)) {
1331 return;
1332 }
1333
Kenichi Ishibashi10111e82021-03-23 02:19:061334 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Bence Békyb6300042020-01-28 21:18:201335 context_.params()->origins_to_force_quic_on.insert(
1336 HostPortPair::FromString("mail.example.org:443"));
1337
1338 MockQuicData mock_quic_data(version_);
1339 int write_packet_num = 1;
1340 mock_quic_data.AddWrite(SYNCHRONOUS,
1341 ConstructInitialSettingsPacket(write_packet_num++));
1342 mock_quic_data.AddWrite(
1343 SYNCHRONOUS,
1344 ConstructClientRequestHeadersPacket(
1345 write_packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1346 true, true, GetRequestHeaders("GET", "https", "/")));
1347
1348 const quic::QuicStreamId request_stream_id =
1349 GetNthClientInitiatedBidirectionalStreamId(0);
Bence Béky4c325e52020-10-22 20:48:011350 spdy::Http2HeaderBlock empty_response_headers;
Bence Békyb6300042020-01-28 21:18:201351 const std::string response_data = server_maker_.QpackEncodeHeaders(
1352 request_stream_id, std::move(empty_response_headers), nullptr);
1353 uint64_t read_packet_num = 1;
1354 mock_quic_data.AddRead(
1355 ASYNC, ConstructServerDataPacket(read_packet_num++, request_stream_id,
1356 false, false, response_data));
1357 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1358
1359 mock_quic_data.AddWrite(
Kenichi Ishibashi10111e82021-03-23 02:19:061360 ASYNC, ConstructClientAckDataAndRst(
1361 write_packet_num++, true, request_stream_id,
1362 quic::QUIC_STREAM_GENERAL_PROTOCOL_ERROR, 1, 1,
1363 GetQpackDecoderStreamId(), false,
1364 StreamCancellationQpackDecoderInstruction(request_stream_id)));
Bence Békyb6300042020-01-28 21:18:201365
1366 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1367
1368 CreateSession();
1369
1370 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1371 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261372 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Bence Békyb6300042020-01-28 21:18:201373 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Kenichi Ishibashi10111e82021-03-23 02:19:061374 EXPECT_THAT(callback.WaitForResult(), IsError(net::ERR_QUIC_PROTOCOL_ERROR));
1375 base::RunLoop().RunUntilIdle();
1376 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1377 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
Bence Békyb6300042020-01-28 21:18:201378}
1379
rchbd089ab2017-05-26 23:05:041380TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381381 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041382 HostPortPair::FromString("mail.example.org:443"));
1383
Ryan Hamiltonabad59e2019-06-06 04:02:591384 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231385 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251386 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231387 mock_quic_data.AddWrite(SYNCHRONOUS,
1388 ConstructInitialSettingsPacket(packet_num++));
1389 }
rchbd089ab2017-05-26 23:05:041390 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231391 SYNCHRONOUS,
1392 ConstructClientRequestHeadersPacket(
1393 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1394 true, GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashif8634ab2021-03-16 23:41:281395 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200");
rchbd089ab2017-05-26 23:05:041396 response_headers["key1"] = std::string(30000, 'A');
1397 response_headers["key2"] = std::string(30000, 'A');
1398 response_headers["key3"] = std::string(30000, 'A');
1399 response_headers["key4"] = std::string(30000, 'A');
1400 response_headers["key5"] = std::string(30000, 'A');
1401 response_headers["key6"] = std::string(30000, 'A');
1402 response_headers["key7"] = std::string(30000, 'A');
1403 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451404 quic::QuicStreamId stream_id;
1405 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251406 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451407 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281408 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451409 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451410 } else {
1411 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1412 spdy::SpdyHeadersIR headers_frame(
1413 GetNthClientInitiatedBidirectionalStreamId(0),
1414 std::move(response_headers));
1415 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1416 spdy::SpdySerializedFrame spdy_frame =
1417 response_framer.SerializeFrame(headers_frame);
1418 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1419 }
rchbd089ab2017-05-26 23:05:041420
Fan Yangac867502019-01-28 21:10:231421 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041422 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451423 for (size_t offset = 0; offset < response_data.length();
1424 offset += chunk_size) {
1425 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431426 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451427 ASYNC, ConstructServerDataPacket(
1428 packet_number++, stream_id, false, false,
Victor Vasiliev502ba582020-09-15 23:16:151429 absl::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041430 }
1431
1432 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331433 ASYNC, ConstructServerDataPacket(
1434 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Bence Béky319388a882020-09-23 18:42:521435 false, true, ConstructDataFrame("hello!")));
rchbd089ab2017-05-26 23:05:041436 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341437 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Renjie Tangaadb84b2019-08-31 01:00:231438 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341439 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3));
rchbd089ab2017-05-26 23:05:041440
1441 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1442
1443 CreateSession();
1444
1445 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421446 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1447 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041448}
1449
1450TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381451 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1452 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041453 HostPortPair::FromString("mail.example.org:443"));
1454
Ryan Hamiltonabad59e2019-06-06 04:02:591455 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231456 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251457 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231458 mock_quic_data.AddWrite(SYNCHRONOUS,
1459 ConstructInitialSettingsPacket(packet_num++));
1460 }
rchbd089ab2017-05-26 23:05:041461 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231462 SYNCHRONOUS,
1463 ConstructClientRequestHeadersPacket(
1464 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1465 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451466
Kenichi Ishibashif8634ab2021-03-16 23:41:281467 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200");
rchbd089ab2017-05-26 23:05:041468 response_headers["key1"] = std::string(30000, 'A');
1469 response_headers["key2"] = std::string(30000, 'A');
1470 response_headers["key3"] = std::string(30000, 'A');
1471 response_headers["key4"] = std::string(30000, 'A');
1472 response_headers["key5"] = std::string(30000, 'A');
1473 response_headers["key6"] = std::string(30000, 'A');
1474 response_headers["key7"] = std::string(30000, 'A');
1475 response_headers["key8"] = std::string(30000, 'A');
1476 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451477
1478 quic::QuicStreamId stream_id;
1479 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251480 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451481 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281482 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451483 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451484 } else {
1485 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1486 spdy::SpdyHeadersIR headers_frame(
1487 GetNthClientInitiatedBidirectionalStreamId(0),
1488 std::move(response_headers));
1489 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1490 spdy::SpdySerializedFrame spdy_frame =
1491 response_framer.SerializeFrame(headers_frame);
1492 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1493 }
rchbd089ab2017-05-26 23:05:041494
Fan Yangac867502019-01-28 21:10:231495 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041496 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451497 for (size_t offset = 0; offset < response_data.length();
1498 offset += chunk_size) {
1499 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431500 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451501 ASYNC, ConstructServerDataPacket(
1502 packet_number++, stream_id, false, false,
Victor Vasiliev502ba582020-09-15 23:16:151503 absl::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041504 }
1505
1506 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331507 ASYNC, ConstructServerDataPacket(
1508 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Bence Béky319388a882020-09-23 18:42:521509 false, true, ConstructDataFrame("hello!")));
rchbd089ab2017-05-26 23:05:041510 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341511 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431512 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331513 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231514 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:341515 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3));
rchbd089ab2017-05-26 23:05:041516
1517 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1518
1519 CreateSession();
1520
1521 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1522 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261523 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rchbd089ab2017-05-26 23:05:041524 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1525 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1526}
1527
Kenichi Ishibashifd2d3e62022-03-01 22:54:051528TEST_P(QuicNetworkTransactionTest, RedirectMultipleLocations) {
1529 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1530 context_.params()->origins_to_force_quic_on.insert(
1531 HostPortPair::FromString("mail.example.org:443"));
1532
1533 MockQuicData mock_quic_data(version_);
1534 int packet_num = 1;
1535 if (VersionUsesHttp3(version_.transport_version)) {
1536 mock_quic_data.AddWrite(SYNCHRONOUS,
1537 ConstructInitialSettingsPacket(packet_num++));
1538 }
1539 mock_quic_data.AddWrite(
1540 SYNCHRONOUS,
1541 ConstructClientRequestHeadersPacket(
1542 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1543 true, GetRequestHeaders("GET", "https", "/")));
1544
1545 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("301");
1546 response_headers.AppendValueOrAddHeader("location", "https://example1.test");
1547 response_headers.AppendValueOrAddHeader("location", "https://example2.test");
1548
1549 if (quic::VersionUsesHttp3(version_.transport_version)) {
1550 const quic::QuicStreamId stream_id =
1551 GetNthClientInitiatedBidirectionalStreamId(0);
1552 const std::string response_data = server_maker_.QpackEncodeHeaders(
1553 stream_id, std::move(response_headers), nullptr);
1554 ASSERT_LT(response_data.size(), 1200u);
1555 mock_quic_data.AddRead(
1556 ASYNC, ConstructServerDataPacket(/*packet_number=*/1, stream_id,
1557 /*should_include_version=*/false,
1558 /*fin=*/true, response_data));
1559 } else {
1560 const quic::QuicStreamId stream_id =
1561 quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1562 spdy::SpdyHeadersIR headers_frame(
1563 GetNthClientInitiatedBidirectionalStreamId(0),
1564 std::move(response_headers));
1565 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1566 spdy::SpdySerializedFrame spdy_frame =
1567 response_framer.SerializeFrame(headers_frame);
1568 const std::string response_data =
1569 std::string(spdy_frame.data(), spdy_frame.size());
1570 ASSERT_LT(response_data.size(), 1200u);
1571 mock_quic_data.AddRead(
1572 ASYNC, ConstructServerDataPacket(/*packet_number=*/1, stream_id,
1573 /*should_include_version=*/false,
1574 /*fin=*/false, response_data));
1575 }
1576 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1577
1578 mock_quic_data.AddWrite(
1579 ASYNC, ConstructClientAckAndRstPacket(
1580 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1581 quic::QUIC_STREAM_CANCELLED,
1582 /*largest_received=*/1, /*smallest_received=*/1));
1583
1584 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1585
1586 CreateSession();
1587
1588 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1589 TestCompletionCallback callback;
1590 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
1591 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1592 ASSERT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1593}
1594
rcha2bd44b2016-07-02 00:42:551595TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Victor Vasilieva1e66d72019-12-05 17:55:381596 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551597
Ryan Hamilton9835e662018-08-02 05:36:271598 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551599
Ryan Hamiltonabad59e2019-06-06 04:02:591600 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231601 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251602 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231603 mock_quic_data.AddWrite(SYNCHRONOUS,
1604 ConstructInitialSettingsPacket(packet_num++));
1605 }
rch5cb522462017-04-25 20:18:361606 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231607 SYNCHRONOUS,
1608 ConstructClientRequestHeadersPacket(
1609 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1610 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431611 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331612 ASYNC, ConstructServerResponseHeadersPacket(
1613 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281614 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331615 mock_quic_data.AddRead(
1616 ASYNC, ConstructServerDataPacket(
1617 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521618 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231619 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341620 ConstructClientAckPacket(packet_num++, 2, 1));
rcha2bd44b2016-07-02 00:42:551621 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1622
1623 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1624
1625 CreateSession();
1626
1627 SendRequestAndExpectQuicResponse("hello!");
1628 EXPECT_TRUE(
1629 test_socket_performance_watcher_factory_.rtt_notification_received());
1630}
1631
David Schinazif832cb82019-11-08 22:25:271632// Regression test for https://crbug.com/695225
1633TEST_P(QuicNetworkTransactionTest, 408Response) {
Victor Vasilieva1e66d72019-12-05 17:55:381634 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
David Schinazif832cb82019-11-08 22:25:271635
1636 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1637
1638 MockQuicData mock_quic_data(version_);
1639 int packet_num = 1;
1640 if (VersionUsesHttp3(version_.transport_version)) {
1641 mock_quic_data.AddWrite(SYNCHRONOUS,
1642 ConstructInitialSettingsPacket(packet_num++));
1643 }
1644 mock_quic_data.AddWrite(
1645 SYNCHRONOUS,
1646 ConstructClientRequestHeadersPacket(
1647 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1648 true, GetRequestHeaders("GET", "https", "/")));
1649 mock_quic_data.AddRead(
1650 ASYNC, ConstructServerResponseHeadersPacket(
1651 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281652 GetResponseHeaders("408")));
David Schinazif832cb82019-11-08 22:25:271653 mock_quic_data.AddRead(
1654 ASYNC, ConstructServerDataPacket(
1655 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521656 ConstructDataFrame("hello!")));
David Schinazif832cb82019-11-08 22:25:271657 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341658 ConstructClientAckPacket(packet_num++, 2, 1));
David Schinazif832cb82019-11-08 22:25:271659 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1660
1661 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1662
1663 CreateSession();
1664
Kenichi Ishibashif8634ab2021-03-16 23:41:281665 SendRequestAndExpectQuicResponse("hello!", "HTTP/1.1 408");
David Schinazif832cb82019-11-08 22:25:271666}
1667
[email protected]cf3e3cd62014-02-05 16:16:161668TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411669 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561670 proxy_resolution_service_ =
1671 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
1672 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161673
Ryan Hamiltonabad59e2019-06-06 04:02:591674 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231675 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251676 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231677 mock_quic_data.AddWrite(SYNCHRONOUS,
1678 ConstructInitialSettingsPacket(packet_num++));
1679 }
rch5cb522462017-04-25 20:18:361680 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231681 SYNCHRONOUS,
1682 ConstructClientRequestHeadersPacket(
1683 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1684 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431685 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331686 ASYNC, ConstructServerResponseHeadersPacket(
1687 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281688 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331689 mock_quic_data.AddRead(
1690 ASYNC, ConstructServerDataPacket(
1691 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521692 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231693 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341694 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:501695 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211696 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
[email protected]cf3e3cd62014-02-05 16:16:161697
rcha5399e02015-04-21 19:32:041698 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161699
tbansal0f56a39a2016-04-07 22:03:381700 EXPECT_FALSE(
1701 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161702 // There is no need to set up an alternate protocol job, because
1703 // no attempt will be made to speak to the proxy over TCP.
1704
rch9ae5b3b2016-02-11 00:36:291705 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161706 CreateSession();
1707
bnc62a44f022015-04-02 15:59:411708 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381709 EXPECT_TRUE(
1710 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161711}
1712
bnc313ba9c2015-06-11 15:42:311713// Regression test for https://crbug.com/492458. Test that for an HTTP
1714// connection through a QUIC proxy, the certificate exhibited by the proxy is
1715// checked against the proxy hostname, not the origin hostname.
1716TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291717 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311718 const std::string proxy_host = "www.example.org";
1719
mmenke6ddfbea2017-05-31 21:48:411720 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561721 proxy_resolution_service_ =
1722 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
1723 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311724
Zhongyi Shi1c022d22020-03-20 19:00:161725 client_maker_->set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591726 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231727 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251728 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231729 mock_quic_data.AddWrite(SYNCHRONOUS,
1730 ConstructInitialSettingsPacket(packet_num++));
1731 }
rch5cb522462017-04-25 20:18:361732 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231733 SYNCHRONOUS,
1734 ConstructClientRequestHeadersPacket(
1735 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1736 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431737 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331738 ASYNC, ConstructServerResponseHeadersPacket(
1739 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281740 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331741 mock_quic_data.AddRead(
1742 ASYNC, ConstructServerDataPacket(
1743 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521744 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231745 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341746 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:501747 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211748 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc313ba9c2015-06-11 15:42:311749 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1750
1751 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291752 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311753 ASSERT_TRUE(cert.get());
1754 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241755 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1756 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311757 ProofVerifyDetailsChromium verify_details;
1758 verify_details.cert_verify_result.verified_cert = cert;
1759 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561760 ProofVerifyDetailsChromium verify_details2;
1761 verify_details2.cert_verify_result.verified_cert = cert;
1762 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311763
1764 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091765 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321766 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271767 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311768 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1769}
1770
rchbe69cb902016-02-11 01:10:481771TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Victor Vasilieva1e66d72019-12-05 17:55:381772 context_.params()->allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481773 HostPortPair origin("www.example.org", 443);
1774 HostPortPair alternative("mail.example.org", 443);
1775
1776 base::FilePath certs_dir = GetTestCertsDirectory();
1777 scoped_refptr<X509Certificate> cert(
1778 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1779 ASSERT_TRUE(cert.get());
1780 // TODO(rch): the connection should be "to" the origin, so if the cert is
1781 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241782 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1783 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481784 ProofVerifyDetailsChromium verify_details;
1785 verify_details.cert_verify_result.verified_cert = cert;
1786 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1787
Zhongyi Shi1c022d22020-03-20 19:00:161788 client_maker_->set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591789 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021790
Renjie Tangaadb84b2019-08-31 01:00:231791 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251792 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231793 mock_quic_data.AddWrite(SYNCHRONOUS,
1794 ConstructInitialSettingsPacket(packet_num++));
1795 }
rch5cb522462017-04-25 20:18:361796 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231797 SYNCHRONOUS,
1798 ConstructClientRequestHeadersPacket(
1799 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1800 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431801 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331802 ASYNC, ConstructServerResponseHeadersPacket(
1803 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281804 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331805 mock_quic_data.AddRead(
1806 ASYNC, ConstructServerDataPacket(
1807 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521808 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231809 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341810 ConstructClientAckPacket(packet_num++, 2, 1));
rchbe69cb902016-02-11 01:10:481811 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211812 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rchbe69cb902016-02-11 01:10:481813 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1814
1815 request_.url = GURL("https://" + origin.host());
1816 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271817 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091818 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321819 CreateSession();
rchbe69cb902016-02-11 01:10:481820
1821 SendRequestAndExpectQuicResponse("hello!");
1822}
1823
zhongyief3f4ce52017-07-05 23:53:281824TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
David Schinazi84c58bb2020-06-04 20:14:331825 quic::ParsedQuicVersion unsupported_version =
1826 quic::ParsedQuicVersion::Unsupported();
Bence Békyb89104962020-01-24 00:05:171827 // Add support for another QUIC version besides |version_|. Also find an
zhongyief3f4ce52017-07-05 23:53:281828 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561829 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281830 if (version == version_)
1831 continue;
1832 if (supported_versions_.size() != 2) {
1833 supported_versions_.push_back(version);
1834 continue;
1835 }
1836 unsupported_version = version;
1837 break;
1838 }
Bence Békyb89104962020-01-24 00:05:171839 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:331840 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), unsupported_version);
zhongyief3f4ce52017-07-05 23:53:281841
1842 // Set up alternative service to use QUIC with a version that is not
1843 // supported.
1844 url::SchemeHostPort server(request_.url);
1845 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1846 443);
Peter Kastinge5a38ed2021-10-02 03:06:351847 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:491848 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071849 server, NetworkIsolationKey(), alternative_service, expiration,
1850 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281851
1852 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491853 http_server_properties_->GetAlternativeServiceInfos(
1854 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281855 EXPECT_EQ(1u, alt_svc_info_vector.size());
1856 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1857 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1858 EXPECT_EQ(unsupported_version,
1859 alt_svc_info_vector[0].advertised_versions()[0]);
1860
1861 // First request should still be sent via TCP as the QUIC version advertised
1862 // in the stored AlternativeService is not supported by the client. However,
1863 // the response from the server will advertise new Alt-Svc with supported
1864 // versions.
David Schinazifbd4c432020-04-07 19:23:551865 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyief3f4ce52017-07-05 23:53:281866 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:171867 MockRead("HTTP/1.1 200 OK\r\n"),
1868 MockRead(altsvc_header.c_str()),
1869 MockRead("\r\n"),
zhongyief3f4ce52017-07-05 23:53:281870 MockRead("hello world"),
1871 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1872 MockRead(ASYNC, OK)};
1873
Ryan Sleevib8d7ea02018-05-07 20:01:011874 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281875 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081876 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281877 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1878
1879 // Second request should be sent via QUIC as a new list of verions supported
1880 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591881 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231882 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251883 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231884 mock_quic_data.AddWrite(SYNCHRONOUS,
1885 ConstructInitialSettingsPacket(packet_num++));
1886 }
zhongyief3f4ce52017-07-05 23:53:281887 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231888 SYNCHRONOUS,
1889 ConstructClientRequestHeadersPacket(
1890 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1891 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431892 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331893 ASYNC, ConstructServerResponseHeadersPacket(
1894 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281895 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331896 mock_quic_data.AddRead(
1897 ASYNC, ConstructServerDataPacket(
1898 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521899 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231900 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341901 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyief3f4ce52017-07-05 23:53:281902 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211903 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyief3f4ce52017-07-05 23:53:281904
1905 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1906
1907 AddHangingNonAlternateProtocolSocketData();
1908
1909 CreateSession(supported_versions_);
1910
1911 SendRequestAndExpectHttpResponse("hello world");
1912 SendRequestAndExpectQuicResponse("hello!");
1913
1914 // Check alternative service list is updated with new versions.
1915 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491916 session_->http_server_properties()->GetAlternativeServiceInfos(
1917 server, NetworkIsolationKey());
Victor Vasiliev22dd3f212022-02-11 21:57:291918 VerifyQuicVersionsInAlternativeServices(alt_svc_info_vector,
1919 supported_versions_);
zhongyief3f4ce52017-07-05 23:53:281920}
1921
bncaccd4962017-04-06 21:00:261922// Regression test for https://crbug.com/546991.
1923// The server might not be able to serve a request on an alternative connection,
1924// and might send a 421 Misdirected Request response status to indicate this.
1925// HttpNetworkTransaction should reset the request and retry without using
1926// alternative services.
1927TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1928 // Set up alternative service to use QUIC.
1929 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1930 // that overrides |enable_alternative_services|.
1931 url::SchemeHostPort server(request_.url);
1932 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1933 443);
Peter Kastinge5a38ed2021-10-02 03:06:351934 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:491935 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071936 server, NetworkIsolationKey(), alternative_service, expiration,
1937 supported_versions_);
bncaccd4962017-04-06 21:00:261938
davidbena4449722017-05-05 23:30:531939 // First try: The alternative job uses QUIC and reports an HTTP 421
1940 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1941 // paused at Connect(), so it will never exit the socket pool. This ensures
1942 // that the alternate job always wins the race and keeps whether the
1943 // |http_data| exits the socket pool before the main job is aborted
1944 // deterministic. The first main job gets aborted without the socket pool ever
1945 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591946 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231947 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251948 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231949 mock_quic_data.AddWrite(SYNCHRONOUS,
1950 ConstructInitialSettingsPacket(packet_num++));
1951 }
rch5cb522462017-04-25 20:18:361952 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231953 SYNCHRONOUS,
1954 ConstructClientRequestHeadersPacket(
1955 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1956 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331957 mock_quic_data.AddRead(
1958 ASYNC, ConstructServerResponseHeadersPacket(
1959 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021960 GetResponseHeaders("421")));
David Schinazi395918c2021-02-05 18:56:211961 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncaccd4962017-04-06 21:00:261962 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1963
davidbena4449722017-05-05 23:30:531964 // Second try: The main job uses TCP, and there is no alternate job. Once the
1965 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1966 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261967 // Note that if there was an alternative QUIC Job created for the second try,
1968 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1969 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531970 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1971 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1972 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1973 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1974 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1975 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011976 reads, writes);
bncaccd4962017-04-06 21:00:261977 socket_factory_.AddSocketDataProvider(&http_data);
1978 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1979
bncaccd4962017-04-06 21:00:261980 CreateSession();
1981 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531982
1983 // Run until |mock_quic_data| has failed and |http_data| has paused.
1984 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261985 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
davidbena4449722017-05-05 23:30:531986 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1987 base::RunLoop().RunUntilIdle();
1988
1989 // |mock_quic_data| must have run to completion.
1990 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1991 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1992
1993 // Now that the QUIC data has been consumed, unblock |http_data|.
1994 http_data.socket()->OnConnectComplete(MockConnect());
1995
1996 // The retry logic must hide the 421 status. The transaction succeeds on
1997 // |http_data|.
1998 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261999 CheckWasHttpResponse(&trans);
2000 CheckResponsePort(&trans, 443);
2001 CheckResponseData(&trans, "hello!");
2002}
2003
[email protected]1e960032013-12-20 19:00:202004TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Victor Vasilieva1e66d72019-12-05 17:55:382005 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:572006 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:302007
Ryan Hamiltonabad59e2019-06-06 04:02:592008 MockQuicData mock_quic_data1(version_);
Victor Vasiliev7da08172019-10-14 06:04:252009 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232010 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:402011 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Zhongyi Shi1c022d22020-03-20 19:00:162012 client_maker_->Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:592013 MockQuicData mock_quic_data2(version_);
Victor Vasiliev7da08172019-10-14 06:04:252014 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232015 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:302016 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:402017 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:432018 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:402019
2020 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
2021 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:302022
2023 CreateSession();
2024
tbansal0f56a39a2016-04-07 22:03:382025 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:402026 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:162027 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:402028 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262029 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:012030 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2031 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:382032 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:532033
2034 NetErrorDetails details;
2035 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522036 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:402037 }
[email protected]cebe3282013-05-22 23:49:302038}
2039
tbansalc8a94ea2015-11-02 23:58:512040TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
2041 // Attempt to "force" quic on 443, which will not be honored.
Victor Vasilieva1e66d72019-12-05 17:55:382042 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:572043 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:512044
2045 MockRead http_reads[] = {
2046 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
2047 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2048 MockRead(ASYNC, OK)};
2049
Ryan Sleevib8d7ea02018-05-07 20:01:012050 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:512051 socket_factory_.AddSocketDataProvider(&data);
2052 SSLSocketDataProvider ssl(ASYNC, OK);
2053 socket_factory_.AddSSLSocketDataProvider(&ssl);
2054
2055 CreateSession();
2056
2057 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:382058 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:512059}
2060
bncc958faa2015-07-31 18:14:522061TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:352062 if (version_.AlpnDeferToRFCv1()) {
2063 // These versions currently do not support Alt-Svc.
2064 return;
2065 }
bncc958faa2015-07-31 18:14:522066 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452067 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:562068 MockRead("hello world"),
bncc958faa2015-07-31 18:14:522069 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2070 MockRead(ASYNC, OK)};
2071
Ryan Sleevib8d7ea02018-05-07 20:01:012072 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:522073 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082074 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:562075 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:522076
Ryan Hamiltonabad59e2019-06-06 04:02:592077 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232078 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252079 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232080 mock_quic_data.AddWrite(SYNCHRONOUS,
2081 ConstructInitialSettingsPacket(packet_num++));
2082 }
rch5cb522462017-04-25 20:18:362083 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232084 SYNCHRONOUS,
2085 ConstructClientRequestHeadersPacket(
2086 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2087 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432088 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332089 ASYNC, ConstructServerResponseHeadersPacket(
2090 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282091 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332092 mock_quic_data.AddRead(
2093 ASYNC, ConstructServerDataPacket(
2094 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522095 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232096 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342097 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:522098 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212099 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:522100
2101 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2102
rtennetib8e80fb2016-05-16 00:12:092103 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322104 CreateSession();
bncc958faa2015-07-31 18:14:522105
2106 SendRequestAndExpectHttpResponse("hello world");
2107 SendRequestAndExpectQuicResponse("hello!");
2108}
2109
Ryan Hamilton64f21d52019-08-31 07:10:512110TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:352111 if (version_.AlpnDeferToRFCv1()) {
2112 // These versions currently do not support Alt-Svc.
2113 return;
2114 }
Ryan Hamilton64f21d52019-08-31 07:10:512115 std::string alt_svc_header =
2116 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
2117 MockRead http_reads[] = {
2118 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
2119 MockRead("hello world"),
2120 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2121 MockRead(ASYNC, OK)};
2122
2123 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2124 socket_factory_.AddSocketDataProvider(&http_data);
2125 AddCertificate(&ssl_data_);
2126 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2127
2128 MockQuicData mock_quic_data(version_);
2129 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252130 if (VersionUsesHttp3(version_.transport_version)) {
Ryan Hamilton64f21d52019-08-31 07:10:512131 mock_quic_data.AddWrite(SYNCHRONOUS,
2132 ConstructInitialSettingsPacket(packet_num++));
2133 }
2134 mock_quic_data.AddWrite(
2135 SYNCHRONOUS,
2136 ConstructClientRequestHeadersPacket(
2137 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2138 true, GetRequestHeaders("GET", "https", "/")));
2139 mock_quic_data.AddRead(
2140 ASYNC, ConstructServerResponseHeadersPacket(
2141 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282142 GetResponseHeaders("200")));
Ryan Hamilton64f21d52019-08-31 07:10:512143 mock_quic_data.AddRead(
2144 ASYNC, ConstructServerDataPacket(
2145 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522146 ConstructDataFrame("hello!")));
Ryan Hamilton64f21d52019-08-31 07:10:512147 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342148 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton64f21d52019-08-31 07:10:512149 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212150 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamilton64f21d52019-08-31 07:10:512151
2152 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2153
2154 AddHangingNonAlternateProtocolSocketData();
2155 CreateSession();
2156
2157 SendRequestAndExpectHttpResponse("hello world");
2158 SendRequestAndExpectQuicResponse("hello!");
2159}
2160
Matt Menke3233d8f22019-08-20 21:01:492161// Much like above, but makes sure NetworkIsolationKey is respected.
2162TEST_P(QuicNetworkTransactionTest,
2163 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:352164 if (version_.AlpnDeferToRFCv1()) {
2165 // These versions currently do not support Alt-Svc.
2166 return;
2167 }
Matt Menke3233d8f22019-08-20 21:01:492168 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:052169 feature_list.InitWithFeatures(
2170 // enabled_features
2171 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2172 features::kPartitionConnectionsByNetworkIsolationKey},
2173 // disabled_features
2174 {});
Matt Menke3233d8f22019-08-20 21:01:492175 // Since HttpServerProperties caches the feature value, have to create a new
2176 // one.
2177 http_server_properties_ = std::make_unique<HttpServerProperties>();
2178
Matt Menke4807a9a2020-11-21 00:14:412179 const SchemefulSite kSite1(GURL("https://foo.test/"));
2180 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
2181 const SchemefulSite kSite2(GURL("https://bar.test/"));
2182 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menke3233d8f22019-08-20 21:01:492183
2184 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452185 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Matt Menke3233d8f22019-08-20 21:01:492186 MockRead("hello world"),
2187 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2188 MockRead(ASYNC, OK)};
2189
2190 AddCertificate(&ssl_data_);
2191
2192 // Request with empty NetworkIsolationKey.
2193 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2194 socket_factory_.AddSocketDataProvider(&http_data1);
2195 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2196
2197 // First request with kNetworkIsolationKey1.
2198 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2199 socket_factory_.AddSocketDataProvider(&http_data2);
2200 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2201
2202 // Request with kNetworkIsolationKey2.
2203 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2204 socket_factory_.AddSocketDataProvider(&http_data3);
2205 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2206
2207 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2208 // alternative service infrmation has been received in this context before.
2209 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232210 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252211 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232212 mock_quic_data.AddWrite(SYNCHRONOUS,
2213 ConstructInitialSettingsPacket(packet_num++));
2214 }
Matt Menke3233d8f22019-08-20 21:01:492215 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232216 SYNCHRONOUS,
2217 ConstructClientRequestHeadersPacket(
2218 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2219 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492220 mock_quic_data.AddRead(
2221 ASYNC, ConstructServerResponseHeadersPacket(
2222 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282223 GetResponseHeaders("200")));
Matt Menke3233d8f22019-08-20 21:01:492224 mock_quic_data.AddRead(
2225 ASYNC, ConstructServerDataPacket(
2226 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522227 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232228 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342229 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menke3233d8f22019-08-20 21:01:492230 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212231 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Matt Menke3233d8f22019-08-20 21:01:492232
2233 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2234
2235 AddHangingNonAlternateProtocolSocketData();
2236 CreateSession();
2237
2238 // This is first so that the test fails if alternative service info is
2239 // written with the right NetworkIsolationKey, but always queried with an
2240 // empty one.
2241 request_.network_isolation_key = NetworkIsolationKey();
2242 SendRequestAndExpectHttpResponse("hello world");
2243 request_.network_isolation_key = kNetworkIsolationKey1;
2244 SendRequestAndExpectHttpResponse("hello world");
2245 request_.network_isolation_key = kNetworkIsolationKey2;
2246 SendRequestAndExpectHttpResponse("hello world");
2247
2248 // Only use QUIC when using a NetworkIsolationKey which has been used when
2249 // alternative service information was received.
2250 request_.network_isolation_key = kNetworkIsolationKey1;
2251 SendRequestAndExpectQuicResponse("hello!");
2252}
2253
zhongyia00ca012017-07-06 23:36:392254TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
Ryan Hamiltona51800a2022-02-12 19:34:352255 if (version_.AlpnDeferToRFCv1()) {
2256 // These versions currently do not support Alt-Svc.
2257 return;
2258 }
Victor Vasiliev22dd3f212022-02-11 21:57:292259 // Both client and server supports two QUIC versions:
2260 // Client supports |supported_versions_[0]| and |supported_versions_[1]|,
2261 // server supports |version_| and |advertised_version_2|.
2262 // Only |version_| (same as |supported_versions_[0]|) is supported by both.
zhongyia00ca012017-07-06 23:36:392263 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2264 // PacketMakers are using |version_|.
2265
Victor Vasiliev22dd3f212022-02-11 21:57:292266 // Compare ALPN strings instead of ParsedQuicVersions because QUIC v1 and v2
2267 // have the same ALPN string.
2268 ASSERT_EQ(1u, supported_versions_.size());
2269 ASSERT_EQ(supported_versions_[0], version_);
David Schinazi84c58bb2020-06-04 20:14:332270 quic::ParsedQuicVersion advertised_version_2 =
2271 quic::ParsedQuicVersion::Unsupported();
Nick Harper23290b82019-05-02 00:02:562272 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Victor Vasiliev22dd3f212022-02-11 21:57:292273 if (quic::AlpnForVersion(version) == quic::AlpnForVersion(version_)) {
zhongyia00ca012017-07-06 23:36:392274 continue;
Victor Vasiliev22dd3f212022-02-11 21:57:292275 }
zhongyia00ca012017-07-06 23:36:392276 if (supported_versions_.size() != 2) {
2277 supported_versions_.push_back(version);
2278 continue;
2279 }
Victor Vasiliev22dd3f212022-02-11 21:57:292280 if (supported_versions_.size() == 2 &&
2281 quic::AlpnForVersion(supported_versions_[1]) ==
2282 quic::AlpnForVersion(version)) {
2283 continue;
2284 }
zhongyia00ca012017-07-06 23:36:392285 advertised_version_2 = version;
2286 break;
2287 }
Bence Békyb89104962020-01-24 00:05:172288 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:332289 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), advertised_version_2);
zhongyia00ca012017-07-06 23:36:392290
Bence Békyb89104962020-01-24 00:05:172291 std::string QuicAltSvcWithVersionHeader =
2292 base::StringPrintf("Alt-Svc: %s=\":443\", %s=\":443\"\r\n\r\n",
2293 quic::AlpnForVersion(advertised_version_2).c_str(),
2294 quic::AlpnForVersion(version_).c_str());
zhongyia00ca012017-07-06 23:36:392295
2296 MockRead http_reads[] = {
2297 MockRead("HTTP/1.1 200 OK\r\n"),
2298 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2299 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2300 MockRead(ASYNC, OK)};
2301
Ryan Sleevib8d7ea02018-05-07 20:01:012302 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392303 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082304 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392305 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2306
Ryan Hamiltonabad59e2019-06-06 04:02:592307 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232308 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252309 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232310 mock_quic_data.AddWrite(SYNCHRONOUS,
2311 ConstructInitialSettingsPacket(packet_num++));
2312 }
zhongyia00ca012017-07-06 23:36:392313 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232314 SYNCHRONOUS,
2315 ConstructClientRequestHeadersPacket(
2316 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2317 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432318 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332319 ASYNC, ConstructServerResponseHeadersPacket(
2320 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282321 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332322 mock_quic_data.AddRead(
2323 ASYNC, ConstructServerDataPacket(
2324 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522325 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232326 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342327 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392328 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212329 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyia00ca012017-07-06 23:36:392330
2331 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2332
2333 AddHangingNonAlternateProtocolSocketData();
2334 CreateSession(supported_versions_);
2335
2336 SendRequestAndExpectHttpResponse("hello world");
2337 SendRequestAndExpectQuicResponse("hello!");
2338}
2339
Zhongyi Shi1c022d22020-03-20 19:00:162340TEST_P(QuicNetworkTransactionTest,
2341 PickQuicVersionWhenMultipleVersionsAreSupported) {
2342 // Client and server both support more than one QUIC_VERSION.
2343 // Client prefers |version_|, and then common_version_2.
2344 // Server prefers common_version_2, and then |version_|.
David Schinazifbd4c432020-04-07 19:23:552345 // We should honor the server's preference.
Zhongyi Shi1c022d22020-03-20 19:00:162346 // The picked version is verified via checking the version used by the
2347 // TestPacketMakers and the response.
Bence Békyb89104962020-01-24 00:05:172348
Zhongyi Shi1c022d22020-03-20 19:00:162349 // Find an alternative commonly supported version other than |version_|.
David Schinazi84c58bb2020-06-04 20:14:332350 quic::ParsedQuicVersion common_version_2 =
2351 quic::ParsedQuicVersion::Unsupported();
2352 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Ryan Hamiltona51800a2022-02-12 19:34:352353 if (version != version_ && !version.AlpnDeferToRFCv1()) {
Zhongyi Shi1c022d22020-03-20 19:00:162354 common_version_2 = version;
2355 break;
2356 }
zhongyia00ca012017-07-06 23:36:392357 }
David Schinazi84c58bb2020-06-04 20:14:332358 ASSERT_NE(common_version_2, quic::ParsedQuicVersion::Unsupported());
zhongyia00ca012017-07-06 23:36:392359
Zhongyi Shi1c022d22020-03-20 19:00:162360 // Setting up client's preference list: {|version_|, |common_version_2|}.
2361 supported_versions_.clear();
2362 supported_versions_.push_back(version_);
2363 supported_versions_.push_back(common_version_2);
zhongyia00ca012017-07-06 23:36:392364
Zhongyi Shi1c022d22020-03-20 19:00:162365 // Setting up server's Alt-Svc header in the following preference order:
2366 // |common_version_2|, |version_|.
2367 std::string QuicAltSvcWithVersionHeader;
David Schinazi84c58bb2020-06-04 20:14:332368 quic::ParsedQuicVersion picked_version =
2369 quic::ParsedQuicVersion::Unsupported();
2370 QuicAltSvcWithVersionHeader =
2371 "Alt-Svc: " + quic::AlpnForVersion(common_version_2) +
2372 "=\":443\"; ma=3600, " + quic::AlpnForVersion(version_) +
2373 "=\":443\"; ma=3600\r\n\r\n";
2374 picked_version = common_version_2; // Use server's preference.
zhongyia00ca012017-07-06 23:36:392375
2376 MockRead http_reads[] = {
2377 MockRead("HTTP/1.1 200 OK\r\n"),
2378 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2379 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2380 MockRead(ASYNC, OK)};
2381
Ryan Sleevib8d7ea02018-05-07 20:01:012382 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392383 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082384 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392385 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2386
Zhongyi Shi1c022d22020-03-20 19:00:162387 MockQuicData mock_quic_data(picked_version);
2388
2389 // Reset QuicTestPacket makers as the version picked may not be |version_|.
Renjie Tang6ff9a9b2021-02-03 22:11:092390 client_maker_ = std::make_unique<QuicTestPacketMaker>(
Zhongyi Shi1c022d22020-03-20 19:00:162391 picked_version,
2392 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2393 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Renjie Tang6ff9a9b2021-02-03 22:11:092394 client_headers_include_h2_stream_dependency_);
Zhongyi Shi1c022d22020-03-20 19:00:162395 QuicTestPacketMaker server_maker(
2396 picked_version,
2397 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2398 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
2399 false);
2400
Renjie Tangaadb84b2019-08-31 01:00:232401 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:162402 if (VersionUsesHttp3(picked_version.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232403 mock_quic_data.AddWrite(SYNCHRONOUS,
2404 ConstructInitialSettingsPacket(packet_num++));
2405 }
Zhongyi Shi1c022d22020-03-20 19:00:162406
2407 quic::QuicStreamId client_stream_0 =
2408 quic::test::GetNthClientInitiatedBidirectionalStreamId(
2409 picked_version.transport_version, 0);
2410 mock_quic_data.AddWrite(SYNCHRONOUS,
2411 ConstructClientRequestHeadersPacket(
2412 packet_num++, client_stream_0, true, true,
2413 GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashif8634ab2021-03-16 23:41:282414 mock_quic_data.AddRead(ASYNC,
2415 server_maker.MakeResponseHeadersPacket(
2416 1, client_stream_0, false, false,
2417 server_maker.GetResponseHeaders("200"), nullptr));
Fan Yang32c5a112018-12-10 20:06:332418 mock_quic_data.AddRead(
Bence Béky319388a882020-09-23 18:42:522419 ASYNC, server_maker.MakeDataPacket(
2420 2, client_stream_0, false, true,
2421 ConstructDataFrameForVersion("hello!", picked_version)));
Renjie Tangaadb84b2019-08-31 01:00:232422 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342423 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392424 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212425 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyia00ca012017-07-06 23:36:392426
2427 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2428
2429 AddHangingNonAlternateProtocolSocketData();
2430 CreateSession(supported_versions_);
2431
2432 SendRequestAndExpectHttpResponse("hello world");
Zhongyi Shi1c022d22020-03-20 19:00:162433 SendRequestAndExpectQuicResponseMaybeFromProxy(
Kenichi Ishibashif8634ab2021-03-16 23:41:282434 "hello!", false, 443, "HTTP/1.1 200", picked_version);
zhongyia00ca012017-07-06 23:36:392435}
2436
zhongyi3d4a55e72016-04-22 20:36:462437TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
Ryan Hamiltona51800a2022-02-12 19:34:352438 if (version_.AlpnDeferToRFCv1()) {
2439 // These versions currently do not support Alt-Svc.
2440 return;
2441 }
Ryan Hamiltona2dcbae2022-02-09 19:02:452442 std::string alt_svc_header = base::StrCat(
2443 {"Alt-Svc: ",
2444 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.com", 443), ",",
2445 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
zhongyi3d4a55e72016-04-22 20:36:462446 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452447 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
zhongyi3d4a55e72016-04-22 20:36:462448 MockRead("hello world"),
2449 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2450 MockRead(ASYNC, OK)};
2451
Ryan Sleevib8d7ea02018-05-07 20:01:012452 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462453 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082454 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462455 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2456
2457 CreateSession();
bncb26024382016-06-29 02:39:452458 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462459 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452460 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462461 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402462 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462463 session_->http_server_properties();
2464 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2465 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2466 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462467 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492468 2u, http_server_properties
2469 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2470 .size());
bncb26024382016-06-29 02:39:452471 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492472 http_server_properties
2473 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2474 .empty());
zhongyi3d4a55e72016-04-22 20:36:462475}
2476
2477TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
Ryan Hamiltona51800a2022-02-12 19:34:352478 if (version_.AlpnDeferToRFCv1()) {
2479 // These versions currently do not support Alt-Svc.
2480 return;
2481 }
Ryan Hamiltona2dcbae2022-02-09 19:02:452482 std::string alt_svc_header = base::StrCat(
2483 {"Alt-Svc: ",
2484 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.com", 443), ",",
2485 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
zhongyi3d4a55e72016-04-22 20:36:462486 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452487 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
zhongyi3d4a55e72016-04-22 20:36:462488 MockRead("hello world"),
2489 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2490 MockRead(ASYNC, OK)};
2491
Ryan Sleevib8d7ea02018-05-07 20:01:012492 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082493 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462494
2495 socket_factory_.AddSocketDataProvider(&http_data);
2496 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2497 socket_factory_.AddSocketDataProvider(&http_data);
2498 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2499
2500 CreateSession();
2501
2502 // Send https request and set alternative services if response header
2503 // advertises alternative service for mail.example.org.
2504 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402505 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462506 session_->http_server_properties();
2507
2508 const url::SchemeHostPort https_server(request_.url);
2509 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342510 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492511 2u, http_server_properties
2512 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2513 .size());
zhongyi3d4a55e72016-04-22 20:36:462514
2515 // Send http request to the same origin but with diffrent scheme, should not
2516 // use QUIC.
2517 request_.url = GURL("http://mail.example.org:443");
2518 SendRequestAndExpectHttpResponse("hello world");
2519}
2520
zhongyie537a002017-06-27 16:48:212521TEST_P(QuicNetworkTransactionTest,
2522 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442523 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562524 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Bence Békyb89104962020-01-24 00:05:172525 if (version != version_) {
2526 supported_versions_.push_back(version);
2527 break;
2528 }
zhongyi86838d52017-06-30 01:19:442529 }
2530
David Schinazifbd4c432020-04-07 19:23:552531 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyie537a002017-06-27 16:48:212532 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:172533 MockRead("HTTP/1.1 200 OK\r\n"),
2534 MockRead(altsvc_header.c_str()),
2535 MockRead("\r\n"),
zhongyie537a002017-06-27 16:48:212536 MockRead("hello world"),
2537 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2538 MockRead(ASYNC, OK)};
2539
Ryan Sleevib8d7ea02018-05-07 20:01:012540 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212541 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082542 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212543 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2544
Ryan Hamiltonabad59e2019-06-06 04:02:592545 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232546 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252547 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232548 mock_quic_data.AddWrite(SYNCHRONOUS,
2549 ConstructInitialSettingsPacket(packet_num++));
2550 }
zhongyie537a002017-06-27 16:48:212551 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232552 SYNCHRONOUS,
2553 ConstructClientRequestHeadersPacket(
2554 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2555 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432556 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332557 ASYNC, ConstructServerResponseHeadersPacket(
2558 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282559 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332560 mock_quic_data.AddRead(
2561 ASYNC, ConstructServerDataPacket(
2562 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522563 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232564 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342565 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyie537a002017-06-27 16:48:212566 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212567 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyie537a002017-06-27 16:48:212568
2569 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2570
2571 AddHangingNonAlternateProtocolSocketData();
2572
zhongyi86838d52017-06-30 01:19:442573 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212574
2575 SendRequestAndExpectHttpResponse("hello world");
2576 SendRequestAndExpectQuicResponse("hello!");
2577
Bence Békyb89104962020-01-24 00:05:172578 // Alt-Svc header contains all possible versions, so alternative services
2579 // should contain all of |supported_versions_|.
zhongyie537a002017-06-27 16:48:212580 const url::SchemeHostPort https_server(request_.url);
2581 const AlternativeServiceInfoVector alt_svc_info_vector =
2582 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492583 https_server, NetworkIsolationKey());
Victor Vasiliev22dd3f212022-02-11 21:57:292584 VerifyQuicVersionsInAlternativeServices(alt_svc_info_vector,
2585 supported_versions_);
zhongyie537a002017-06-27 16:48:212586}
2587
danzh3134c2562016-08-12 14:07:522588TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Ryan Hamiltona51800a2022-02-12 19:34:352589 if (version_.AlpnDeferToRFCv1()) {
2590 // These versions currently do not support Alt-Svc.
2591 return;
2592 }
Nick Harper23290b82019-05-02 00:02:562593 std::string altsvc_header = base::StringPrintf(
Bence Békyb89104962020-01-24 00:05:172594 "Alt-Svc: %s=\":443\"\r\n\r\n", quic::AlpnForVersion(version_).c_str());
bnc8be55ebb2015-10-30 14:12:072595 MockRead http_reads[] = {
2596 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2597 MockRead("hello world"),
2598 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2599 MockRead(ASYNC, OK)};
2600
Ryan Sleevib8d7ea02018-05-07 20:01:012601 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072602 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082603 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072604 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2605
Ryan Hamiltonabad59e2019-06-06 04:02:592606 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232607 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252608 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232609 mock_quic_data.AddWrite(SYNCHRONOUS,
2610 ConstructInitialSettingsPacket(packet_num++));
2611 }
rch5cb522462017-04-25 20:18:362612 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232613 SYNCHRONOUS,
2614 ConstructClientRequestHeadersPacket(
2615 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2616 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432617 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332618 ASYNC, ConstructServerResponseHeadersPacket(
2619 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282620 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332621 mock_quic_data.AddRead(
2622 ASYNC, ConstructServerDataPacket(
2623 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522624 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232625 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342626 ConstructClientAckPacket(packet_num++, 2, 1));
bnc8be55ebb2015-10-30 14:12:072627 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212628 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc8be55ebb2015-10-30 14:12:072629
2630 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2631
rtennetib8e80fb2016-05-16 00:12:092632 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322633 CreateSession();
bnc8be55ebb2015-10-30 14:12:072634
2635 SendRequestAndExpectHttpResponse("hello world");
2636 SendRequestAndExpectQuicResponse("hello!");
2637}
2638
zhongyi6b5a3892016-03-12 04:46:202639TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harperc6cb7a612020-02-24 20:03:322640 if (version_.HasIetfQuicFrames()) {
Renjie Tangba21e032019-09-27 21:52:282641 // GoAway is not available under version 99
Frank Kastenholz6e4c5382018-06-21 23:00:092642 return;
2643 }
Ryan Hamiltonabad59e2019-06-06 04:02:592644 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232645 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252646 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232647 mock_quic_data.AddWrite(SYNCHRONOUS,
2648 ConstructInitialSettingsPacket(packet_num++));
2649 }
rch5cb522462017-04-25 20:18:362650 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232651 SYNCHRONOUS,
2652 ConstructClientRequestHeadersPacket(
2653 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2654 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332655 mock_quic_data.AddRead(
2656 ASYNC, ConstructServerResponseHeadersPacket(
2657 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282658 GetResponseHeaders("200")));
zhongyi6b5a3892016-03-12 04:46:202659 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522660 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432661 mock_quic_data.AddRead(SYNCHRONOUS,
2662 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522663 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432664 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232665 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342666 ConstructClientAckPacket(packet_num++, 2, 1));
Fan Yang32c5a112018-12-10 20:06:332667 mock_quic_data.AddRead(
2668 SYNCHRONOUS, ConstructServerDataPacket(
2669 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:522670 true, ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232671 mock_quic_data.AddWrite(
2672 SYNCHRONOUS,
2673 ConstructClientAckAndRstPacket(
2674 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:342675 quic::QUIC_STREAM_CANCELLED, 3, 3));
zhongyi6b5a3892016-03-12 04:46:202676 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212677 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi6b5a3892016-03-12 04:46:202678
2679 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2680
2681 // The non-alternate protocol job needs to hang in order to guarantee that
2682 // the alternate-protocol job will "win".
2683 AddHangingNonAlternateProtocolSocketData();
2684
2685 // In order for a new QUIC session to be established via alternate-protocol
2686 // without racing an HTTP connection, we need the host resolution to happen
2687 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2688 // connection to the the server, in this test we require confirmation
2689 // before encrypting so the HTTP job will still start.
2690 host_resolver_.set_synchronous_mode(true);
2691 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2692 "");
zhongyi6b5a3892016-03-12 04:46:202693
2694 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432695 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2696 false);
Ryan Hamilton9835e662018-08-02 05:36:272697 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202698
bnc691fda62016-08-12 00:43:162699 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202700 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262701 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:012702 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202703
Fan Yang3673cc72020-02-07 14:49:282704 crypto_client_stream_factory_.last_stream()
2705 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:012706 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202707
2708 // Check whether this transaction is correctly marked as received a go-away
2709 // because of migrating port.
2710 NetErrorDetails details;
2711 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162712 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202713 EXPECT_TRUE(details.quic_port_migration_detected);
2714}
2715
Zhongyi Shia6b68d112018-09-24 07:49:032716// This test verifies that a new QUIC connection will be attempted on the
2717// alternate network if the original QUIC connection fails with idle timeout
2718// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2719// alternate network as well, QUIC is marked as broken and the brokenness will
2720// not expire when default network changes.
Renjie Tangb6fc5e02020-06-30 00:48:342721// TODO(fayang): Add time driven idle network detection test.
2722TEST_P(QuicNetworkTransactionTest,
2723 DISABLED_QuicFailsOnBothNetworksWhileTCPSucceeds) {
Ryan Hamiltona51800a2022-02-12 19:34:352724 if (version_.AlpnDeferToRFCv1()) {
2725 // These versions currently do not support Alt-Svc.
2726 return;
2727 }
Renjie Tangb6fc5e02020-06-30 00:48:342728 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432729 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2730 return;
2731 }
Zhongyi Shia6b68d112018-09-24 07:49:032732 SetUpTestForRetryConnectionOnAlternateNetwork();
2733
Zhongyi Shi1c022d22020-03-20 19:00:162734 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032735
2736 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592737 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032738 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2739 int packet_num = 1;
2740 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162741 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:592742 // Retransmit the handshake messages.
Zhongyi Shia6b68d112018-09-24 07:49:032743 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162744 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032745 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162746 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032747 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162748 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032749 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162750 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032751 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2752 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162753 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:032754 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522755 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:032756 quic_data.AddSocketDataToFactory(&socket_factory_);
2757
2758 // Add successful TCP data so that TCP job will succeed.
2759 MockWrite http_writes[] = {
2760 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2761 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2762 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2763
Ryan Hamiltona2dcbae2022-02-09 19:02:452764 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2765 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
2766 MockRead(SYNCHRONOUS, 5, "TCP succeeds"),
2767 MockRead(SYNCHRONOUS, OK, 6)};
Zhongyi Shia6b68d112018-09-24 07:49:032768 SequencedSocketData http_data(http_reads, http_writes);
2769 socket_factory_.AddSocketDataProvider(&http_data);
2770 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2771
2772 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592773 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032774 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2775 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2776 quic_data2.AddSocketDataToFactory(&socket_factory_);
2777
2778 // Resolve the host resolution synchronously.
2779 host_resolver_.set_synchronous_mode(true);
2780 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2781 "");
Zhongyi Shia6b68d112018-09-24 07:49:032782
2783 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432784 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2785 false);
Zhongyi Shia6b68d112018-09-24 07:49:032786 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032787 QuicStreamFactoryPeer::SetAlarmFactory(
2788 session_->quic_stream_factory(),
2789 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222790 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032791 // Add alternate protocol mapping to race QUIC and TCP.
2792 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2793 // peer.
2794 AddQuicAlternateProtocolMapping(
2795 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2796
2797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2798 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262799 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Zhongyi Shia6b68d112018-09-24 07:49:032800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2801
2802 // Pump the message loop to get the request started.
2803 // Request will be served with TCP job.
2804 base::RunLoop().RunUntilIdle();
2805 EXPECT_THAT(callback.WaitForResult(), IsOk());
2806 CheckResponseData(&trans, "TCP succeeds");
2807
Zhongyi Shia6b68d112018-09-24 07:49:032808 // Fast forward to idle timeout the original connection. A new connection will
2809 // be kicked off on the alternate network.
2810 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2811 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2812 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2813
2814 // Run the message loop to execute posted tasks, which will report job status.
2815 base::RunLoop().RunUntilIdle();
2816
2817 // Verify that QUIC is marked as broken.
2818 ExpectBrokenAlternateProtocolMapping();
2819
2820 // Deliver a message to notify the new network becomes default, the brokenness
2821 // will not expire as QUIC is broken on both networks.
2822 scoped_mock_change_notifier_->mock_network_change_notifier()
2823 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2824 ExpectBrokenAlternateProtocolMapping();
2825
2826 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2827 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2828}
2829
2830// This test verifies that a new QUIC connection will be attempted on the
2831// alternate network if the original QUIC connection fails with idle timeout
2832// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2833// alternate network, QUIC is marked as broken. The brokenness will expire when
2834// the default network changes.
Renjie Tangb6fc5e02020-06-30 00:48:342835// TODO(fayang): Add time driven idle network detection test.
2836TEST_P(QuicNetworkTransactionTest,
2837 DISABLED_RetryOnAlternateNetworkWhileTCPSucceeds) {
Ryan Hamiltona51800a2022-02-12 19:34:352838 if (version_.AlpnDeferToRFCv1()) {
2839 // These versions currently do not support Alt-Svc.
2840 return;
2841 }
Renjie Tangb6fc5e02020-06-30 00:48:342842 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432843 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2844 return;
2845 }
2846
Zhongyi Shia6b68d112018-09-24 07:49:032847 SetUpTestForRetryConnectionOnAlternateNetwork();
2848
Zhongyi Shi1c022d22020-03-20 19:00:162849 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032850
2851 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592852 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032853 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2854 int packet_num = 1;
2855 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162856 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:592857 // Retransmit the handshake messages.
Zhongyi Shia6b68d112018-09-24 07:49:032858 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162859 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032860 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162861 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032862 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162863 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032864 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162865 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032866 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2867 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162868 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:032869 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522870 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:032871 quic_data.AddSocketDataToFactory(&socket_factory_);
2872
2873 // Add successful TCP data so that TCP job will succeed.
2874 MockWrite http_writes[] = {
2875 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2876 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2877 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2878
Ryan Hamiltona2dcbae2022-02-09 19:02:452879 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2880 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
2881 MockRead(SYNCHRONOUS, 5, "TCP succeeds"),
2882 MockRead(SYNCHRONOUS, OK, 6)};
Zhongyi Shia6b68d112018-09-24 07:49:032883 SequencedSocketData http_data(http_reads, http_writes);
2884 socket_factory_.AddSocketDataProvider(&http_data);
2885 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2886
2887 // Quic connection will be retried on the alternate network after the initial
2888 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592889 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032890 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2891 quic_data2.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162892 client_maker_->MakeDummyCHLOPacket(1)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:032893
Zhongyi Shi1c022d22020-03-20 19:00:162894 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252895 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232896 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032897 quic_data2.AddSocketDataToFactory(&socket_factory_);
2898
2899 // Resolve the host resolution synchronously.
2900 host_resolver_.set_synchronous_mode(true);
2901 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2902 "");
Zhongyi Shia6b68d112018-09-24 07:49:032903
2904 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432905 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2906 false);
Zhongyi Shia6b68d112018-09-24 07:49:032907 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032908 QuicStreamFactoryPeer::SetAlarmFactory(
2909 session_->quic_stream_factory(),
2910 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222911 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032912 // Add alternate protocol mapping to race QUIC and TCP.
2913 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2914 // peer.
2915 AddQuicAlternateProtocolMapping(
2916 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2917
2918 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2919 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262920 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Zhongyi Shia6b68d112018-09-24 07:49:032921 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2922
2923 // Pump the message loop to get the request started.
2924 // Request will be served with TCP job.
2925 base::RunLoop().RunUntilIdle();
2926 EXPECT_THAT(callback.WaitForResult(), IsOk());
2927 CheckResponseData(&trans, "TCP succeeds");
2928
Zhongyi Shia6b68d112018-09-24 07:49:032929 // Fast forward to idle timeout the original connection. A new connection will
2930 // be kicked off on the alternate network.
2931 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2932 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2933 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2934
2935 // The second connection hasn't finish handshake, verify that QUIC is not
2936 // marked as broken.
2937 ExpectQuicAlternateProtocolMapping();
2938 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:282939 crypto_client_stream_factory_.last_stream()
2940 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia6b68d112018-09-24 07:49:032941 // Run message loop to execute posted tasks, which will notify JoController
2942 // about the orphaned job status.
2943 base::RunLoop().RunUntilIdle();
2944
2945 // Verify that QUIC is marked as broken.
2946 ExpectBrokenAlternateProtocolMapping();
2947
2948 // Deliver a message to notify the new network becomes default, the previous
2949 // brokenness will be clear as the brokenness is bond with old default
2950 // network.
2951 scoped_mock_change_notifier_->mock_network_change_notifier()
2952 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2953 ExpectQuicAlternateProtocolMapping();
2954
2955 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2956 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2957}
2958
Matt Menkeb32ba5122019-09-10 19:17:052959// Much like above test, but verifies NetworkIsolationKeys are respected.
Renjie Tangb6fc5e02020-06-30 00:48:342960// TODO(fayang): Add time driven idle network detection test.
2961TEST_P(
2962 QuicNetworkTransactionTest,
2963 DISABLED_RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:352964 if (version_.AlpnDeferToRFCv1()) {
2965 // These versions currently do not support Alt-Svc.
2966 return;
2967 }
Renjie Tangb6fc5e02020-06-30 00:48:342968 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432969 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2970 return;
2971 }
2972
Matt Menke4807a9a2020-11-21 00:14:412973 const SchemefulSite kSite1(GURL("https://foo.test/"));
2974 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
2975 const SchemefulSite kSite2(GURL("https://bar.test/"));
2976 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:052977
2978 base::test::ScopedFeatureList feature_list;
2979 feature_list.InitWithFeatures(
2980 // enabled_features
2981 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2982 // Need to partition connections by NetworkIsolationKey for
2983 // QuicSessionAliasKey to include NetworkIsolationKeys.
2984 features::kPartitionConnectionsByNetworkIsolationKey},
2985 // disabled_features
2986 {});
2987 // Since HttpServerProperties caches the feature value, have to create a new
2988 // one.
2989 http_server_properties_ = std::make_unique<HttpServerProperties>();
2990
2991 SetUpTestForRetryConnectionOnAlternateNetwork();
2992
Zhongyi Shi1c022d22020-03-20 19:00:162993 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Matt Menkeb32ba5122019-09-10 19:17:052994
2995 // The request will initially go out over QUIC.
2996 MockQuicData quic_data(version_);
2997 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2998 int packet_num = 1;
2999 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163000 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:593001 // Retransmit the handshake messages.
Matt Menkeb32ba5122019-09-10 19:17:053002 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163003 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:053004 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163005 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:053006 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163007 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:053008 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163009 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:053010 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
3011 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163012 client_maker_->MakeConnectionClosePacket(
Matt Menkeb32ba5122019-09-10 19:17:053013 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523014 "No recent network activity after 4s. Timeout:4s"));
Matt Menkeb32ba5122019-09-10 19:17:053015 quic_data.AddSocketDataToFactory(&socket_factory_);
3016
3017 // Add successful TCP data so that TCP job will succeed.
3018 MockWrite http_writes[] = {
3019 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3020 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3021 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3022
Ryan Hamiltona2dcbae2022-02-09 19:02:453023 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3024 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3025 MockRead(SYNCHRONOUS, 5, "TCP succeeds"),
3026 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:053027 SequencedSocketData http_data(http_reads, http_writes);
3028 socket_factory_.AddSocketDataProvider(&http_data);
3029 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3030
3031 // Quic connection will be retried on the alternate network after the initial
3032 // one fails on the default network.
3033 MockQuicData quic_data2(version_);
3034 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
3035 quic_data2.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163036 client_maker_->MakeDummyCHLOPacket(1)); // CHLO
Matt Menkeb32ba5122019-09-10 19:17:053037
Zhongyi Shi1c022d22020-03-20 19:00:163038 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253039 if (VersionUsesHttp3(version_.transport_version))
Matt Menkeb32ba5122019-09-10 19:17:053040 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
3041 quic_data2.AddSocketDataToFactory(&socket_factory_);
3042
3043 // Resolve the host resolution synchronously.
3044 host_resolver_.set_synchronous_mode(true);
3045 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3046 "");
3047
3048 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433049 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3050 false);
Matt Menkeb32ba5122019-09-10 19:17:053051 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
3052 QuicStreamFactoryPeer::SetAlarmFactory(
3053 session_->quic_stream_factory(),
3054 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223055 context_.clock()));
Matt Menkeb32ba5122019-09-10 19:17:053056 // Add alternate protocol mapping to race QUIC and TCP.
3057 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3058 // peer.
3059 AddQuicAlternateProtocolMapping(
3060 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
3061 AddQuicAlternateProtocolMapping(
3062 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
3063
3064 request_.network_isolation_key = kNetworkIsolationKey1;
3065 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3066 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263067 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeb32ba5122019-09-10 19:17:053068 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3069
3070 // Pump the message loop to get the request started.
3071 // Request will be served with TCP job.
3072 base::RunLoop().RunUntilIdle();
3073 EXPECT_THAT(callback.WaitForResult(), IsOk());
3074 CheckResponseData(&trans, "TCP succeeds");
3075
3076 // Fast forward to idle timeout the original connection. A new connection will
3077 // be kicked off on the alternate network.
3078 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3079 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3080 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3081
3082 // The second connection hasn't finish handshake, verify that QUIC is not
3083 // marked as broken.
3084 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
3085 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3086 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:283087 crypto_client_stream_factory_.last_stream()
3088 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:053089 // Run message loop to execute posted tasks, which will notify JoController
3090 // about the orphaned job status.
3091 base::RunLoop().RunUntilIdle();
3092
3093 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
3094 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3095 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3096
3097 // Deliver a message to notify the new network becomes default, the previous
3098 // brokenness will be clear as the brokenness is bond with old default
3099 // network.
3100 scoped_mock_change_notifier_->mock_network_change_notifier()
3101 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3102 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
3103 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3104
3105 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3106 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3107}
3108
Zhongyi Shia6b68d112018-09-24 07:49:033109// This test verifies that a new QUIC connection will be attempted on the
3110// alternate network if the original QUIC connection fails with idle timeout
3111// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
3112// alternative network succeeds, QUIC is not marked as broken.
Renjie Tangb6fc5e02020-06-30 00:48:343113// TODO(fayang): Add time driven idle network detection test.
3114TEST_P(QuicNetworkTransactionTest,
3115 DISABLED_RetryOnAlternateNetworkWhileTCPHanging) {
3116 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433117 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3118 return;
3119 }
3120
Zhongyi Shia6b68d112018-09-24 07:49:033121 SetUpTestForRetryConnectionOnAlternateNetwork();
3122
Zhongyi Shi1c022d22020-03-20 19:00:163123 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:033124
3125 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593126 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:033127 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
3128 int packet_num = 1;
3129 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163130 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:593131 // Retransmit the handshake messages.
Zhongyi Shia6b68d112018-09-24 07:49:033132 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163133 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033134 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163135 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033136 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163137 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033138 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163139 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033140 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
3141 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163142 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:033143 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523144 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:033145 quic_data.AddSocketDataToFactory(&socket_factory_);
3146
3147 // Add hanging TCP data so that TCP job will never succeeded.
3148 AddHangingNonAlternateProtocolSocketData();
3149
3150 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:593151 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:233152 packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:163153 quic_data2.AddWrite(
3154 SYNCHRONOUS,
3155 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:033156
Victor Vasiliev076657c2019-03-12 02:46:433157 const std::string body = "hello!";
Renjief49758b2019-01-11 23:32:413158
Zhongyi Shi1c022d22020-03-20 19:00:163159 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253160 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233161 quic_data2.AddWrite(SYNCHRONOUS,
3162 ConstructInitialSettingsPacket(packet_num++));
3163 }
Zhongyi Shia6b68d112018-09-24 07:49:033164 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233165 SYNCHRONOUS,
3166 ConstructClientRequestHeadersPacket(
3167 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3168 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:033169 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333170 ASYNC, ConstructServerResponseHeadersPacket(
3171 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283172 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:333173 quic_data2.AddRead(
3174 ASYNC, ConstructServerDataPacket(
3175 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523176 ConstructDataFrame(body)));
Renjie Tangaadb84b2019-08-31 01:00:233177 quic_data2.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343178 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shia6b68d112018-09-24 07:49:033179 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
3180 quic_data2.AddSocketDataToFactory(&socket_factory_);
3181
3182 // Resolve the host resolution synchronously.
3183 host_resolver_.set_synchronous_mode(true);
3184 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3185 "");
Zhongyi Shia6b68d112018-09-24 07:49:033186
3187 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433188 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3189 false);
Zhongyi Shia6b68d112018-09-24 07:49:033190 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:033191 QuicStreamFactoryPeer::SetAlarmFactory(
3192 session_->quic_stream_factory(),
3193 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223194 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:033195 // Add alternate protocol mapping to race QUIC and TCP.
3196 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3197 // peer.
3198 AddQuicAlternateProtocolMapping(
3199 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3200
3201 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3202 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263203 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Zhongyi Shia6b68d112018-09-24 07:49:033204 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3205
3206 // Pump the message loop to get the request started.
3207 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:033208
3209 // Fast forward to idle timeout the original connection. A new connection will
3210 // be kicked off on the alternate network.
3211 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3212 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3213 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3214
3215 // Verify that QUIC is not marked as broken.
3216 ExpectQuicAlternateProtocolMapping();
3217 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:283218 crypto_client_stream_factory_.last_stream()
3219 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia6b68d112018-09-24 07:49:033220
3221 // Read the response.
3222 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:413223 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:033224 // Verify that QUIC is not marked as broken.
3225 ExpectQuicAlternateProtocolMapping();
3226
3227 // Deliver a message to notify the new network becomes default.
3228 scoped_mock_change_notifier_->mock_network_change_notifier()
3229 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3230 ExpectQuicAlternateProtocolMapping();
3231 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3232 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3233}
3234
rch9ecde09b2017-04-08 00:18:233235// Verify that if a QUIC connection times out, the QuicHttpStream will
3236// return QUIC_PROTOCOL_ERROR.
3237TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:383238 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Peter Kastinge5a38ed2021-10-02 03:06:353239 context_.params()->idle_connection_timeout = base::Seconds(5);
rch9ecde09b2017-04-08 00:18:233240
3241 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593242 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133243 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233244 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3245
Zhongyi Shi1c022d22020-03-20 19:00:163246 client_maker_->set_save_packet_frames(true);
3247 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493248 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253249 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493250 quic_data.AddWrite(SYNCHRONOUS,
3251 ConstructInitialSettingsPacket(packet_num++));
3252 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023253 quic_data.AddWrite(
3254 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163255 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493256 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3257 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453258
Zhongyi Shi1c022d22020-03-20 19:00:163259 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233260
Victor Vasiliev7da08172019-10-14 06:04:253261 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper0b214c132020-10-26 20:10:233262 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3263 // sending PTO packets.
3264 packet_num++;
3265 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163266 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493267 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233268 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3269 // sending PTO packets.
3270 packet_num++;
3271 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163272 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493273 2, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233274 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3275 // sending PTO packets.
3276 packet_num++;
3277 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163278 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493279 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233280
3281 quic_data.AddWrite(SYNCHRONOUS,
3282 client_maker_->MakeConnectionClosePacket(
3283 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3284 "No recent network activity after 4s. Timeout:4s"));
Yutaka Hiranobba79bc2022-05-09 03:11:473285 } else {
Nick Harper0b214c132020-10-26 20:10:233286 // Settings were sent in the request packet so there is only 1 packet to
3287 // retransmit.
3288 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3289 // sending PTO packets.
3290 packet_num++;
3291 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163292 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493293 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233294 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3295 // sending PTO packets.
3296 packet_num++;
3297 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163298 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493299 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233300 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3301 // sending PTO packets.
3302 packet_num++;
3303 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163304 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper0b214c132020-10-26 20:10:233305 1, packet_num++, true));
Ryan Hamilton3cc2c152019-07-09 19:36:013306
Findit2403b85d2019-11-19 05:06:373307 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163308 client_maker_->MakeConnectionClosePacket(
Findit2403b85d2019-11-19 05:06:373309 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523310 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493311 }
Fan Yang928f1632017-12-14 18:55:223312
rch9ecde09b2017-04-08 00:18:233313 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3314 quic_data.AddRead(ASYNC, OK);
3315 quic_data.AddSocketDataToFactory(&socket_factory_);
3316
3317 // In order for a new QUIC session to be established via alternate-protocol
3318 // without racing an HTTP connection, we need the host resolution to happen
3319 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3320 // connection to the the server, in this test we require confirmation
3321 // before encrypting so the HTTP job will still start.
3322 host_resolver_.set_synchronous_mode(true);
3323 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3324 "");
rch9ecde09b2017-04-08 00:18:233325
3326 CreateSession();
3327 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233328 QuicStreamFactoryPeer::SetAlarmFactory(
3329 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193330 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223331 context_.clock()));
rch9ecde09b2017-04-08 00:18:233332
Ryan Hamilton9835e662018-08-02 05:36:273333 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233334
3335 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3336 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263337 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch9ecde09b2017-04-08 00:18:233338 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3339
3340 // Pump the message loop to get the request started.
3341 base::RunLoop().RunUntilIdle();
3342 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283343 crypto_client_stream_factory_.last_stream()
3344 ->NotifySessionOneRttKeyAvailable();
rch9ecde09b2017-04-08 00:18:233345
3346 // Run the QUIC session to completion.
3347 quic_task_runner_->RunUntilIdle();
3348
3349 ExpectQuicAlternateProtocolMapping();
3350 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3351 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3352}
3353
David Schinazi7e980ab2020-05-13 20:26:553354// TODO(fayang): Add time driven TOO_MANY_RTOS test.
rch9ecde09b2017-04-08 00:18:233355
rch2f2991c2017-04-13 19:28:173356// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3357// the request fails with QUIC_PROTOCOL_ERROR.
3358TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:383359 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173360 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593361 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:163362 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493363 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253364 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493365 quic_data.AddWrite(SYNCHRONOUS,
3366 ConstructInitialSettingsPacket(packet_num++));
3367 }
3368 quic_data.AddWrite(
3369 SYNCHRONOUS,
3370 ConstructClientRequestHeadersPacket(
3371 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3372 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163373 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553374 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173375 // Peer sending data from an non-existing stream causes this end to raise
3376 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333377 quic_data.AddRead(
3378 ASYNC, ConstructServerRstPacket(
3379 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3380 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173381 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:343382 quic_data.AddWrite(
3383 SYNCHRONOUS,
3384 ConstructClientAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:343385 packet_num++, 1, 1,
Renjie Tang248e36ea2020-06-26 00:12:343386 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
3387 : quic::QUIC_INVALID_STREAM_ID,
Renjie Tanga35322a2020-12-02 20:12:273388 quic_error_details,
3389 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
3390 : quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173391 quic_data.AddSocketDataToFactory(&socket_factory_);
3392
3393 // In order for a new QUIC session to be established via alternate-protocol
3394 // without racing an HTTP connection, we need the host resolution to happen
3395 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3396 // connection to the the server, in this test we require confirmation
3397 // before encrypting so the HTTP job will still start.
3398 host_resolver_.set_synchronous_mode(true);
3399 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3400 "");
rch2f2991c2017-04-13 19:28:173401
3402 CreateSession();
3403
Ryan Hamilton9835e662018-08-02 05:36:273404 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173405
3406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3407 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263408 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:173409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3410
3411 // Pump the message loop to get the request started.
3412 base::RunLoop().RunUntilIdle();
3413 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283414 crypto_client_stream_factory_.last_stream()
3415 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:173416
3417 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553418 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173419
3420 // Run the QUIC session to completion.
3421 base::RunLoop().RunUntilIdle();
3422 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3423 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3424
3425 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3426 ExpectQuicAlternateProtocolMapping();
3427 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3428}
3429
rch2f2991c2017-04-13 19:28:173430// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3431// connection times out, then QUIC will be marked as broken and the request
3432// retried over TCP.
3433TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Ryan Hamiltona51800a2022-02-12 19:34:353434 if (version_.AlpnDeferToRFCv1()) {
3435 // These versions currently do not support Alt-Svc.
3436 return;
3437 }
Peter Kastinge5a38ed2021-10-02 03:06:353438 context_.params()->idle_connection_timeout = base::Seconds(5);
rch2f2991c2017-04-13 19:28:173439
3440 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593441 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133442 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173443 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3444
Zhongyi Shi1c022d22020-03-20 19:00:163445 client_maker_->set_save_packet_frames(true);
3446 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493447 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253448 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493449 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163450 client_maker_->MakeInitialSettingsPacket(packet_num++));
Nick Harper057264a82019-09-12 23:33:493451 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023452 quic_data.AddWrite(
3453 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163454 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493455 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3456 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453457
Zhongyi Shi1c022d22020-03-20 19:00:163458 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253459 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper0b214c132020-10-26 20:10:233460 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3461 // sending PTO packets.
3462 packet_num++;
3463 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163464 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493465 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233466
3467 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3468 // sending PTO packets.
3469 packet_num++;
3470 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163471 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493472 2, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233473
3474 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3475 // sending PTO packets.
3476 packet_num++;
3477 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163478 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493479 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233480
3481 quic_data.AddWrite(SYNCHRONOUS,
3482 client_maker_->MakeConnectionClosePacket(
3483 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3484 "No recent network activity after 4s. Timeout:4s"));
Yutaka Hiranobba79bc2022-05-09 03:11:473485 } else {
Nick Harper0b214c132020-10-26 20:10:233486 // Settings were sent in the request packet so there is only 1 packet to
3487 // retransmit.
3488 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3489 // sending PTO packets.
3490 packet_num++;
3491 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163492 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493493 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233494 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3495 // sending PTO packets.
3496 packet_num++;
3497 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163498 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493499 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233500 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3501 // sending PTO packets.
3502 packet_num++;
3503 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163504 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper0b214c132020-10-26 20:10:233505 1, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373506
3507 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163508 client_maker_->MakeConnectionClosePacket(
Findit2403b85d2019-11-19 05:06:373509 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523510 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493511 }
Fan Yang928f1632017-12-14 18:55:223512
rch2f2991c2017-04-13 19:28:173513 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3514 quic_data.AddRead(ASYNC, OK);
3515 quic_data.AddSocketDataToFactory(&socket_factory_);
3516
3517 // After that fails, it will be resent via TCP.
3518 MockWrite http_writes[] = {
3519 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3520 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3521 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3522
Ryan Hamiltona2dcbae2022-02-09 19:02:453523 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3524 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3525 MockRead(SYNCHRONOUS, 5, "hello world"),
3526 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013527 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173528 socket_factory_.AddSocketDataProvider(&http_data);
3529 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3530
3531 // In order for a new QUIC session to be established via alternate-protocol
3532 // without racing an HTTP connection, we need the host resolution to happen
3533 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3534 // connection to the the server, in this test we require confirmation
3535 // before encrypting so the HTTP job will still start.
3536 host_resolver_.set_synchronous_mode(true);
3537 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3538 "");
rch2f2991c2017-04-13 19:28:173539
3540 CreateSession();
3541 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173542 QuicStreamFactoryPeer::SetAlarmFactory(
3543 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193544 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223545 context_.clock()));
rch2f2991c2017-04-13 19:28:173546
Ryan Hamilton9835e662018-08-02 05:36:273547 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173548
3549 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3550 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263551 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:173552 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3553
3554 // Pump the message loop to get the request started.
3555 base::RunLoop().RunUntilIdle();
3556 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283557 crypto_client_stream_factory_.last_stream()
3558 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:173559
3560 // Run the QUIC session to completion.
3561 quic_task_runner_->RunUntilIdle();
3562 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3563
3564 ExpectQuicAlternateProtocolMapping();
3565
3566 // Let the transaction proceed which will result in QUIC being marked
3567 // as broken and the request falling back to TCP.
3568 EXPECT_THAT(callback.WaitForResult(), IsOk());
3569
3570 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3571 ASSERT_FALSE(http_data.AllReadDataConsumed());
3572
3573 // Read the response body over TCP.
3574 CheckResponseData(&trans, "hello world");
3575 ExpectBrokenAlternateProtocolMapping();
3576 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3577 ASSERT_TRUE(http_data.AllReadDataConsumed());
3578}
3579
rch2f2991c2017-04-13 19:28:173580// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3581// protocol error occurs after the handshake is confirmed, the request
3582// retried over TCP and the QUIC will be marked as broken.
3583TEST_P(QuicNetworkTransactionTest,
3584 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:353585 if (version_.AlpnDeferToRFCv1()) {
3586 // These versions currently do not support Alt-Svc.
3587 return;
3588 }
Peter Kastinge5a38ed2021-10-02 03:06:353589 context_.params()->idle_connection_timeout = base::Seconds(5);
rch2f2991c2017-04-13 19:28:173590
3591 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593592 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:163593 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493594 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253595 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493596 quic_data.AddWrite(SYNCHRONOUS,
3597 ConstructInitialSettingsPacket(packet_num++));
3598 }
3599 quic_data.AddWrite(
3600 SYNCHRONOUS,
3601 ConstructClientRequestHeadersPacket(
3602 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3603 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163604 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553605 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3606
rch2f2991c2017-04-13 19:28:173607 // Peer sending data from an non-existing stream causes this end to raise
3608 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333609 quic_data.AddRead(
3610 ASYNC, ConstructServerRstPacket(
3611 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3612 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173613 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:343614 quic_data.AddWrite(
3615 SYNCHRONOUS,
3616 ConstructClientAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:343617 packet_num++, 1, 1,
Renjie Tang248e36ea2020-06-26 00:12:343618 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
3619 : quic::QUIC_INVALID_STREAM_ID,
Renjie Tanga35322a2020-12-02 20:12:273620 quic_error_details,
3621 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
3622 : quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173623 quic_data.AddSocketDataToFactory(&socket_factory_);
3624
3625 // After that fails, it will be resent via TCP.
3626 MockWrite http_writes[] = {
3627 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3628 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3629 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3630
Ryan Hamiltona2dcbae2022-02-09 19:02:453631 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3632 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3633 MockRead(SYNCHRONOUS, 5, "hello world"),
3634 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013635 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173636 socket_factory_.AddSocketDataProvider(&http_data);
3637 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3638
3639 // In order for a new QUIC session to be established via alternate-protocol
3640 // without racing an HTTP connection, we need the host resolution to happen
3641 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3642 // connection to the the server, in this test we require confirmation
3643 // before encrypting so the HTTP job will still start.
3644 host_resolver_.set_synchronous_mode(true);
3645 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3646 "");
rch2f2991c2017-04-13 19:28:173647
3648 CreateSession();
3649
Ryan Hamilton9835e662018-08-02 05:36:273650 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173651
3652 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3653 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263654 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:173655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3656
3657 // Pump the message loop to get the request started.
3658 base::RunLoop().RunUntilIdle();
3659 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283660 crypto_client_stream_factory_.last_stream()
3661 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553662 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173663
3664 // Run the QUIC session to completion.
3665 base::RunLoop().RunUntilIdle();
3666 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3667
3668 ExpectQuicAlternateProtocolMapping();
3669
3670 // Let the transaction proceed which will result in QUIC being marked
3671 // as broken and the request falling back to TCP.
3672 EXPECT_THAT(callback.WaitForResult(), IsOk());
3673
3674 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3675 ASSERT_FALSE(http_data.AllReadDataConsumed());
3676
3677 // Read the response body over TCP.
3678 CheckResponseData(&trans, "hello world");
3679 ExpectBrokenAlternateProtocolMapping();
3680 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3681 ASSERT_TRUE(http_data.AllReadDataConsumed());
3682}
3683
Matt Menkeb32ba5122019-09-10 19:17:053684// Much like above test, but verifies that NetworkIsolationKey is respected.
3685TEST_P(QuicNetworkTransactionTest,
3686 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:353687 if (version_.AlpnDeferToRFCv1()) {
3688 // These versions currently do not support Alt-Svc.
3689 return;
3690 }
Matt Menke4807a9a2020-11-21 00:14:413691 const SchemefulSite kSite1(GURL("https://foo.test/"));
3692 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
3693 const SchemefulSite kSite2(GURL("https://bar.test/"));
3694 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:053695
3696 base::test::ScopedFeatureList feature_list;
3697 feature_list.InitWithFeatures(
3698 // enabled_features
3699 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3700 features::kPartitionConnectionsByNetworkIsolationKey},
3701 // disabled_features
3702 {});
3703 // Since HttpServerProperties caches the feature value, have to create a new
3704 // one.
3705 http_server_properties_ = std::make_unique<HttpServerProperties>();
3706
Peter Kastinge5a38ed2021-10-02 03:06:353707 context_.params()->idle_connection_timeout = base::Seconds(5);
Matt Menkeb32ba5122019-09-10 19:17:053708
3709 // The request will initially go out over QUIC.
3710 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:563711 uint64_t packet_number = 1;
Zhongyi Shi1c022d22020-03-20 19:00:163712 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:253713 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:563714 quic_data.AddWrite(SYNCHRONOUS,
3715 ConstructInitialSettingsPacket(packet_number++));
3716 }
3717 quic_data.AddWrite(
3718 SYNCHRONOUS,
3719 ConstructClientRequestHeadersPacket(
3720 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3721 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163722 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:053723 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3724
3725 // Peer sending data from an non-existing stream causes this end to raise
3726 // error and close connection.
3727 quic_data.AddRead(
3728 ASYNC, ConstructServerRstPacket(
3729 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3730 quic::QUIC_STREAM_LAST_ERROR));
3731 std::string quic_error_details = "Data for nonexistent stream";
Nick Harper1ccb0ce2020-10-07 00:28:583732 quic::QuicErrorCode quic_error_code = quic::QUIC_INVALID_STREAM_ID;
3733 if (version_.HasIetfQuicFrames()) {
3734 quic_error_code = quic::QUIC_HTTP_STREAM_WRONG_DIRECTION;
3735 }
Renjie Tanga35322a2020-12-02 20:12:273736 quic_data.AddWrite(
3737 SYNCHRONOUS,
3738 ConstructClientAckAndConnectionClosePacket(
3739 packet_number++, 1, 1, quic_error_code, quic_error_details,
3740 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
3741 : quic::IETF_RST_STREAM));
Matt Menkeb32ba5122019-09-10 19:17:053742 quic_data.AddSocketDataToFactory(&socket_factory_);
3743
3744 // After that fails, it will be resent via TCP.
3745 MockWrite http_writes[] = {
3746 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3747 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3748 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3749
Ryan Hamiltona2dcbae2022-02-09 19:02:453750 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3751 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3752 MockRead(SYNCHRONOUS, 5, "hello world"),
3753 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:053754 SequencedSocketData http_data(http_reads, http_writes);
3755 socket_factory_.AddSocketDataProvider(&http_data);
3756 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3757
3758 // In order for a new QUIC session to be established via alternate-protocol
3759 // without racing an HTTP connection, we need the host resolution to happen
3760 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3761 // connection to the the server, in this test we require confirmation
3762 // before encrypting so the HTTP job will still start.
3763 host_resolver_.set_synchronous_mode(true);
3764 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3765 "");
3766
3767 CreateSession();
3768
3769 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3770 kNetworkIsolationKey1);
3771 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3772 kNetworkIsolationKey2);
3773
3774 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3775 TestCompletionCallback callback;
3776 request_.network_isolation_key = kNetworkIsolationKey1;
Matt Reichhoff0049a0b72021-10-20 20:44:263777 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeb32ba5122019-09-10 19:17:053778 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3779
3780 // Pump the message loop to get the request started.
3781 base::RunLoop().RunUntilIdle();
3782 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283783 crypto_client_stream_factory_.last_stream()
3784 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:053785 quic_data.Resume();
3786
3787 // Run the QUIC session to completion.
3788 base::RunLoop().RunUntilIdle();
3789 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3790
3791 // Let the transaction proceed which will result in QUIC being marked
3792 // as broken and the request falling back to TCP.
3793 EXPECT_THAT(callback.WaitForResult(), IsOk());
3794 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3795 ASSERT_FALSE(http_data.AllReadDataConsumed());
3796
3797 // Read the response body over TCP.
3798 CheckResponseData(&trans, "hello world");
3799 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3800 ASSERT_TRUE(http_data.AllReadDataConsumed());
3801
3802 // The alternative service shouldhave been marked as broken under
3803 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3804 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3805 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3806
3807 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3808 AddHttpDataAndRunRequest();
3809 // Requests using other NetworkIsolationKeys can still use QUIC.
3810 request_.network_isolation_key = kNetworkIsolationKey2;
3811 AddQuicDataAndRunRequest();
3812
3813 // The last two requests should not have changed the alternative service
3814 // mappings.
3815 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3816 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3817}
3818
rch30943ee2017-06-12 21:28:443819// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3820// request is reset from, then QUIC will be marked as broken and the request
3821// retried over TCP.
3822TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:353823 if (version_.AlpnDeferToRFCv1()) {
3824 // These versions currently do not support Alt-Svc.
3825 return;
3826 }
rch30943ee2017-06-12 21:28:443827 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593828 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133829 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443830 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3831
Zhongyi Shi1c022d22020-03-20 19:00:163832 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493833 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253834 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493835 quic_data.AddWrite(SYNCHRONOUS,
3836 ConstructInitialSettingsPacket(packet_num++));
3837 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023838 quic_data.AddWrite(
3839 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163840 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493841 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3842 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453843
Zhongyi Shi1c022d22020-03-20 19:00:163844 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553845 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443846
Fan Yang32c5a112018-12-10 20:06:333847 quic_data.AddRead(ASYNC,
3848 ConstructServerRstPacket(
3849 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3850 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443851
Bence Béky6e243aa2019-12-13 19:01:073852 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang248e36ea2020-06-26 00:12:343853 quic_data.AddWrite(
Renjie Tanga35322a2020-12-02 20:12:273854 SYNCHRONOUS,
Fan Yang8d4177792021-07-16 17:48:533855 client_maker_->MakeAckRstAndDataPacket(
Renjie Tanga35322a2020-12-02 20:12:273856 packet_num++, true, GetNthClientInitiatedBidirectionalStreamId(0),
3857 quic::QUIC_HEADERS_TOO_LARGE, 1, 1, GetQpackDecoderStreamId(),
3858 false, StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:073859 }
3860
rch30943ee2017-06-12 21:28:443861 quic_data.AddRead(ASYNC, OK);
3862 quic_data.AddSocketDataToFactory(&socket_factory_);
3863
3864 // After that fails, it will be resent via TCP.
3865 MockWrite http_writes[] = {
3866 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3867 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3868 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3869
Ryan Hamiltona2dcbae2022-02-09 19:02:453870 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3871 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3872 MockRead(SYNCHRONOUS, 5, "hello world"),
3873 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013874 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443875 socket_factory_.AddSocketDataProvider(&http_data);
3876 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3877
3878 // In order for a new QUIC session to be established via alternate-protocol
3879 // without racing an HTTP connection, we need the host resolution to happen
3880 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3881 // connection to the the server, in this test we require confirmation
3882 // before encrypting so the HTTP job will still start.
3883 host_resolver_.set_synchronous_mode(true);
3884 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3885 "");
rch30943ee2017-06-12 21:28:443886
3887 CreateSession();
3888
Ryan Hamilton9835e662018-08-02 05:36:273889 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443890
3891 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3892 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263893 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch30943ee2017-06-12 21:28:443894 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3895
3896 // Pump the message loop to get the request started.
3897 base::RunLoop().RunUntilIdle();
3898 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283899 crypto_client_stream_factory_.last_stream()
3900 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553901 quic_data.Resume();
rch30943ee2017-06-12 21:28:443902
3903 // Run the QUIC session to completion.
3904 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3905
3906 ExpectQuicAlternateProtocolMapping();
3907
3908 // Let the transaction proceed which will result in QUIC being marked
3909 // as broken and the request falling back to TCP.
3910 EXPECT_THAT(callback.WaitForResult(), IsOk());
3911
3912 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3913 ASSERT_FALSE(http_data.AllReadDataConsumed());
3914
3915 // Read the response body over TCP.
3916 CheckResponseData(&trans, "hello world");
3917 ExpectBrokenAlternateProtocolMapping();
3918 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3919 ASSERT_TRUE(http_data.AllReadDataConsumed());
3920}
3921
Ryan Hamilton6c2a2a82017-12-15 02:06:283922// Verify that when an origin has two alt-svc advertisements, one local and one
3923// remote, that when the local is broken the request will go over QUIC via
3924// the remote Alt-Svc.
3925// This is a regression test for crbug/825646.
3926TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:383927 context_.params()->allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:283928
3929 GURL origin1 = request_.url; // mail.example.org
3930 GURL origin2("https://www.example.org/");
3931 ASSERT_NE(origin1.host(), origin2.host());
3932
3933 scoped_refptr<X509Certificate> cert(
3934 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243935 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3936 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283937
3938 ProofVerifyDetailsChromium verify_details;
3939 verify_details.cert_verify_result.verified_cert = cert;
3940 verify_details.cert_verify_result.is_issued_by_known_root = true;
3941 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3942
Ryan Hamiltonabad59e2019-06-06 04:02:593943 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233944 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253945 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233946 mock_quic_data.AddWrite(SYNCHRONOUS,
3947 ConstructInitialSettingsPacket(packet_num++));
3948 }
Ryan Hamilton6c2a2a82017-12-15 02:06:283949 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233950 SYNCHRONOUS,
3951 ConstructClientRequestHeadersPacket(
3952 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3953 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433954 mock_quic_data.AddRead(
3955 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333956 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283957 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433958 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333959 ASYNC, ConstructServerDataPacket(
3960 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523961 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233962 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343963 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283964 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213965 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamilton6c2a2a82017-12-15 02:06:283966
3967 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:593968 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:283969 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3970 AddHangingNonAlternateProtocolSocketData();
3971
3972 CreateSession();
3973
3974 // Set up alternative service for |origin1|.
3975 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3976 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
Peter Kastinge5a38ed2021-10-02 03:06:353977 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamilton6c2a2a82017-12-15 02:06:283978 AlternativeServiceInfoVector alternative_services;
3979 alternative_services.push_back(
3980 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3981 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383982 context_.params()->supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:283983 alternative_services.push_back(
3984 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3985 remote_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383986 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:493987 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
3988 NetworkIsolationKey(),
3989 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:283990
Matt Menkeb32ba5122019-09-10 19:17:053991 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
3992 NetworkIsolationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:283993
3994 SendRequestAndExpectQuicResponse("hello!");
3995}
3996
Ryan Hamilton899c2e082019-11-14 01:22:023997// Verify that when multiple alternatives are broken,
3998// ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
3999// This is a regression test for crbug/1024613.
4000TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
Ryan Hamiltona51800a2022-02-12 19:34:354001 if (version_.AlpnDeferToRFCv1()) {
4002 // These versions currently do not support Alt-Svc.
4003 return;
4004 }
Ryan Hamilton899c2e082019-11-14 01:22:024005 base::HistogramTester histogram_tester;
4006
4007 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454008 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Ryan Hamilton899c2e082019-11-14 01:22:024009 MockRead("hello world"),
4010 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4011 MockRead(ASYNC, OK)};
4012
4013 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4014 socket_factory_.AddSocketDataProvider(&http_data);
4015 AddCertificate(&ssl_data_);
4016 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4017
4018 GURL origin1 = request_.url; // mail.example.org
4019
4020 scoped_refptr<X509Certificate> cert(
4021 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
4022 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
4023
4024 ProofVerifyDetailsChromium verify_details;
4025 verify_details.cert_verify_result.verified_cert = cert;
4026 verify_details.cert_verify_result.is_issued_by_known_root = true;
4027 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4028
4029 CreateSession();
4030
4031 // Set up alternative service for |origin1|.
4032 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
Peter Kastinge5a38ed2021-10-02 03:06:354033 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamilton899c2e082019-11-14 01:22:024034 AlternativeServiceInfoVector alternative_services;
4035 alternative_services.push_back(
4036 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4037 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384038 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024039 alternative_services.push_back(
4040 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4041 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384042 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024043 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4044 NetworkIsolationKey(),
4045 alternative_services);
4046
4047 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4048 NetworkIsolationKey());
4049
4050 SendRequestAndExpectHttpResponse("hello world");
4051
4052 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
4053 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
4054}
4055
rch30943ee2017-06-12 21:28:444056// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4057// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:054058// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:444059// connection instead of going back to the broken QUIC connection.
4060// This is a regression tests for crbug/731303.
4061TEST_P(QuicNetworkTransactionTest,
4062 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:354063 if (version_.AlpnDeferToRFCv1()) {
4064 // These versions currently do not support Alt-Svc.
4065 return;
4066 }
Victor Vasilieva1e66d72019-12-05 17:55:384067 context_.params()->allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444068
4069 GURL origin1 = request_.url;
4070 GURL origin2("https://www.example.org/");
4071 ASSERT_NE(origin1.host(), origin2.host());
4072
Ryan Hamiltonabad59e2019-06-06 04:02:594073 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:444074
4075 scoped_refptr<X509Certificate> cert(
4076 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244077 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4078 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444079
4080 ProofVerifyDetailsChromium verify_details;
4081 verify_details.cert_verify_result.verified_cert = cert;
4082 verify_details.cert_verify_result.is_issued_by_known_root = true;
4083 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4084
Renjie Tangaadb84b2019-08-31 01:00:234085 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254086 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234087 mock_quic_data.AddWrite(SYNCHRONOUS,
4088 ConstructInitialSettingsPacket(packet_num++));
4089 }
rch30943ee2017-06-12 21:28:444090 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434091 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234092 SYNCHRONOUS,
4093 ConstructClientRequestHeadersPacket(
4094 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4095 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434096 mock_quic_data.AddRead(
4097 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334098 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284099 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434100 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334101 ASYNC, ConstructServerDataPacket(
4102 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524103 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234104 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344105 ConstructClientAckPacket(packet_num++, 2, 1));
rch30943ee2017-06-12 21:28:444106
4107 // Second request will go over the pooled QUIC connection, but will be
4108 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054109 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224110 version_,
4111 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4112 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054113 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174114 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224115 version_,
4116 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4117 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434118 mock_quic_data.AddWrite(
4119 SYNCHRONOUS,
4120 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234121 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4122 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024123 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334124 mock_quic_data.AddRead(
4125 ASYNC, ConstructServerRstPacket(
4126 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4127 quic::QUIC_HEADERS_TOO_LARGE));
Bence Béky6e243aa2019-12-13 19:01:074128
4129 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangcd594f32020-07-11 20:18:344130 mock_quic_data.AddWrite(
4131 SYNCHRONOUS,
Fan Yang8d4177792021-07-16 17:48:534132 client_maker_->MakeAckRstAndDataPacket(
Renjie Tanga35322a2020-12-02 20:12:274133 packet_num++, /*include_version=*/true,
4134 GetNthClientInitiatedBidirectionalStreamId(1),
4135 quic::QUIC_HEADERS_TOO_LARGE, 3, 2, GetQpackDecoderStreamId(),
Renjie Tangcd594f32020-07-11 20:18:344136 /*fin=*/false, StreamCancellationQpackDecoderInstruction(1)));
Bence Béky6e243aa2019-12-13 19:01:074137 }
4138
rch30943ee2017-06-12 21:28:444139 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214140 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rch30943ee2017-06-12 21:28:444141
4142 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4143
4144 // After that fails, it will be resent via TCP.
4145 MockWrite http_writes[] = {
4146 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4147 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4148 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4149
Ryan Hamiltona2dcbae2022-02-09 19:02:454150 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4151 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
4152 MockRead(SYNCHRONOUS, 5, "hello world"),
4153 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014154 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444155 socket_factory_.AddSocketDataProvider(&http_data);
4156 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4157
Ryan Hamilton6c2a2a82017-12-15 02:06:284158 // Then the next request to the second origin will be sent over TCP.
4159 socket_factory_.AddSocketDataProvider(&http_data);
4160 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444161
4162 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564163 QuicStreamFactoryPeer::SetAlarmFactory(
4164 session_->quic_stream_factory(),
4165 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224166 context_.clock()));
rch30943ee2017-06-12 21:28:444167
4168 // Set up alternative service for |origin1|.
Peter Kastinge5a38ed2021-10-02 03:06:354169 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244170 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494171 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074172 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4173 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:444174
4175 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244176 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494177 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074178 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4179 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344180
rch30943ee2017-06-12 21:28:444181 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524182 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444183 SendRequestAndExpectQuicResponse("hello!");
4184
4185 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524186 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:054187 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:444188 request_.url = origin2;
4189 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:054190 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
4191 alternative1, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244192 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:054193 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
4194 alternative2, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244195 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444196
Matt Menkeb32ba5122019-09-10 19:17:054197 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:444198 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284199 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444200}
4201
bnc8be55ebb2015-10-30 14:12:074202TEST_P(QuicNetworkTransactionTest,
4203 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Ryan Hamiltona51800a2022-02-12 19:34:354204 if (version_.AlpnDeferToRFCv1()) {
4205 // These versions currently do not support Alt-Svc.
4206 return;
4207 }
Nick Harper23290b82019-05-02 00:02:564208 std::string altsvc_header =
4209 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4210 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074211 MockRead http_reads[] = {
4212 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4213 MockRead("hello world"),
4214 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4215 MockRead(ASYNC, OK)};
4216
Ryan Sleevib8d7ea02018-05-07 20:01:014217 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074218 socket_factory_.AddSocketDataProvider(&http_data);
4219 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4220 socket_factory_.AddSocketDataProvider(&http_data);
4221 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4222
rch3f4b8452016-02-23 16:59:324223 CreateSession();
bnc8be55ebb2015-10-30 14:12:074224
4225 SendRequestAndExpectHttpResponse("hello world");
4226 SendRequestAndExpectHttpResponse("hello world");
4227}
4228
Xida Chen9bfe0b62018-04-24 19:52:214229// When multiple alternative services are advertised, HttpStreamFactory should
4230// select the alternative service which uses existing QUIC session if available.
4231// If no existing QUIC session can be used, use the first alternative service
4232// from the list.
zhongyi32569c62016-01-08 02:54:304233TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:354234 if (version_.AlpnDeferToRFCv1()) {
4235 // These versions currently do not support Alt-Svc.
4236 return;
4237 }
Victor Vasilieva1e66d72019-12-05 17:55:384238 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltona2dcbae2022-02-09 19:02:454239 std::string alt_svc_header = base::StrCat(
4240 {"Alt-Svc: ",
4241 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.org", 443), ",",
4242 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
bncc958faa2015-07-31 18:14:524243 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454244 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
bncc958faa2015-07-31 18:14:524245 MockRead("hello world"),
4246 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4247 MockRead(ASYNC, OK)};
4248
Ryan Sleevib8d7ea02018-05-07 20:01:014249 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524250 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084251 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564252 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524253
zhongyi32569c62016-01-08 02:54:304254 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294255 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304256 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594257 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234258 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254259 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234260 mock_quic_data.AddWrite(SYNCHRONOUS,
4261 ConstructInitialSettingsPacket(packet_num++));
4262 }
rch5cb522462017-04-25 20:18:364263 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234264 SYNCHRONOUS,
4265 ConstructClientRequestHeadersPacket(
4266 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4267 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304268
Ryan Hamiltona2dcbae2022-02-09 19:02:454269 std::string alt_svc_list = base::StrCat(
4270 {GenerateQuicAltSvcHeaderValue({version_}, "mail.example.org", 444), ",",
4271 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.org", 443), ",",
4272 GenerateQuicAltSvcHeaderValue({version_}, "bar.example.org", 445)});
Zhongyi Shi32f2fd02018-04-16 18:23:434273 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024274 ASYNC, ConstructServerResponseHeadersPacket(
4275 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284276 GetResponseHeaders("200", alt_svc_list)));
Zhongyi Shi32f2fd02018-04-16 18:23:434277 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334278 ASYNC, ConstructServerDataPacket(
4279 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524280 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234281 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344282 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:304283
4284 // Second QUIC request data.
4285 // Connection pooling, using existing session, no need to include version
4286 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584287 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234288 SYNCHRONOUS,
4289 ConstructClientRequestHeadersPacket(
4290 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4291 true, GetRequestHeaders("GET", "https", "/"),
4292 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434293 mock_quic_data.AddRead(
4294 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334295 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284296 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434297 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334298 ASYNC, ConstructServerDataPacket(
4299 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524300 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474301 mock_quic_data.AddWrite(SYNCHRONOUS,
4302 ConstructClientAckPacket(packet_num++, 4, 3));
bncc958faa2015-07-31 18:14:524303 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214304 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:524305
4306 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4307
rtennetib8e80fb2016-05-16 00:12:094308 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324309 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564310 QuicStreamFactoryPeer::SetAlarmFactory(
4311 session_->quic_stream_factory(),
4312 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224313 context_.clock()));
bncc958faa2015-07-31 18:14:524314
4315 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304316
bnc359ed2a2016-04-29 20:43:454317 SendRequestAndExpectQuicResponse("hello!");
4318 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304319}
4320
Ryan Hamilton8d9ee76e2018-05-29 23:52:524321// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454322// even if alternative service destination is different.
4323TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Victor Vasilieva1e66d72019-12-05 17:55:384324 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594325 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454326
Renjie Tangaadb84b2019-08-31 01:00:234327 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254328 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234329 mock_quic_data.AddWrite(SYNCHRONOUS,
4330 ConstructInitialSettingsPacket(packet_num++));
4331 }
bnc359ed2a2016-04-29 20:43:454332 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434333 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234334 SYNCHRONOUS,
4335 ConstructClientRequestHeadersPacket(
4336 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4337 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434338 mock_quic_data.AddRead(
4339 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334340 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284341 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434342 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334343 ASYNC, ConstructServerDataPacket(
4344 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524345 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234346 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344347 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:304348
bnc359ed2a2016-04-29 20:43:454349 // Second request.
alyssar2adf3ac2016-05-03 17:12:584350 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234351 SYNCHRONOUS,
4352 ConstructClientRequestHeadersPacket(
4353 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4354 true, GetRequestHeaders("GET", "https", "/"),
4355 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434356 mock_quic_data.AddRead(
4357 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334358 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284359 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434360 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334361 ASYNC, ConstructServerDataPacket(
4362 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524363 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474364 mock_quic_data.AddWrite(SYNCHRONOUS,
4365 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:304366 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214367 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi32569c62016-01-08 02:54:304368
4369 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454370
4371 AddHangingNonAlternateProtocolSocketData();
4372 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304373
rch3f4b8452016-02-23 16:59:324374 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564375 QuicStreamFactoryPeer::SetAlarmFactory(
4376 session_->quic_stream_factory(),
4377 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224378 context_.clock()));
zhongyi32569c62016-01-08 02:54:304379
bnc359ed2a2016-04-29 20:43:454380 const char destination1[] = "first.example.com";
4381 const char destination2[] = "second.example.com";
4382
4383 // Set up alternative service entry to destination1.
4384 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214385 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
Peter Kastinge5a38ed2021-10-02 03:06:354386 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:494387 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074388 server, NetworkIsolationKey(), alternative_service, expiration,
4389 supported_versions_);
bnc359ed2a2016-04-29 20:43:454390 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524391 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454392 SendRequestAndExpectQuicResponse("hello!");
4393
4394 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214395 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494396 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074397 server, NetworkIsolationKey(), alternative_service, expiration,
4398 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524399 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454400 // even though alternative service destination is different.
4401 SendRequestAndExpectQuicResponse("hello!");
4402}
4403
4404// Pool to existing session with matching destination and matching certificate
4405// even if origin is different, and even if the alternative service with
4406// matching destination is not the first one on the list.
4407TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Victor Vasilieva1e66d72019-12-05 17:55:384408 context_.params()->allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454409 GURL origin1 = request_.url;
4410 GURL origin2("https://www.example.org/");
4411 ASSERT_NE(origin1.host(), origin2.host());
4412
Ryan Hamiltonabad59e2019-06-06 04:02:594413 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454414
Renjie Tangaadb84b2019-08-31 01:00:234415 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254416 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234417 mock_quic_data.AddWrite(SYNCHRONOUS,
4418 ConstructInitialSettingsPacket(packet_num++));
4419 }
bnc359ed2a2016-04-29 20:43:454420 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434421 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234422 SYNCHRONOUS,
4423 ConstructClientRequestHeadersPacket(
4424 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4425 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434426 mock_quic_data.AddRead(
4427 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334428 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284429 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434430 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334431 ASYNC, ConstructServerDataPacket(
4432 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524433 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234434 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344435 ConstructClientAckPacket(packet_num++, 2, 1));
bnc359ed2a2016-04-29 20:43:454436
4437 // Second request.
Yixin Wang079ad542018-01-11 04:06:054438 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224439 version_,
4440 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4441 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054442 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174443 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224444 version_,
4445 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4446 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584447 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434448 SYNCHRONOUS,
4449 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234450 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4451 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024452 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434453 mock_quic_data.AddRead(
4454 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334455 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284456 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:434457 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334458 ASYNC, ConstructServerDataPacket(
4459 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524460 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474461 mock_quic_data.AddWrite(SYNCHRONOUS,
4462 ConstructClientAckPacket(packet_num++, 4, 3));
bnc359ed2a2016-04-29 20:43:454463 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214464 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:454465
4466 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4467
4468 AddHangingNonAlternateProtocolSocketData();
4469 AddHangingNonAlternateProtocolSocketData();
4470
4471 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564472 QuicStreamFactoryPeer::SetAlarmFactory(
4473 session_->quic_stream_factory(),
4474 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224475 context_.clock()));
bnc359ed2a2016-04-29 20:43:454476
4477 const char destination1[] = "first.example.com";
4478 const char destination2[] = "second.example.com";
4479
4480 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214481 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
Peter Kastinge5a38ed2021-10-02 03:06:354482 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:494483 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074484 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4485 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454486
4487 // Set up multiple alternative service entries for |origin2|,
4488 // the first one with a different destination as for |origin1|,
4489 // the second one with the same. The second one should be used,
4490 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214491 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454492 AlternativeServiceInfoVector alternative_services;
4493 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214494 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4495 alternative_service2, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384496 context_.params()->supported_versions));
bnc359ed2a2016-04-29 20:43:454497 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214498 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4499 alternative_service1, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384500 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494501 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4502 NetworkIsolationKey(),
4503 alternative_services);
bnc359ed2a2016-04-29 20:43:454504 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524505 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454506 SendRequestAndExpectQuicResponse("hello!");
4507
4508 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524509 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454510 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584511
bnc359ed2a2016-04-29 20:43:454512 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304513}
4514
4515// Multiple origins have listed the same alternative services. When there's a
4516// existing QUIC session opened by a request to other origin,
4517// if the cert is valid, should select this QUIC session to make the request
4518// if this is also the first existing QUIC session.
4519TEST_P(QuicNetworkTransactionTest,
4520 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltona51800a2022-02-12 19:34:354521 if (version_.AlpnDeferToRFCv1()) {
4522 // These versions currently do not support Alt-Svc.
4523 return;
4524 }
Victor Vasilieva1e66d72019-12-05 17:55:384525 context_.params()->allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294526 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304527
rch9ae5b3b2016-02-11 00:36:294528 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304529 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454530 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rch9ae5b3b2016-02-11 00:36:294531 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304532 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4533 MockRead(ASYNC, OK)};
4534
Ryan Sleevib8d7ea02018-05-07 20:01:014535 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304536 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084537 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304538 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4539
4540 // HTTP data for request to mail.example.org.
Ryan Hamiltona2dcbae2022-02-09 19:02:454541 std::string alt_svc_header2 = base::StrCat(
4542 {"Alt-Svc: ", GenerateQuicAltSvcHeaderValue({version_}, 444), ",",
4543 GenerateQuicAltSvcHeaderValue({version_}, "www.example.org", 443),
4544 "\r\n\r\n"});
zhongyi32569c62016-01-08 02:54:304545 MockRead http_reads2[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454546 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header2.data()),
zhongyi32569c62016-01-08 02:54:304547 MockRead("hello world from mail.example.org"),
4548 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4549 MockRead(ASYNC, OK)};
4550
Ryan Sleevib8d7ea02018-05-07 20:01:014551 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304552 socket_factory_.AddSocketDataProvider(&http_data2);
4553 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4554
Yixin Wang079ad542018-01-11 04:06:054555 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:224556 version_,
4557 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4558 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054559 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584560 server_maker_.set_hostname("www.example.org");
Zhongyi Shi1c022d22020-03-20 19:00:164561 client_maker_->set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594562 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234563 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254564 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234565 mock_quic_data.AddWrite(SYNCHRONOUS,
4566 ConstructInitialSettingsPacket(packet_num++));
4567 }
zhongyi32569c62016-01-08 02:54:304568 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584569 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234570 SYNCHRONOUS,
4571 ConstructClientRequestHeadersPacket(
4572 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4573 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434574
4575 mock_quic_data.AddRead(
4576 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334577 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284578 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334579 mock_quic_data.AddRead(
4580 ASYNC, ConstructServerDataPacket(
4581 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524582 ConstructDataFrame("hello from mail QUIC!")));
Renjie Tangaadb84b2019-08-31 01:00:234583 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344584 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434585 // Second QUIC request data.
4586 mock_quic_data.AddWrite(
4587 SYNCHRONOUS,
4588 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234589 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4590 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024591 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434592 mock_quic_data.AddRead(
4593 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334594 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284595 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334596 mock_quic_data.AddRead(
4597 ASYNC, ConstructServerDataPacket(
4598 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524599 ConstructDataFrame("hello from mail QUIC!")));
Renjie Tangb7afea82020-07-15 23:35:474600 mock_quic_data.AddWrite(SYNCHRONOUS,
4601 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:304602 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214603 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi32569c62016-01-08 02:54:304604
4605 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304606
rtennetib8e80fb2016-05-16 00:12:094607 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324608 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564609 QuicStreamFactoryPeer::SetAlarmFactory(
4610 session_->quic_stream_factory(),
4611 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224612 context_.clock()));
zhongyi32569c62016-01-08 02:54:304613
4614 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294615 request_.url = GURL("https://www.example.org/");
4616 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304617 request_.url = GURL("https://mail.example.org/");
4618 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4619
rch9ae5b3b2016-02-11 00:36:294620 // Open a QUIC session to mail.example.org:443 when making request
4621 // to mail.example.org.
4622 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454623 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304624
rch9ae5b3b2016-02-11 00:36:294625 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304626 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454627 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524628}
4629
4630TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
Ryan Hamiltona51800a2022-02-12 19:34:354631 if (version_.AlpnDeferToRFCv1()) {
4632 // These versions currently do not support Alt-Svc.
4633 return;
4634 }
Ryan Hamiltona2dcbae2022-02-09 19:02:454635 std::string alt_svc_header =
4636 base::StrCat({"Alt-Svc: ", GenerateQuicAltSvcHeaderValue({version_}, 137),
4637 "\r\n\r\n"});
bncc958faa2015-07-31 18:14:524638 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454639 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
bncc958faa2015-07-31 18:14:524640 MockRead("hello world"),
4641 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4642 MockRead(ASYNC, OK)};
4643
Ryan Sleevib8d7ea02018-05-07 20:01:014644 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524645 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084646 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564647 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524648
rtennetib8e80fb2016-05-16 00:12:094649 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324650 CreateSession();
bncc958faa2015-07-31 18:14:524651
4652 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454653
4654 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344655 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494656 http_server_properties_->GetAlternativeServiceInfos(
4657 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344658 ASSERT_EQ(1u, alternative_service_info_vector.size());
4659 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544660 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344661 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4662 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4663 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524664}
4665
4666TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
Ryan Hamiltona51800a2022-02-12 19:34:354667 if (version_.AlpnDeferToRFCv1()) {
4668 // These versions currently do not support Alt-Svc.
4669 return;
4670 }
bncc958faa2015-07-31 18:14:524671 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454672 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:564673 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524674 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4675 MockRead(ASYNC, OK)};
4676
Ryan Sleevib8d7ea02018-05-07 20:01:014677 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524678 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084679 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564680 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524681
Ryan Hamiltonabad59e2019-06-06 04:02:594682 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234683 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254684 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234685 mock_quic_data.AddWrite(SYNCHRONOUS,
4686 ConstructInitialSettingsPacket(packet_num++));
4687 }
rch5cb522462017-04-25 20:18:364688 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234689 SYNCHRONOUS,
4690 ConstructClientRequestHeadersPacket(
4691 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4692 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434693 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334694 ASYNC, ConstructServerResponseHeadersPacket(
4695 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284696 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334697 mock_quic_data.AddRead(
4698 ASYNC, ConstructServerDataPacket(
4699 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524700 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234701 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344702 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:524703 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214704 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:524705
4706 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4707
rtennetib8e80fb2016-05-16 00:12:094708 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324709 CreateSession();
bncc958faa2015-07-31 18:14:524710
bnc3472afd2016-11-17 15:27:214711 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524712 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494713 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054714 alternative_service, NetworkIsolationKey());
Matt Menke3233d8f22019-08-20 21:01:494715 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054716 alternative_service, NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524717
4718 SendRequestAndExpectHttpResponse("hello world");
4719 SendRequestAndExpectQuicResponse("hello!");
4720
mmenkee24011922015-12-17 22:12:594721 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524722
Matt Menke3233d8f22019-08-20 21:01:494723 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054724 alternative_service, NetworkIsolationKey()));
Matt Menke19475f72019-08-21 18:57:444725 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4726 url::SchemeHostPort("https", request_.url.host(), 443),
4727 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524728}
4729
Matt Menkeb32ba5122019-09-10 19:17:054730TEST_P(QuicNetworkTransactionTest,
4731 ConfirmAlternativeServiceWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:354732 if (version_.AlpnDeferToRFCv1()) {
4733 // These versions currently do not support Alt-Svc.
4734 return;
4735 }
Matt Menke4807a9a2020-11-21 00:14:414736 const SchemefulSite kSite1(GURL("https://foo.test/"));
4737 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
4738 const SchemefulSite kSite2(GURL("https://bar.test/"));
4739 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:054740
4741 base::test::ScopedFeatureList feature_list;
4742 feature_list.InitWithFeatures(
4743 // enabled_features
4744 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4745 features::kPartitionConnectionsByNetworkIsolationKey},
4746 // disabled_features
4747 {});
4748 // Since HttpServerProperties caches the feature value, have to create a new
4749 // one.
4750 http_server_properties_ = std::make_unique<HttpServerProperties>();
4751
4752 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454753 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Matt Menkeb32ba5122019-09-10 19:17:054754 MockRead("hello world"),
4755 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4756 MockRead(ASYNC, OK)};
4757
4758 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4759 socket_factory_.AddSocketDataProvider(&http_data);
4760 AddCertificate(&ssl_data_);
4761 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4762
4763 MockQuicData mock_quic_data(version_);
4764 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254765 if (VersionUsesHttp3(version_.transport_version)) {
Matt Menkeb32ba5122019-09-10 19:17:054766 mock_quic_data.AddWrite(SYNCHRONOUS,
4767 ConstructInitialSettingsPacket(packet_num++));
4768 }
4769 mock_quic_data.AddWrite(
4770 SYNCHRONOUS,
4771 ConstructClientRequestHeadersPacket(
4772 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4773 true, GetRequestHeaders("GET", "https", "/")));
4774 mock_quic_data.AddRead(
4775 ASYNC, ConstructServerResponseHeadersPacket(
4776 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284777 GetResponseHeaders("200")));
Matt Menkeb32ba5122019-09-10 19:17:054778 mock_quic_data.AddRead(
4779 ASYNC, ConstructServerDataPacket(
4780 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524781 ConstructDataFrame("hello!")));
Matt Menkeb32ba5122019-09-10 19:17:054782 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344783 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menkeb32ba5122019-09-10 19:17:054784 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214785 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Matt Menkeb32ba5122019-09-10 19:17:054786
4787 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4788
4789 CreateSession();
4790
4791 AlternativeService alternative_service(kProtoQUIC,
4792 HostPortPair::FromURL(request_.url));
4793 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4794 alternative_service, kNetworkIsolationKey1);
4795 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4796 alternative_service, kNetworkIsolationKey2);
4797 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4798 alternative_service, kNetworkIsolationKey1));
4799 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4800 alternative_service, kNetworkIsolationKey2));
4801
4802 request_.network_isolation_key = kNetworkIsolationKey1;
4803 SendRequestAndExpectHttpResponse("hello world");
4804 SendRequestAndExpectQuicResponse("hello!");
4805
4806 mock_quic_data.Resume();
4807
4808 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4809 alternative_service, kNetworkIsolationKey1));
4810 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4811 url::SchemeHostPort("https", request_.url.host(), 443),
4812 kNetworkIsolationKey1));
4813 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4814 alternative_service, kNetworkIsolationKey2));
4815 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4816 url::SchemeHostPort("https", request_.url.host(), 443),
4817 kNetworkIsolationKey2));
4818}
4819
bncc958faa2015-07-31 18:14:524820TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
Ryan Hamiltona51800a2022-02-12 19:34:354821 if (version_.AlpnDeferToRFCv1()) {
4822 // These versions currently do not support Alt-Svc.
4823 return;
4824 }
bncc958faa2015-07-31 18:14:524825 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454826 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:564827 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524828 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4829 MockRead(ASYNC, OK)};
4830
Ryan Sleevib8d7ea02018-05-07 20:01:014831 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524832 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564833 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524834
Ryan Hamiltonabad59e2019-06-06 04:02:594835 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234836 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254837 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234838 mock_quic_data.AddWrite(SYNCHRONOUS,
4839 ConstructInitialSettingsPacket(packet_num++));
4840 }
rch5cb522462017-04-25 20:18:364841 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234842 SYNCHRONOUS,
4843 ConstructClientRequestHeadersPacket(
4844 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4845 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434846 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334847 ASYNC, ConstructServerResponseHeadersPacket(
4848 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284849 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334850 mock_quic_data.AddRead(
4851 ASYNC, ConstructServerDataPacket(
4852 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524853 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234854 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344855 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:524856 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4857
4858 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4859
4860 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324861 CreateSession();
bncc958faa2015-07-31 18:14:524862
4863 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4864 SendRequestAndExpectHttpResponse("hello world");
4865}
4866
bnc1c196c6e2016-05-28 13:51:484867TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
Ryan Hamiltona51800a2022-02-12 19:34:354868 if (version_.AlpnDeferToRFCv1()) {
4869 // These versions currently do not support Alt-Svc.
4870 return;
4871 }
[email protected]dda75ab2013-06-22 22:43:304872 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274873 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304874
4875 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564876 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294877 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564878 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304879
Ryan Hamiltona2dcbae2022-02-09 19:02:454880 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4881 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
4882 MockRead(SYNCHRONOUS, 5, "hello world"),
4883 MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304884
Ryan Sleevib8d7ea02018-05-07 20:01:014885 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504886 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084887 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504888 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304889
4890 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454891 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304892 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454893 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304894 };
Ryan Sleevib8d7ea02018-05-07 20:01:014895 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504896 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304897
4898 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014899 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504900 socket_factory_.AddSocketDataProvider(&http_data2);
4901 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304902
bnc912a04b2016-04-20 14:19:504903 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304904
4905 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304906 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174907 ASSERT_TRUE(http_data.AllReadDataConsumed());
4908 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304909
4910 // Now run the second request in which the QUIC socket hangs,
4911 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304912 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454913 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304914
rch37de576c2015-05-17 20:28:174915 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4916 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454917 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304918}
4919
[email protected]1e960032013-12-20 19:00:204920TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594921 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164922 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494923 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254924 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:494925 mock_quic_data.AddWrite(SYNCHRONOUS,
4926 ConstructInitialSettingsPacket(packet_num++));
4927 }
Zhongyi Shi32f2fd02018-04-16 18:23:434928 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494929 SYNCHRONOUS,
4930 ConstructClientRequestHeadersPacket(
4931 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4932 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:164933 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4934 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Zhongyi Shi32f2fd02018-04-16 18:23:434935 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334936 ASYNC, ConstructServerResponseHeadersPacket(
4937 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284938 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334939 mock_quic_data.AddRead(
4940 ASYNC, ConstructServerDataPacket(
4941 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524942 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:494943 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344944 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:504945 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214946 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
[email protected]8ba81212013-05-03 13:11:484947
rcha5399e02015-04-21 19:32:044948 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484949
rtennetib8e80fb2016-05-16 00:12:094950 // The non-alternate protocol job needs to hang in order to guarantee that
4951 // the alternate-protocol job will "win".
4952 AddHangingNonAlternateProtocolSocketData();
4953
rch3f4b8452016-02-23 16:59:324954 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274955 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yang1ef6dfef2021-07-24 16:20:164956 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4957 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264958 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Fan Yang1ef6dfef2021-07-24 16:20:164959 IsError(ERR_IO_PENDING));
4960 // Complete host resolution in next message loop so that QUIC job could
4961 // proceed.
4962 base::RunLoop().RunUntilIdle();
4963 // Explicitly confirm the handshake.
4964 crypto_client_stream_factory_.last_stream()
4965 ->NotifySessionOneRttKeyAvailable();
4966
4967 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
4968 mock_quic_data.Resume();
4969
4970 // Run the QUIC session to completion.
4971 base::RunLoop().RunUntilIdle();
4972
4973 EXPECT_THAT(callback.WaitForResult(), IsOk());
4974
4975 CheckWasQuicResponse(&trans);
4976 CheckResponseData(&trans, "hello!");
rchac7f35e2017-03-15 20:42:304977
Matt Menke19475f72019-08-21 18:57:444978 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4979 url::SchemeHostPort("https", request_.url.host(), 443),
4980 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:484981}
4982
[email protected]1e960032013-12-20 19:00:204983TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594984 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164985 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494986 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:254987 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:494988 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:164989 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:494990 }
Fan Yang32c5a112018-12-10 20:06:334991 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494992 SYNCHRONOUS,
4993 ConstructClientRequestHeadersPacket(
4994 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4995 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:164996 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4997 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Zhongyi Shi32f2fd02018-04-16 18:23:434998 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334999 ASYNC, ConstructServerResponseHeadersPacket(
5000 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285001 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335002 mock_quic_data.AddRead(
5003 ASYNC, ConstructServerDataPacket(
5004 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525005 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:495006 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345007 ConstructClientAckPacket(packet_number++, 2, 1));
rchb27683c2015-07-29 23:53:505008 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215009 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rcha5399e02015-04-21 19:32:045010 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275011
5012 // In order for a new QUIC session to be established via alternate-protocol
5013 // without racing an HTTP connection, we need the host resolution to happen
5014 // synchronously.
5015 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295016 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565017 "");
[email protected]3a120a6b2013-06-25 01:08:275018
rtennetib8e80fb2016-05-16 00:12:095019 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325020 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275021 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yang1ef6dfef2021-07-24 16:20:165022 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5023 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265024 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Fan Yang1ef6dfef2021-07-24 16:20:165025 IsError(ERR_IO_PENDING));
5026 // Complete host resolution in next message loop so that QUIC job could
5027 // proceed.
5028 base::RunLoop().RunUntilIdle();
5029 // Explicitly confirm the handshake.
5030 crypto_client_stream_factory_.last_stream()
5031 ->NotifySessionOneRttKeyAvailable();
5032
5033 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
5034 mock_quic_data.Resume();
5035
5036 // Run the QUIC session to completion.
5037 base::RunLoop().RunUntilIdle();
5038
5039 EXPECT_THAT(callback.WaitForResult(), IsOk());
5040
5041 CheckWasQuicResponse(&trans);
5042 CheckResponseData(&trans, "hello!");
[email protected]3a120a6b2013-06-25 01:08:275043}
5044
[email protected]0fc924b2014-03-31 04:34:155045TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ryan Hamiltona51800a2022-02-12 19:34:355046 if (version_.AlpnDeferToRFCv1()) {
5047 // These versions currently do not support Alt-Svc.
5048 return;
5049 }
Nicolas Arciniegad2013f92020-02-07 23:00:565050 proxy_resolution_service_ =
5051 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
5052 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155053
5054 // Since we are using a proxy, the QUIC job will not succeed.
5055 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295056 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5057 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565058 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155059
Ryan Hamiltona2dcbae2022-02-09 19:02:455060 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
5061 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
5062 MockRead(SYNCHRONOUS, 5, "hello world"),
5063 MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155064
Ryan Sleevib8d7ea02018-05-07 20:01:015065 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155066 socket_factory_.AddSocketDataProvider(&http_data);
5067
5068 // In order for a new QUIC session to be established via alternate-protocol
5069 // without racing an HTTP connection, we need the host resolution to happen
5070 // synchronously.
5071 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295072 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565073 "");
[email protected]0fc924b2014-03-31 04:34:155074
rch9ae5b3b2016-02-11 00:36:295075 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325076 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275077 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155078 SendRequestAndExpectHttpResponse("hello world");
5079}
5080
[email protected]1e960032013-12-20 19:00:205081TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:595082 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235083 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165084 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255085 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235086 mock_quic_data.AddWrite(SYNCHRONOUS,
5087 ConstructInitialSettingsPacket(packet_num++));
5088 }
Zhongyi Shi1c022d22020-03-20 19:00:165089 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365090 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235091 SYNCHRONOUS,
5092 ConstructClientRequestHeadersPacket(
5093 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5094 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435095 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335096 ASYNC, ConstructServerResponseHeadersPacket(
5097 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285098 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335099 mock_quic_data.AddRead(
5100 ASYNC, ConstructServerDataPacket(
5101 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525102 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235103 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345104 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:595105 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045106 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125107
rtennetib8e80fb2016-05-16 00:12:095108 // The non-alternate protocol job needs to hang in order to guarantee that
5109 // the alternate-protocol job will "win".
5110 AddHangingNonAlternateProtocolSocketData();
5111
[email protected]11c05872013-08-20 02:04:125112 // In order for a new QUIC session to be established via alternate-protocol
5113 // without racing an HTTP connection, we need the host resolution to happen
5114 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5115 // connection to the the server, in this test we require confirmation
5116 // before encrypting so the HTTP job will still start.
5117 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295118 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565119 "");
[email protected]11c05872013-08-20 02:04:125120
rch3f4b8452016-02-23 16:59:325121 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435122 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5123 false);
Ryan Hamilton9835e662018-08-02 05:36:275124 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125125
bnc691fda62016-08-12 00:43:165126 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125127 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265128 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015129 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125130
Fan Yang3673cc72020-02-07 14:49:285131 crypto_client_stream_factory_.last_stream()
5132 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015133 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505134
bnc691fda62016-08-12 00:43:165135 CheckWasQuicResponse(&trans);
5136 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125137}
5138
Steven Valdez58097ec32018-07-16 18:29:045139TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015140 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595141 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165142 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255143 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495144 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:165145 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:495146 }
Steven Valdez58097ec32018-07-16 18:29:045147 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015148 SYNCHRONOUS,
5149 ConstructClientRequestHeadersPacket(
5150 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5151 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335152 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025153 ASYNC, ConstructServerResponseHeadersPacket(
5154 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285155 GetResponseHeaders("425")));
Bence Béky6e243aa2019-12-13 19:01:075156 if (VersionUsesHttp3(version_.transport_version)) {
5157 mock_quic_data.AddWrite(
5158 SYNCHRONOUS,
5159 ConstructClientAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:345160 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, false,
Bence Béky6e243aa2019-12-13 19:01:075161 StreamCancellationQpackDecoderInstruction(0)));
5162 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165163 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075164 packet_number++, false,
5165 GetNthClientInitiatedBidirectionalStreamId(0),
5166 quic::QUIC_STREAM_CANCELLED));
5167 } else {
5168 mock_quic_data.AddWrite(
5169 SYNCHRONOUS,
5170 ConstructClientAckAndRstPacket(
5171 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:345172 quic::QUIC_STREAM_CANCELLED, 1, 1));
Bence Béky6e243aa2019-12-13 19:01:075173 }
Steven Valdez58097ec32018-07-16 18:29:045174
Zhongyi Shi1c022d22020-03-20 19:00:165175 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:045176
Steven Valdez58097ec32018-07-16 18:29:045177 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015178 SYNCHRONOUS,
5179 ConstructClientRequestHeadersPacket(
5180 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5181 true, GetRequestHeaders("GET", "https", "/"),
5182 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045183 mock_quic_data.AddRead(
5184 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335185 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285186 GetResponseHeaders("200")));
Steven Valdez58097ec32018-07-16 18:29:045187 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335188 ASYNC, ConstructServerDataPacket(
5189 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:525190 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:475191 mock_quic_data.AddWrite(SYNCHRONOUS,
5192 ConstructClientAckPacket(packet_number++, 3, 1));
Steven Valdez58097ec32018-07-16 18:29:045193 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215194 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Steven Valdez58097ec32018-07-16 18:29:045195
5196 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5197
5198 // In order for a new QUIC session to be established via alternate-protocol
5199 // without racing an HTTP connection, we need the host resolution to happen
5200 // synchronously.
5201 host_resolver_.set_synchronous_mode(true);
5202 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5203 "");
Steven Valdez58097ec32018-07-16 18:29:045204
5205 AddHangingNonAlternateProtocolSocketData();
5206 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275207 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565208 QuicStreamFactoryPeer::SetAlarmFactory(
5209 session_->quic_stream_factory(),
5210 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225211 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045212
5213 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5214 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265215 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Steven Valdez58097ec32018-07-16 18:29:045216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5217
5218 // Confirm the handshake after the 425 Too Early.
5219 base::RunLoop().RunUntilIdle();
5220
5221 // The handshake hasn't been confirmed yet, so the retry should not have
5222 // succeeded.
5223 EXPECT_FALSE(callback.have_result());
5224
Fan Yang3673cc72020-02-07 14:49:285225 crypto_client_stream_factory_.last_stream()
5226 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:045227
5228 EXPECT_THAT(callback.WaitForResult(), IsOk());
5229 CheckWasQuicResponse(&trans);
5230 CheckResponseData(&trans, "hello!");
5231}
5232
5233TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015234 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595235 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165236 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255237 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495238 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:165239 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:495240 }
Steven Valdez58097ec32018-07-16 18:29:045241 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015242 SYNCHRONOUS,
5243 ConstructClientRequestHeadersPacket(
5244 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5245 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335246 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025247 ASYNC, ConstructServerResponseHeadersPacket(
5248 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285249 GetResponseHeaders("425")));
Bence Béky6e243aa2019-12-13 19:01:075250 if (VersionUsesHttp3(version_.transport_version)) {
5251 mock_quic_data.AddWrite(
5252 SYNCHRONOUS,
5253 ConstructClientAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:345254 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, false,
Bence Béky6e243aa2019-12-13 19:01:075255 StreamCancellationQpackDecoderInstruction(0)));
5256 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165257 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075258 packet_number++, false,
5259 GetNthClientInitiatedBidirectionalStreamId(0),
5260 quic::QUIC_STREAM_CANCELLED));
5261 } else {
5262 mock_quic_data.AddWrite(
5263 SYNCHRONOUS,
5264 ConstructClientAckAndRstPacket(
5265 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:345266 quic::QUIC_STREAM_CANCELLED, 1, 1));
Bence Béky6e243aa2019-12-13 19:01:075267 }
Steven Valdez58097ec32018-07-16 18:29:045268
Zhongyi Shi1c022d22020-03-20 19:00:165269 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:045270
Steven Valdez58097ec32018-07-16 18:29:045271 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015272 SYNCHRONOUS,
5273 ConstructClientRequestHeadersPacket(
5274 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5275 true, GetRequestHeaders("GET", "https", "/"),
5276 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335277 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025278 ASYNC, ConstructServerResponseHeadersPacket(
5279 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285280 GetResponseHeaders("425")));
Bence Béky6e243aa2019-12-13 19:01:075281 if (VersionUsesHttp3(version_.transport_version)) {
5282 mock_quic_data.AddWrite(
5283 SYNCHRONOUS,
5284 ConstructClientAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:345285 packet_number++, false, GetQpackDecoderStreamId(), 2, 1, false,
Renjie Tang248e36ea2020-06-26 00:12:345286 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:075287 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165288 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075289 packet_number++, false,
5290 GetNthClientInitiatedBidirectionalStreamId(1),
5291 quic::QUIC_STREAM_CANCELLED));
5292 } else {
5293 mock_quic_data.AddWrite(
5294 SYNCHRONOUS,
5295 ConstructClientAckAndRstPacket(
5296 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
Renjie Tangcd594f32020-07-11 20:18:345297 quic::QUIC_STREAM_CANCELLED, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:075298 }
Steven Valdez58097ec32018-07-16 18:29:045299 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215300 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Steven Valdez58097ec32018-07-16 18:29:045301
5302 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5303
5304 // In order for a new QUIC session to be established via alternate-protocol
5305 // without racing an HTTP connection, we need the host resolution to happen
5306 // synchronously.
5307 host_resolver_.set_synchronous_mode(true);
5308 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5309 "");
Steven Valdez58097ec32018-07-16 18:29:045310
5311 AddHangingNonAlternateProtocolSocketData();
5312 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275313 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565314 QuicStreamFactoryPeer::SetAlarmFactory(
5315 session_->quic_stream_factory(),
5316 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225317 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045318
5319 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5320 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265321 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Steven Valdez58097ec32018-07-16 18:29:045322 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5323
5324 // Confirm the handshake after the 425 Too Early.
5325 base::RunLoop().RunUntilIdle();
5326
5327 // The handshake hasn't been confirmed yet, so the retry should not have
5328 // succeeded.
5329 EXPECT_FALSE(callback.have_result());
5330
Fan Yang3673cc72020-02-07 14:49:285331 crypto_client_stream_factory_.last_stream()
5332 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:045333
5334 EXPECT_THAT(callback.WaitForResult(), IsOk());
5335 const HttpResponseInfo* response = trans.GetResponseInfo();
5336 ASSERT_TRUE(response != nullptr);
5337 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:285338 EXPECT_EQ("HTTP/1.1 425", response->headers->GetStatusLine());
Steven Valdez58097ec32018-07-16 18:29:045339 EXPECT_TRUE(response->was_fetched_via_spdy);
5340 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085341 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5342 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045343}
5344
zhongyica364fbb2015-12-12 03:39:125345TEST_P(QuicNetworkTransactionTest,
5346 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Victor Vasilieva1e66d72019-12-05 17:55:385347 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595348 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235349 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165350 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255351 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235352 mock_quic_data.AddWrite(SYNCHRONOUS,
5353 ConstructInitialSettingsPacket(packet_num++));
5354 }
Zhongyi Shi1c022d22020-03-20 19:00:165355 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365356 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235357 SYNCHRONOUS,
5358 ConstructClientRequestHeadersPacket(
5359 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5360 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125361 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525362 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435363 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125364 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5365
5366 // The non-alternate protocol job needs to hang in order to guarantee that
5367 // the alternate-protocol job will "win".
5368 AddHangingNonAlternateProtocolSocketData();
5369
5370 // In order for a new QUIC session to be established via alternate-protocol
5371 // without racing an HTTP connection, we need the host resolution to happen
5372 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5373 // connection to the the server, in this test we require confirmation
5374 // before encrypting so the HTTP job will still start.
5375 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295376 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125377 "");
zhongyica364fbb2015-12-12 03:39:125378
rch3f4b8452016-02-23 16:59:325379 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435380 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5381 false);
Ryan Hamilton9835e662018-08-02 05:36:275382 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125383
bnc691fda62016-08-12 00:43:165384 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125385 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265386 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015387 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125388
Fan Yang3673cc72020-02-07 14:49:285389 crypto_client_stream_factory_.last_stream()
5390 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015391 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125392
5393 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525394 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125395
bnc691fda62016-08-12 00:43:165396 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125397 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525398 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5399 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125400}
5401
5402TEST_P(QuicNetworkTransactionTest,
5403 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Victor Vasilieva1e66d72019-12-05 17:55:385404 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595405 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235406 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165407 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255408 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235409 mock_quic_data.AddWrite(SYNCHRONOUS,
5410 ConstructInitialSettingsPacket(packet_num++));
5411 }
Zhongyi Shi1c022d22020-03-20 19:00:165412 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365413 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235414 SYNCHRONOUS,
5415 ConstructClientRequestHeadersPacket(
5416 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5417 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215418 // Peer sending data from an non-existing stream causes this end to raise
5419 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335420 mock_quic_data.AddRead(
5421 ASYNC, ConstructServerRstPacket(
5422 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5423 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215424 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:375425 mock_quic_data.AddWrite(
Renjie Tang248e36ea2020-06-26 00:12:345426 SYNCHRONOUS,
5427 ConstructClientAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:345428 packet_num++, 1, 1,
Renjie Tang248e36ea2020-06-26 00:12:345429 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
5430 : quic::QUIC_INVALID_STREAM_ID,
Renjie Tanga35322a2020-12-02 20:12:275431 quic_error_details,
5432 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
5433 : quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125434 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5435
5436 // The non-alternate protocol job needs to hang in order to guarantee that
5437 // the alternate-protocol job will "win".
5438 AddHangingNonAlternateProtocolSocketData();
5439
5440 // In order for a new QUIC session to be established via alternate-protocol
5441 // without racing an HTTP connection, we need the host resolution to happen
5442 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5443 // connection to the the server, in this test we require confirmation
5444 // before encrypting so the HTTP job will still start.
5445 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295446 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125447 "");
zhongyica364fbb2015-12-12 03:39:125448
rch3f4b8452016-02-23 16:59:325449 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435450 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5451 false);
Ryan Hamilton9835e662018-08-02 05:36:275452 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125453
bnc691fda62016-08-12 00:43:165454 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125455 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265456 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015457 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125458
Fan Yang3673cc72020-02-07 14:49:285459 crypto_client_stream_factory_.last_stream()
5460 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015461 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125462 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525463 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125464
bnc691fda62016-08-12 00:43:165465 trans.PopulateNetErrorDetails(&details);
Renjie Tang248e36ea2020-06-26 00:12:345466 EXPECT_EQ(version_.HasIetfQuicFrames()
5467 ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
5468 : quic::QUIC_INVALID_STREAM_ID,
5469 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125470}
5471
Nick Harper057264a82019-09-12 23:33:495472TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:595473 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235474 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165475 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255476 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235477 mock_quic_data.AddWrite(SYNCHRONOUS,
5478 ConstructInitialSettingsPacket(packet_num++));
5479 }
Zhongyi Shi1c022d22020-03-20 19:00:165480 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365481 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235482 SYNCHRONOUS,
5483 ConstructClientRequestHeadersPacket(
5484 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5485 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485486 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335487 mock_quic_data.AddRead(
5488 ASYNC, ConstructServerResponseHeadersPacket(
5489 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285490 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335491 mock_quic_data.AddRead(
5492 ASYNC, ConstructServerRstPacket(
5493 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5494 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075495
5496 if (VersionUsesHttp3(version_.transport_version)) {
5497 mock_quic_data.AddWrite(
Renjie Tanga35322a2020-12-02 20:12:275498 SYNCHRONOUS,
5499 client_maker_->MakeAckRstAndDataPacket(
5500 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5501 quic::QUIC_STREAM_CANCELLED, 2, 1, GetQpackDecoderStreamId(), false,
5502 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:075503 } else {
5504 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345505 ConstructClientAckPacket(packet_num++, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:075506 }
rchcd5f1c62016-06-23 02:43:485507 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5508 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5509
5510 // The non-alternate protocol job needs to hang in order to guarantee that
5511 // the alternate-protocol job will "win".
5512 AddHangingNonAlternateProtocolSocketData();
5513
5514 // In order for a new QUIC session to be established via alternate-protocol
5515 // without racing an HTTP connection, we need the host resolution to happen
5516 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5517 // connection to the the server, in this test we require confirmation
5518 // before encrypting so the HTTP job will still start.
5519 host_resolver_.set_synchronous_mode(true);
5520 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5521 "");
rchcd5f1c62016-06-23 02:43:485522
5523 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435524 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5525 false);
Ryan Hamilton9835e662018-08-02 05:36:275526 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485527
bnc691fda62016-08-12 00:43:165528 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485529 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265530 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015531 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485532
Fan Yang3673cc72020-02-07 14:49:285533 crypto_client_stream_factory_.last_stream()
5534 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:485535 // Read the headers.
robpercival214763f2016-07-01 23:27:015536 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485537
bnc691fda62016-08-12 00:43:165538 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485539 ASSERT_TRUE(response != nullptr);
5540 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:285541 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
rchcd5f1c62016-06-23 02:43:485542 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525543 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085544 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5545 response->connection_info);
rchcd5f1c62016-06-23 02:43:485546
5547 std::string response_data;
bnc691fda62016-08-12 00:43:165548 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485549}
5550
Nick Harper057264a82019-09-12 23:33:495551TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:385552 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595553 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235554 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165555 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255556 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235557 mock_quic_data.AddWrite(SYNCHRONOUS,
5558 ConstructInitialSettingsPacket(packet_num++));
5559 }
Zhongyi Shi1c022d22020-03-20 19:00:165560 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365561 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235562 SYNCHRONOUS,
5563 ConstructClientRequestHeadersPacket(
5564 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5565 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335566 mock_quic_data.AddRead(
5567 ASYNC, ConstructServerRstPacket(
5568 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5569 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075570
5571 if (VersionUsesHttp3(version_.transport_version)) {
5572 mock_quic_data.AddWrite(
Renjie Tanga35322a2020-12-02 20:12:275573 SYNCHRONOUS,
Fan Yang8d4177792021-07-16 17:48:535574 client_maker_->MakeAckRstAndDataPacket(
Renjie Tanga35322a2020-12-02 20:12:275575 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5576 quic::QUIC_STREAM_CANCELLED, 1, 1, GetQpackDecoderStreamId(), false,
5577 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:075578 }
5579
rchcd5f1c62016-06-23 02:43:485580 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5581 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5582
5583 // The non-alternate protocol job needs to hang in order to guarantee that
5584 // the alternate-protocol job will "win".
5585 AddHangingNonAlternateProtocolSocketData();
5586
5587 // In order for a new QUIC session to be established via alternate-protocol
5588 // without racing an HTTP connection, we need the host resolution to happen
5589 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5590 // connection to the the server, in this test we require confirmation
5591 // before encrypting so the HTTP job will still start.
5592 host_resolver_.set_synchronous_mode(true);
5593 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5594 "");
rchcd5f1c62016-06-23 02:43:485595
5596 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435597 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5598 false);
Ryan Hamilton9835e662018-08-02 05:36:275599 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485600
bnc691fda62016-08-12 00:43:165601 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485602 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265603 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015604 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485605
Fan Yang3673cc72020-02-07 14:49:285606 crypto_client_stream_factory_.last_stream()
5607 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:485608 // Read the headers.
robpercival214763f2016-07-01 23:27:015609 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485610}
5611
[email protected]1e960032013-12-20 19:00:205612TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305613 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525614 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585615 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305616 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505617 MockRead(ASYNC, close->data(), close->length()),
5618 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5619 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305620 };
Ryan Sleevib8d7ea02018-05-07 20:01:015621 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305622 socket_factory_.AddSocketDataProvider(&quic_data);
5623
5624 // Main job which will succeed even though the alternate job fails.
5625 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025626 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5627 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5628 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305629
Ryan Sleevib8d7ea02018-05-07 20:01:015630 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305631 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565632 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305633
rch3f4b8452016-02-23 16:59:325634 CreateSession();
David Schinazic8281052019-01-24 06:14:175635 AddQuicAlternateProtocolMapping(
5636 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195637 SendRequestAndExpectHttpResponse("hello from http");
5638 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305639}
5640
Matt Menkeb32ba5122019-09-10 19:17:055641TEST_P(QuicNetworkTransactionTest,
5642 BrokenAlternateProtocolWithNetworkIsolationKey) {
Matt Menke4807a9a2020-11-21 00:14:415643 const SchemefulSite kSite1(GURL("https://foo.test/"));
5644 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
5645 const SchemefulSite kSite2(GURL("https://bar.test/"));
5646 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:055647
5648 base::test::ScopedFeatureList feature_list;
5649 feature_list.InitWithFeatures(
5650 // enabled_features
5651 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5652 features::kPartitionConnectionsByNetworkIsolationKey},
5653 // disabled_features
5654 {});
5655 // Since HttpServerProperties caches the feature value, have to create a new
5656 // one.
5657 http_server_properties_ = std::make_unique<HttpServerProperties>();
5658
5659 // Alternate-protocol job
5660 std::unique_ptr<quic::QuicEncryptedPacket> close(
5661 ConstructServerConnectionClosePacket(1));
5662 MockRead quic_reads[] = {
5663 MockRead(ASYNC, close->data(), close->length()),
5664 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5665 MockRead(ASYNC, OK), // EOF
5666 };
5667 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5668 socket_factory_.AddSocketDataProvider(&quic_data);
5669
5670 // Main job which will succeed even though the alternate job fails.
5671 MockRead http_reads[] = {
5672 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5673 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5674 MockRead(ASYNC, OK)};
5675
5676 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5677 socket_factory_.AddSocketDataProvider(&http_data);
5678 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5679
5680 CreateSession();
5681 AddQuicAlternateProtocolMapping(
5682 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5683 AddQuicAlternateProtocolMapping(
5684 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5685 request_.network_isolation_key = kNetworkIsolationKey1;
5686 SendRequestAndExpectHttpResponse("hello from http");
5687
5688 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5689 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5690}
5691
[email protected]1e960032013-12-20 19:00:205692TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595693 // Alternate-protocol job
5694 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025695 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595696 };
Ryan Sleevib8d7ea02018-05-07 20:01:015697 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595698 socket_factory_.AddSocketDataProvider(&quic_data);
5699
5700 // Main job which will succeed even though the alternate job fails.
5701 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025702 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5703 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5704 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595705
Ryan Sleevib8d7ea02018-05-07 20:01:015706 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595707 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565708 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595709
rch3f4b8452016-02-23 16:59:325710 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595711
Ryan Hamilton9835e662018-08-02 05:36:275712 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195713 SendRequestAndExpectHttpResponse("hello from http");
5714 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595715}
5716
[email protected]00c159f2014-05-21 22:38:165717TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535718 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165719 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025720 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165721 };
Ryan Sleevib8d7ea02018-05-07 20:01:015722 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165723 socket_factory_.AddSocketDataProvider(&quic_data);
5724
[email protected]eb71ab62014-05-23 07:57:535725 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165726 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025727 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165728 };
5729
Ryan Sleevib8d7ea02018-05-07 20:01:015730 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165731 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5732 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565733 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165734
rtennetib8e80fb2016-05-16 00:12:095735 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325736 CreateSession();
[email protected]00c159f2014-05-21 22:38:165737
Ryan Hamilton9835e662018-08-02 05:36:275738 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165739 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165740 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265741 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5743 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165744 ExpectQuicAlternateProtocolMapping();
5745}
5746
Zhongyi Shia0cef1082017-08-25 01:49:505747TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5748 // Tests that TCP job is delayed and QUIC job does not require confirmation
5749 // if QUIC was recently supported on the same IP on start.
5750
5751 // Set QUIC support on the last IP address, which is same with the local IP
5752 // address. Require confirmation mode will be turned off immediately when
5753 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435754 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5755 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:505756
Ryan Hamiltonabad59e2019-06-06 04:02:595757 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165758 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495759 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255760 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495761 mock_quic_data.AddWrite(SYNCHRONOUS,
5762 ConstructInitialSettingsPacket(packet_number++));
5763 }
Zhongyi Shi32f2fd02018-04-16 18:23:435764 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495765 SYNCHRONOUS,
5766 ConstructClientRequestHeadersPacket(
5767 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5768 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:165769 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5770 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
Zhongyi Shi32f2fd02018-04-16 18:23:435771 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335772 ASYNC, ConstructServerResponseHeadersPacket(
5773 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285774 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335775 mock_quic_data.AddRead(
5776 ASYNC, ConstructServerDataPacket(
5777 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525778 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:495779 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345780 ConstructClientAckPacket(packet_number++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505781 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215782 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Zhongyi Shia0cef1082017-08-25 01:49:505783
5784 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5785 // No HTTP data is mocked as TCP job never starts in this case.
5786
5787 CreateSession();
5788 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:435789 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5790 false);
Zhongyi Shia0cef1082017-08-25 01:49:505791
Ryan Hamilton9835e662018-08-02 05:36:275792 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505793
5794 // Stall host resolution so that QUIC job will not succeed synchronously.
5795 // Socket will not be configured immediately and QUIC support is not sorted
5796 // out, TCP job will still be delayed as server properties indicates QUIC
5797 // support on last IP address.
5798 host_resolver_.set_synchronous_mode(false);
5799
5800 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5801 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265802 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Zhongyi Shia0cef1082017-08-25 01:49:505803 IsError(ERR_IO_PENDING));
5804 // Complete host resolution in next message loop so that QUIC job could
5805 // proceed.
5806 base::RunLoop().RunUntilIdle();
Fan Yang1ef6dfef2021-07-24 16:20:165807 // Explicitly confirm the handshake.
5808 crypto_client_stream_factory_.last_stream()
5809 ->NotifySessionOneRttKeyAvailable();
5810
5811 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
5812 mock_quic_data.Resume();
5813
5814 // Run the QUIC session to completion.
5815 base::RunLoop().RunUntilIdle();
Zhongyi Shia0cef1082017-08-25 01:49:505816 EXPECT_THAT(callback.WaitForResult(), IsOk());
5817
5818 CheckWasQuicResponse(&trans);
5819 CheckResponseData(&trans, "hello!");
5820}
5821
5822TEST_P(QuicNetworkTransactionTest,
5823 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5824 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5825 // was recently supported on a different IP address on start.
5826
5827 // Set QUIC support on the last IP address, which is different with the local
5828 // IP address. Require confirmation mode will remain when local IP address is
5829 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435830 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5831 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:505832
Ryan Hamiltonabad59e2019-06-06 04:02:595833 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235834 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165835 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255836 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235837 mock_quic_data.AddWrite(SYNCHRONOUS,
5838 ConstructInitialSettingsPacket(packet_num++));
5839 }
Zhongyi Shi1c022d22020-03-20 19:00:165840 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:505841 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235842 SYNCHRONOUS,
5843 ConstructClientRequestHeadersPacket(
5844 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5845 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435846 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335847 ASYNC, ConstructServerResponseHeadersPacket(
5848 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285849 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335850 mock_quic_data.AddRead(
5851 ASYNC, ConstructServerDataPacket(
5852 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525853 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235854 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345855 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505856 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5857 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5858 // No HTTP data is mocked as TCP job will be delayed and never starts.
5859
5860 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435861 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5862 false);
Ryan Hamilton9835e662018-08-02 05:36:275863 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505864
5865 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5866 // Socket will not be configured immediately and QUIC support is not sorted
5867 // out, TCP job will still be delayed as server properties indicates QUIC
5868 // support on last IP address.
5869 host_resolver_.set_synchronous_mode(false);
5870
5871 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5872 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265873 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Zhongyi Shia0cef1082017-08-25 01:49:505874 IsError(ERR_IO_PENDING));
5875
5876 // Complete host resolution in next message loop so that QUIC job could
5877 // proceed.
5878 base::RunLoop().RunUntilIdle();
5879 // Explicitly confirm the handshake so that QUIC job could succeed.
Fan Yang3673cc72020-02-07 14:49:285880 crypto_client_stream_factory_.last_stream()
5881 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia0cef1082017-08-25 01:49:505882 EXPECT_THAT(callback.WaitForResult(), IsOk());
5883
5884 CheckWasQuicResponse(&trans);
5885 CheckResponseData(&trans, "hello!");
5886}
5887
Ryan Hamilton75f197262017-08-17 14:00:075888TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5889 // Test that NetErrorDetails is correctly populated, even if the
5890 // handshake has not yet been confirmed and no stream has been created.
5891
5892 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595893 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075894 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5895 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5896 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5897
5898 // Main job will also fail.
5899 MockRead http_reads[] = {
5900 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5901 };
5902
Ryan Sleevib8d7ea02018-05-07 20:01:015903 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075904 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5905 socket_factory_.AddSocketDataProvider(&http_data);
5906 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5907
5908 AddHangingNonAlternateProtocolSocketData();
5909 CreateSession();
5910 // Require handshake confirmation to ensure that no QUIC streams are
5911 // created, and to ensure that the TCP job does not wait for the QUIC
5912 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:435913 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5914 false);
Ryan Hamilton75f197262017-08-17 14:00:075915
Ryan Hamilton9835e662018-08-02 05:36:275916 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5918 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265919 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton75f197262017-08-17 14:00:075920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5921 // Allow the TCP job to fail.
5922 base::RunLoop().RunUntilIdle();
5923 // Now let the QUIC job fail.
5924 mock_quic_data.Resume();
5925 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5926 ExpectQuicAlternateProtocolMapping();
5927 NetErrorDetails details;
5928 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525929 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075930}
5931
[email protected]1e960032013-12-20 19:00:205932TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455933 // Alternate-protocol job
5934 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025935 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455936 };
Ryan Sleevib8d7ea02018-05-07 20:01:015937 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455938 socket_factory_.AddSocketDataProvider(&quic_data);
5939
[email protected]c92c1b52014-05-31 04:16:065940 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015941 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065942 socket_factory_.AddSocketDataProvider(&quic_data2);
5943
[email protected]4d283b32013-10-17 12:57:275944 // Final job that will proceed when the QUIC job fails.
5945 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025946 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5947 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5948 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275949
Ryan Sleevib8d7ea02018-05-07 20:01:015950 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275951 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565952 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275953
rch3f4b8452016-02-23 16:59:325954 CreateSession();
[email protected]77c6c162013-08-17 02:57:455955
Ryan Hamilton9835e662018-08-02 05:36:275956 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455957
[email protected]4d283b32013-10-17 12:57:275958 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455959
5960 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275961
rch37de576c2015-05-17 20:28:175962 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5963 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455964}
5965
Matt Menkeb32ba5122019-09-10 19:17:055966TEST_P(QuicNetworkTransactionTest,
5967 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
5968 base::test::ScopedFeatureList feature_list;
5969 feature_list.InitWithFeatures(
5970 // enabled_features
5971 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5972 features::kPartitionConnectionsByNetworkIsolationKey},
5973 // disabled_features
5974 {});
5975 // Since HttpServerProperties caches the feature value, have to create a new
5976 // one.
5977 http_server_properties_ = std::make_unique<HttpServerProperties>();
5978
Matt Menke4807a9a2020-11-21 00:14:415979 const SchemefulSite kSite1(GURL("https://foo.test/"));
5980 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
5981 const SchemefulSite kSite2(GURL("https://bar.test/"));
5982 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:055983
5984 // Alternate-protocol job
5985 MockRead quic_reads[] = {
5986 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5987 };
5988 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5989 socket_factory_.AddSocketDataProvider(&quic_data);
5990
5991 // Second Alternate-protocol job which will race with the TCP job.
5992 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
5993 socket_factory_.AddSocketDataProvider(&quic_data2);
5994
5995 // Final job that will proceed when the QUIC job fails.
5996 MockRead http_reads[] = {
5997 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5998 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5999 MockRead(ASYNC, OK)};
6000
6001 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
6002 socket_factory_.AddSocketDataProvider(&http_data);
6003 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6004
6005 CreateSession();
6006
6007 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6008 kNetworkIsolationKey1);
6009 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6010 kNetworkIsolationKey2);
6011
6012 request_.network_isolation_key = kNetworkIsolationKey1;
6013 SendRequestAndExpectHttpResponse("hello from http");
6014 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6015 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
6016
6017 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6018 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6019
6020 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
6021 AddHttpDataAndRunRequest();
6022 // Requests using other NetworkIsolationKeys can still use QUIC.
6023 request_.network_isolation_key = kNetworkIsolationKey2;
6024 AddQuicDataAndRunRequest();
6025
6026 // The last two requests should not have changed the alternative service
6027 // mappings.
6028 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6029 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6030}
6031
[email protected]eb71ab62014-05-23 07:57:536032TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:336033 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:016034 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:496035 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:336036 socket_factory_.AddSocketDataProvider(&quic_data);
6037
6038 // Main job which will succeed even though the alternate job fails.
6039 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026040 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6041 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6042 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:336043
Ryan Sleevib8d7ea02018-05-07 20:01:016044 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:336045 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566046 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:336047
rch3f4b8452016-02-23 16:59:326048 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276049 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:336050 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:536051
6052 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:336053}
6054
[email protected]4fee9672014-01-08 14:47:156055TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltona51800a2022-02-12 19:34:356056 if (version_.AlpnDeferToRFCv1()) {
6057 // These versions currently do not support Alt-Svc.
6058 return;
6059 }
Ryan Hamiltonabad59e2019-06-06 04:02:596060 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:166061 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:176062 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:046063 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:156064
6065 // When the QUIC connection fails, we will try the request again over HTTP.
6066 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:456067 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:566068 MockRead("hello world"),
6069 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6070 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:156071
Ryan Sleevib8d7ea02018-05-07 20:01:016072 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:156073 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566074 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:156075
6076 // In order for a new QUIC session to be established via alternate-protocol
6077 // without racing an HTTP connection, we need the host resolution to happen
6078 // synchronously.
6079 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:296080 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:566081 "");
[email protected]4fee9672014-01-08 14:47:156082
rch3f4b8452016-02-23 16:59:326083 CreateSession();
David Schinazic8281052019-01-24 06:14:176084 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
6085 AddQuicAlternateProtocolMapping(
6086 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:156087 SendRequestAndExpectHttpResponse("hello world");
6088}
6089
tbansalc3308d72016-08-27 10:25:046090TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltona51800a2022-02-12 19:34:356091 if (version_.AlpnDeferToRFCv1()) {
6092 // These versions currently do not support Alt-Svc.
6093 return;
6094 }
Ryan Hamiltonabad59e2019-06-06 04:02:596095 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:166096 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:176097 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:336098 mock_quic_data.AddWrite(
6099 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6100 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
6101 true, GetRequestHeaders("GET", "https", "/")));
Renjie Tangcd594f32020-07-11 20:18:346102 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1));
tbansalc3308d72016-08-27 10:25:046103 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6104
6105 // When the QUIC connection fails, we will try the request again over HTTP.
6106 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:456107 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
tbansalc3308d72016-08-27 10:25:046108 MockRead("hello world"),
6109 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6110 MockRead(ASYNC, OK)};
6111
Ryan Sleevib8d7ea02018-05-07 20:01:016112 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:046113 socket_factory_.AddSocketDataProvider(&http_data);
6114 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6115
6116 TestProxyDelegate test_proxy_delegate;
6117 const HostPortPair host_port_pair("myproxy.org", 443);
tbansalc3308d72016-08-27 10:25:046118
Nicolas Arciniegad2013f92020-02-07 23:00:566119 proxy_resolution_service_ =
6120 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Matt Menke7bc4def2020-07-29 20:54:516121 "QUIC myproxy.org:443; HTTPS myproxy.org:443",
6122 TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526123 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046124 request_.url = GURL("http://mail.example.org/");
6125
6126 // In order for a new QUIC session to be established via alternate-protocol
6127 // without racing an HTTP connection, we need the host resolution to happen
6128 // synchronously.
6129 host_resolver_.set_synchronous_mode(true);
6130 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:046131
6132 CreateSession();
David Schinazic8281052019-01-24 06:14:176133 crypto_client_stream_factory_.set_handshake_mode(
6134 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:046135 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596136 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166137 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046138}
6139
bnc508835902015-05-12 20:10:296140TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
Zhongyi Shi1c022d22020-03-20 19:00:166141 client_maker_->set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386142 EXPECT_FALSE(
6143 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:596144 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236145 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256146 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236147 mock_quic_data.AddWrite(SYNCHRONOUS,
6148 ConstructInitialSettingsPacket(packet_num++));
6149 }
rch5cb522462017-04-25 20:18:366150 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236151 SYNCHRONOUS,
6152 ConstructClientRequestHeadersPacket(
6153 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6154 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436155 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336156 ASYNC, ConstructServerResponseHeadersPacket(
6157 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286158 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336159 mock_quic_data.AddRead(
6160 ASYNC, ConstructServerDataPacket(
6161 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526162 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:236163 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346164 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:506165 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296166 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6167
bncb07c05532015-05-14 19:07:206168 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096169 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326170 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276171 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296172 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386173 EXPECT_TRUE(
6174 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296175}
6176
rtenneti56977812016-01-15 19:26:566177TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Victor Vasilieva1e66d72019-12-05 17:55:386178 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576179 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566180
Renjie Tangaadb84b2019-08-31 01:00:236181 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:256182 if (!VersionUsesHttp3(version_.transport_version))
David Schinazi395918c2021-02-05 18:56:216183 mock_quic_data.AddRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED);
Renjie Tangaadb84b2019-08-31 01:00:236184 else
6185 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6186 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6187 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6188
6189 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6190 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
6191 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:016192 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:236193 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:566194
rtennetib8e80fb2016-05-16 00:12:096195 // The non-alternate protocol job needs to hang in order to guarantee that
6196 // the alternate-protocol job will "win".
6197 AddHangingNonAlternateProtocolSocketData();
6198
rtenneti56977812016-01-15 19:26:566199 CreateSession();
6200 request_.method = "POST";
6201 ChunkedUploadDataStream upload_data(0);
6202 upload_data.AppendData("1", 1, true);
6203
6204 request_.upload_data_stream = &upload_data;
6205
bnc691fda62016-08-12 00:43:166206 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566207 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266208 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:016209 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566210 EXPECT_NE(OK, callback.WaitForResult());
6211}
6212
rche11300ef2016-09-02 01:44:286213TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Victor Vasilieva1e66d72019-12-05 17:55:386214 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286215 ScopedMockNetworkChangeNotifier network_change_notifier;
6216 MockNetworkChangeNotifier* mock_ncn =
6217 network_change_notifier.mock_network_change_notifier();
6218 mock_ncn->ForceNetworkHandlesSupported();
6219 mock_ncn->SetConnectedNetworksList(
6220 {kDefaultNetworkForTests, kNewNetworkForTests});
6221
Victor Vasilieva1e66d72019-12-05 17:55:386222 context_.params()->origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286223 HostPortPair::FromString("mail.example.org:443"));
Victor Vasilieva1e66d72019-12-05 17:55:386224 context_.params()->migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286225
Ryan Hamiltonabad59e2019-06-06 04:02:596226 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286227 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236228 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256229 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236230 socket_data.AddWrite(SYNCHRONOUS,
6231 ConstructInitialSettingsPacket(packet_num++));
6232 }
Fan Yang32c5a112018-12-10 20:06:336233 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236234 SYNCHRONOUS,
6235 ConstructClientRequestHeadersPacket(
6236 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6237 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:286238 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6239 socket_data.AddSocketDataToFactory(&socket_factory_);
6240
Ryan Hamiltonabad59e2019-06-06 04:02:596241 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286242 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6243 socket_data2.AddSocketDataToFactory(&socket_factory_);
6244
6245 // The non-alternate protocol job needs to hang in order to guarantee that
6246 // the alternate-protocol job will "win".
6247 AddHangingNonAlternateProtocolSocketData();
6248
6249 CreateSession();
6250 request_.method = "POST";
6251 ChunkedUploadDataStream upload_data(0);
6252
6253 request_.upload_data_stream = &upload_data;
6254
Tsuyoshi Horof8861cb2022-07-05 23:50:206255 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
6256 session_.get());
rche11300ef2016-09-02 01:44:286257 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266258 int rv = trans->Start(&request_, callback.callback(), net_log_with_source_);
rche11300ef2016-09-02 01:44:286259 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6260
6261 base::RunLoop().RunUntilIdle();
6262 upload_data.AppendData("1", 1, true);
6263 base::RunLoop().RunUntilIdle();
6264
6265 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506266 trans.reset();
rche11300ef2016-09-02 01:44:286267 session_.reset();
6268}
6269
Ryan Hamilton4b3574532017-10-30 20:17:256270TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386271 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256272 HostPortPair::FromString("mail.example.org:443"));
6273
Ryan Hamiltonabad59e2019-06-06 04:02:596274 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236275 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256276 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236277 socket_data.AddWrite(SYNCHRONOUS,
6278 ConstructInitialSettingsPacket(packet_num++));
6279 }
Ryan Hamilton4b3574532017-10-30 20:17:256280 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336281 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236282 SYNCHRONOUS,
6283 ConstructClientRequestHeadersPacket(
6284 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6285 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436286 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336287 ASYNC, ConstructServerResponseHeadersPacket(
6288 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286289 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336290 socket_data.AddRead(
6291 ASYNC, ConstructServerDataPacket(
6292 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526293 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:236294 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346295 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256296 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi1c022d22020-03-20 19:00:166297 socket_data.AddWrite(SYNCHRONOUS,
6298 client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:346299 packet_num++, false, 2, 1,
Zhongyi Shi1c022d22020-03-20 19:00:166300 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256301
6302 socket_data.AddSocketDataToFactory(&socket_factory_);
6303
6304 CreateSession();
6305
6306 SendRequestAndExpectQuicResponse("hello!");
6307 session_.reset();
6308}
6309
6310TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386311 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256312 HostPortPair::FromString("mail.example.org:443"));
6313
Ryan Hamiltonabad59e2019-06-06 04:02:596314 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236315 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256316 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236317 socket_data.AddWrite(SYNCHRONOUS,
6318 ConstructInitialSettingsPacket(packet_num++));
6319 }
Ryan Hamilton4b3574532017-10-30 20:17:256320 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336321 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236322 SYNCHRONOUS,
6323 ConstructClientRequestHeadersPacket(
6324 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6325 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436326 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336327 ASYNC, ConstructServerResponseHeadersPacket(
6328 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286329 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336330 socket_data.AddRead(
6331 ASYNC, ConstructServerDataPacket(
6332 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526333 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:236334 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346335 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256336 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi1c022d22020-03-20 19:00:166337 socket_data.AddWrite(SYNCHRONOUS,
6338 client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:346339 packet_num++, false, 2, 1,
Zhongyi Shi1c022d22020-03-20 19:00:166340 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256341
6342 socket_data.AddSocketDataToFactory(&socket_factory_);
6343
6344 CreateSession();
6345
6346 SendRequestAndExpectQuicResponse("hello!");
6347 session_.reset();
6348}
6349
Ryan Hamilton9edcf1a2017-11-22 05:55:176350TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386351 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6352 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256353 HostPortPair::FromString("mail.example.org:443"));
6354
Ryan Hamiltonabad59e2019-06-06 04:02:596355 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256356 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256357 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236358 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176359 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256360 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6361 }
6362 socket_data.AddSocketDataToFactory(&socket_factory_);
6363
6364 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176365 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176366 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6367 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256368
Victor Vasiliev7752898d2019-11-14 21:30:226369 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256370 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6371 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266372 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton4b3574532017-10-30 20:17:256373 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176374 while (!callback.have_result()) {
6375 base::RunLoop().RunUntilIdle();
6376 quic_task_runner_->RunUntilIdle();
6377 }
6378 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256379 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176380 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6381 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6382 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226383 EXPECT_TRUE(context_.clock()->Now() - start >
6384 quic::QuicTime::Delta::FromSeconds(4));
6385 EXPECT_TRUE(context_.clock()->Now() - start <
6386 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256387}
6388
Ryan Hamilton9edcf1a2017-11-22 05:55:176389TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386390 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6391 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256392 HostPortPair::FromString("mail.example.org:443"));
6393
Ryan Hamiltonabad59e2019-06-06 04:02:596394 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256395 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256396 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236397 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176398 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256399 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6400 }
6401 socket_data.AddSocketDataToFactory(&socket_factory_);
6402
6403 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176404 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176405 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6406 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256407
Victor Vasiliev7752898d2019-11-14 21:30:226408 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256409 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6410 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266411 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton4b3574532017-10-30 20:17:256412 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176413 while (!callback.have_result()) {
6414 base::RunLoop().RunUntilIdle();
6415 quic_task_runner_->RunUntilIdle();
6416 }
6417 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256418 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176419 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6420 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6421 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226422 EXPECT_TRUE(context_.clock()->Now() - start >
6423 quic::QuicTime::Delta::FromSeconds(4));
6424 EXPECT_TRUE(context_.clock()->Now() - start <
6425 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256426}
6427
Cherie Shi7596de632018-02-22 07:28:186428TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Victor Vasilieva1e66d72019-12-05 17:55:386429 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6430 context_.params()->origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186431 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev62c09dc2020-11-06 18:18:296432 const std::string error_details = base::StrCat(
6433 {"Write failed with error: ", base::NumberToString(ERR_MSG_TOO_BIG), " (",
6434 strerror(ERR_MSG_TOO_BIG), ")"});
Cherie Shi7596de632018-02-22 07:28:186435
Ryan Hamiltonabad59e2019-06-06 04:02:596436 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186437 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236438 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256439 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236440 socket_data.AddWrite(SYNCHRONOUS,
6441 ConstructInitialSettingsPacket(packet_num++));
6442 }
Cherie Shi7596de632018-02-22 07:28:186443 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6444 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526445 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236446 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:166447 client_maker_->MakeConnectionClosePacket(
Renjie Tangaadb84b2019-08-31 01:00:236448 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186449 socket_data.AddSocketDataToFactory(&socket_factory_);
6450
6451 CreateSession();
6452
6453 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6454 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266455 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Cherie Shi7596de632018-02-22 07:28:186456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6457 base::RunLoop().RunUntilIdle();
6458 ASSERT_TRUE(callback.have_result());
6459 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6460 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6461 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6462}
6463
ckrasic769733c2016-06-30 00:42:136464// Adds coverage to catch regression such as https://crbug.com/622043
6465TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Victor Vasiliev638956df2021-04-05 16:41:406466 if (VersionUsesHttp3(version_.transport_version)) {
6467 return;
6468 }
Victor Vasilieva1e66d72019-12-05 17:55:386469 context_.params()->origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136470 HostPortPair::FromString("mail.example.org:443"));
6471
Ryan Hamiltonabad59e2019-06-06 04:02:596472 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236473 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436474 mock_quic_data.AddWrite(
6475 SYNCHRONOUS,
6476 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336477 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026478 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436479 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:476480 ASYNC, ConstructServerPushPromisePacket(
6481 1, GetNthClientInitiatedBidirectionalStreamId(0),
6482 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6483 GetRequestHeaders("GET", "https", "/pushed.jpg")));
Haoyue Wang9d70d65c2020-05-29 22:45:346484 const bool should_send_priority_packet =
6485 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:346486 !VersionUsesHttp3(version_.transport_version);
6487 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346488 mock_quic_data.AddWrite(
6489 SYNCHRONOUS,
6490 ConstructClientAckAndPriorityPacket(
6491 client_packet_number++, false,
6492 /*largest_received=*/1, /*smallest_received=*/1,
6493 GetNthServerInitiatedUnidirectionalStreamId(0),
6494 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576495 }
Zhongyi Shi32f2fd02018-04-16 18:23:436496 mock_quic_data.AddRead(
6497 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336498 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286499 GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:006500 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346501 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346502 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346503 }
Zhongyi Shi32f2fd02018-04-16 18:23:436504 mock_quic_data.AddRead(
6505 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336506 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286507 false, GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:006508 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346509 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346510 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346511 }
Zhongyi Shi32f2fd02018-04-16 18:23:436512 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336513 ASYNC, ConstructServerDataPacket(
6514 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526515 ConstructDataFrame("hello!")));
Fan Yang32d79502020-06-24 22:36:006516 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346517 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346518 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:346519 }
Zhongyi Shi32f2fd02018-04-16 18:23:436520 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336521 ASYNC, ConstructServerDataPacket(
6522 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526523 ConstructDataFrame("and hello!")));
Fan Yang32d79502020-06-24 22:36:006524 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346525 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346526 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:346527 }
Renjie Tangee921d12020-02-06 00:41:496528 if (!VersionUsesHttp3(version_.transport_version)) {
6529 mock_quic_data.AddWrite(SYNCHRONOUS,
6530 ConstructClientAckAndRstPacket(
6531 client_packet_number++,
6532 GetNthServerInitiatedUnidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:346533 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
Renjie Tangee921d12020-02-06 00:41:496534 } else {
6535 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:166536 SYNCHRONOUS, client_maker_->MakeAckAndPriorityUpdatePacket(
Renjie Tangcd594f32020-07-11 20:18:346537 client_packet_number++, true, 5, 5, 3,
Renjie Tangee921d12020-02-06 00:41:496538 GetNthServerInitiatedUnidirectionalStreamId(0)));
6539 }
ckrasic769733c2016-06-30 00:42:136540 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216541 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
ckrasic769733c2016-06-30 00:42:136542 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6543
6544 // The non-alternate protocol job needs to hang in order to guarantee that
6545 // the alternate-protocol job will "win".
6546 AddHangingNonAlternateProtocolSocketData();
6547
6548 CreateSession();
6549
6550 // PUSH_PROMISE handling in the http layer gets exercised here.
6551 SendRequestAndExpectQuicResponse("hello!");
6552
6553 request_.url = GURL("https://mail.example.org/pushed.jpg");
6554 SendRequestAndExpectQuicResponse("and hello!");
6555
6556 // Check that the NetLog was filled reasonably.
Matt Reichhoff0049a0b72021-10-20 20:44:266557 auto entries = net_log_observer_.GetEntries();
ckrasic769733c2016-06-30 00:42:136558 EXPECT_LT(0u, entries.size());
6559
6560 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6561 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006562 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6563 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136564 EXPECT_LT(0, pos);
6565}
6566
Matt Menked804aaf2020-07-21 21:25:486567// Checks that if the same resource is pushed using two different
6568// NetworkIsolationKeys, both pushed resources are tracked independently, and
6569// NetworkIsolationKeys are respected.
6570TEST_P(QuicNetworkTransactionTest, QuicServerPushRespectsNetworkIsolationKey) {
Victor Vasiliev638956df2021-04-05 16:41:406571 if (VersionUsesHttp3(version_.transport_version)) {
6572 return;
6573 }
Matt Menked804aaf2020-07-21 21:25:486574 base::test::ScopedFeatureList feature_list;
6575 feature_list.InitAndEnableFeature(
6576 features::kPartitionConnectionsByNetworkIsolationKey);
Matt Menked804aaf2020-07-21 21:25:486577 context_.params()->origins_to_force_quic_on.insert(
6578 HostPortPair::FromString("mail.example.org:443"));
6579
6580 MockQuicData mock_quic_data1(version_);
6581 uint64_t client_packet_number1 = 1;
Matt Menked804aaf2020-07-21 21:25:486582 mock_quic_data1.AddWrite(
6583 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6584 client_packet_number1++,
6585 GetNthClientInitiatedBidirectionalStreamId(0), true,
6586 true, GetRequestHeaders("GET", "https", "/")));
6587 mock_quic_data1.AddRead(
6588 ASYNC, ConstructServerPushPromisePacket(
6589 1, GetNthClientInitiatedBidirectionalStreamId(0),
6590 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6591 GetRequestHeaders("GET", "https", "/pushed.jpg")));
6592 const bool should_send_priority_packet =
6593 client_headers_include_h2_stream_dependency_ &&
6594 !VersionUsesHttp3(version_.transport_version);
6595 if (should_send_priority_packet) {
6596 mock_quic_data1.AddWrite(
6597 SYNCHRONOUS,
6598 ConstructClientAckAndPriorityPacket(
6599 client_packet_number1++, false,
6600 /*largest_received=*/1, /*smallest_received=*/1,
6601 GetNthServerInitiatedUnidirectionalStreamId(0),
6602 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
6603 }
6604 mock_quic_data1.AddRead(
6605 ASYNC, ConstructServerResponseHeadersPacket(
6606 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286607 GetResponseHeaders("200")));
Matt Menked804aaf2020-07-21 21:25:486608 if (!should_send_priority_packet) {
6609 mock_quic_data1.AddWrite(
6610 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 2, 1));
6611 }
6612 mock_quic_data1.AddRead(
6613 ASYNC, ConstructServerResponseHeadersPacket(
6614 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286615 false, GetResponseHeaders("200")));
Matt Menked804aaf2020-07-21 21:25:486616 if (should_send_priority_packet) {
6617 mock_quic_data1.AddWrite(
6618 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 3, 1));
6619 }
Matt Menked804aaf2020-07-21 21:25:486620 mock_quic_data1.AddRead(
6621 ASYNC, ConstructServerDataPacket(
6622 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526623 ConstructDataFrame("hello1")));
Matt Menked804aaf2020-07-21 21:25:486624 if (!should_send_priority_packet) {
6625 mock_quic_data1.AddWrite(
6626 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 4, 3));
6627 }
Matt Menked804aaf2020-07-21 21:25:486628 mock_quic_data1.AddRead(
6629 ASYNC, ConstructServerDataPacket(
6630 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526631 ConstructDataFrame("and hello1")));
Matt Menked804aaf2020-07-21 21:25:486632 if (should_send_priority_packet) {
6633 mock_quic_data1.AddWrite(
6634 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 5, 3));
6635 }
6636 if (!VersionUsesHttp3(version_.transport_version)) {
6637 mock_quic_data1.AddWrite(SYNCHRONOUS,
6638 ConstructClientAckAndRstPacket(
6639 client_packet_number1++,
6640 GetNthServerInitiatedUnidirectionalStreamId(0),
6641 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
6642 } else {
6643 mock_quic_data1.AddWrite(
6644 SYNCHRONOUS, client_maker_->MakeAckAndPriorityUpdatePacket(
6645 client_packet_number1++, true, 5, 5, 3,
6646 GetNthServerInitiatedUnidirectionalStreamId(0)));
6647 }
6648 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6649 mock_quic_data1.AddRead(ASYNC, 0); // EOF
6650 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
6651
6652 QuicTestPacketMaker client_maker2(
6653 version_,
6654 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
6655 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
6656 client_headers_include_h2_stream_dependency_);
Matt Menked804aaf2020-07-21 21:25:486657 QuicTestPacketMaker server_maker2(
6658 version_,
6659 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
6660 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
6661 false);
6662 MockQuicData mock_quic_data2(version_);
6663 uint64_t client_packet_number2 = 1;
6664 if (VersionUsesHttp3(version_.transport_version)) {
6665 mock_quic_data2.AddWrite(
6666 SYNCHRONOUS,
6667 client_maker2.MakeInitialSettingsPacket(client_packet_number2++));
6668 }
6669 mock_quic_data2.AddWrite(
6670 SYNCHRONOUS,
6671 client_maker2.MakeRequestHeadersPacket(
6672 client_packet_number2++,
6673 GetNthClientInitiatedBidirectionalStreamId(0), true, true,
6674 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
6675 GetRequestHeaders("GET", "https", "/"), 0, nullptr));
6676 mock_quic_data2.AddRead(
6677 ASYNC, server_maker2.MakePushPromisePacket(
6678 1, GetNthClientInitiatedBidirectionalStreamId(0),
6679 GetNthServerInitiatedUnidirectionalStreamId(0), false, false,
6680 GetRequestHeaders("GET", "https", "/pushed.jpg"), nullptr));
6681 if (should_send_priority_packet) {
6682 mock_quic_data2.AddWrite(
6683 SYNCHRONOUS,
6684 client_maker2.MakeAckAndPriorityPacket(
6685 client_packet_number2++, false,
6686 /*largest_received=*/1, /*smallest_received=*/1,
6687 GetNthServerInitiatedUnidirectionalStreamId(0),
6688 GetNthClientInitiatedBidirectionalStreamId(0),
6689 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)));
6690 }
6691 mock_quic_data2.AddRead(
6692 ASYNC, server_maker2.MakeResponseHeadersPacket(
6693 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286694 GetResponseHeaders("200"), nullptr));
Matt Menked804aaf2020-07-21 21:25:486695 if (!should_send_priority_packet) {
6696 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6697 client_packet_number2++, 2, 1));
6698 }
6699 mock_quic_data2.AddRead(
6700 ASYNC, server_maker2.MakeResponseHeadersPacket(
6701 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286702 false, GetResponseHeaders("200"), nullptr));
Matt Menked804aaf2020-07-21 21:25:486703 if (should_send_priority_packet) {
6704 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6705 client_packet_number2++, 3, 1));
6706 }
Matt Menked804aaf2020-07-21 21:25:486707 mock_quic_data2.AddRead(
6708 ASYNC, server_maker2.MakeDataPacket(
6709 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526710 ConstructDataFrame("hello2")));
Matt Menked804aaf2020-07-21 21:25:486711 if (!should_send_priority_packet) {
6712 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6713 client_packet_number2++, 4, 3));
6714 }
Matt Menked804aaf2020-07-21 21:25:486715 mock_quic_data2.AddRead(
6716 ASYNC, server_maker2.MakeDataPacket(
6717 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526718 ConstructDataFrame("and hello2")));
Matt Menked804aaf2020-07-21 21:25:486719 if (should_send_priority_packet) {
6720 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6721 client_packet_number2++, 5, 3));
6722 }
6723 if (!VersionUsesHttp3(version_.transport_version)) {
6724 mock_quic_data2.AddWrite(SYNCHRONOUS,
6725 client_maker2.MakeAckAndRstPacket(
6726 client_packet_number2++, false,
6727 GetNthServerInitiatedUnidirectionalStreamId(0),
6728 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
6729 } else {
6730 mock_quic_data2.AddWrite(
6731 SYNCHRONOUS, client_maker2.MakeAckAndPriorityUpdatePacket(
6732 client_packet_number2++, true, 5, 5, 3,
6733 GetNthServerInitiatedUnidirectionalStreamId(0)));
6734 }
6735 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6736 mock_quic_data2.AddRead(ASYNC, 0); // EOF
6737 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
6738
6739 scoped_refptr<X509Certificate> cert(
6740 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
6741 verify_details_.cert_verify_result.verified_cert = cert;
6742 verify_details_.cert_verify_result.is_issued_by_known_root = true;
6743 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
6744
6745 // The non-alternate protocol jobs need to hang in order to guarantee that
6746 // the alternate-protocol job will "win". Use "AddTcpSocketDataProvider()", as
6747 // the connection requests may or may not actually make it to the socket
6748 // factory, there may or may not be a TCP connection made in between the two
6749 // QUIC connection attempts.
6750 StaticSocketDataProvider hanging_data1;
6751 hanging_data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
6752 socket_factory_.AddTcpSocketDataProvider(&hanging_data1);
6753 StaticSocketDataProvider hanging_data2;
6754 hanging_data2.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
6755 socket_factory_.AddTcpSocketDataProvider(&hanging_data2);
6756
6757 CreateSession();
6758
6759 NetworkIsolationKey network_isolation_key1 =
6760 NetworkIsolationKey::CreateTransient();
6761 NetworkIsolationKey network_isolation_key2 =
6762 NetworkIsolationKey::CreateTransient();
6763
6764 // Creates the first QUIC session, and triggers the first push.
6765 request_.network_isolation_key = network_isolation_key1;
6766 SendRequestAndExpectQuicResponse("hello1");
6767
6768 // Use a different NIK, which creates another QUIC session, triggering a
6769 // second push,
6770 request_.network_isolation_key = network_isolation_key2;
6771 SendRequestAndExpectQuicResponse("hello2");
6772
6773 // Use the second NIK again, should receive the push body from the second
6774 // session.
6775 request_.url = GURL("https://mail.example.org/pushed.jpg");
6776 SendRequestAndExpectQuicResponse("and hello2");
6777
6778 // Use the first NIK again, should receive the push body from the first
6779 // session.
6780 request_.network_isolation_key = network_isolation_key1;
6781 SendRequestAndExpectQuicResponse("and hello1");
6782}
6783
rch56ec40a2017-06-23 14:48:446784// Regression test for http://crbug.com/719461 in which a promised stream
6785// is closed before the pushed headers arrive, but after the connection
6786// is closed and before the callbacks are executed.
6787TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Victor Vasiliev638956df2021-04-05 16:41:406788 if (VersionUsesHttp3(version_.transport_version)) {
6789 return;
6790 }
Victor Vasilieva1e66d72019-12-05 17:55:386791 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6792 context_.params()->origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446793 HostPortPair::FromString("mail.example.org:443"));
6794
Ryan Hamiltonabad59e2019-06-06 04:02:596795 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236796 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446797 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436798 mock_quic_data.AddWrite(
6799 SYNCHRONOUS,
6800 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336801 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026802 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446803 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436804 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:476805 ASYNC, ConstructServerPushPromisePacket(
6806 1, GetNthClientInitiatedBidirectionalStreamId(0),
6807 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6808 GetRequestHeaders("GET", "https", "/pushed.jpg")));
Haoyue Wang9d70d65c2020-05-29 22:45:346809 const bool should_send_priority_packet =
6810 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:346811 !VersionUsesHttp3(version_.transport_version);
6812 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346813 mock_quic_data.AddWrite(
6814 SYNCHRONOUS,
6815 ConstructClientAckAndPriorityPacket(
6816 client_packet_number++, false,
6817 /*largest_received=*/1, /*smallest_received=*/1,
6818 GetNthServerInitiatedUnidirectionalStreamId(0),
6819 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576820 }
rch56ec40a2017-06-23 14:48:446821 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436822 mock_quic_data.AddRead(
6823 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336824 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286825 GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:006826 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346827 // Client ACKs the response headers.
6828 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346829 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346830 }
rch56ec40a2017-06-23 14:48:446831 // Response body for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436832 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336833 ASYNC, ConstructServerDataPacket(
6834 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526835 ConstructDataFrame("hello!")));
Fan Yang32d79502020-06-24 22:36:006836 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346837 // Client ACKs the response headers.
6838 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346839 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346840 }
rch56ec40a2017-06-23 14:48:446841 // Write error for the third request.
6842 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6843 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216844 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rch56ec40a2017-06-23 14:48:446845 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6846
6847 CreateSession();
6848
6849 // Send a request which triggers a push promise from the server.
6850 SendRequestAndExpectQuicResponse("hello!");
6851
6852 // Start a push transaction that will be cancelled after the connection
6853 // is closed, but before the callback is executed.
6854 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196855 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446856 session_.get());
6857 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:266858 int rv = trans2->Start(&request_, callback2.callback(), net_log_with_source_);
rch56ec40a2017-06-23 14:48:446859 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6860 base::RunLoop().RunUntilIdle();
6861
6862 // Cause the connection to close on a write error.
6863 HttpRequestInfo request3;
6864 request3.method = "GET";
6865 request3.url = GURL("https://mail.example.org/");
6866 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106867 request3.traffic_annotation =
6868 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446869 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6870 TestCompletionCallback callback3;
Matt Reichhoff0049a0b72021-10-20 20:44:266871 EXPECT_THAT(
6872 trans3.Start(&request3, callback3.callback(), net_log_with_source_),
6873 IsError(ERR_IO_PENDING));
rch56ec40a2017-06-23 14:48:446874
6875 base::RunLoop().RunUntilIdle();
6876
6877 // When |trans2| is destroyed, the underlying stream will be closed.
6878 EXPECT_FALSE(callback2.have_result());
6879 trans2 = nullptr;
6880
6881 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6882}
6883
ckrasicda193a82016-07-09 00:39:366884TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Victor Vasilieva1e66d72019-12-05 17:55:386885 context_.params()->origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366886 HostPortPair::FromString("mail.example.org:443"));
6887
Ryan Hamiltonabad59e2019-06-06 04:02:596888 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:366889
Renjief49758b2019-01-11 23:32:416890 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:256891 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236892 mock_quic_data.AddWrite(
6893 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
6894 }
ckrasicda193a82016-07-09 00:39:366895
Bence Béky319388a882020-09-23 18:42:526896 mock_quic_data.AddWrite(
6897 SYNCHRONOUS,
6898 ConstructClientRequestHeadersAndDataFramesPacket(
6899 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6900 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
6901 0, nullptr, {ConstructDataFrame("1")}));
ckrasicda193a82016-07-09 00:39:366902
Zhongyi Shi32f2fd02018-04-16 18:23:436903 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336904 ASYNC, ConstructServerResponseHeadersPacket(
6905 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286906 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336907
6908 mock_quic_data.AddRead(
6909 ASYNC, ConstructServerDataPacket(
6910 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526911 ConstructDataFrame("hello!")));
ckrasicda193a82016-07-09 00:39:366912
Renjie Tangcd594f32020-07-11 20:18:346913 mock_quic_data.AddWrite(SYNCHRONOUS,
6914 ConstructClientAckPacket(write_packet_index++, 2, 1));
ckrasicda193a82016-07-09 00:39:366915
6916 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216917 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
ckrasicda193a82016-07-09 00:39:366918 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6919
6920 // The non-alternate protocol job needs to hang in order to guarantee that
6921 // the alternate-protocol job will "win".
6922 AddHangingNonAlternateProtocolSocketData();
6923
6924 CreateSession();
6925 request_.method = "POST";
6926 ChunkedUploadDataStream upload_data(0);
6927 upload_data.AppendData("1", 1, true);
6928
6929 request_.upload_data_stream = &upload_data;
6930
6931 SendRequestAndExpectQuicResponse("hello!");
6932}
6933
Ryan Sleevia9d6aa62019-07-26 13:32:186934TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
Ryan Hamiltona51800a2022-02-12 19:34:356935 if (version_.AlpnDeferToRFCv1()) {
6936 // These versions currently do not support Alt-Svc.
6937 return;
6938 }
Ryan Sleevia9d6aa62019-07-26 13:32:186939 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:206940
6941 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:456942 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yixin Wang10f477ed2017-11-21 04:20:206943 MockRead("hello world"),
6944 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6945 MockRead(ASYNC, OK)};
6946
Ryan Sleevib8d7ea02018-05-07 20:01:016947 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206948 socket_factory_.AddSocketDataProvider(&http_data);
6949 AddCertificate(&ssl_data_);
6950 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6951
Ryan Hamiltonabad59e2019-06-06 04:02:596952 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236953 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256954 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236955 mock_quic_data.AddWrite(SYNCHRONOUS,
6956 ConstructInitialSettingsPacket(packet_num++));
6957 }
Yixin Wang10f477ed2017-11-21 04:20:206958 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236959 SYNCHRONOUS,
6960 ConstructClientRequestHeadersPacket(
6961 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6962 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436963 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336964 ASYNC, ConstructServerResponseHeadersPacket(
6965 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286966 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:336967 mock_quic_data.AddRead(
6968 ASYNC, ConstructServerDataPacket(
6969 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526970 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:236971 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346972 ConstructClientAckPacket(packet_num++, 2, 1));
Yixin Wang10f477ed2017-11-21 04:20:206973 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216974 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang10f477ed2017-11-21 04:20:206975
6976 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6977
6978 AddHangingNonAlternateProtocolSocketData();
6979 CreateSession();
6980
6981 SendRequestAndExpectHttpResponse("hello world");
6982 SendRequestAndExpectQuicResponse("hello!");
6983}
6984
Ryan Sleevia9d6aa62019-07-26 13:32:186985TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
Ryan Hamiltona51800a2022-02-12 19:34:356986 if (version_.AlpnDeferToRFCv1()) {
6987 // These versions currently do not support Alt-Svc.
6988 return;
6989 }
Ryan Sleevia9d6aa62019-07-26 13:32:186990 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:206991
6992 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:456993 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yixin Wang10f477ed2017-11-21 04:20:206994 MockRead("hello world"),
6995 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6996 MockRead(ASYNC, OK)};
6997
Ryan Sleevib8d7ea02018-05-07 20:01:016998 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206999 socket_factory_.AddSocketDataProvider(&http_data);
7000 AddCertificate(&ssl_data_);
7001 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7002 socket_factory_.AddSocketDataProvider(&http_data);
7003 AddCertificate(&ssl_data_);
7004 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7005
7006 AddHangingNonAlternateProtocolSocketData();
7007 CreateSession();
7008
7009 SendRequestAndExpectHttpResponse("hello world");
7010 SendRequestAndExpectHttpResponse("hello world");
7011}
7012
bnc359ed2a2016-04-29 20:43:457013class QuicNetworkTransactionWithDestinationTest
7014 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:017015 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:057016 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:457017 protected:
7018 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:557019 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:057020 client_headers_include_h2_stream_dependency_(
7021 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:567022 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:457023 destination_type_(GetParam().destination_type),
Tsuyoshi Horof8861cb2022-07-05 23:50:207024 ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()),
Nicolas Arciniegad2013f92020-02-07 23:00:567025 proxy_resolution_service_(
7026 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:117027 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Ryan Hamiltonf9a421f2020-01-31 21:09:527028 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:197029 FLAGS_quic_enable_http3_grease_randomness = false;
Ryan Hamiltonf9a421f2020-01-31 21:09:527030 }
bnc359ed2a2016-04-29 20:43:457031
7032 void SetUp() override {
7033 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557034 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457035
Matt Menke30a878c2021-07-20 22:25:097036 HttpNetworkSessionParams session_params;
mmenke6ddfbea2017-05-31 21:48:417037 session_params.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:387038 context_.params()->allow_remote_alt_svc = true;
7039 context_.params()->supported_versions = supported_versions_;
7040 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:057041 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:417042
Matt Menke30a878c2021-07-20 22:25:097043 HttpNetworkSessionContext session_context;
bnc359ed2a2016-04-29 20:43:457044
Victor Vasiliev7752898d2019-11-14 21:30:227045 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
bnc359ed2a2016-04-29 20:43:457046
7047 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277048 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:417049 session_context.quic_crypto_client_stream_factory =
7050 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:457051
Victor Vasiliev7752898d2019-11-14 21:30:227052 session_context.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:417053 session_context.client_socket_factory = &socket_factory_;
7054 session_context.host_resolver = &host_resolver_;
7055 session_context.cert_verifier = &cert_verifier_;
7056 session_context.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:417057 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
7058 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:457059 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:417060 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:597061 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:417062 session_context.http_auth_handler_factory = auth_handler_factory_.get();
7063 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:457064
Renjie Tang6ff9a9b2021-02-03 22:11:097065 session_ =
7066 std::make_unique<HttpNetworkSession>(session_params, session_context);
Matt Menkeb566c392019-09-11 23:22:437067 session_->quic_stream_factory()
7068 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:457069 }
7070
7071 void TearDown() override {
7072 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7073 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557074 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457075 PlatformTest::TearDown();
7076 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557077 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:407078 session_.reset();
bnc359ed2a2016-04-29 20:43:457079 }
7080
zhongyie537a002017-06-27 16:48:217081 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:457082 HostPortPair destination;
7083 switch (destination_type_) {
7084 case SAME_AS_FIRST:
7085 destination = HostPortPair(origin1_, 443);
7086 break;
7087 case SAME_AS_SECOND:
7088 destination = HostPortPair(origin2_, 443);
7089 break;
7090 case DIFFERENT:
7091 destination = HostPortPair(kDifferentHostname, 443);
7092 break;
7093 }
bnc3472afd2016-11-17 15:27:217094 AlternativeService alternative_service(kProtoQUIC, destination);
Peter Kastinge5a38ed2021-10-02 03:06:357095 base::Time expiration = base::Time::Now() + base::Days(1);
zhongyie537a002017-06-27 16:48:217096 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:077097 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
7098 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:457099 }
7100
Ryan Hamilton8d9ee76e2018-05-29 23:52:527101 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237102 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527103 quic::QuicStreamId stream_id,
7104 bool should_include_version,
7105 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527106 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137107 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457108 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Bence Béky4c325e52020-10-22 20:48:017109 spdy::Http2HeaderBlock headers(
Ryan Hamilton0239aac2018-05-19 00:03:137110 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027111 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457112 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027113 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:457114 }
7115
Ryan Hamilton8d9ee76e2018-05-29 23:52:527116 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237117 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527118 quic::QuicStreamId stream_id,
7119 bool should_include_version,
7120 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587121 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:027122 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:457123 }
7124
Ryan Hamilton8d9ee76e2018-05-29 23:52:527125 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237126 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527127 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527128 QuicTestPacketMaker* maker) {
Kenichi Ishibashif8634ab2021-03-16 23:41:287129 spdy::Http2HeaderBlock headers(maker->GetResponseHeaders("200"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027130 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
7131 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:457132 }
7133
Ryan Hamilton8d9ee76e2018-05-29 23:52:527134 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237135 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527136 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457137 QuicTestPacketMaker* maker) {
Bence Béky319388a882020-09-23 18:42:527138 return maker->MakeDataPacket(
7139 packet_number, stream_id, false, true,
7140 ConstructDataFrameForVersion("hello", version_));
bnc359ed2a2016-04-29 20:43:457141 }
7142
Ryan Hamilton8d9ee76e2018-05-29 23:52:527143 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237144 uint64_t packet_number,
7145 uint64_t largest_received,
7146 uint64_t smallest_received,
bnc359ed2a2016-04-29 20:43:457147 QuicTestPacketMaker* maker) {
7148 return maker->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:347149 smallest_received);
bnc359ed2a2016-04-29 20:43:457150 }
7151
Ryan Hamilton8d9ee76e2018-05-29 23:52:527152 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237153 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:377154 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027155 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:377156 }
7157
bnc359ed2a2016-04-29 20:43:457158 void AddRefusedSocketData() {
Tsuyoshi Horof8861cb2022-07-05 23:50:207159 auto refused_data = std::make_unique<StaticSocketDataProvider>();
bnc359ed2a2016-04-29 20:43:457160 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7161 refused_data->set_connect_data(refused_connect);
7162 socket_factory_.AddSocketDataProvider(refused_data.get());
7163 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7164 }
7165
7166 void AddHangingSocketData() {
Tsuyoshi Horof8861cb2022-07-05 23:50:207167 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
bnc359ed2a2016-04-29 20:43:457168 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7169 hanging_data->set_connect_data(hanging_connect);
7170 socket_factory_.AddSocketDataProvider(hanging_data.get());
7171 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7172 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7173 }
7174
7175 bool AllDataConsumed() {
7176 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7177 if (!socket_data_ptr->AllReadDataConsumed() ||
7178 !socket_data_ptr->AllWriteDataConsumed()) {
7179 return false;
7180 }
7181 }
7182 return true;
7183 }
7184
7185 void SendRequestAndExpectQuicResponse(const std::string& host) {
7186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7187 HttpRequestInfo request;
7188 std::string url("https://");
7189 url.append(host);
7190 request.url = GURL(url);
7191 request.load_flags = 0;
7192 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107193 request.traffic_annotation =
7194 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457195 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267196 int rv = trans.Start(&request, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:017197 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457198
7199 std::string response_data;
robpercival214763f2016-07-01 23:27:017200 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457201 EXPECT_EQ("hello", response_data);
7202
7203 const HttpResponseInfo* response = trans.GetResponseInfo();
7204 ASSERT_TRUE(response != nullptr);
7205 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:287206 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
bnc359ed2a2016-04-29 20:43:457207 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527208 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:087209 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457210 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377211 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457212 }
7213
Fan Yang32c5a112018-12-10 20:06:337214 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567215 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7216 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367217 }
7218
Patrick Meenan0041f332022-05-19 23:48:357219 quic::test::QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Nick Harper23290b82019-05-02 00:02:567220 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057221 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567222 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457223 DestinationType destination_type_;
7224 std::string origin1_;
7225 std::string origin2_;
Victor Vasiliev7752898d2019-11-14 21:30:227226 MockQuicContext context_;
bnc359ed2a2016-04-29 20:43:457227 std::unique_ptr<HttpNetworkSession> session_;
7228 MockClientSocketFactory socket_factory_;
Eric Orthbe86fee2021-10-28 22:31:117229 MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
7230 RuleResolver::GetLocalhostResult()};
bnc359ed2a2016-04-29 20:43:457231 MockCertVerifier cert_verifier_;
7232 TransportSecurityState transport_security_state_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237233 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457234 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077235 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:267236 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457237 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:267238 HttpServerProperties http_server_properties_;
Matt Reichhoff0049a0b72021-10-20 20:44:267239 NetLogWithSource net_log_with_source_{
7240 NetLogWithSource::Make(NetLogSourceType::NONE)};
bnc359ed2a2016-04-29 20:43:457241 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7242 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7243 static_socket_data_provider_vector_;
7244 SSLSocketDataProvider ssl_data_;
7245};
7246
Victor Costane635086f2019-01-27 05:20:307247INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7248 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:577249 ::testing::ValuesIn(GetPoolingTestParams()),
7250 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:457251
7252// A single QUIC request fails because the certificate does not match the origin
7253// hostname, regardless of whether it matches the alternative service hostname.
7254TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7255 if (destination_type_ == DIFFERENT)
7256 return;
7257
7258 GURL url("https://mail.example.com/");
7259 origin1_ = url.host();
7260
7261 // Not used for requests, but this provides a test case where the certificate
7262 // is valid for the hostname of the alternative service.
7263 origin2_ = "mail.example.org";
7264
zhongyie537a002017-06-27 16:48:217265 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457266
7267 scoped_refptr<X509Certificate> cert(
7268 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247269 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7270 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457271
7272 ProofVerifyDetailsChromium verify_details;
7273 verify_details.cert_verify_result.verified_cert = cert;
7274 verify_details.cert_verify_result.is_issued_by_known_root = true;
7275 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7276
Ryan Hamiltonabad59e2019-06-06 04:02:597277 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457278 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
David Schinazi395918c2021-02-05 18:56:217279 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:457280
7281 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7282
7283 AddRefusedSocketData();
7284
7285 HttpRequestInfo request;
7286 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107287 request.traffic_annotation =
7288 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457289
7290 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7291 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267292 int rv = trans.Start(&request, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:017293 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457294
7295 EXPECT_TRUE(AllDataConsumed());
7296}
7297
7298// First request opens QUIC session to alternative service. Second request
7299// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527300// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457301TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7302 origin1_ = "mail.example.org";
7303 origin2_ = "news.example.org";
7304
zhongyie537a002017-06-27 16:48:217305 SetQuicAlternativeService(origin1_);
7306 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457307
7308 scoped_refptr<X509Certificate> cert(
7309 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247310 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7311 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7312 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457313
7314 ProofVerifyDetailsChromium verify_details;
7315 verify_details.cert_verify_result.verified_cert = cert;
7316 verify_details.cert_verify_result.is_issued_by_known_root = true;
7317 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7318
Yixin Wang079ad542018-01-11 04:06:057319 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227320 version_,
7321 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7322 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057323 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177324 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227325 version_,
7326 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7327 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457328
Ryan Hamiltonabad59e2019-06-06 04:02:597329 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237330 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257331 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237332 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7333 packet_num++, &client_maker));
7334 }
Fan Yang32c5a112018-12-10 20:06:337335 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237336 SYNCHRONOUS,
7337 ConstructClientRequestHeadersPacket(
7338 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7339 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:027340 mock_quic_data.AddRead(
7341 ASYNC,
7342 ConstructServerResponseHeadersPacket(
7343 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437344 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337345 ASYNC,
7346 ConstructServerDataPacket(
7347 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237348 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347349 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457350
Yixin Wang079ad542018-01-11 04:06:057351 client_maker.set_hostname(origin2_);
7352 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457353
Zhongyi Shi32f2fd02018-04-16 18:23:437354 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027355 SYNCHRONOUS,
7356 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237357 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027358 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7359 mock_quic_data.AddRead(
7360 ASYNC,
7361 ConstructServerResponseHeadersPacket(
7362 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437363 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337364 ASYNC,
7365 ConstructServerDataPacket(
7366 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237367 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347368 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3, &client_maker));
bnc359ed2a2016-04-29 20:43:457369 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:217370 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:457371
7372 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7373
7374 AddHangingSocketData();
7375 AddHangingSocketData();
7376
Tsuyoshi Horo2c0a5042022-07-06 05:53:077377 auto quic_task_runner =
7378 base::MakeRefCounted<TestTaskRunner>(context_.mock_clock());
Fan Yangc9e00dc2018-10-09 14:17:567379 QuicStreamFactoryPeer::SetAlarmFactory(
7380 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097381 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Victor Vasiliev7752898d2019-11-14 21:30:227382 context_.clock()));
Fan Yangc9e00dc2018-10-09 14:17:567383
bnc359ed2a2016-04-29 20:43:457384 SendRequestAndExpectQuicResponse(origin1_);
7385 SendRequestAndExpectQuicResponse(origin2_);
7386
7387 EXPECT_TRUE(AllDataConsumed());
7388}
7389
7390// First request opens QUIC session to alternative service. Second request does
7391// not pool to it, even though destination matches, because certificate is not
7392// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527393// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457394TEST_P(QuicNetworkTransactionWithDestinationTest,
7395 DoNotPoolIfCertificateInvalid) {
7396 origin1_ = "news.example.org";
7397 origin2_ = "mail.example.com";
7398
zhongyie537a002017-06-27 16:48:217399 SetQuicAlternativeService(origin1_);
7400 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457401
7402 scoped_refptr<X509Certificate> cert1(
7403 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247404 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7405 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7406 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457407
7408 scoped_refptr<X509Certificate> cert2(
7409 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247410 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7411 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457412
7413 ProofVerifyDetailsChromium verify_details1;
7414 verify_details1.cert_verify_result.verified_cert = cert1;
7415 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7416 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7417
7418 ProofVerifyDetailsChromium verify_details2;
7419 verify_details2.cert_verify_result.verified_cert = cert2;
7420 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7421 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7422
Yixin Wang079ad542018-01-11 04:06:057423 QuicTestPacketMaker client_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227424 version_,
7425 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7426 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057427 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177428 QuicTestPacketMaker server_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227429 version_,
7430 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7431 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457432
Ryan Hamiltonabad59e2019-06-06 04:02:597433 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:237434 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257435 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237436 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7437 packet_num++, &client_maker1));
7438 }
Fan Yang32c5a112018-12-10 20:06:337439 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237440 SYNCHRONOUS,
7441 ConstructClientRequestHeadersPacket(
7442 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7443 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437444 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337445 ASYNC,
7446 ConstructServerResponseHeadersPacket(
7447 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437448 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337449 ASYNC,
7450 ConstructServerDataPacket(
7451 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437452 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237453 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347454 ConstructClientAckPacket(packet_num++, 2, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457455 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7456 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7457
7458 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7459
Yixin Wang079ad542018-01-11 04:06:057460 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227461 version_,
7462 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7463 context_.clock(), origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057464 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177465 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227466 version_,
7467 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7468 context_.clock(), origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457469
Ryan Hamiltonabad59e2019-06-06 04:02:597470 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:237471 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:257472 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237473 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7474 packet_num2++, &client_maker2));
7475 }
Fan Yang32c5a112018-12-10 20:06:337476 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237477 SYNCHRONOUS,
7478 ConstructClientRequestHeadersPacket(
7479 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7480 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437481 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337482 ASYNC,
7483 ConstructServerResponseHeadersPacket(
7484 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437485 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337486 ASYNC,
7487 ConstructServerDataPacket(
7488 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437489 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237490 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347491 ConstructClientAckPacket(packet_num2++, 2, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457492 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7493 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7494
7495 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7496
bnc359ed2a2016-04-29 20:43:457497 SendRequestAndExpectQuicResponse(origin1_);
7498 SendRequestAndExpectQuicResponse(origin2_);
7499
7500 EXPECT_TRUE(AllDataConsumed());
7501}
7502
ckrasicdee37572017-04-06 22:42:277503// crbug.com/705109 - this confirms that matching request with a body
7504// triggers a crash (pre-fix).
7505TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Victor Vasiliev638956df2021-04-05 16:41:407506 if (VersionUsesHttp3(version_.transport_version)) {
7507 return;
7508 }
Victor Vasilieva1e66d72019-12-05 17:55:387509 context_.params()->origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277510 HostPortPair::FromString("mail.example.org:443"));
7511
Ryan Hamiltonabad59e2019-06-06 04:02:597512 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237513 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437514 mock_quic_data.AddWrite(
7515 SYNCHRONOUS,
7516 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337517 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027518 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437519 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:477520 ASYNC, ConstructServerPushPromisePacket(
7521 1, GetNthClientInitiatedBidirectionalStreamId(0),
7522 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7523 GetRequestHeaders("GET", "https", "/pushed.jpg")));
Renjie Tang703fea92019-07-23 21:08:317524
Haoyue Wang9d70d65c2020-05-29 22:45:347525 const bool should_send_priority_packet =
7526 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:347527 !VersionUsesHttp3(version_.transport_version);
7528 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347529 mock_quic_data.AddWrite(
7530 SYNCHRONOUS,
7531 ConstructClientAckAndPriorityPacket(
7532 client_packet_number++, false,
7533 /*largest_received=*/1, /*smallest_received=*/1,
7534 GetNthServerInitiatedUnidirectionalStreamId(0),
7535 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577536 }
Zhongyi Shi32f2fd02018-04-16 18:23:437537 mock_quic_data.AddRead(
7538 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337539 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287540 GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:007541 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347542 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347543 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:347544 }
Zhongyi Shi32f2fd02018-04-16 18:23:437545 mock_quic_data.AddRead(
7546 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337547 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287548 false, GetResponseHeaders("200")));
Fan Yang32d79502020-06-24 22:36:007549 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347550 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347551 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:347552 }
Zhongyi Shi32f2fd02018-04-16 18:23:437553 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337554 ASYNC, ConstructServerDataPacket(
7555 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527556 ConstructDataFrame("hello!")));
Fan Yang32d79502020-06-24 22:36:007557 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347558 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347559 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:347560 }
Renjief49758b2019-01-11 23:32:417561
Zhongyi Shi32f2fd02018-04-16 18:23:437562 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337563 ASYNC, ConstructServerDataPacket(
7564 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527565 ConstructDataFrame("and hello!")));
Fan Yang32d79502020-06-24 22:36:007566 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347567 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347568 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:347569 }
ckrasicdee37572017-04-06 22:42:277570
7571 // Because the matching request has a body, we will see the push
7572 // stream get cancelled, and the matching request go out on the
7573 // wire.
Fan Yang32d79502020-06-24 22:36:007574 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347575 mock_quic_data.AddWrite(
7576 SYNCHRONOUS,
7577 ConstructClientRstPacket(client_packet_number++,
7578 GetNthServerInitiatedUnidirectionalStreamId(0),
7579 quic::QUIC_STREAM_CANCELLED));
7580 } else {
7581 mock_quic_data.AddWrite(SYNCHRONOUS,
7582 ConstructClientAckAndRstPacket(
7583 client_packet_number++,
7584 GetNthServerInitiatedUnidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:347585 quic::QUIC_STREAM_CANCELLED, 5, 5));
Haoyue Wang9d70d65c2020-05-29 22:45:347586 }
Bence Béky319388a882020-09-23 18:42:527587 mock_quic_data.AddWrite(
7588 SYNCHRONOUS,
7589 ConstructClientRequestHeadersAndDataFramesPacket(
7590 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
7591 false, true, DEFAULT_PRIORITY,
7592 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7593 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7594 {ConstructDataFrame("1")}));
ckrasicdee37572017-04-06 22:42:277595
7596 // We see the same response as for the earlier pushed and cancelled
7597 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437598 mock_quic_data.AddRead(
7599 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337600 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287601 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:437602 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337603 ASYNC, ConstructServerDataPacket(
7604 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:527605 ConstructDataFrame("and hello!")));
ckrasicdee37572017-04-06 22:42:277606
Yixin Wangb470bc882018-02-15 18:43:577607 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347608 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6));
ckrasicdee37572017-04-06 22:42:277609 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:217610 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
ckrasicdee37572017-04-06 22:42:277611 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7612
7613 // The non-alternate protocol job needs to hang in order to guarantee that
7614 // the alternate-protocol job will "win".
7615 AddHangingNonAlternateProtocolSocketData();
7616
7617 CreateSession();
7618
7619 // PUSH_PROMISE handling in the http layer gets exercised here.
7620 SendRequestAndExpectQuicResponse("hello!");
7621
7622 request_.url = GURL("https://mail.example.org/pushed.jpg");
7623 ChunkedUploadDataStream upload_data(0);
7624 upload_data.AppendData("1", 1, true);
7625 request_.upload_data_stream = &upload_data;
7626 SendRequestAndExpectQuicResponse("and hello!");
7627}
7628
Bence Béky7538a952018-02-01 16:59:527629// Regression test for https://crbug.com/797825: If pushed headers describe a
7630// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7631// not be called (otherwise a DCHECK fails).
7632TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Victor Vasiliev638956df2021-04-05 16:41:407633 if (VersionUsesHttp3(version_.transport_version)) {
7634 return;
7635 }
Bence Béky4c325e52020-10-22 20:48:017636 spdy::Http2HeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527637 pushed_request_headers[":authority"] = "";
7638 pushed_request_headers[":method"] = "GET";
7639 pushed_request_headers[":path"] = "/";
7640 pushed_request_headers[":scheme"] = "nosuchscheme";
7641
Victor Vasilieva1e66d72019-12-05 17:55:387642 context_.params()->origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:527643 HostPortPair::FromString("mail.example.org:443"));
7644
Ryan Hamiltonabad59e2019-06-06 04:02:597645 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:527646
Renjie Tangaadb84b2019-08-31 01:00:237647 int packet_num = 1;
Bence Béky7538a952018-02-01 16:59:527648 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237649 SYNCHRONOUS,
7650 ConstructClientRequestHeadersPacket(
7651 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7652 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:527653
Fan Yang32c5a112018-12-10 20:06:337654 mock_quic_data.AddRead(
7655 ASYNC, ConstructServerPushPromisePacket(
7656 1, GetNthClientInitiatedBidirectionalStreamId(0),
7657 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Renjie Tangb7afea82020-07-15 23:35:477658 std::move(pushed_request_headers)));
Renjie Tangcd594f32020-07-11 20:18:347659 mock_quic_data.AddWrite(
7660 SYNCHRONOUS,
7661 ConstructClientAckAndRstPacket(
7662 packet_num++, GetNthServerInitiatedUnidirectionalStreamId(0),
7663 quic::QUIC_INVALID_PROMISE_URL, 1, 1));
Bence Béky7538a952018-02-01 16:59:527664
Zhongyi Shi32f2fd02018-04-16 18:23:437665 mock_quic_data.AddRead(
7666 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337667 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287668 GetResponseHeaders("200")));
Bence Béky7538a952018-02-01 16:59:527669
Zhongyi Shi32f2fd02018-04-16 18:23:437670 mock_quic_data.AddRead(
7671 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337672 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287673 false, GetResponseHeaders("200")));
Renjie Tangcd594f32020-07-11 20:18:347674 mock_quic_data.AddWrite(SYNCHRONOUS,
7675 ConstructClientAckPacket(packet_num++, 3, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:437676 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337677 ASYNC, ConstructServerDataPacket(
7678 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527679 ConstructDataFrame("hello!")));
Bence Béky7538a952018-02-01 16:59:527680
David Schinazi395918c2021-02-05 18:56:217681 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Bence Béky7538a952018-02-01 16:59:527682 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7683
7684 // The non-alternate protocol job needs to hang in order to guarantee that
7685 // the alternate-protocol job will "win".
7686 AddHangingNonAlternateProtocolSocketData();
7687
7688 CreateSession();
7689
7690 // PUSH_PROMISE handling in the http layer gets exercised here.
7691 SendRequestAndExpectQuicResponse("hello!");
7692
7693 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7694 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7695}
7696
Yixin Wang46a273ec302018-01-23 17:59:567697// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147698TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567699 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147700 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567701 proxy_resolution_service_ =
7702 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
7703 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567704
Ryan Hamiltonabad59e2019-06-06 04:02:597705 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237706 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257707 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237708 mock_quic_data.AddWrite(SYNCHRONOUS,
7709 ConstructInitialSettingsPacket(packet_num++));
7710 }
Fan Yang32c5a112018-12-10 20:06:337711 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237712 SYNCHRONOUS,
7713 ConstructClientRequestHeadersPacket(
7714 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:497715 false,
7716 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:577717 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:497718 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:237719 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337720 mock_quic_data.AddRead(
7721 ASYNC, ConstructServerResponseHeadersPacket(
7722 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287723 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:567724
7725 const char get_request[] =
7726 "GET / HTTP/1.1\r\n"
7727 "Host: mail.example.org\r\n"
7728 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:527729 mock_quic_data.AddWrite(
7730 SYNCHRONOUS,
7731 ConstructClientAckAndDataPacket(
7732 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
7733 1, false, ConstructDataFrame(get_request)));
Renjief49758b2019-01-11 23:32:417734
Yixin Wang46a273ec302018-01-23 17:59:567735 const char get_response[] =
7736 "HTTP/1.1 200 OK\r\n"
7737 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437738 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337739 ASYNC, ConstructServerDataPacket(
7740 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527741 ConstructDataFrame(get_response)));
Fan Yang32c5a112018-12-10 20:06:337742 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417743 SYNCHRONOUS, ConstructServerDataPacket(
7744 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527745 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:237746 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347747 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:567748 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7749
Bence Béky6e243aa2019-12-13 19:01:077750 if (VersionUsesHttp3(version_.transport_version)) {
7751 mock_quic_data.AddWrite(
7752 SYNCHRONOUS, ConstructClientDataPacket(
7753 packet_num++, GetQpackDecoderStreamId(), true, false,
7754 StreamCancellationQpackDecoderInstruction(0)));
7755 }
7756
Yixin Wang46a273ec302018-01-23 17:59:567757 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417758 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237759 ConstructClientRstPacket(packet_num++,
7760 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417761 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567762
7763 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7764
7765 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7766
7767 CreateSession();
7768
7769 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097770 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567771 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567772 RunTransaction(&trans);
7773 CheckWasHttpResponse(&trans);
7774 CheckResponsePort(&trans, 70);
7775 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:567776 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7777
Cammie Smith Barnesbf91e2a2020-12-23 20:49:047778 // DNS aliases should be empty when using a proxy.
7779 EXPECT_TRUE(trans.GetResponseInfo()->dns_aliases.empty());
7780
Yixin Wang46a273ec302018-01-23 17:59:567781 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7782 // proxy socket to disconnect.
7783 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7784
7785 base::RunLoop().RunUntilIdle();
7786 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7787 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7788}
7789
7790// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147791TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567792 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147793 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567794 proxy_resolution_service_ =
7795 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
7796 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567797
Ryan Hamiltonabad59e2019-06-06 04:02:597798 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237799 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257800 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237801 mock_quic_data.AddWrite(SYNCHRONOUS,
7802 ConstructInitialSettingsPacket(packet_num++));
7803 }
Fan Yang32c5a112018-12-10 20:06:337804 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237805 SYNCHRONOUS,
7806 ConstructClientRequestHeadersPacket(
7807 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:497808 false,
7809 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:577810 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:497811 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:237812 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337813 mock_quic_data.AddRead(
7814 ASYNC, ConstructServerResponseHeadersPacket(
7815 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287816 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:567817
7818 SpdyTestUtil spdy_util;
7819
Ryan Hamilton0239aac2018-05-19 00:03:137820 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567821 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:527822 mock_quic_data.AddWrite(
7823 SYNCHRONOUS,
7824 ConstructClientAckAndDataPacket(
7825 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
7826 1, false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Ryan Hamilton0239aac2018-05-19 00:03:137827 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567828 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:437829 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177830 ASYNC, ConstructServerDataPacket(
7831 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527832 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:567833
Ryan Hamilton0239aac2018-05-19 00:03:137834 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197835 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Zhongyi Shi32f2fd02018-04-16 18:23:437836 mock_quic_data.AddRead(
7837 SYNCHRONOUS,
7838 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337839 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527840 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Renjie Tangaadb84b2019-08-31 01:00:237841 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347842 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:567843 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7844
Bence Béky6e243aa2019-12-13 19:01:077845 if (VersionUsesHttp3(version_.transport_version)) {
7846 mock_quic_data.AddWrite(
7847 SYNCHRONOUS, ConstructClientDataPacket(
7848 packet_num++, GetQpackDecoderStreamId(), true, false,
7849 StreamCancellationQpackDecoderInstruction(0)));
7850 }
7851
Yixin Wang46a273ec302018-01-23 17:59:567852 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437853 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237854 ConstructClientRstPacket(packet_num++,
7855 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417856 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567857
7858 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7859
7860 SSLSocketDataProvider ssl_data(ASYNC, OK);
7861 ssl_data.next_proto = kProtoHTTP2;
7862 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7863
7864 CreateSession();
7865
7866 request_.url = GURL("https://mail.example.org/");
7867 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567868 RunTransaction(&trans);
7869 CheckWasSpdyResponse(&trans);
7870 CheckResponsePort(&trans, 70);
7871 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:567872 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7873
Wez0e717112018-06-18 23:09:227874 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7875 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567876 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7877
7878 base::RunLoop().RunUntilIdle();
7879 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7880 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7881}
7882
7883// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7884// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147885TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567886 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147887 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567888 proxy_resolution_service_ =
7889 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
7890 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567891
Ryan Hamiltonabad59e2019-06-06 04:02:597892 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:417893 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:257894 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237895 mock_quic_data.AddWrite(
7896 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7897 }
Fan Yang32c5a112018-12-10 20:06:337898 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417899 SYNCHRONOUS,
7900 ConstructClientRequestHeadersPacket(
7901 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangee921d12020-02-06 00:41:497902 true, false,
7903 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:577904 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:497905 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027906 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337907 mock_quic_data.AddRead(
7908 ASYNC, ConstructServerResponseHeadersPacket(
7909 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287910 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:567911
Yixin Wang46a273ec302018-01-23 17:59:567912 const char get_request_1[] =
7913 "GET / HTTP/1.1\r\n"
7914 "Host: mail.example.org\r\n"
7915 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:527916 mock_quic_data.AddWrite(
7917 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7918 write_packet_index++, false,
7919 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
7920 false, ConstructDataFrame(get_request_1)));
Renjief49758b2019-01-11 23:32:417921
Yixin Wang46a273ec302018-01-23 17:59:567922 const char get_response_1[] =
7923 "HTTP/1.1 200 OK\r\n"
7924 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437925 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437926 ASYNC, ConstructServerDataPacket(
7927 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527928 ConstructDataFrame(get_response_1)));
Yixin Wang46a273ec302018-01-23 17:59:567929
Fan Yang32c5a112018-12-10 20:06:337930 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177931 SYNCHRONOUS, ConstructServerDataPacket(
7932 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527933 false, ConstructDataFrame("0123456789")));
Yixin Wang46a273ec302018-01-23 17:59:567934
Renjie Tangcd594f32020-07-11 20:18:347935 mock_quic_data.AddWrite(SYNCHRONOUS,
7936 ConstructClientAckPacket(write_packet_index++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:567937
7938 const char get_request_2[] =
7939 "GET /2 HTTP/1.1\r\n"
7940 "Host: mail.example.org\r\n"
7941 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:527942 mock_quic_data.AddWrite(
7943 SYNCHRONOUS,
7944 ConstructClientDataPacket(
7945 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7946 false, false, ConstructDataFrame(get_request_2)));
Yixin Wang46a273ec302018-01-23 17:59:567947
7948 const char get_response_2[] =
7949 "HTTP/1.1 200 OK\r\n"
7950 "Content-Length: 7\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437951 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437952 ASYNC, ConstructServerDataPacket(
7953 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527954 ConstructDataFrame(get_response_2)));
Yixin Wang46a273ec302018-01-23 17:59:567955
Ryan Hamilton8d9ee76e2018-05-29 23:52:527956 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177957 SYNCHRONOUS, ConstructServerDataPacket(
7958 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527959 false, ConstructDataFrame("0123456")));
Yixin Wang46a273ec302018-01-23 17:59:567960
Renjie Tangcd594f32020-07-11 20:18:347961 mock_quic_data.AddWrite(SYNCHRONOUS,
7962 ConstructClientAckPacket(write_packet_index++, 5, 4));
Yixin Wang46a273ec302018-01-23 17:59:567963 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7964
Bence Béky6e243aa2019-12-13 19:01:077965 if (VersionUsesHttp3(version_.transport_version)) {
7966 mock_quic_data.AddWrite(
7967 SYNCHRONOUS, ConstructClientDataPacket(
7968 write_packet_index++, GetQpackDecoderStreamId(), true,
7969 false, StreamCancellationQpackDecoderInstruction(0)));
7970 }
7971
Renjief49758b2019-01-11 23:32:417972 mock_quic_data.AddWrite(
7973 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417974 ConstructClientRstPacket(write_packet_index++,
7975 GetNthClientInitiatedBidirectionalStreamId(0),
7976 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567977
7978 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7979
7980 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7981
7982 CreateSession();
7983
7984 request_.url = GURL("https://mail.example.org/");
7985 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567986 RunTransaction(&trans_1);
7987 CheckWasHttpResponse(&trans_1);
7988 CheckResponsePort(&trans_1, 70);
7989 CheckResponseData(&trans_1, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:567990 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7991
7992 request_.url = GURL("https://mail.example.org/2");
7993 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567994 RunTransaction(&trans_2);
7995 CheckWasHttpResponse(&trans_2);
7996 CheckResponsePort(&trans_2, 70);
7997 CheckResponseData(&trans_2, "0123456");
Yixin Wang46a273ec302018-01-23 17:59:567998 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7999
8000 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8001 // proxy socket to disconnect.
8002 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8003
8004 base::RunLoop().RunUntilIdle();
8005 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8006 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8007}
8008
8009// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
8010// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
8011// server is reused for the second request.
Bence Békyf6bb6b22020-04-17 20:22:118012TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:568013 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148014 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568015 proxy_resolution_service_ =
8016 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8017 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568018
Ryan Hamiltonabad59e2019-06-06 04:02:598019 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238020 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258021 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238022 mock_quic_data.AddWrite(SYNCHRONOUS,
8023 ConstructInitialSettingsPacket(packet_num++));
8024 }
Yixin Wang46a273ec302018-01-23 17:59:568025
8026 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:338027 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238028 SYNCHRONOUS,
8029 ConstructClientRequestHeadersPacket(
8030 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498031 false,
8032 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578033 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498034 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238035 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438036 mock_quic_data.AddRead(
8037 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338038 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288039 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:568040
8041 // GET request, response, and data over QUIC tunnel for first request
8042 const char get_request[] =
8043 "GET / HTTP/1.1\r\n"
8044 "Host: mail.example.org\r\n"
8045 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:528046 mock_quic_data.AddWrite(
8047 SYNCHRONOUS,
8048 ConstructClientAckAndDataPacket(
8049 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
8050 1, false, ConstructDataFrame(get_request)));
Renjief49758b2019-01-11 23:32:418051
Yixin Wang46a273ec302018-01-23 17:59:568052 const char get_response[] =
8053 "HTTP/1.1 200 OK\r\n"
8054 "Content-Length: 10\r\n\r\n";
8055 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338056 ASYNC, ConstructServerDataPacket(
8057 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:528058 ConstructDataFrame(get_response)));
Fan Yang32c5a112018-12-10 20:06:338059 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418060 SYNCHRONOUS, ConstructServerDataPacket(
8061 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:528062 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238063 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348064 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:568065
8066 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438067 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238068 SYNCHRONOUS,
8069 ConstructClientRequestHeadersPacket(
8070 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Renjie Tangee921d12020-02-06 00:41:498071 false,
8072 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578073 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498074 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238075 ConnectRequestHeaders("different.example.org:443"),
8076 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438077 mock_quic_data.AddRead(
8078 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338079 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288080 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:568081
8082 // GET request, response, and data over QUIC tunnel for second request
8083 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138084 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568085 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:528086 mock_quic_data.AddWrite(
8087 SYNCHRONOUS,
8088 ConstructClientAckAndDataPacket(
8089 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 4,
8090 4, false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:568091
Ryan Hamilton0239aac2018-05-19 00:03:138092 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568093 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:438094 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178095 ASYNC, ConstructServerDataPacket(
8096 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:528097 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:568098
Ryan Hamilton0239aac2018-05-19 00:03:138099 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198100 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Zhongyi Shi32f2fd02018-04-16 18:23:438101 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438102 ASYNC, ConstructServerDataPacket(
8103 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:528104 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:568105
Renjie Tangaadb84b2019-08-31 01:00:238106 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348107 ConstructClientAckPacket(packet_num++, 6, 5));
Yixin Wang46a273ec302018-01-23 17:59:568108 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8109
Bence Béky6e243aa2019-12-13 19:01:078110 if (VersionUsesHttp3(version_.transport_version)) {
8111 mock_quic_data.AddWrite(
8112 SYNCHRONOUS, ConstructClientDataPacket(
8113 packet_num++, GetQpackDecoderStreamId(), true, false,
8114 StreamCancellationQpackDecoderInstruction(0)));
8115 }
8116
Yixin Wang46a273ec302018-01-23 17:59:568117 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418118 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238119 ConstructClientRstPacket(packet_num++,
8120 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418121 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:078122
8123 if (VersionUsesHttp3(version_.transport_version)) {
8124 mock_quic_data.AddWrite(
8125 SYNCHRONOUS, ConstructClientDataPacket(
8126 packet_num++, GetQpackDecoderStreamId(), true, false,
Bence Békyf6bb6b22020-04-17 20:22:118127 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078128 }
8129
Yixin Wang46a273ec302018-01-23 17:59:568130 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438131 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238132 ConstructClientRstPacket(packet_num++,
8133 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418134 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568135
8136 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8137
8138 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8139
8140 SSLSocketDataProvider ssl_data(ASYNC, OK);
8141 ssl_data.next_proto = kProtoHTTP2;
8142 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8143
8144 CreateSession();
8145
8146 request_.url = GURL("https://mail.example.org/");
8147 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568148 RunTransaction(&trans_1);
8149 CheckWasHttpResponse(&trans_1);
8150 CheckResponsePort(&trans_1, 70);
8151 CheckResponseData(&trans_1, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568152 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8153
8154 request_.url = GURL("https://different.example.org/");
8155 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568156 RunTransaction(&trans_2);
8157 CheckWasSpdyResponse(&trans_2);
8158 CheckResponsePort(&trans_2, 70);
8159 CheckResponseData(&trans_2, "0123456");
Yixin Wang46a273ec302018-01-23 17:59:568160 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8161
8162 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8163 // proxy socket to disconnect.
8164 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8165
8166 base::RunLoop().RunUntilIdle();
8167 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8168 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8169}
8170
8171// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148172TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568173 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148174 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568175 proxy_resolution_service_ =
8176 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8177 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568178
Ryan Hamiltonabad59e2019-06-06 04:02:598179 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238180 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258181 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238182 mock_quic_data.AddWrite(SYNCHRONOUS,
8183 ConstructInitialSettingsPacket(packet_num++));
8184 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:528185 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238186 SYNCHRONOUS,
8187 ConstructClientRequestHeadersPacket(
8188 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498189 false,
8190 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578191 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498192 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238193 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338194 mock_quic_data.AddRead(
8195 ASYNC, ConstructServerResponseHeadersPacket(
8196 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8197 GetResponseHeaders("500")));
8198 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:238199 mock_quic_data.AddWrite(
8200 SYNCHRONOUS,
8201 ConstructClientAckAndRstPacket(
8202 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:348203 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568204
8205 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8206
8207 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8208
8209 CreateSession();
8210
8211 request_.url = GURL("https://mail.example.org/");
8212 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568213 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268214 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:568215 EXPECT_EQ(ERR_IO_PENDING, rv);
8216 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
Yixin Wang46a273ec302018-01-23 17:59:568217
8218 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8219 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8220}
8221
8222// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148223TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568224 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148225 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568226 proxy_resolution_service_ =
8227 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8228 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568229
Ryan Hamiltonabad59e2019-06-06 04:02:598230 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238231 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258232 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238233 mock_quic_data.AddWrite(SYNCHRONOUS,
8234 ConstructInitialSettingsPacket(packet_num++));
8235 }
Fan Yang32c5a112018-12-10 20:06:338236 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238237 SYNCHRONOUS,
8238 ConstructClientRequestHeadersPacket(
8239 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498240 false,
8241 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578242 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498243 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238244 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:568245 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8246
8247 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8248
8249 CreateSession();
8250
8251 request_.url = GURL("https://mail.example.org/");
8252 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568253 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268254 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:568255 EXPECT_EQ(ERR_IO_PENDING, rv);
8256 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8257
8258 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8259 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8260}
8261
8262// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8263// host. Retries request and succeeds.
Bence Békyf6bb6b22020-04-17 20:22:118264TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568265 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148266 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568267 proxy_resolution_service_ =
8268 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8269 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568270
Ryan Hamiltonabad59e2019-06-06 04:02:598271 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238272 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258273 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238274 mock_quic_data.AddWrite(SYNCHRONOUS,
8275 ConstructInitialSettingsPacket(packet_num++));
8276 }
Fan Yang32c5a112018-12-10 20:06:338277 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238278 SYNCHRONOUS,
8279 ConstructClientRequestHeadersPacket(
8280 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498281 false,
8282 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578283 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498284 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238285 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438286 mock_quic_data.AddRead(
8287 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338288 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288289 GetResponseHeaders("200")));
Bence Béky6e243aa2019-12-13 19:01:078290 if (VersionUsesHttp3(version_.transport_version)) {
8291 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:348292 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8293 packet_num++, false, GetQpackDecoderStreamId(), 1, 1,
8294 false, StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:078295 mock_quic_data.AddWrite(
8296 SYNCHRONOUS,
8297 ConstructClientRstPacket(packet_num++,
8298 GetNthClientInitiatedBidirectionalStreamId(0),
8299 quic::QUIC_STREAM_CANCELLED));
8300 } else {
8301 mock_quic_data.AddWrite(
8302 SYNCHRONOUS,
8303 ConstructClientAckAndRstPacket(
8304 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:348305 quic::QUIC_STREAM_CANCELLED, 1, 1));
Bence Béky6e243aa2019-12-13 19:01:078306 }
Yixin Wang46a273ec302018-01-23 17:59:568307
Zhongyi Shi32f2fd02018-04-16 18:23:438308 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238309 SYNCHRONOUS,
8310 ConstructClientRequestHeadersPacket(
8311 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Renjie Tangee921d12020-02-06 00:41:498312 false,
8313 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578314 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498315 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238316 ConnectRequestHeaders("mail.example.org:443"),
8317 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438318 mock_quic_data.AddRead(
8319 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338320 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288321 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:568322
8323 const char get_request[] =
8324 "GET / HTTP/1.1\r\n"
8325 "Host: mail.example.org\r\n"
8326 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:528327 mock_quic_data.AddWrite(
8328 SYNCHRONOUS,
8329 ConstructClientAckAndDataPacket(
8330 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 2,
8331 2, false, ConstructDataFrame(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:568332 const char get_response[] =
8333 "HTTP/1.1 200 OK\r\n"
8334 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:438335 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338336 ASYNC, ConstructServerDataPacket(
8337 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:528338 ConstructDataFrame(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528339
Fan Yang32c5a112018-12-10 20:06:338340 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418341 SYNCHRONOUS, ConstructServerDataPacket(
8342 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:528343 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238344 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348345 ConstructClientAckPacket(packet_num++, 4, 3));
Yixin Wang46a273ec302018-01-23 17:59:568346 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8347
Bence Béky6e243aa2019-12-13 19:01:078348 if (VersionUsesHttp3(version_.transport_version)) {
8349 mock_quic_data.AddWrite(
8350 SYNCHRONOUS, ConstructClientDataPacket(
8351 packet_num++, GetQpackDecoderStreamId(), true, false,
Bence Békyf6bb6b22020-04-17 20:22:118352 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078353 }
Yixin Wang46a273ec302018-01-23 17:59:568354 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418355 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238356 ConstructClientRstPacket(packet_num++,
8357 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418358 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568359
8360 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8361
8362 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8363 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8364
8365 SSLSocketDataProvider ssl_data(ASYNC, OK);
8366 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8367
8368 CreateSession();
8369
8370 request_.url = GURL("https://mail.example.org/");
8371 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568372 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268373 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:568374 EXPECT_EQ(ERR_IO_PENDING, rv);
8375 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8376
8377 rv = trans.RestartIgnoringLastError(callback.callback());
8378 EXPECT_EQ(ERR_IO_PENDING, rv);
8379 EXPECT_EQ(OK, callback.WaitForResult());
8380
8381 CheckWasHttpResponse(&trans);
8382 CheckResponsePort(&trans, 70);
8383 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568384 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8385
8386 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8387 // proxy socket to disconnect.
8388 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8389
8390 base::RunLoop().RunUntilIdle();
8391 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8392 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8393}
8394
8395// Checks if a request's specified "user-agent" header shows up correctly in the
8396// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148397TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008398 const char kConfiguredUserAgent[] = "Configured User-Agent";
8399 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568400 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148401 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568402 proxy_resolution_service_ =
8403 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8404 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568405
Ryan Hamiltonabad59e2019-06-06 04:02:598406 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238407 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258408 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238409 mock_quic_data.AddWrite(SYNCHRONOUS,
8410 ConstructInitialSettingsPacket(packet_num++));
8411 }
Yixin Wang46a273ec302018-01-23 17:59:568412
Bence Béky4c325e52020-10-22 20:48:018413 spdy::Http2HeaderBlock headers =
8414 ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008415 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338416 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028417 SYNCHRONOUS,
8418 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238419 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498420 false,
8421 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578422 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498423 : HttpProxyConnectJob::kH2QuicTunnelPriority,
8424 std::move(headers), 0));
Yixin Wang46a273ec302018-01-23 17:59:568425 // Return an error, so the transaction stops here (this test isn't interested
8426 // in the rest).
8427 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8428
8429 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8430
Matt Menked732ea42019-03-08 12:05:008431 StaticHttpUserAgentSettings http_user_agent_settings(
8432 std::string() /* accept_language */, kConfiguredUserAgent);
8433 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568434 CreateSession();
8435
8436 request_.url = GURL("https://mail.example.org/");
8437 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008438 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568439 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568440 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268441 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:568442 EXPECT_EQ(ERR_IO_PENDING, rv);
8443 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8444
8445 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8446 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8447}
8448
Yixin Wang00fc44c2018-01-23 21:12:208449// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8450// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148451TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208452 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148453 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568454 proxy_resolution_service_ =
8455 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8456 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208457
8458 const RequestPriority request_priority = MEDIUM;
8459
Ryan Hamiltonabad59e2019-06-06 04:02:598460 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238461 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258462 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238463 mock_quic_data.AddWrite(SYNCHRONOUS,
8464 ConstructInitialSettingsPacket(packet_num++));
8465 }
Zhongyi Shi32f2fd02018-04-16 18:23:438466 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238467 SYNCHRONOUS,
8468 ConstructClientRequestHeadersPacket(
8469 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498470 false,
8471 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578472 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498473 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238474 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:208475 // Return an error, so the transaction stops here (this test isn't interested
8476 // in the rest).
8477 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8478
8479 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8480
8481 CreateSession();
8482
8483 request_.url = GURL("https://mail.example.org/");
8484 HttpNetworkTransaction trans(request_priority, session_.get());
8485 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268486 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang00fc44c2018-01-23 21:12:208487 EXPECT_EQ(ERR_IO_PENDING, rv);
8488 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8489
8490 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8491 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8492}
8493
Matt Menkeedaf3b82019-03-14 21:39:448494// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8495// HTTP/2 stream dependency and weights given the request priority.
8496TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8497 session_params_.enable_quic = true;
8498 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568499 proxy_resolution_service_ =
8500 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8501 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeedaf3b82019-03-14 21:39:448502
8503 const RequestPriority kRequestPriority = MEDIUM;
8504 const RequestPriority kRequestPriority2 = LOWEST;
8505
Ryan Hamiltonabad59e2019-06-06 04:02:598506 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:258507 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238508 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
8509 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8510 } else {
8511 mock_quic_data.AddWrite(
8512 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8513 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
8514 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8515 ConnectRequestHeaders("mail.example.org:443"), 0));
8516 }
Matt Menkeedaf3b82019-03-14 21:39:448517 // This should never be reached.
8518 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8519 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8520
8521 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:598522 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:448523 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8524 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8525
8526 int original_max_sockets_per_group =
8527 ClientSocketPoolManager::max_sockets_per_group(
8528 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8529 ClientSocketPoolManager::set_max_sockets_per_group(
8530 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8531 int original_max_sockets_per_pool =
8532 ClientSocketPoolManager::max_sockets_per_pool(
8533 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8534 ClientSocketPoolManager::set_max_sockets_per_pool(
8535 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8536 CreateSession();
8537
8538 request_.url = GURL("https://mail.example.org/");
8539 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8540 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268541 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeedaf3b82019-03-14 21:39:448542 EXPECT_EQ(ERR_IO_PENDING, rv);
8543
8544 HttpRequestInfo request2;
8545 request2.url = GURL("https://mail.example.org/some/other/path/");
8546 request2.traffic_annotation =
8547 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8548
8549 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8550 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:268551 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
Matt Menkeedaf3b82019-03-14 21:39:448552 EXPECT_EQ(ERR_IO_PENDING, rv2);
8553
8554 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8555 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8556
8557 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8558
8559 ClientSocketPoolManager::set_max_sockets_per_pool(
8560 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8561 original_max_sockets_per_pool);
8562 ClientSocketPoolManager::set_max_sockets_per_group(
8563 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8564 original_max_sockets_per_group);
8565}
8566
Yixin Wang46a273ec302018-01-23 17:59:568567// Test the request-challenge-retry sequence for basic auth, over a QUIC
8568// connection when setting up a QUIC proxy tunnel.
Bence Békyf6bb6b22020-04-17 20:22:118569TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Jan Wilken Dörriec92a6d7242021-03-23 17:43:488570 const std::u16string kBaz(u"baz");
8571 const std::u16string kFoo(u"foo");
Yixin Wang46a273ec302018-01-23 17:59:568572
Yixin Wang46a273ec302018-01-23 17:59:568573 // On the second pass, the body read of the auth challenge is synchronous, so
8574 // IsConnectedAndIdle returns false. The socket should still be drained and
8575 // reused. See http://crbug.com/544255.
8576 for (int i = 0; i < 2; ++i) {
Bence Béky6e243aa2019-12-13 19:01:078577 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:228578 version_,
8579 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8580 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky6e243aa2019-12-13 19:01:078581 client_headers_include_h2_stream_dependency_);
8582 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:228583 version_,
8584 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8585 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Bence Béky6e243aa2019-12-13 19:01:078586 false);
Yixin Wang46a273ec302018-01-23 17:59:568587
8588 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148589 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568590 proxy_resolution_service_ =
Nicolas Arciniegad2013f92020-02-07 23:00:568591 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498592 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568593
Ryan Hamiltonabad59e2019-06-06 04:02:598594 MockQuicData mock_quic_data(version_);
Yixin Wang46a273ec302018-01-23 17:59:568595
Renjie Tangaadb84b2019-08-31 01:00:238596 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258597 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238598 mock_quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:078599 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Renjie Tangaadb84b2019-08-31 01:00:238600 }
Yixin Wang46a273ec302018-01-23 17:59:568601
8602 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438603 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:078604 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238605 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8606 false,
Renjie Tangee921d12020-02-06 00:41:498607 VersionUsesHttp3(version_.transport_version)
Dan Zhangfc4c085b2020-11-10 16:33:168608 ? quic::QuicStream::kDefaultUrgency
Renjie Tangee921d12020-02-06 00:41:498609 : ConvertRequestPriorityToQuicPriority(
8610 HttpProxyConnectJob::kH2QuicTunnelPriority),
Bence Béky6e243aa2019-12-13 19:01:078611 client_maker.ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028612 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568613
Kenichi Ishibashif8634ab2021-03-16 23:41:288614 spdy::Http2HeaderBlock headers = server_maker.GetResponseHeaders("407");
Yixin Wang46a273ec302018-01-23 17:59:568615 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8616 headers["content-length"] = "10";
8617 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078618 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338619 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028620 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568621
8622 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438623 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078624 ASYNC, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338625 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178626 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568627 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438628 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078629 SYNCHRONOUS, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338630 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:178631 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568632 }
Yixin Wang46a273ec302018-01-23 17:59:568633
Bence Béky7a45d4d2020-05-08 01:59:238634 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348635 client_maker.MakeAckPacket(packet_num++, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:078636
8637 if (VersionUsesHttp3(version_.transport_version)) {
8638 mock_quic_data.AddWrite(
8639 SYNCHRONOUS,
8640 client_maker.MakeDataPacket(
8641 packet_num++, GetQpackDecoderStreamId(),
8642 /* should_include_version = */ true,
8643 /* fin = */ false, StreamCancellationQpackDecoderInstruction(0)));
8644 }
Yixin Wang46a273ec302018-01-23 17:59:568645
8646 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338647 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:078648 client_maker.MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:238649 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418650 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:188651 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568652
Bence Béky6e243aa2019-12-13 19:01:078653 headers = client_maker.ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:568654 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8655 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048656 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:078657 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238658 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8659 false,
Renjie Tangee921d12020-02-06 00:41:498660 VersionUsesHttp3(version_.transport_version)
Dan Zhangfc4c085b2020-11-10 16:33:168661 ? quic::QuicStream::kDefaultUrgency
Renjie Tangee921d12020-02-06 00:41:498662 : ConvertRequestPriorityToQuicPriority(
8663 HttpProxyConnectJob::kH2QuicTunnelPriority),
Matt Menke6e879bd2019-03-18 17:26:048664 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:028665 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568666
8667 // Response to wrong password
Kenichi Ishibashif8634ab2021-03-16 23:41:288668 headers = server_maker.GetResponseHeaders("407");
Yixin Wang46a273ec302018-01-23 17:59:568669 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8670 headers["content-length"] = "10";
8671 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078672 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338673 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028674 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568675 mock_quic_data.AddRead(SYNCHRONOUS,
8676 ERR_IO_PENDING); // No more data to read
8677
Bence Béky6e243aa2019-12-13 19:01:078678 if (VersionUsesHttp3(version_.transport_version)) {
8679 mock_quic_data.AddWrite(
8680 SYNCHRONOUS,
8681 client_maker.MakeAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:348682 packet_num++, false, GetQpackDecoderStreamId(), 3, 3, false,
Bence Békyf6bb6b22020-04-17 20:22:118683 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078684 mock_quic_data.AddWrite(SYNCHRONOUS,
8685 client_maker.MakeRstPacket(
8686 packet_num++, false,
8687 GetNthClientInitiatedBidirectionalStreamId(1),
8688 quic::QUIC_STREAM_CANCELLED));
8689 } else {
8690 mock_quic_data.AddWrite(SYNCHRONOUS,
8691 client_maker.MakeAckAndRstPacket(
8692 packet_num++, false,
8693 GetNthClientInitiatedBidirectionalStreamId(1),
Renjie Tangcd594f32020-07-11 20:18:348694 quic::QUIC_STREAM_CANCELLED, 3, 3));
Bence Béky6e243aa2019-12-13 19:01:078695 }
Yixin Wang46a273ec302018-01-23 17:59:568696
8697 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8698 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8699
8700 CreateSession();
8701
8702 request_.url = GURL("https://mail.example.org/");
8703 // Ensure that proxy authentication is attempted even
Matt Menke25eaa432020-08-25 00:10:008704 // when privacy mode is enabled.
8705 request_.privacy_mode = PRIVACY_MODE_ENABLED;
Yixin Wang46a273ec302018-01-23 17:59:568706 {
8707 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568708 RunTransaction(&trans);
8709
8710 const HttpResponseInfo* response = trans.GetResponseInfo();
8711 ASSERT_TRUE(response != nullptr);
8712 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:288713 EXPECT_EQ("HTTP/1.1 407", response->headers->GetStatusLine());
Yixin Wang46a273ec302018-01-23 17:59:568714 EXPECT_TRUE(response->headers->IsKeepAlive());
8715 EXPECT_EQ(407, response->headers->response_code());
8716 EXPECT_EQ(10, response->headers->GetContentLength());
8717 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Anton Bikineev068d2912021-05-15 20:43:528718 absl::optional<AuthChallengeInfo> auth_challenge =
Emily Starkf2c9bbd2019-04-09 17:08:588719 response->auth_challenge;
8720 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568721 EXPECT_TRUE(auth_challenge->is_proxy);
8722 EXPECT_EQ("https://proxy.example.org:70",
8723 auth_challenge->challenger.Serialize());
8724 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8725 EXPECT_EQ("basic", auth_challenge->scheme);
8726
8727 TestCompletionCallback callback;
8728 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8729 callback.callback());
8730 EXPECT_EQ(ERR_IO_PENDING, rv);
8731 EXPECT_EQ(OK, callback.WaitForResult());
8732
8733 response = trans.GetResponseInfo();
8734 ASSERT_TRUE(response != nullptr);
8735 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:288736 EXPECT_EQ("HTTP/1.1 407", response->headers->GetStatusLine());
Yixin Wang46a273ec302018-01-23 17:59:568737 EXPECT_TRUE(response->headers->IsKeepAlive());
8738 EXPECT_EQ(407, response->headers->response_code());
8739 EXPECT_EQ(10, response->headers->GetContentLength());
8740 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588741 auth_challenge = response->auth_challenge;
8742 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568743 EXPECT_TRUE(auth_challenge->is_proxy);
8744 EXPECT_EQ("https://proxy.example.org:70",
8745 auth_challenge->challenger.Serialize());
8746 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8747 EXPECT_EQ("basic", auth_challenge->scheme);
8748 }
8749 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8750 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8751 // reused because it's not connected).
8752 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8753 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8754 }
8755}
8756
Yixin Wang385652a2018-02-16 02:37:238757TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8758 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8759 // in HEADERS frames for requests and PRIORITY frames).
David Schinazi84c58bb2020-06-04 20:14:338760 if (!client_headers_include_h2_stream_dependency_) {
Yixin Wang385652a2018-02-16 02:37:238761 return;
8762 }
8763
Victor Vasiliev7da08172019-10-14 06:04:258764 if (quic::VersionUsesHttp3(version_.transport_version)) {
Renjie Tangba21e032019-09-27 21:52:288765 // HTTP/3 currently doesn't support PRIORITY.
Ryan Hamiltone940bd12019-06-30 02:46:458766 return;
8767 }
8768
Victor Vasilieva1e66d72019-12-05 17:55:388769 context_.params()->origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:238770 HostPortPair::FromString("mail.example.org:443"));
8771
Fan Yang32c5a112018-12-10 20:06:338772 const quic::QuicStreamId client_stream_0 =
8773 GetNthClientInitiatedBidirectionalStreamId(0);
8774 const quic::QuicStreamId client_stream_1 =
8775 GetNthClientInitiatedBidirectionalStreamId(1);
8776 const quic::QuicStreamId client_stream_2 =
8777 GetNthClientInitiatedBidirectionalStreamId(2);
8778 const quic::QuicStreamId push_stream_0 =
8779 GetNthServerInitiatedUnidirectionalStreamId(0);
8780 const quic::QuicStreamId push_stream_1 =
8781 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238782
Ryan Hamiltonabad59e2019-06-06 04:02:598783 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238784 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258785 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238786 mock_quic_data.AddWrite(SYNCHRONOUS,
8787 ConstructInitialSettingsPacket(packet_num++));
8788 }
Yixin Wang385652a2018-02-16 02:37:238789
8790 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:238791 mock_quic_data.AddWrite(
8792 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8793 packet_num++, client_stream_0, true, true, HIGHEST,
8794 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:028795 mock_quic_data.AddWrite(
8796 SYNCHRONOUS,
8797 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238798 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028799 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
8800 mock_quic_data.AddWrite(
8801 SYNCHRONOUS,
8802 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238803 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028804 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:238805
8806 // Server replies "OK" for the three requests.
Kenichi Ishibashif8634ab2021-03-16 23:41:288807 mock_quic_data.AddRead(
8808 ASYNC, ConstructServerResponseHeadersPacket(
8809 1, client_stream_0, false, false, GetResponseHeaders("200")));
8810 mock_quic_data.AddRead(
8811 ASYNC, ConstructServerResponseHeadersPacket(
8812 2, client_stream_1, false, false, GetResponseHeaders("200")));
Renjie Tangaadb84b2019-08-31 01:00:238813 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348814 ConstructClientAckPacket(packet_num++, 2, 1));
Kenichi Ishibashif8634ab2021-03-16 23:41:288815 mock_quic_data.AddRead(
8816 ASYNC, ConstructServerResponseHeadersPacket(
8817 3, client_stream_2, false, false, GetResponseHeaders("200")));
Yixin Wang385652a2018-02-16 02:37:238818
8819 // Server sends two push promises associated with |client_stream_0|; client
8820 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8821 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:028822 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:478823 ASYNC, ConstructServerPushPromisePacket(
8824 4, client_stream_0, push_stream_0, false,
8825 GetRequestHeaders("GET", "https", "/pushed_0.jpg")));
Yixin Wang385652a2018-02-16 02:37:238826 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438827 SYNCHRONOUS,
8828 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangcd594f32020-07-11 20:18:348829 packet_num++, false, 4, 3,
Zhongyi Shi32f2fd02018-04-16 18:23:438830 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:028831 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
8832 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:478833 ASYNC, ConstructServerPushPromisePacket(
8834 5, client_stream_0, push_stream_1, false,
8835 GetRequestHeaders("GET", "https", "/pushed_1.jpg")));
8836 mock_quic_data.AddWrite(SYNCHRONOUS,
8837 ConstructClientAckAndPriorityPacket(
8838 packet_num++, false,
8839 /*largest_received=*/5, /*smallest_received=*/4,
8840 push_stream_1, push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:238841
8842 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438843 mock_quic_data.AddRead(
8844 ASYNC, ConstructServerResponseHeadersPacket(
Kenichi Ishibashif8634ab2021-03-16 23:41:288845 6, push_stream_0, false, false, GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:438846 mock_quic_data.AddRead(
8847 ASYNC, ConstructServerResponseHeadersPacket(
Kenichi Ishibashif8634ab2021-03-16 23:41:288848 7, push_stream_1, false, false, GetResponseHeaders("200")));
Renjie Tangcd594f32020-07-11 20:18:348849 mock_quic_data.AddWrite(SYNCHRONOUS,
8850 ConstructClientAckPacket(packet_num++, 7, 5));
Yixin Wang385652a2018-02-16 02:37:238851
8852 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8853 // priority updates to match the request's priority. Client sends PRIORITY
8854 // frames to inform server of new HTTP/2 stream dependencies.
Bence Béky319388a882020-09-23 18:42:528855 mock_quic_data.AddWrite(
8856 SYNCHRONOUS,
8857 ConstructClientPriorityFramesPacket(
8858 packet_num++, false,
8859 {{push_stream_1, client_stream_2,
8860 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8861 {push_stream_0, client_stream_0,
8862 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:238863
8864 // Server sends data for the three requests and the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438865 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178866 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Bence Béky319388a882020-09-23 18:42:528867 ConstructDataFrame("hello 0!")));
Zhongyi Shi32f2fd02018-04-16 18:23:438868 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178869 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Bence Béky319388a882020-09-23 18:42:528870 ConstructDataFrame("hello 1!")));
Renjie Tangaadb84b2019-08-31 01:00:238871 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348872 ConstructClientAckPacket(packet_num++, 9, 8));
Zhongyi Shi32f2fd02018-04-16 18:23:438873 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178874 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Bence Béky319388a882020-09-23 18:42:528875 ConstructDataFrame("hello 2!")));
8876 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
8877 11, push_stream_0, false, true,
8878 ConstructDataFrame("and hello 0!")));
Renjie Tangaadb84b2019-08-31 01:00:238879 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348880 ConstructClientAckPacket(packet_num++, 11, 10));
Zhongyi Shi32f2fd02018-04-16 18:23:438881 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178882 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Bence Béky319388a882020-09-23 18:42:528883 ConstructDataFrame("and hello 1!")));
Yixin Wang385652a2018-02-16 02:37:238884
Yixin Wang385652a2018-02-16 02:37:238885 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:218886 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang385652a2018-02-16 02:37:238887 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8888
8889 // The non-alternate protocol job needs to hang in order to guarantee that
8890 // the alternate-protocol job will "win".
8891 AddHangingNonAlternateProtocolSocketData();
8892
8893 CreateSession();
8894
8895 request_.url = GURL("https://mail.example.org/0.jpg");
8896 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8897 TestCompletionCallback callback_0;
Matt Reichhoff0049a0b72021-10-20 20:44:268898 EXPECT_EQ(ERR_IO_PENDING, trans_0.Start(&request_, callback_0.callback(),
8899 net_log_with_source_));
Yixin Wang385652a2018-02-16 02:37:238900 base::RunLoop().RunUntilIdle();
8901
8902 request_.url = GURL("https://mail.example.org/1.jpg");
8903 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8904 TestCompletionCallback callback_1;
Matt Reichhoff0049a0b72021-10-20 20:44:268905 EXPECT_EQ(ERR_IO_PENDING, trans_1.Start(&request_, callback_1.callback(),
8906 net_log_with_source_));
Yixin Wang385652a2018-02-16 02:37:238907 base::RunLoop().RunUntilIdle();
8908
8909 request_.url = GURL("https://mail.example.org/2.jpg");
8910 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8911 TestCompletionCallback callback_2;
Matt Reichhoff0049a0b72021-10-20 20:44:268912 EXPECT_EQ(ERR_IO_PENDING, trans_2.Start(&request_, callback_2.callback(),
8913 net_log_with_source_));
Yixin Wang385652a2018-02-16 02:37:238914 base::RunLoop().RunUntilIdle();
8915
8916 // Client makes request that matches resource pushed in |pushed_stream_0|.
8917 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8918 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8919 TestCompletionCallback callback_3;
Matt Reichhoff0049a0b72021-10-20 20:44:268920 EXPECT_EQ(ERR_IO_PENDING, trans_3.Start(&request_, callback_3.callback(),
8921 net_log_with_source_));
Yixin Wang385652a2018-02-16 02:37:238922 base::RunLoop().RunUntilIdle();
8923
8924 EXPECT_TRUE(callback_0.have_result());
8925 EXPECT_EQ(OK, callback_0.WaitForResult());
8926 EXPECT_TRUE(callback_1.have_result());
8927 EXPECT_EQ(OK, callback_1.WaitForResult());
8928 EXPECT_TRUE(callback_2.have_result());
8929 EXPECT_EQ(OK, callback_2.WaitForResult());
8930
8931 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8932 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8933 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8934 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8935
8936 mock_quic_data.Resume();
8937 base::RunLoop().RunUntilIdle();
8938 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8939 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8940}
8941
Matt Menke26e41542019-06-05 01:09:518942// Test that NetworkIsolationKey is respected by QUIC connections, when
8943// kPartitionConnectionsByNetworkIsolationKey is enabled.
8944TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Matt Menke4807a9a2020-11-21 00:14:418945 const SchemefulSite kSite1(GURL("http://origin1/"));
8946 const SchemefulSite kSite2(GURL("http://origin2/"));
8947 NetworkIsolationKey network_isolation_key1(kSite1, kSite1);
8948 NetworkIsolationKey network_isolation_key2(kSite2, kSite2);
Matt Menke26e41542019-06-05 01:09:518949
Victor Vasilieva1e66d72019-12-05 17:55:388950 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:518951 HostPortPair::FromString("mail.example.org:443"));
8952
8953 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
8954 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
8955 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
8956 // the same way as the HTTP over H2 proxy case.
8957 for (bool use_proxy : {false, true}) {
8958 SCOPED_TRACE(use_proxy);
8959
8960 if (use_proxy) {
8961 proxy_resolution_service_ =
Nicolas Arciniegad2013f92020-02-07 23:00:568962 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Matt Menke26e41542019-06-05 01:09:518963 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
8964 } else {
Nicolas Arciniegad2013f92020-02-07 23:00:568965 proxy_resolution_service_ =
8966 ConfiguredProxyResolutionService::CreateDirect();
Matt Menke26e41542019-06-05 01:09:518967 }
8968
8969 GURL url1;
8970 GURL url2;
8971 GURL url3;
8972 if (use_proxy) {
8973 url1 = GURL("http://mail.example.org/1");
8974 url2 = GURL("http://mail.example.org/2");
8975 url3 = GURL("http://mail.example.org/3");
8976 } else {
8977 url1 = GURL("https://mail.example.org/1");
8978 url2 = GURL("https://mail.example.org/2");
8979 url3 = GURL("https://mail.example.org/3");
8980 }
8981
8982 for (bool partition_connections : {false, true}) {
8983 SCOPED_TRACE(partition_connections);
8984
8985 base::test::ScopedFeatureList feature_list;
8986 if (partition_connections) {
8987 feature_list.InitAndEnableFeature(
8988 features::kPartitionConnectionsByNetworkIsolationKey);
8989 } else {
8990 feature_list.InitAndDisableFeature(
8991 features::kPartitionConnectionsByNetworkIsolationKey);
8992 }
8993
8994 // Reads and writes for the unpartitioned case, where only one socket is
8995 // used.
8996
Victor Vasilieva1e66d72019-12-05 17:55:388997 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:518998 HostPortPair::FromString("mail.example.org:443"));
8999
Ryan Hamiltonabad59e2019-06-06 04:02:599000 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:519001 QuicTestPacketMaker client_maker1(
9002 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229003 quic::QuicUtils::CreateRandomConnectionId(
9004 context_.random_generator()),
9005 context_.clock(), kDefaultServerHostName,
9006 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519007 client_headers_include_h2_stream_dependency_);
9008 QuicTestPacketMaker server_maker1(
9009 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229010 quic::QuicUtils::CreateRandomConnectionId(
9011 context_.random_generator()),
9012 context_.clock(), kDefaultServerHostName,
9013 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519014
Renjie Tangaadb84b2019-08-31 01:00:239015 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259016 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239017 unpartitioned_mock_quic_data.AddWrite(
9018 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
9019 }
Matt Menke26e41542019-06-05 01:09:519020
9021 unpartitioned_mock_quic_data.AddWrite(
9022 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029023 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239024 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9025 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029026 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519027 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029028 ASYNC, server_maker1.MakeResponseHeadersPacket(
9029 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289030 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519031 unpartitioned_mock_quic_data.AddRead(
9032 ASYNC, server_maker1.MakeDataPacket(
9033 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529034 true, ConstructDataFrame("1")));
Matt Menke26e41542019-06-05 01:09:519035 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349036 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menke26e41542019-06-05 01:09:519037
9038 unpartitioned_mock_quic_data.AddWrite(
9039 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029040 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239041 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
9042 false, true,
Matt Menke26e41542019-06-05 01:09:519043 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029044 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519045 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029046 ASYNC, server_maker1.MakeResponseHeadersPacket(
9047 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289048 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519049 unpartitioned_mock_quic_data.AddRead(
9050 ASYNC, server_maker1.MakeDataPacket(
9051 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:529052 true, ConstructDataFrame("2")));
Matt Menke26e41542019-06-05 01:09:519053 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangb7afea82020-07-15 23:35:479054 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3));
Matt Menke26e41542019-06-05 01:09:519055
9056 unpartitioned_mock_quic_data.AddWrite(
9057 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029058 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239059 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
9060 false, true,
Matt Menke26e41542019-06-05 01:09:519061 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029062 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519063 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029064 ASYNC, server_maker1.MakeResponseHeadersPacket(
9065 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289066 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519067 unpartitioned_mock_quic_data.AddRead(
9068 ASYNC, server_maker1.MakeDataPacket(
9069 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Bence Béky319388a882020-09-23 18:42:529070 true, ConstructDataFrame("3")));
Matt Menke26e41542019-06-05 01:09:519071 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangb7afea82020-07-15 23:35:479072 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 6, 5));
Matt Menke26e41542019-06-05 01:09:519073
9074 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9075
9076 // Reads and writes for the partitioned case, where two sockets are used.
9077
Ryan Hamiltonabad59e2019-06-06 04:02:599078 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:519079 QuicTestPacketMaker client_maker2(
9080 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229081 quic::QuicUtils::CreateRandomConnectionId(
9082 context_.random_generator()),
9083 context_.clock(), kDefaultServerHostName,
9084 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519085 client_headers_include_h2_stream_dependency_);
9086 QuicTestPacketMaker server_maker2(
9087 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229088 quic::QuicUtils::CreateRandomConnectionId(
9089 context_.random_generator()),
9090 context_.clock(), kDefaultServerHostName,
9091 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519092
Renjie Tangaadb84b2019-08-31 01:00:239093 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259094 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239095 partitioned_mock_quic_data1.AddWrite(
9096 SYNCHRONOUS,
9097 client_maker2.MakeInitialSettingsPacket(packet_num2++));
9098 }
Matt Menke26e41542019-06-05 01:09:519099
9100 partitioned_mock_quic_data1.AddWrite(
9101 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029102 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239103 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
9104 true, true,
Matt Menke26e41542019-06-05 01:09:519105 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029106 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519107 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029108 ASYNC, server_maker2.MakeResponseHeadersPacket(
9109 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289110 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519111 partitioned_mock_quic_data1.AddRead(
9112 ASYNC, server_maker2.MakeDataPacket(
9113 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529114 true, ConstructDataFrame("1")));
Matt Menke26e41542019-06-05 01:09:519115 partitioned_mock_quic_data1.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349116 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 2, 1));
Matt Menke26e41542019-06-05 01:09:519117
9118 partitioned_mock_quic_data1.AddWrite(
9119 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029120 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239121 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
9122 false, true,
Matt Menke26e41542019-06-05 01:09:519123 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029124 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519125 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029126 ASYNC, server_maker2.MakeResponseHeadersPacket(
9127 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289128 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519129 partitioned_mock_quic_data1.AddRead(
9130 ASYNC, server_maker2.MakeDataPacket(
9131 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:529132 true, ConstructDataFrame("3")));
Matt Menke26e41542019-06-05 01:09:519133 partitioned_mock_quic_data1.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349134 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 4, 3));
Matt Menke26e41542019-06-05 01:09:519135
9136 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9137
Ryan Hamiltonabad59e2019-06-06 04:02:599138 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:519139 QuicTestPacketMaker client_maker3(
9140 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229141 quic::QuicUtils::CreateRandomConnectionId(
9142 context_.random_generator()),
9143 context_.clock(), kDefaultServerHostName,
9144 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519145 client_headers_include_h2_stream_dependency_);
9146 QuicTestPacketMaker server_maker3(
9147 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229148 quic::QuicUtils::CreateRandomConnectionId(
9149 context_.random_generator()),
9150 context_.clock(), kDefaultServerHostName,
9151 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519152
Renjie Tangaadb84b2019-08-31 01:00:239153 int packet_num3 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259154 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239155 partitioned_mock_quic_data2.AddWrite(
9156 SYNCHRONOUS,
9157 client_maker3.MakeInitialSettingsPacket(packet_num3++));
9158 }
Matt Menke26e41542019-06-05 01:09:519159
9160 partitioned_mock_quic_data2.AddWrite(
9161 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029162 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239163 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9164 true, true,
Matt Menke26e41542019-06-05 01:09:519165 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029166 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519167 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029168 ASYNC, server_maker3.MakeResponseHeadersPacket(
9169 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289170 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519171 partitioned_mock_quic_data2.AddRead(
9172 ASYNC, server_maker3.MakeDataPacket(
9173 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529174 true, ConstructDataFrame("2")));
Matt Menke26e41542019-06-05 01:09:519175 partitioned_mock_quic_data2.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349176 SYNCHRONOUS, client_maker3.MakeAckPacket(packet_num3++, 2, 1));
Matt Menke26e41542019-06-05 01:09:519177
9178 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9179
9180 if (partition_connections) {
9181 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9182 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9183 } else {
9184 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9185 }
9186
9187 CreateSession();
9188
9189 TestCompletionCallback callback;
9190 HttpRequestInfo request1;
9191 request1.method = "GET";
9192 request1.url = GURL(url1);
9193 request1.traffic_annotation =
9194 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9195 request1.network_isolation_key = network_isolation_key1;
9196 HttpNetworkTransaction trans1(LOWEST, session_.get());
9197 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9198 EXPECT_THAT(callback.GetResult(rv), IsOk());
9199 std::string response_data1;
9200 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9201 EXPECT_EQ("1", response_data1);
9202
9203 HttpRequestInfo request2;
9204 request2.method = "GET";
9205 request2.url = GURL(url2);
9206 request2.traffic_annotation =
9207 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9208 request2.network_isolation_key = network_isolation_key2;
9209 HttpNetworkTransaction trans2(LOWEST, session_.get());
9210 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9211 EXPECT_THAT(callback.GetResult(rv), IsOk());
9212 std::string response_data2;
9213 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9214 EXPECT_EQ("2", response_data2);
9215
9216 HttpRequestInfo request3;
9217 request3.method = "GET";
9218 request3.url = GURL(url3);
9219 request3.traffic_annotation =
9220 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9221 request3.network_isolation_key = network_isolation_key1;
9222 HttpNetworkTransaction trans3(LOWEST, session_.get());
9223 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9224 EXPECT_THAT(callback.GetResult(rv), IsOk());
9225 std::string response_data3;
9226 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9227 EXPECT_EQ("3", response_data3);
9228
9229 if (partition_connections) {
9230 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9231 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9232 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9233 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9234 } else {
9235 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9236 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9237 }
9238 }
9239 }
9240}
9241
9242// Test that two requests to the same origin over QUIC tunnels use different
9243// QUIC sessions if their NetworkIsolationKeys don't match, and
9244// kPartitionConnectionsByNetworkIsolationKey is enabled.
9245TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9246 base::test::ScopedFeatureList feature_list;
9247 feature_list.InitAndEnableFeature(
9248 features::kPartitionConnectionsByNetworkIsolationKey);
9249
9250 session_params_.enable_quic = true;
9251 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:569252 proxy_resolution_service_ =
9253 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
9254 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menke26e41542019-06-05 01:09:519255
9256 const char kGetRequest[] =
9257 "GET / HTTP/1.1\r\n"
9258 "Host: mail.example.org\r\n"
9259 "Connection: keep-alive\r\n\r\n";
9260 const char kGetResponse[] =
9261 "HTTP/1.1 200 OK\r\n"
9262 "Content-Length: 10\r\n\r\n";
9263
Ryan Hamiltonabad59e2019-06-06 04:02:599264 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9265 std::make_unique<MockQuicData>(version_),
9266 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519267
9268 for (int index : {0, 1}) {
9269 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229270 version_,
9271 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9272 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519273 client_headers_include_h2_stream_dependency_);
9274 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229275 version_,
9276 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9277 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9278 false);
Matt Menke26e41542019-06-05 01:09:519279
Renjie Tangaadb84b2019-08-31 01:00:239280 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259281 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239282 mock_quic_data[index]->AddWrite(
9283 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
9284 }
Matt Menke26e41542019-06-05 01:09:519285
Ryan Hamiltonabad59e2019-06-06 04:02:599286 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519287 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029288 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239289 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9290 false,
Renjie Tangee921d12020-02-06 00:41:499291 VersionUsesHttp3(version_.transport_version)
Dan Zhangfc4c085b2020-11-10 16:33:169292 ? quic::QuicStream::kDefaultUrgency
Renjie Tangee921d12020-02-06 00:41:499293 : ConvertRequestPriorityToQuicPriority(
9294 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:029295 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:599296 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029297 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:519298 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289299 false, GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:519300
Bence Béky319388a882020-09-23 18:42:529301 mock_quic_data[index]->AddWrite(
9302 SYNCHRONOUS,
9303 client_maker.MakeAckAndDataPacket(
9304 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
9305 1, 1, false, ConstructDataFrame(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:519306
Ryan Hamiltonabad59e2019-06-06 04:02:599307 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519308 ASYNC, server_maker.MakeDataPacket(
9309 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529310 false, ConstructDataFrame(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599311 mock_quic_data[index]->AddRead(
Bence Béky319388a882020-09-23 18:42:529312 SYNCHRONOUS, server_maker.MakeDataPacket(
9313 3, GetNthClientInitiatedBidirectionalStreamId(0),
9314 false, false, ConstructDataFrame("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599315 mock_quic_data[index]->AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349316 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2));
Ryan Hamiltonabad59e2019-06-06 04:02:599317 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9318 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:519319
Ryan Hamiltonabad59e2019-06-06 04:02:599320 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:519321 }
9322
9323 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9324 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9325 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9326
9327 CreateSession();
9328
9329 request_.url = GURL("https://mail.example.org/");
9330 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9331 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9332 RunTransaction(&trans);
9333 CheckResponseData(&trans, "0123456789");
9334
9335 HttpRequestInfo request2;
Matt Menke4807a9a2020-11-21 00:14:419336 const SchemefulSite kSite1(GURL("http://origin1/"));
9337 request_.network_isolation_key = NetworkIsolationKey(kSite1, kSite1);
Matt Menke26e41542019-06-05 01:09:519338 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9339 RunTransaction(&trans2);
9340 CheckResponseData(&trans2, "0123456789");
9341
Ryan Hamiltonabad59e2019-06-06 04:02:599342 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9343 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9344 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9345 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:519346}
9347
Yoichi Osato4c75c0c2020-06-24 08:03:579348TEST_P(QuicNetworkTransactionTest, AllowHTTP1FalseProhibitsH1) {
9349 MockRead http_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING),
9350 MockRead(ASYNC, OK)};
9351 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
9352 socket_factory_.AddSocketDataProvider(&http_data);
9353 AddCertificate(&ssl_data_);
9354 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9355
9356 CreateSession();
9357
9358 request_.method = "POST";
9359 UploadDataStreamNotAllowHTTP1 upload_data("");
9360 request_.upload_data_stream = &upload_data;
9361
9362 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9363 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:269364 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:579365 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9366 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_H2_OR_QUIC_REQUIRED));
9367}
9368
9369// Confirm mock class UploadDataStreamNotAllowHTTP1 can upload content over
9370// QUIC.
9371TEST_P(QuicNetworkTransactionTest, AllowHTTP1MockTest) {
9372 context_.params()->origins_to_force_quic_on.insert(
9373 HostPortPair::FromString("mail.example.org:443"));
9374
9375 MockQuicData mock_quic_data(version_);
9376 int write_packet_index = 1;
9377 if (VersionUsesHttp3(version_.transport_version)) {
9378 mock_quic_data.AddWrite(
9379 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9380 }
9381 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:529382 mock_quic_data.AddWrite(
9383 SYNCHRONOUS,
9384 ConstructClientRequestHeadersAndDataFramesPacket(
9385 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9386 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9387 0, nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:579388 mock_quic_data.AddRead(
9389 ASYNC, ConstructServerResponseHeadersPacket(
9390 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289391 GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:579392
Yoichi Osato4c75c0c2020-06-24 08:03:579393 mock_quic_data.AddRead(
9394 ASYNC, ConstructServerDataPacket(
9395 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:529396 ConstructDataFrame("hello!")));
Yoichi Osato4c75c0c2020-06-24 08:03:579397
Renjie Tangcd594f32020-07-11 20:18:349398 mock_quic_data.AddWrite(SYNCHRONOUS,
9399 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:579400
9401 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:219402 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:579403 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9404
9405 // The non-alternate protocol job needs to hang in order to guarantee that
9406 // the alternate-protocol job will "win".
9407 AddHangingNonAlternateProtocolSocketData();
9408
9409 CreateSession();
9410 request_.method = "POST";
9411 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9412 request_.upload_data_stream = &upload_data;
9413
9414 SendRequestAndExpectQuicResponse("hello!");
9415}
9416
9417TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadPauseAndResume) {
9418 context_.params()->origins_to_force_quic_on.insert(
9419 HostPortPair::FromString("mail.example.org:443"));
9420
9421 MockQuicData mock_quic_data(version_);
9422 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
9423 int write_packet_index = 1;
9424 mock_quic_data.AddWrite(
9425 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
9426 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
9427 if (VersionUsesHttp3(version_.transport_version)) {
9428 mock_quic_data.AddWrite(
9429 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9430 }
9431 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:529432 mock_quic_data.AddWrite(
9433 SYNCHRONOUS,
9434 ConstructClientRequestHeadersAndDataFramesPacket(
9435 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9436 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9437 0, nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:579438 mock_quic_data.AddRead(
9439 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
9440 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289441 false, GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:579442 mock_quic_data.AddRead(
9443 SYNCHRONOUS, ConstructServerDataPacket(
9444 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529445 true, ConstructDataFrame("hello!")));
Yoichi Osato4c75c0c2020-06-24 08:03:579446
Renjie Tangcd594f32020-07-11 20:18:349447 mock_quic_data.AddWrite(SYNCHRONOUS,
9448 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:579449 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:219450 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:579451 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9452 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
9453
9454 CreateSession();
9455
9456 AddQuicAlternateProtocolMapping(
9457 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
9458
9459 // Set up request.
9460 request_.method = "POST";
9461 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9462 request_.upload_data_stream = &upload_data;
9463
9464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9465 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:269466 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:579467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9468 base::RunLoop().RunUntilIdle();
9469 // Resume QUIC job
9470 crypto_client_stream_factory_.last_stream()
9471 ->NotifySessionOneRttKeyAvailable();
9472 socket_data->Resume();
9473
9474 base::RunLoop().RunUntilIdle();
9475 CheckResponseData(&trans, "hello!");
9476}
9477
9478TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadFailH1AndResumeQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:359479 if (version_.AlpnDeferToRFCv1()) {
9480 // These versions currently do not support Alt-Svc.
9481 return;
9482 }
Yoichi Osato4c75c0c2020-06-24 08:03:579483 // This test confirms failed main job should not bother quic job.
9484 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:459485 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yoichi Osato4c75c0c2020-06-24 08:03:579486 MockRead("1.1 Body"),
9487 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9488 MockRead(ASYNC, OK)};
9489 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
9490 socket_factory_.AddSocketDataProvider(&http_data);
9491 AddCertificate(&ssl_data_);
9492 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9493
9494 MockQuicData mock_quic_data(version_);
9495 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
9496 int write_packet_index = 1;
9497 mock_quic_data.AddWrite(
9498 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
9499 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
9500 if (VersionUsesHttp3(version_.transport_version)) {
9501 mock_quic_data.AddWrite(
9502 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9503 }
9504 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:529505 mock_quic_data.AddWrite(
9506 SYNCHRONOUS,
9507 ConstructClientRequestHeadersAndDataFramesPacket(
9508 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9509 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9510 0, nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:579511 mock_quic_data.AddRead(
9512 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
9513 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289514 false, GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:579515 mock_quic_data.AddRead(
9516 SYNCHRONOUS, ConstructServerDataPacket(
9517 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529518 true, ConstructDataFrame("hello!")));
Renjie Tangcd594f32020-07-11 20:18:349519 mock_quic_data.AddWrite(SYNCHRONOUS,
9520 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:579521 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:219522 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:579523 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9524 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
9525
9526 // This packet won't be read because AllowHTTP1:false doesn't allow H/1
9527 // connection.
9528 MockRead http_reads2[] = {MockRead("HTTP/1.1 200 OK\r\n")};
9529 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
9530 socket_factory_.AddSocketDataProvider(&http_data2);
9531 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9532
9533 CreateSession();
9534
9535 // Send the first request via TCP and set up alternative service (QUIC) for
9536 // the origin.
9537 SendRequestAndExpectHttpResponse("1.1 Body");
9538
9539 // Settings to resume main H/1 job quickly while pausing quic job.
9540 AddQuicAlternateProtocolMapping(
9541 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
9542 ServerNetworkStats stats1;
Peter Kastinge5a38ed2021-10-02 03:06:359543 stats1.srtt = base::Microseconds(10);
Yoichi Osato4c75c0c2020-06-24 08:03:579544 http_server_properties_->SetServerNetworkStats(
9545 url::SchemeHostPort(request_.url), NetworkIsolationKey(), stats1);
9546
9547 // Set up request.
9548 request_.method = "POST";
9549 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9550 request_.upload_data_stream = &upload_data;
9551
9552 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9553 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:269554 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:579555 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9556 // Confirm TCP job was resumed.
9557 // We can not check its failure because HttpStreamFactory::JobController.
9558 // main_job_net_error is not exposed.
9559 while (socket_factory_.mock_data().next_index() < 3u)
9560 base::RunLoop().RunUntilIdle();
9561 // Resume QUIC job.
9562 crypto_client_stream_factory_.last_stream()
9563 ->NotifySessionOneRttKeyAvailable();
9564 socket_data->Resume();
9565 base::RunLoop().RunUntilIdle();
9566 CheckResponseData(&trans, "hello!");
9567}
9568
Bence Békyc164e0d22020-09-22 20:08:599569TEST_P(QuicNetworkTransactionTest, IncorrectHttp3GoAway) {
9570 if (!version_.HasIetfQuicFrames()) {
9571 return;
9572 }
9573
9574 context_.params()->retry_without_alt_svc_on_quic_errors = false;
9575
9576 MockQuicData mock_quic_data(version_);
9577 int write_packet_number = 1;
9578 mock_quic_data.AddWrite(
9579 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number++));
9580 mock_quic_data.AddWrite(
9581 SYNCHRONOUS,
9582 ConstructClientRequestHeadersPacket(
9583 write_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
9584 true, true, GetRequestHeaders("GET", "https", "/")));
9585
9586 int read_packet_number = 1;
9587 mock_quic_data.AddRead(
9588 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number++));
9589 // The GOAWAY frame sent by the server MUST have a stream ID corresponding to
9590 // a client-initiated bidirectional stream. Any other kind of stream ID
9591 // should cause the client to close the connection.
9592 quic::GoAwayFrame goaway{3};
9593 std::unique_ptr<char[]> goaway_buffer;
9594 auto goaway_length =
9595 quic::HttpEncoder::SerializeGoAwayFrame(goaway, &goaway_buffer);
9596 const quic::QuicStreamId control_stream_id =
9597 quic::QuicUtils::GetFirstUnidirectionalStreamId(
9598 version_.transport_version, quic::Perspective::IS_SERVER);
9599 mock_quic_data.AddRead(
Victor Vasiliev47ecb6a2020-10-14 17:22:109600 ASYNC, ConstructServerDataPacket(
9601 read_packet_number++, control_stream_id, false, false,
9602 absl::string_view(goaway_buffer.get(), goaway_length)));
Bence Békyc164e0d22020-09-22 20:08:599603 mock_quic_data.AddWrite(
9604 SYNCHRONOUS,
9605 ConstructClientAckAndConnectionClosePacket(
9606 write_packet_number++, 2, 4, quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
9607 "GOAWAY with invalid stream ID", 0));
9608 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9609
9610 // In order for a new QUIC session to be established via alternate-protocol
9611 // without racing an HTTP connection, we need the host resolution to happen
9612 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
9613 // connection to the the server, in this test we require confirmation
9614 // before encrypting so the HTTP job will still start.
9615 host_resolver_.set_synchronous_mode(true);
9616 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
9617 "");
9618
9619 CreateSession();
9620 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9621
9622 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9623 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:269624 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Bence Békyc164e0d22020-09-22 20:08:599625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9626
9627 crypto_client_stream_factory_.last_stream()
9628 ->NotifySessionOneRttKeyAvailable();
9629 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
9630
9631 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9632 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9633
9634 NetErrorDetails details;
9635 trans.PopulateNetErrorDetails(&details);
9636 EXPECT_THAT(details.quic_connection_error,
9637 quic::test::IsError(quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID));
9638}
9639
Bence Béky2ee18922020-09-25 12:11:329640TEST_P(QuicNetworkTransactionTest, RetryOnHttp3GoAway) {
9641 if (!version_.HasIetfQuicFrames()) {
9642 return;
9643 }
9644
9645 MockQuicData mock_quic_data1(version_);
9646 int write_packet_number1 = 1;
9647 mock_quic_data1.AddWrite(
9648 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number1++));
9649 const quic::QuicStreamId stream_id1 =
9650 GetNthClientInitiatedBidirectionalStreamId(0);
9651 mock_quic_data1.AddWrite(SYNCHRONOUS,
9652 ConstructClientRequestHeadersPacket(
9653 write_packet_number1++, stream_id1, true, true,
9654 GetRequestHeaders("GET", "https", "/")));
9655 const quic::QuicStreamId stream_id2 =
9656 GetNthClientInitiatedBidirectionalStreamId(1);
9657 mock_quic_data1.AddWrite(SYNCHRONOUS,
9658 ConstructClientRequestHeadersPacket(
9659 write_packet_number1++, stream_id2, true, true,
9660 GetRequestHeaders("GET", "https", "/foo")));
9661
9662 int read_packet_number1 = 1;
9663 mock_quic_data1.AddRead(
9664 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number1++));
9665
9666 // GOAWAY with stream_id2 informs the client that stream_id2 (and streams with
9667 // larger IDs) have not been processed and can safely be retried.
9668 quic::GoAwayFrame goaway{stream_id2};
9669 std::unique_ptr<char[]> goaway_buffer;
9670 auto goaway_length =
9671 quic::HttpEncoder::SerializeGoAwayFrame(goaway, &goaway_buffer);
9672 const quic::QuicStreamId control_stream_id =
9673 quic::QuicUtils::GetFirstUnidirectionalStreamId(
9674 version_.transport_version, quic::Perspective::IS_SERVER);
9675 mock_quic_data1.AddRead(
Victor Vasiliev47ecb6a2020-10-14 17:22:109676 ASYNC, ConstructServerDataPacket(
9677 read_packet_number1++, control_stream_id, false, false,
9678 absl::string_view(goaway_buffer.get(), goaway_length)));
Bence Béky2ee18922020-09-25 12:11:329679 mock_quic_data1.AddWrite(
9680 ASYNC, ConstructClientAckPacket(write_packet_number1++, 2, 1));
9681
9682 // Response to first request is accepted after GOAWAY.
9683 mock_quic_data1.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9684 read_packet_number1++, stream_id1, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289685 false, GetResponseHeaders("200")));
Bence Béky2ee18922020-09-25 12:11:329686 mock_quic_data1.AddRead(
9687 ASYNC, ConstructServerDataPacket(
9688 read_packet_number1++, stream_id1, false, true,
9689 ConstructDataFrame("response on the first connection")));
9690 mock_quic_data1.AddWrite(
9691 ASYNC, ConstructClientAckPacket(write_packet_number1++, 4, 1));
Bence Békye7426ec2021-02-02 18:18:199692 // Make socket hang to make sure connection stays in connection pool.
9693 // This should not prevent the retry from opening a new connection.
9694 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING);
David Schinazi395918c2021-02-05 18:56:219695 mock_quic_data1.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Bence Béky2ee18922020-09-25 12:11:329696 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9697
9698 // Second request is retried on a new connection.
9699 MockQuicData mock_quic_data2(version_);
9700 QuicTestPacketMaker client_maker2(
9701 version_,
9702 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9703 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9704 client_headers_include_h2_stream_dependency_);
9705 int write_packet_number2 = 1;
9706 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(
9707 write_packet_number2++));
9708 spdy::SpdyPriority priority =
9709 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
9710 mock_quic_data2.AddWrite(
9711 SYNCHRONOUS, client_maker2.MakeRequestHeadersPacket(
9712 write_packet_number2++, stream_id1, true, true, priority,
9713 GetRequestHeaders("GET", "https", "/foo"), 0, nullptr));
9714
9715 QuicTestPacketMaker server_maker2(
9716 version_,
9717 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9718 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9719 false);
9720 int read_packet_number2 = 1;
9721 mock_quic_data2.AddRead(ASYNC,
9722 server_maker2.MakeResponseHeadersPacket(
9723 read_packet_number2++, stream_id1, false, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:289724 GetResponseHeaders("200"), nullptr));
Bence Béky2ee18922020-09-25 12:11:329725 mock_quic_data2.AddRead(
9726 ASYNC, server_maker2.MakeDataPacket(
9727 read_packet_number2++, stream_id1, false, true,
9728 ConstructDataFrame("response on the second connection")));
9729 mock_quic_data2.AddWrite(
9730 ASYNC, client_maker2.MakeAckPacket(write_packet_number2++, 2, 1));
9731 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9732 mock_quic_data2.AddRead(ASYNC, 0); // EOF
9733 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9734
9735 AddHangingNonAlternateProtocolSocketData();
9736 CreateSession();
9737 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9738
9739 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
9740 TestCompletionCallback callback1;
Matt Reichhoff0049a0b72021-10-20 20:44:269741 int rv = trans1.Start(&request_, callback1.callback(), net_log_with_source_);
Bence Béky2ee18922020-09-25 12:11:329742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9743 base::RunLoop().RunUntilIdle();
9744
9745 HttpRequestInfo request2;
9746 request2.method = "GET";
9747 std::string url("https://");
9748 url.append(kDefaultServerHostName);
9749 url.append("/foo");
9750 request2.url = GURL(url);
9751 request2.load_flags = 0;
9752 request2.traffic_annotation =
9753 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9754 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9755 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:269756 rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
Bence Béky2ee18922020-09-25 12:11:329757 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9758
9759 EXPECT_THAT(callback1.WaitForResult(), IsOk());
9760 CheckResponseData(&trans1, "response on the first connection");
9761
9762 EXPECT_THAT(callback2.WaitForResult(), IsOk());
9763 CheckResponseData(&trans2, "response on the second connection");
9764
Bence Békye7426ec2021-02-02 18:18:199765 mock_quic_data1.Resume();
Bence Béky2ee18922020-09-25 12:11:329766 mock_quic_data2.Resume();
9767 EXPECT_TRUE(mock_quic_data1.AllWriteDataConsumed());
9768 EXPECT_TRUE(mock_quic_data1.AllReadDataConsumed());
9769 EXPECT_TRUE(mock_quic_data2.AllWriteDataConsumed());
9770 EXPECT_TRUE(mock_quic_data2.AllReadDataConsumed());
9771}
9772
Yoichi Osato4c75c0c2020-06-24 08:03:579773// TODO(yoichio): Add the TCP job reuse case. See crrev.com/c/2174099.
9774
Tsuyoshi Horo4f516be2022-06-14 11:53:139775} // namespace net::test