blob: 7173ffc6f4d384d76d6348187b7e9c32d08e9005 [file] [log] [blame]
Avi Drissman64595482022-09-14 20:52:291// Copyright 2012 The Chromium Authors
[email protected]61a527782013-02-21 03:58:002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
rchbd089ab2017-05-26 23:05:045#include <algorithm>
bnc359ed2a2016-04-29 20:43:456#include <ostream>
bnc912a04b2016-04-20 14:19:507#include <string>
8#include <utility>
[email protected]1e960032013-12-20 19:00:209#include <vector>
10
[email protected]61a527782013-02-21 03:58:0011#include "base/compiler_specific.h"
Avi Drissman41c4a412023-01-11 22:45:3712#include "base/functional/bind.h"
Keishi Hattori0e45c022021-11-27 09:25:5213#include "base/memory/raw_ptr.h"
mmenke651bae7f2015-12-18 21:26:4514#include "base/run_loop.h"
Bence Béky319388a882020-09-23 18:42:5215#include "base/strings/strcat.h"
zhongyie537a002017-06-27 16:48:2116#include "base/strings/string_number_conversions.h"
Bence Békyd74f4382018-02-20 18:26:1917#include "base/strings/string_piece.h"
bnc8be55ebb2015-10-30 14:12:0718#include "base/strings/stringprintf.h"
Devlin Cronine4bcb40e2018-06-05 18:02:4719#include "base/test/metrics/histogram_tester.h"
Matt Menke26e41542019-06-05 01:09:5120#include "base/test/scoped_feature_list.h"
rtenneti56977812016-01-15 19:26:5621#include "net/base/chunked_upload_data_stream.h"
Bence Békyd8a21fc32018-06-27 18:29:5822#include "net/base/completion_once_callback.h"
Matt Menke26e41542019-06-05 01:09:5123#include "net/base/features.h"
Tsuyoshi Horo01faed62019-02-20 22:11:3724#include "net/base/ip_endpoint.h"
mgershaf9a9232017-04-13 20:19:0325#include "net/base/mock_network_change_notifier.h"
Brianna Goldsteind22b0642022-10-11 16:30:5026#include "net/base/network_anonymization_key.h"
Andrew Williams13e652b2024-01-02 16:49:1227#include "net/base/proxy_chain.h"
Ciara McMullin4672e2d2023-10-31 19:14:1128#include "net/base/proxy_server.h"
29#include "net/base/proxy_string_util.h"
Matt Menke4807a9a2020-11-21 00:14:4130#include "net/base/schemeful_site.h"
[email protected]61a527782013-02-21 03:58:0031#include "net/base/test_completion_callback.h"
[email protected]6e7845ae2013-03-29 21:48:1132#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5333#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0034#include "net/http/http_auth_handler_factory.h"
Tsuyoshi Horo3023b5d2023-11-28 21:40:3135#include "net/http/http_connection_info.h"
[email protected]61a527782013-02-21 03:58:0036#include "net/http/http_network_session.h"
37#include "net/http/http_network_transaction.h"
Matt Menke6e879bd2019-03-18 17:26:0438#include "net/http/http_proxy_connect_job.h"
Matt Menke609160742019-08-02 18:47:2639#include "net/http/http_server_properties.h"
[email protected]61a527782013-02-21 03:58:0040#include "net/http/http_stream.h"
41#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1942#include "net/http/http_transaction_test_util.h"
Yoichi Osato4c75c0c2020-06-24 08:03:5743#include "net/http/test_upload_data_stream_not_allow_http1.h"
[email protected]b1c988b2013-06-13 06:48:1144#include "net/http/transport_security_state.h"
Matt Reichhoff0049a0b72021-10-20 20:44:2645#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0046#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5147#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4648#include "net/log/test_net_log_util.h"
Nicolas Arciniegad2013f92020-02-07 23:00:5649#include "net/proxy_resolution/configured_proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4050#include "net/proxy_resolution/proxy_config_service_fixed.h"
51#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0852#include "net/quic/crypto/proof_verifier_chromium.h"
53#include "net/quic/mock_crypto_client_stream_factory.h"
Victor Vasiliev7752898d2019-11-14 21:30:2254#include "net/quic/mock_quic_context.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0855#include "net/quic/mock_quic_data.h"
56#include "net/quic/quic_chromium_alarm_factory.h"
Patrick Meenan885a00652023-02-15 20:07:0257#include "net/quic/quic_context.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0858#include "net/quic/quic_http_stream.h"
59#include "net/quic/quic_http_utils.h"
60#include "net/quic/quic_stream_factory_peer.h"
61#include "net/quic/quic_test_packet_maker.h"
62#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0063#include "net/socket/client_socket_factory.h"
64#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2165#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2866#include "net/socket/socket_performance_watcher.h"
67#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0068#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5869#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5770#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2971#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0172#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4373#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4074#include "net/test/test_with_task_environment.h"
Ryan Hamiltonea4fa192022-04-12 18:30:4975#include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_decrypter.h"
76#include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_encrypter.h"
77#include "net/third_party/quiche/src/quiche/quic/core/quic_framer.h"
78#include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
79#include "net/third_party/quiche/src/quiche/quic/platform/api/quic_test.h"
80#include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
81#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_clock.h"
82#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
83#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_session_peer.h"
84#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
85#include "net/third_party/quiche/src/quiche/spdy/core/spdy_frame_builder.h"
86#include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2987#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0088#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4889#include "net/url_request/url_request.h"
Matt Menkea9606a0eb2020-09-11 20:36:3890#include "net/url_request/url_request_job_factory.h"
allada71b2efb2016-09-09 04:57:4891#include "net/url_request/url_request_test_util.h"
Momoka Yamamotoff688972022-11-02 03:37:4692#include "net/websockets/websocket_test_util.h"
robpercival214763f2016-07-01 23:27:0193#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0094#include "testing/gtest/include/gtest/gtest.h"
95#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4696#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0097
Reilly Grant89a7e512018-01-20 01:57:1698using ::testing::ElementsAre;
99using ::testing::Key;
100
Tsuyoshi Horo4f516be2022-06-14 11:53:13101namespace net::test {
[email protected]61a527782013-02-21 03:58:00102
103namespace {
104
bnc359ed2a2016-04-29 20:43:45105enum DestinationType {
106 // In pooling tests with two requests for different origins to the same
107 // destination, the destination should be
108 SAME_AS_FIRST, // the same as the first origin,
109 SAME_AS_SECOND, // the same as the second origin, or
110 DIFFERENT, // different from both.
111};
112
rch9ae5b3b2016-02-11 00:36:29113const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45114const char kDifferentHostname[] = "different.example.com";
115
David Schinazi09e9a6012019-10-03 17:37:57116struct TestParams {
117 quic::ParsedQuicVersion version;
Patrick Meenan0b1b18cf2023-09-21 20:19:47118 bool priority_header_enabled;
David Schinazi09e9a6012019-10-03 17:37:57119};
120
121// Used by ::testing::PrintToStringParamName().
122std::string PrintToString(const TestParams& p) {
Patrick Meenan0b1b18cf2023-09-21 20:19:47123 return base::StrCat({ParsedQuicVersionToString(p.version), "_",
124 p.priority_header_enabled ? "PriorityHeaderEnabled"
125 : "PriorityHeaderDisabled"});
David Schinazi09e9a6012019-10-03 17:37:57126}
127
bnc359ed2a2016-04-29 20:43:45128// Run QuicNetworkTransactionWithDestinationTest instances with all value
129// combinations of version and destination_type.
130struct PoolingTestParams {
Nick Harper23290b82019-05-02 00:02:56131 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45132 DestinationType destination_type;
133};
134
David Schinazi09e9a6012019-10-03 17:37:57135// Used by ::testing::PrintToStringParamName().
136std::string PrintToString(const PoolingTestParams& p) {
137 const char* destination_string = "";
138 switch (p.destination_type) {
139 case SAME_AS_FIRST:
140 destination_string = "SAME_AS_FIRST";
141 break;
142 case SAME_AS_SECOND:
143 destination_string = "SAME_AS_SECOND";
144 break;
145 case DIFFERENT:
146 destination_string = "DIFFERENT";
147 break;
148 }
Victor Vasiliev62c09dc2020-11-06 18:18:29149 return base::StrCat(
Bence Béky957bab12023-01-31 16:40:10150 {ParsedQuicVersionToString(p.version), "_", destination_string});
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 =
Patrick Meenan885a00652023-02-15 20:07:02189 AllSupportedQuicVersions();
Nico Weber6dcde5b2020-02-22 20:49:20190 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
Patrick Meenan0b1b18cf2023-09-21 20:19:47191 params.push_back(TestParams{version, true});
192 params.push_back(TestParams{version, false});
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 =
Patrick Meenan885a00652023-02-15 20:07:02200 AllSupportedQuicVersions();
Nico Weber6dcde5b2020-02-22 20:49:20201 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
Bence Béky957bab12023-01-31 16:40:10202 params.push_back(PoolingTestParams{version, SAME_AS_FIRST});
203 params.push_back(PoolingTestParams{version, SAME_AS_SECOND});
204 params.push_back(PoolingTestParams{version, DIFFERENT});
bnc359ed2a2016-04-29 20:43:45205 }
206 return params;
207}
bncb07c05532015-05-14 19:07:20208
Bence Béky319388a882020-09-23 18:42:52209std::string ConstructDataFrameForVersion(base::StringPiece body,
210 quic::ParsedQuicVersion version) {
Victor Vasilievc617d452022-03-07 15:54:25211 quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
212 body.size(), quiche::SimpleBufferAllocator::Get());
Ian Swett17d4d1c02021-06-08 19:52:41213 return base::StrCat({base::StringPiece(buffer.data(), buffer.size()), body});
Bence Béky319388a882020-09-23 18:42:52214}
215
[email protected]61a527782013-02-21 03:58:00216} // namespace
217
tbansal0f56a39a2016-04-07 22:03:38218class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40219 public:
tbansal180587c2017-02-16 15:13:23220 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
221 bool* rtt_notification_received)
222 : should_notify_updated_rtt_(should_notify_updated_rtt),
223 rtt_notification_received_(rtt_notification_received) {}
Peter Boström293b1342021-09-22 17:31:43224
225 TestSocketPerformanceWatcher(const TestSocketPerformanceWatcher&) = delete;
226 TestSocketPerformanceWatcher& operator=(const TestSocketPerformanceWatcher&) =
227 delete;
228
Tsuyoshi Horo07c3f0e2022-06-16 07:30:47229 ~TestSocketPerformanceWatcher() override = default;
tbansalfdf5665b2015-09-21 22:46:40230
tbansal180587c2017-02-16 15:13:23231 bool ShouldNotifyUpdatedRTT() const override {
232 return *should_notify_updated_rtt_;
233 }
tbansalfdf5665b2015-09-21 22:46:40234
tbansal0f56a39a2016-04-07 22:03:38235 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
236 *rtt_notification_received_ = true;
237 }
238
239 void OnConnectionChanged() override {}
240
241 private:
Keishi Hattori0e45c022021-11-27 09:25:52242 raw_ptr<bool> should_notify_updated_rtt_;
243 raw_ptr<bool> rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38244};
245
246class TestSocketPerformanceWatcherFactory
247 : public SocketPerformanceWatcherFactory {
248 public:
Tsuyoshi Horo4478fd32022-06-09 01:41:25249 TestSocketPerformanceWatcherFactory() = default;
Peter Boström293b1342021-09-22 17:31:43250
251 TestSocketPerformanceWatcherFactory(
252 const TestSocketPerformanceWatcherFactory&) = delete;
253 TestSocketPerformanceWatcherFactory& operator=(
254 const TestSocketPerformanceWatcherFactory&) = delete;
255
Tsuyoshi Horo07c3f0e2022-06-16 07:30:47256 ~TestSocketPerformanceWatcherFactory() override = default;
tbansal0f56a39a2016-04-07 22:03:38257
258 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42259 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41260 const Protocol protocol,
David Benjamin5241b582023-02-17 03:51:51261 const IPAddress& /* address */) override {
tbansalc8a94ea2015-11-02 23:58:51262 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38263 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51264 }
265 ++watcher_count_;
Tsuyoshi Horof8861cb2022-07-05 23:50:20266 return std::make_unique<TestSocketPerformanceWatcher>(
267 &should_notify_updated_rtt_, &rtt_notification_received_);
tbansalfdf5665b2015-09-21 22:46:40268 }
269
tbansalc8a94ea2015-11-02 23:58:51270 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40271
tbansalc8a94ea2015-11-02 23:58:51272 bool rtt_notification_received() const { return rtt_notification_received_; }
273
tbansal180587c2017-02-16 15:13:23274 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
275 should_notify_updated_rtt_ = should_notify_updated_rtt;
276 }
277
tbansalc8a94ea2015-11-02 23:58:51278 private:
Tsuyoshi Horo4478fd32022-06-09 01:41:25279 size_t watcher_count_ = 0u;
280 bool should_notify_updated_rtt_ = true;
281 bool rtt_notification_received_ = false;
tbansalc8a94ea2015-11-02 23:58:51282};
283
Ryan Hamilton8d9ee76e2018-05-29 23:52:52284class QuicNetworkTransactionTest
285 : public PlatformTest,
David Schinazi09e9a6012019-10-03 17:37:57286 public ::testing::WithParamInterface<TestParams>,
Gabriel Charette694c3c332019-08-19 14:53:05287 public WithTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00288 protected:
[email protected]1c04f9522013-02-21 20:32:43289 QuicNetworkTransactionTest()
David Schinazi09e9a6012019-10-03 17:37:57290 : version_(GetParam().version),
Nick Harper23290b82019-05-02 00:02:56291 supported_versions_(quic::test::SupportedVersions(version_)),
Tsuyoshi Horof8861cb2022-07-05 23:50:20292 client_maker_(std::make_unique<QuicTestPacketMaker>(
Zhongyi Shi1c022d22020-03-20 19:00:16293 version_,
294 quic::QuicUtils::CreateRandomConnectionId(
295 context_.random_generator()),
296 context_.clock(),
297 kDefaultServerHostName,
298 quic::Perspective::IS_CLIENT,
Patrick Meenan0b1b18cf2023-09-21 20:19:47299 /*client_priority_uses_incremental=*/true,
300 /*use_priority_header=*/true)),
Victor Vasiliev7752898d2019-11-14 21:30:22301 server_maker_(version_,
302 quic::QuicUtils::CreateRandomConnectionId(
303 context_.random_generator()),
304 context_.clock(),
305 kDefaultServerHostName,
306 quic::Perspective::IS_SERVER,
Patrick Meenan0b1b18cf2023-09-21 20:19:47307 /*client_priority_uses_incremental=*/false,
308 /*use_priority_header=*/false),
Tsuyoshi Horo2c0a5042022-07-06 05:53:07309 quic_task_runner_(
310 base::MakeRefCounted<TestTaskRunner>(context_.mock_clock())),
Tsuyoshi Horof8861cb2022-07-05 23:50:20311 ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()),
Nicolas Arciniegad2013f92020-02-07 23:00:56312 proxy_resolution_service_(
313 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11314 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke3233d8f22019-08-20 21:01:49315 http_server_properties_(std::make_unique<HttpServerProperties>()),
rchf114d982015-10-21 01:34:56316 ssl_data_(ASYNC, OK) {
Patrick Meenan0b1b18cf2023-09-21 20:19:47317 if (GetParam().priority_header_enabled) {
318 feature_list_.InitAndEnableFeature(net::features::kPriorityHeader);
319 } else {
320 feature_list_.InitAndDisableFeature(net::features::kPriorityHeader);
321 }
Renjie Tang98b4d512020-02-08 01:24:19322 FLAGS_quic_enable_http3_grease_randomness = false;
[email protected]aa9b14d2013-05-10 23:45:19323 request_.method = "GET";
rchf114d982015-10-21 01:34:56324 std::string url("https://");
bncb07c05532015-05-14 19:07:20325 url.append(kDefaultServerHostName);
326 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19327 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10328 request_.traffic_annotation =
329 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Victor Vasiliev7752898d2019-11-14 21:30:22330 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56331
332 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29333 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56334 verify_details_.cert_verify_result.verified_cert = cert;
335 verify_details_.cert_verify_result.is_issued_by_known_root = true;
336 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43337 }
[email protected]61a527782013-02-21 03:58:00338
dcheng67be2b1f2014-10-27 21:47:29339 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00340 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55341 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00342 }
343
dcheng67be2b1f2014-10-27 21:47:29344 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00345 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
346 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55347 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00348 PlatformTest::TearDown();
349 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55350 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40351 session_.reset();
[email protected]61a527782013-02-21 03:58:00352 }
353
Patrick Meenan0b1b18cf2023-09-21 20:19:47354 void DisablePriorityHeader() {
355 // switch client_maker_ to a version that does not add priority headers.
356 client_maker_ = std::make_unique<QuicTestPacketMaker>(
357 version_,
358 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
359 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
360 /*client_priority_uses_incremental=*/true,
361 /*use_priority_header=*/false);
362 }
363
Ryan Hamilton8d9ee76e2018-05-29 23:52:52364 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23365 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03366 return server_maker_.MakeConnectionClosePacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03367 num, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58368 }
369
Ryan Hamilton8d9ee76e2018-05-29 23:52:52370 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23371 uint64_t packet_number,
372 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34373 uint64_t smallest_received) {
Zhongyi Shi1c022d22020-03-20 19:00:16374 return client_maker_->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34375 smallest_received);
fayang3bcb8b502016-12-07 21:44:37376 }
377
Ryan Hamilton8d9ee76e2018-05-29 23:52:52378 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23379 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52380 quic::QuicStreamId stream_id,
381 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23382 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34383 uint64_t smallest_received) {
384 return client_maker_->MakeAckAndRstPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03385 num, stream_id, error_code, largest_received, smallest_received);
zhongyi6b5a3892016-03-12 04:46:20386 }
387
Ryan Hamilton8d9ee76e2018-05-29 23:52:52388 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23389 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52390 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41391 quic::QuicRstStreamErrorCode error_code) {
Tsuyoshi Horoea15e7a2023-05-23 00:12:03392 return client_maker_->MakeRstPacket(num, stream_id, error_code,
Zhongyi Shi1c022d22020-03-20 19:00:16393 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56394 }
395
Ryan Hamilton8d9ee76e2018-05-29 23:52:52396 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58397 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23398 uint64_t num,
Fan Yangac867502019-01-28 21:10:23399 uint64_t largest_received,
400 uint64_t smallest_received,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52401 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29402 const std::string& quic_error_details,
403 uint64_t frame_type) {
Zhongyi Shi1c022d22020-03-20 19:00:16404 return client_maker_->MakeAckAndConnectionClosePacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03405 num, largest_received, smallest_received, quic_error,
Renjie Tangcd594f32020-07-11 20:18:34406 quic_error_details, frame_type);
zhongyica364fbb2015-12-12 03:39:12407 }
408
Ryan Hamilton8d9ee76e2018-05-29 23:52:52409 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23410 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52411 quic::QuicStreamId stream_id,
412 quic::QuicRstStreamErrorCode error_code) {
Tsuyoshi Horoea15e7a2023-05-23 00:12:03413 return server_maker_.MakeRstPacket(num, stream_id, error_code);
zhongyica364fbb2015-12-12 03:39:12414 }
415
Ryan Hamilton8d9ee76e2018-05-29 23:52:52416 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02417 uint64_t packet_number) {
Zhongyi Shi1c022d22020-03-20 19:00:16418 return client_maker_->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37419 }
420
zhongyi32569c62016-01-08 02:54:30421 // Uses default QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01422 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
423 const std::string& scheme,
424 const std::string& path) {
Zhongyi Shi1c022d22020-03-20 19:00:16425 return GetRequestHeaders(method, scheme, path, client_maker_.get());
zhongyi32569c62016-01-08 02:54:30426 }
427
428 // Uses customized QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01429 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
430 const std::string& scheme,
431 const std::string& path,
432 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50433 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00434 }
435
Bence Béky4c325e52020-10-22 20:48:01436 spdy::Http2HeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Zhongyi Shi1c022d22020-03-20 19:00:16437 return client_maker_->ConnectRequestHeaders(host_port);
Yixin Wang46a273ec302018-01-23 17:59:56438 }
439
Bence Béky4c325e52020-10-22 20:48:01440 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58441 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00442 }
443
zhongyi32569c62016-01-08 02:54:30444 // Appends alt_svc headers in the response headers.
Bence Béky4c325e52020-10-22 20:48:01445 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status,
446 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58447 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30448 }
449
Ryan Hamilton8d9ee76e2018-05-29 23:52:52450 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23451 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52452 quic::QuicStreamId stream_id,
[email protected]61a527782013-02-21 03:58:00453 bool fin,
David Benjamin9f3b62e2023-10-02 16:03:42454 std::string_view data) {
Tsuyoshi Horoea15e7a2023-05-23 00:12:03455 return server_maker_.MakeDataPacket(packet_number, stream_id, fin, data);
[email protected]61a527782013-02-21 03:58:00456 }
457
Ryan Hamilton8d9ee76e2018-05-29 23:52:52458 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23459 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52460 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36461 bool fin,
David Benjamin9f3b62e2023-10-02 16:03:42462 std::string_view data) {
Tsuyoshi Horoea15e7a2023-05-23 00:12:03463 return client_maker_->MakeDataPacket(packet_number, stream_id, fin, data);
ckrasicda193a82016-07-09 00:39:36464 }
465
Ryan Hamilton8d9ee76e2018-05-29 23:52:52466 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23467 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52468 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23469 uint64_t largest_received,
470 uint64_t smallest_received,
Yixin Wang46a273ec302018-01-23 17:59:56471 bool fin,
David Benjamin9f3b62e2023-10-02 16:03:42472 std::string_view data) {
Tsuyoshi Horoea15e7a2023-05-23 00:12:03473 return client_maker_->MakeAckAndDataPacket(packet_number, stream_id,
474 largest_received,
Renjie Tangcd594f32020-07-11 20:18:34475 smallest_received, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56476 }
477
Kenichi Ishibashi10111e82021-03-23 02:19:06478 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckDataAndRst(
479 uint64_t packet_number,
Kenichi Ishibashi10111e82021-03-23 02:19:06480 quic::QuicStreamId stream_id,
481 quic::QuicRstStreamErrorCode error_code,
482 uint64_t largest_received,
483 uint64_t smallest_received,
484 quic::QuicStreamId data_id,
485 bool fin,
David Benjamin9f3b62e2023-10-02 16:03:42486 std::string_view data) {
Kenichi Ishibashi10111e82021-03-23 02:19:06487 return client_maker_->MakeAckDataAndRst(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03488 packet_number, stream_id, error_code, largest_received,
Kenichi Ishibashi10111e82021-03-23 02:19:06489 smallest_received, data_id, fin, data);
490 }
491
Ryan Hamilton8d9ee76e2018-05-29 23:52:52492 std::unique_ptr<quic::QuicEncryptedPacket>
Patrick Meenanf741c6082023-01-03 18:06:43493 ConstructClientRequestHeadersPacket(
494 uint64_t packet_number,
495 quic::QuicStreamId stream_id,
Patrick Meenanf741c6082023-01-03 18:06:43496 bool fin,
497 spdy::Http2HeaderBlock headers,
498 bool should_include_priority_frame = true) {
499 return ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03500 packet_number, stream_id, fin, DEFAULT_PRIORITY, std::move(headers),
501 should_include_priority_frame);
zhongyi32569c62016-01-08 02:54:30502 }
503
Ryan Hamilton8d9ee76e2018-05-29 23:52:52504 std::unique_ptr<quic::QuicEncryptedPacket>
Patrick Meenanf741c6082023-01-03 18:06:43505 ConstructClientRequestHeadersPacket(
506 uint64_t packet_number,
507 quic::QuicStreamId stream_id,
Patrick Meenanf741c6082023-01-03 18:06:43508 bool fin,
509 RequestPriority request_priority,
510 spdy::Http2HeaderBlock headers,
Patrick Meenanf741c6082023-01-03 18:06:43511 bool should_include_priority_frame = true) {
Ryan Hamilton0239aac2018-05-19 00:03:13512 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56513 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16514 return client_maker_->MakeRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03515 packet_number, stream_id, fin, priority, std::move(headers), nullptr,
516 should_include_priority_frame);
Patrick Meenanf741c6082023-01-03 18:06:43517 }
518
519 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
520 uint64_t packet_number,
521 quic::QuicStreamId id,
522 RequestPriority request_priority) {
523 spdy::SpdyPriority spdy_priority =
524 ConvertRequestPriorityToQuicPriority(request_priority);
Tsuyoshi Horoea15e7a2023-05-23 00:12:03525 return client_maker_->MakePriorityPacket(packet_number, id, spdy_priority);
[email protected]61a527782013-02-21 03:58:00526 }
527
Ryan Hamilton8d9ee76e2018-05-29 23:52:52528 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25529 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23530 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52531 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25532 bool fin,
533 RequestPriority request_priority,
Bence Béky4c325e52020-10-22 20:48:01534 spdy::Http2HeaderBlock headers,
Yixin Wange7ecc472018-03-06 19:00:25535 size_t* spdy_headers_frame_length,
536 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13537 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25538 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16539 return client_maker_->MakeRequestHeadersAndMultipleDataFramesPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03540 packet_number, stream_id, fin, priority, std::move(headers),
541 spdy_headers_frame_length, data_writes);
Yixin Wange7ecc472018-03-06 19:00:25542 }
543
Ryan Hamilton8d9ee76e2018-05-29 23:52:52544 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23545 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52546 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52547 bool fin,
Bence Béky4c325e52020-10-22 20:48:01548 spdy::Http2HeaderBlock headers) {
Tsuyoshi Horoea15e7a2023-05-23 00:12:03549 return server_maker_.MakeResponseHeadersPacket(
550 packet_number, stream_id, fin, std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30551 }
552
Bence Béky319388a882020-09-23 18:42:52553 std::string ConstructDataFrame(base::StringPiece body) {
554 return ConstructDataFrameForVersion(body, version_);
Renjief49758b2019-01-11 23:32:41555 }
556
Nick Harper23290b82019-05-02 00:02:56557 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41558 session_params_.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:38559 context_.params()->supported_versions = supported_versions;
[email protected]61a527782013-02-21 03:58:00560
Victor Vasiliev7752898d2019-11-14 21:30:22561 session_context_.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:41562 session_context_.client_socket_factory = &socket_factory_;
563 session_context_.quic_crypto_client_stream_factory =
564 &crypto_client_stream_factory_;
565 session_context_.host_resolver = &host_resolver_;
566 session_context_.cert_verifier = &cert_verifier_;
567 session_context_.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:41568 session_context_.socket_performance_watcher_factory =
569 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59570 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41571 session_context_.ssl_config_service = ssl_config_service_.get();
572 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49573 session_context_.http_server_properties = http_server_properties_.get();
Matt Reichhoff0049a0b72021-10-20 20:44:26574 session_context_.net_log = NetLog::Get();
mmenke6ddfbea2017-05-31 21:48:41575
Renjie Tang6ff9a9b2021-02-03 22:11:09576 session_ =
577 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
Matt Menkeb566c392019-09-11 23:22:43578 session_->quic_stream_factory()
579 ->set_is_quic_known_to_work_on_current_network(true);
Yixin Wang46a273ec302018-01-23 17:59:56580 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
581 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00582 }
583
zhongyi86838d52017-06-30 01:19:44584 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21585
David Schinazif832cb82019-11-08 22:25:27586 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
Zhongyi Shi1c022d22020-03-20 19:00:16587 const std::string& status_line,
588 const quic::ParsedQuicVersion& version) {
[email protected]aa9b14d2013-05-10 23:45:19589 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42590 ASSERT_TRUE(response != nullptr);
591 ASSERT_TRUE(response->headers.get() != nullptr);
David Schinazif832cb82019-11-08 22:25:27592 EXPECT_EQ(status_line, response->headers->GetStatusLine());
[email protected]aa9b14d2013-05-10 23:45:19593 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52594 EXPECT_TRUE(response->was_alpn_negotiated);
Victor Vasiliev22dd3f212022-02-11 21:57:29595 auto connection_info =
596 QuicHttpStream::ConnectionInfoFromQuicVersion(version);
597 if (connection_info == response->connection_info) {
598 return;
599 }
600 // QUIC v1 and QUIC v2 are considered a match, because they have the same
601 // ALPN token.
Tsuyoshi Horo3023b5d2023-11-28 21:40:31602 if ((connection_info == HttpConnectionInfo::kQUIC_RFC_V1 ||
603 connection_info == HttpConnectionInfo::kQUIC_2_DRAFT_8) &&
604 (response->connection_info == HttpConnectionInfo::kQUIC_RFC_V1 ||
605 response->connection_info == HttpConnectionInfo::kQUIC_2_DRAFT_8)) {
Victor Vasiliev22dd3f212022-02-11 21:57:29606 return;
607 }
608
609 // They do not match. This EXPECT_EQ will fail and print useful
610 // information.
611 EXPECT_EQ(connection_info, response->connection_info);
[email protected]aa9b14d2013-05-10 23:45:19612 }
613
Zhongyi Shi1c022d22020-03-20 19:00:16614 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
615 const std::string& status_line) {
616 CheckWasQuicResponse(trans, status_line, version_);
617 }
618
David Schinazif832cb82019-11-08 22:25:27619 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
Kenichi Ishibashif8634ab2021-03-16 23:41:28620 CheckWasQuicResponse(trans, "HTTP/1.1 200", version_);
David Schinazif832cb82019-11-08 22:25:27621 }
622
bnc691fda62016-08-12 00:43:16623 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41624 const HttpResponseInfo* response = trans->GetResponseInfo();
625 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37626 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41627 }
628
bnc691fda62016-08-12 00:43:16629 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19630 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42631 ASSERT_TRUE(response != nullptr);
632 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19633 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
634 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52635 EXPECT_FALSE(response->was_alpn_negotiated);
Tsuyoshi Horo3023b5d2023-11-28 21:40:31636 EXPECT_EQ(HttpConnectionInfo::kHTTP1_1, response->connection_info);
[email protected]aa9b14d2013-05-10 23:45:19637 }
638
Yixin Wang46a273ec302018-01-23 17:59:56639 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
640 const HttpResponseInfo* response = trans->GetResponseInfo();
641 ASSERT_TRUE(response != nullptr);
642 ASSERT_TRUE(response->headers.get() != nullptr);
643 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
644 EXPECT_TRUE(response->was_fetched_via_spdy);
645 EXPECT_TRUE(response->was_alpn_negotiated);
Tsuyoshi Horo3023b5d2023-11-28 21:40:31646 EXPECT_EQ(HttpConnectionInfo::kHTTP2, response->connection_info);
Yixin Wang46a273ec302018-01-23 17:59:56647 }
648
bnc691fda62016-08-12 00:43:16649 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19650 const std::string& expected) {
651 std::string response_data;
bnc691fda62016-08-12 00:43:16652 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19653 EXPECT_EQ(expected, response_data);
654 }
655
Andrew Williams13e652b2024-01-02 16:49:12656 void CheckUsedQuicProxyServer(HttpNetworkTransaction* trans) {
657 const ProxyChain& proxy_chain = trans->GetResponseInfo()->proxy_chain;
658 EXPECT_TRUE(proxy_chain.IsValid());
659 ASSERT_FALSE(proxy_chain.is_direct());
660 EXPECT_TRUE(proxy_chain.GetProxyServer(/*chain_index=*/0).is_quic());
661 }
662
bnc691fda62016-08-12 00:43:16663 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19664 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:26665 int rv = trans->Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:01666 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
667 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19668 }
669
670 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16671 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
672 RunTransaction(&trans);
673 CheckWasHttpResponse(&trans);
674 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19675 }
676
tbansalc3308d72016-08-27 10:25:04677 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
678 bool used_proxy,
679 uint16_t port) {
680 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalc3308d72016-08-27 10:25:04681 RunTransaction(&trans);
682 CheckWasHttpResponse(&trans);
683 CheckResponsePort(&trans, port);
684 CheckResponseData(&trans, expected);
tbansal2ecbbc72016-10-06 17:15:47685 if (used_proxy) {
Andrew Williams13e652b2024-01-02 16:49:12686 const ProxyChain& proxy_chain = trans.GetResponseInfo()->proxy_chain;
687 EXPECT_TRUE(proxy_chain.IsValid());
688 ASSERT_FALSE(proxy_chain.is_direct());
689 EXPECT_TRUE(proxy_chain.GetProxyServer(/*chain_index=*/0).is_https());
tbansal2ecbbc72016-10-06 17:15:47690 } else {
Andrew Williamsc3ea3b5d2023-10-25 14:32:46691 EXPECT_TRUE(trans.GetResponseInfo()->proxy_chain.is_direct());
tbansal2ecbbc72016-10-06 17:15:47692 }
tbansalc3308d72016-08-27 10:25:04693 }
David Schinazif832cb82019-11-08 22:25:27694 void SendRequestAndExpectQuicResponse(const std::string& expected,
695 const std::string& status_line) {
696 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443,
697 status_line);
698 }
tbansalc3308d72016-08-27 10:25:04699
[email protected]aa9b14d2013-05-10 23:45:19700 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56701 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12702 }
703
bnc62a44f022015-04-02 15:59:41704 void SendRequestAndExpectQuicResponseFromProxyOnPort(
705 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46706 uint16_t port) {
bnc62a44f022015-04-02 15:59:41707 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19708 }
709
710 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05711 MockCryptoClientStream::HandshakeMode handshake_mode,
Brianna Goldstein02cb74f2022-09-29 05:41:01712 const NetworkAnonymizationKey& network_anonymization_key =
713 NetworkAnonymizationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19714 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46715 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21716 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
Peter Kastinge5a38ed2021-10-02 03:06:35717 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:49718 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:01719 server, network_anonymization_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07720 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19721 }
722
rchbe69cb902016-02-11 01:10:48723 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27724 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48725 const HostPortPair& alternative) {
726 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46727 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21728 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48729 alternative.port());
Peter Kastinge5a38ed2021-10-02 03:06:35730 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:49731 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:01732 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07733 supported_versions_);
rchbe69cb902016-02-11 01:10:48734 }
735
Matt Menkeb32ba5122019-09-10 19:17:05736 void ExpectBrokenAlternateProtocolMapping(
Brianna Goldstein02cb74f2022-09-29 05:41:01737 const NetworkAnonymizationKey& network_anonymization_key =
738 NetworkAnonymizationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46739 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34740 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49741 http_server_properties_->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:01742 server, network_anonymization_key);
zhongyic4de03032017-05-19 04:07:34743 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49744 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05745 alternative_service_info_vector[0].alternative_service(),
Brianna Goldstein02cb74f2022-09-29 05:41:01746 network_anonymization_key));
[email protected]aa9b14d2013-05-10 23:45:19747 }
748
Matt Menkeb32ba5122019-09-10 19:17:05749 void ExpectQuicAlternateProtocolMapping(
Brianna Goldstein02cb74f2022-09-29 05:41:01750 const NetworkAnonymizationKey& network_anonymization_key =
751 NetworkAnonymizationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46752 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34753 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49754 http_server_properties_->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:01755 server, network_anonymization_key);
zhongyic4de03032017-05-19 04:07:34756 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54757 EXPECT_EQ(
758 kProtoQUIC,
759 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49760 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05761 alternative_service_info_vector[0].alternative_service(),
Brianna Goldstein02cb74f2022-09-29 05:41:01762 network_anonymization_key));
[email protected]4d590c9c2014-05-02 05:14:33763 }
764
[email protected]aa9b14d2013-05-10 23:45:19765 void AddHangingNonAlternateProtocolSocketData() {
Lei Zhange00db752021-04-17 00:48:46766 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
[email protected]dda75ab2013-06-22 22:43:30767 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30768 hanging_data->set_connect_data(hanging_connect);
769 hanging_data_.push_back(std::move(hanging_data));
770 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
[email protected]aa9b14d2013-05-10 23:45:19771 }
772
Matt Menkeb32ba5122019-09-10 19:17:05773 // Adds a new socket data provider for an HTTP request, and runs a request,
774 // expecting it to be used.
775 void AddHttpDataAndRunRequest() {
776 MockWrite http_writes[] = {
777 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
778 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
779 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
780
Ryan Hamiltona2dcbae2022-02-09 19:02:45781 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
782 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
783 MockRead(SYNCHRONOUS, 5, "http used"),
784 // Connection closed.
785 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:05786 SequencedSocketData http_data(http_reads, http_writes);
787 socket_factory_.AddSocketDataProvider(&http_data);
788 SSLSocketDataProvider ssl_data(ASYNC, OK);
789 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
790 SendRequestAndExpectHttpResponse("http used");
791 EXPECT_TRUE(http_data.AllWriteDataConsumed());
792 EXPECT_TRUE(http_data.AllReadDataConsumed());
793 }
794
795 // Adds a new socket data provider for a QUIC request, and runs a request,
796 // expecting it to be used. The new QUIC session is not closed.
797 void AddQuicDataAndRunRequest() {
798 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22799 version_,
800 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
801 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Patrick Meenan0b1b18cf2023-09-21 20:19:47802 /*client_priority_uses_incremental=*/true,
803 /*use_priority_header=*/true);
Matt Menkeb32ba5122019-09-10 19:17:05804 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22805 version_,
806 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
807 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Patrick Meenan0b1b18cf2023-09-21 20:19:47808 /*client_priority_uses_incremental=*/false,
809 /*use_priority_header=*/false);
Matt Menkeb32ba5122019-09-10 19:17:05810 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56811 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05812 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:02813 quic_data.AddWrite(SYNCHRONOUS,
814 client_maker.MakeInitialSettingsPacket(packet_number++));
Matt Menkeb32ba5122019-09-10 19:17:05815 quic_data.AddWrite(
816 SYNCHRONOUS,
817 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56818 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:03819 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:10820 GetRequestHeaders("GET", "https", "/", &client_maker), nullptr));
Matt Menkeb32ba5122019-09-10 19:17:05821 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Fan Yang1ef6dfef2021-07-24 16:20:16822 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Matt Menkeb32ba5122019-09-10 19:17:05823 quic_data.AddRead(
824 ASYNC, server_maker.MakeResponseHeadersPacket(
825 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:03826 server_maker.GetResponseHeaders("200"), nullptr));
Matt Menkeb32ba5122019-09-10 19:17:05827 quic_data.AddRead(
828 ASYNC, server_maker.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03829 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
830 ConstructDataFrame("quic used")));
Matt Menkeb32ba5122019-09-10 19:17:05831 // Don't care about the final ack.
832 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
833 // No more data to read.
834 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
835 quic_data.AddSocketDataToFactory(&socket_factory_);
Fan Yang1ef6dfef2021-07-24 16:20:16836
837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
838 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:26839 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Fan Yang1ef6dfef2021-07-24 16:20:16840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
841
842 // Pump the message loop to get the request started.
843 base::RunLoop().RunUntilIdle();
844 // Explicitly confirm the handshake.
845 crypto_client_stream_factory_.last_stream()
846 ->NotifySessionOneRttKeyAvailable();
847
848 ASSERT_FALSE(quic_data.AllReadDataConsumed());
849 quic_data.Resume();
850
851 // Run the QUIC session to completion.
852 base::RunLoop().RunUntilIdle();
Matt Menkeb32ba5122019-09-10 19:17:05853
854 EXPECT_TRUE(quic_data.AllReadDataConsumed());
855 }
856
Bence Béky6e243aa2019-12-13 19:01:07857 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56858 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
859 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36860 }
861
Bence Béky6e243aa2019-12-13 19:01:07862 quic::QuicStreamId GetQpackDecoderStreamId() const {
863 return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
864 version_.transport_version, 1);
865 }
866
867 std::string StreamCancellationQpackDecoderInstruction(int n) const {
Ian Swettb70d9f8f2020-04-10 23:38:43868 return StreamCancellationQpackDecoderInstruction(n, true);
869 }
870
871 std::string StreamCancellationQpackDecoderInstruction(
872 int n,
873 bool create_stream) const {
Bence Béky6e243aa2019-12-13 19:01:07874 const quic::QuicStreamId cancelled_stream_id =
875 GetNthClientInitiatedBidirectionalStreamId(n);
876 EXPECT_LT(cancelled_stream_id, 63u);
877
Peter Kasting241e6d22021-06-09 17:24:58878 const char opcode = 0x40;
Ian Swettb70d9f8f2020-04-10 23:38:43879 if (create_stream) {
Peter Kasting241e6d22021-06-09 17:24:58880 return {0x03, static_cast<char>(opcode | cancelled_stream_id)};
Ian Swettb70d9f8f2020-04-10 23:38:43881 } else {
Peter Kasting241e6d22021-06-09 17:24:58882 return {static_cast<char>(opcode | cancelled_stream_id)};
Ian Swettb70d9f8f2020-04-10 23:38:43883 }
Bence Béky6e243aa2019-12-13 19:01:07884 }
885
Bence Béky230ac612017-08-30 19:17:08886 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49887 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08888 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49889 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08890 }
891
Zhongyi Shi1c022d22020-03-20 19:00:16892 void SendRequestAndExpectQuicResponseMaybeFromProxy(
893 const std::string& expected,
894 bool used_proxy,
895 uint16_t port,
896 const std::string& status_line,
897 const quic::ParsedQuicVersion& version) {
898 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Zhongyi Shi1c022d22020-03-20 19:00:16899 RunTransaction(&trans);
900 CheckWasQuicResponse(&trans, status_line, version);
901 CheckResponsePort(&trans, port);
902 CheckResponseData(&trans, expected);
Zhongyi Shi1c022d22020-03-20 19:00:16903 if (used_proxy) {
Andrew Williams13e652b2024-01-02 16:49:12904 CheckUsedQuicProxyServer(&trans);
Cammie Smith Barnesbf91e2a2020-12-23 20:49:04905 // DNS aliases should be empty when using a proxy.
906 EXPECT_TRUE(trans.GetResponseInfo()->dns_aliases.empty());
Zhongyi Shi1c022d22020-03-20 19:00:16907 } else {
Andrew Williamsc3ea3b5d2023-10-25 14:32:46908 EXPECT_TRUE(trans.GetResponseInfo()->proxy_chain.is_direct());
Zhongyi Shi1c022d22020-03-20 19:00:16909 }
910 }
911
Victor Vasiliev22dd3f212022-02-11 21:57:29912 // Verify that the set of QUIC protocols in `alt_svc_info_vector` and
913 // `supported_versions` is the same. Since QUICv1 and QUICv2 have the same
914 // ALPN token "h3", they cannot be distinguished when parsing ALPN, so
915 // consider them equal. This is accomplished by comparing the set of ALPN
916 // strings (instead of comparing the set of ParsedQuicVersion entities).
917 static void VerifyQuicVersionsInAlternativeServices(
918 const AlternativeServiceInfoVector& alt_svc_info_vector,
919 const quic::ParsedQuicVersionVector& supported_versions) {
920 // Process supported versions.
921 std::set<std::string> supported_alpn;
922 for (const auto& version : supported_versions) {
923 if (version.AlpnDeferToRFCv1()) {
924 // These versions currently do not support Alt-Svc.
925 return;
926 }
927 supported_alpn.insert(quic::ParsedQuicVersionToString(version));
928 }
929
930 // Versions that support the legacy Google-specific Alt-Svc format are sent
931 // in a single Alt-Svc entry, therefore they are accumulated in a single
932 // AlternativeServiceInfo, whereas more recent versions all have their own
933 // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
934 std::set<std::string> alt_svc_negotiated_alpn;
935 for (const auto& alt_svc_info : alt_svc_info_vector) {
936 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
937 for (const auto& version : alt_svc_info.advertised_versions()) {
938 alt_svc_negotiated_alpn.insert(
939 quic::ParsedQuicVersionToString(version));
940 }
941 }
942
943 // Compare.
944 EXPECT_EQ(alt_svc_negotiated_alpn, supported_alpn);
945 }
946
Nick Harper23290b82019-05-02 00:02:56947 const quic::ParsedQuicVersion version_;
Ryan Hamiltona2dcbae2022-02-09 19:02:45948 const std::string alt_svc_header_ =
949 GenerateQuicAltSvcHeader({version_}) + "\r\n";
Nick Harper23290b82019-05-02 00:02:56950 quic::ParsedQuicVersionVector supported_versions_;
Patrick Meenan0041f332022-05-19 23:48:35951 quic::test::QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Victor Vasiliev7752898d2019-11-14 21:30:22952 MockQuicContext context_;
Zhongyi Shi1c022d22020-03-20 19:00:16953 std::unique_ptr<QuicTestPacketMaker> client_maker_;
alyssar2adf3ac2016-05-03 17:12:58954 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:09955 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:42956 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00957 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56958 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05959 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Eric Orthbe86fee2021-10-28 22:31:11960 MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
961 RuleResolver::GetLocalhostResult()};
[email protected]1c04f9522013-02-21 20:32:43962 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11963 TransportSecurityState transport_security_state_;
tbansal0f56a39a2016-04-07 22:03:38964 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07965 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:26966 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42967 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:49968 std::unique_ptr<HttpServerProperties> http_server_properties_;
Matt Menke30a878c2021-07-20 22:25:09969 HttpNetworkSessionParams session_params_;
970 HttpNetworkSessionContext session_context_;
[email protected]aa9b14d2013-05-10 23:45:19971 HttpRequestInfo request_;
Matt Reichhoff0049a0b72021-10-20 20:44:26972 NetLogWithSource net_log_with_source_{
973 NetLogWithSource::Make(NetLogSourceType::NONE)};
974 RecordingNetLogObserver net_log_observer_;
danakjad1777e2016-04-16 00:56:42975 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56976 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03977 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
Patrick Meenan0b1b18cf2023-09-21 20:19:47978 base::test::ScopedFeatureList feature_list_;
tbansal7cec3812015-02-05 21:25:12979
980 private:
981 void SendRequestAndExpectQuicResponseMaybeFromProxy(
982 const std::string& expected,
bnc62a44f022015-04-02 15:59:41983 bool used_proxy,
David Schinazif832cb82019-11-08 22:25:27984 uint16_t port,
985 const std::string& status_line) {
Zhongyi Shi1c022d22020-03-20 19:00:16986 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
987 status_line, version_);
tbansal7cec3812015-02-05 21:25:12988 }
David Schinazif832cb82019-11-08 22:25:27989
990 void SendRequestAndExpectQuicResponseMaybeFromProxy(
991 const std::string& expected,
992 bool used_proxy,
993 uint16_t port) {
994 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
Kenichi Ishibashif8634ab2021-03-16 23:41:28995 "HTTP/1.1 200", version_);
David Schinazif832cb82019-11-08 22:25:27996 }
[email protected]61a527782013-02-21 03:58:00997};
998
David Schinazi09e9a6012019-10-03 17:37:57999INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1000 QuicNetworkTransactionTest,
1001 ::testing::ValuesIn(GetTestParams()),
1002 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201003
Ryan Hamiltona64a5bcf2017-11-30 07:35:281004TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:381005 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281006 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381007 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281008 HostPortPair::FromString("mail.example.org:443"));
1009 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271010 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281011
Ryan Hamiltonabad59e2019-06-06 04:02:591012 MockQuicData mock_quic_data(version_);
Patrick Meenan885a00652023-02-15 20:07:021013 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281014 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1015 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211016 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281017
1018 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1019
1020 CreateSession();
1021
1022 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1023 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261024 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281025 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1026 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1027
1028 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1029 -ERR_INTERNET_DISCONNECTED, 1);
1030 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1031 -ERR_INTERNET_DISCONNECTED, 1);
1032}
1033
1034TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Victor Vasilieva1e66d72019-12-05 17:55:381035 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281036 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381037 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281038 HostPortPair::FromString("mail.example.org:443"));
1039 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271040 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281041
Ryan Hamiltonabad59e2019-06-06 04:02:591042 MockQuicData mock_quic_data(version_);
Patrick Meenan885a00652023-02-15 20:07:021043 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281044 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1045 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211046 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281047
1048 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1049
1050 CreateSession();
1051
1052 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1053 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261054 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1056 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1057
1058 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1059 -ERR_INTERNET_DISCONNECTED, 1);
1060 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1061 -ERR_INTERNET_DISCONNECTED, 1);
1062}
1063
tbansal180587c2017-02-16 15:13:231064TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381065 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231066 HostPortPair::FromString("mail.example.org:443"));
1067
Ryan Hamiltonabad59e2019-06-06 04:02:591068 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231069 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021070 mock_quic_data.AddWrite(SYNCHRONOUS,
1071 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361072 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231073 SYNCHRONOUS,
1074 ConstructClientRequestHeadersPacket(
1075 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031076 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431077 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331078 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031079 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281080 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331081 mock_quic_data.AddRead(
1082 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031083 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:521084 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231085 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341086 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231087 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1088
1089 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1090
1091 CreateSession();
1092 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1093
1094 EXPECT_FALSE(
1095 test_socket_performance_watcher_factory_.rtt_notification_received());
1096 SendRequestAndExpectQuicResponse("hello!");
1097 EXPECT_TRUE(
1098 test_socket_performance_watcher_factory_.rtt_notification_received());
1099}
1100
1101TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381102 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231103 HostPortPair::FromString("mail.example.org:443"));
1104
Ryan Hamiltonabad59e2019-06-06 04:02:591105 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231106 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021107 mock_quic_data.AddWrite(SYNCHRONOUS,
1108 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361109 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231110 SYNCHRONOUS,
1111 ConstructClientRequestHeadersPacket(
1112 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031113 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431114 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331115 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031116 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281117 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331118 mock_quic_data.AddRead(
1119 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031120 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:521121 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231122 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341123 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231124 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1125
1126 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1127
1128 CreateSession();
1129 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1130
1131 EXPECT_FALSE(
1132 test_socket_performance_watcher_factory_.rtt_notification_received());
1133 SendRequestAndExpectQuicResponse("hello!");
1134 EXPECT_FALSE(
1135 test_socket_performance_watcher_factory_.rtt_notification_received());
1136}
1137
[email protected]1e960032013-12-20 19:00:201138TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:381139 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571140 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471141
Ryan Hamiltonabad59e2019-06-06 04:02:591142 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231143 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021144 mock_quic_data.AddWrite(SYNCHRONOUS,
1145 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361146 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231147 SYNCHRONOUS,
1148 ConstructClientRequestHeadersPacket(
1149 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031150 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431151 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331152 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031153 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281154 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331155 mock_quic_data.AddRead(
1156 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031157 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:521158 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231159 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341160 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:591161 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471162
rcha5399e02015-04-21 19:32:041163 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471164
[email protected]4dca587c2013-03-07 16:54:471165 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471166
[email protected]aa9b14d2013-05-10 23:45:191167 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471168
[email protected]98b20ce2013-05-10 05:55:261169 // Check that the NetLog was filled reasonably.
Matt Reichhoff0049a0b72021-10-20 20:44:261170 auto entries = net_log_observer_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261171 EXPECT_LT(0u, entries.size());
1172
1173 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291174 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001175 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1176 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261177 EXPECT_LT(0, pos);
1178
David Schinazi24bfaa02020-10-22 19:54:381179 // ... and also a TYPE_QUIC_SESSION_PACKET_SENT.
1180 pos = ExpectLogContainsSomewhere(entries, 0,
1181 NetLogEventType::QUIC_SESSION_PACKET_SENT,
1182 NetLogEventPhase::NONE);
1183 EXPECT_LT(0, pos);
1184
rchfd527212015-08-25 00:41:261185 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291186 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261187 entries, 0,
mikecirone8b85c432016-09-08 19:11:001188 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1189 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261190 EXPECT_LT(0, pos);
1191
Eric Roman79cc7552019-07-19 02:17:541192 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261193
rchfd527212015-08-25 00:41:261194 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1195 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001196 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1197 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261198 EXPECT_LT(0, pos);
1199
[email protected]98b20ce2013-05-10 05:55:261200 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291201 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001202 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1203 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261204 EXPECT_LT(0, pos);
1205
Eric Roman79cc7552019-07-19 02:17:541206 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Patrick Meenan885a00652023-02-15 20:07:021207 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1208 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471209}
1210
Bence Békyb6300042020-01-28 21:18:201211// Regression test for https://crbug.com/1043531.
1212TEST_P(QuicNetworkTransactionTest, ResetOnEmptyResponseHeaders) {
Kenichi Ishibashi10111e82021-03-23 02:19:061213 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Bence Békyb6300042020-01-28 21:18:201214 context_.params()->origins_to_force_quic_on.insert(
1215 HostPortPair::FromString("mail.example.org:443"));
1216
1217 MockQuicData mock_quic_data(version_);
1218 int write_packet_num = 1;
1219 mock_quic_data.AddWrite(SYNCHRONOUS,
1220 ConstructInitialSettingsPacket(write_packet_num++));
1221 mock_quic_data.AddWrite(
1222 SYNCHRONOUS,
1223 ConstructClientRequestHeadersPacket(
1224 write_packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:031225 true, GetRequestHeaders("GET", "https", "/")));
Bence Békyb6300042020-01-28 21:18:201226
1227 const quic::QuicStreamId request_stream_id =
1228 GetNthClientInitiatedBidirectionalStreamId(0);
Bence Béky4c325e52020-10-22 20:48:011229 spdy::Http2HeaderBlock empty_response_headers;
Bence Békyb6300042020-01-28 21:18:201230 const std::string response_data = server_maker_.QpackEncodeHeaders(
1231 request_stream_id, std::move(empty_response_headers), nullptr);
1232 uint64_t read_packet_num = 1;
1233 mock_quic_data.AddRead(
1234 ASYNC, ConstructServerDataPacket(read_packet_num++, request_stream_id,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031235 false, response_data));
Bence Békyb6300042020-01-28 21:18:201236 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1237
1238 mock_quic_data.AddWrite(
Kenichi Ishibashi10111e82021-03-23 02:19:061239 ASYNC, ConstructClientAckDataAndRst(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031240 write_packet_num++, request_stream_id,
Kenichi Ishibashi10111e82021-03-23 02:19:061241 quic::QUIC_STREAM_GENERAL_PROTOCOL_ERROR, 1, 1,
1242 GetQpackDecoderStreamId(), false,
1243 StreamCancellationQpackDecoderInstruction(request_stream_id)));
Bence Békyb6300042020-01-28 21:18:201244
1245 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1246
1247 CreateSession();
1248
1249 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1250 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261251 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Bence Békyb6300042020-01-28 21:18:201252 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Kenichi Ishibashi10111e82021-03-23 02:19:061253 EXPECT_THAT(callback.WaitForResult(), IsError(net::ERR_QUIC_PROTOCOL_ERROR));
1254 base::RunLoop().RunUntilIdle();
1255 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1256 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
Bence Békyb6300042020-01-28 21:18:201257}
1258
rchbd089ab2017-05-26 23:05:041259TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381260 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041261 HostPortPair::FromString("mail.example.org:443"));
1262
Ryan Hamiltonabad59e2019-06-06 04:02:591263 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231264 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021265 mock_quic_data.AddWrite(SYNCHRONOUS,
1266 ConstructInitialSettingsPacket(packet_num++));
rchbd089ab2017-05-26 23:05:041267 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231268 SYNCHRONOUS,
1269 ConstructClientRequestHeadersPacket(
1270 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031271 GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashif8634ab2021-03-16 23:41:281272 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200");
rchbd089ab2017-05-26 23:05:041273 response_headers["key1"] = std::string(30000, 'A');
1274 response_headers["key2"] = std::string(30000, 'A');
1275 response_headers["key3"] = std::string(30000, 'A');
1276 response_headers["key4"] = std::string(30000, 'A');
1277 response_headers["key5"] = std::string(30000, 'A');
1278 response_headers["key6"] = std::string(30000, 'A');
1279 response_headers["key7"] = std::string(30000, 'A');
1280 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451281 quic::QuicStreamId stream_id;
1282 std::string response_data;
Patrick Meenan885a00652023-02-15 20:07:021283 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1284 response_data = server_maker_.QpackEncodeHeaders(
1285 stream_id, std::move(response_headers), nullptr);
rchbd089ab2017-05-26 23:05:041286
Fan Yangac867502019-01-28 21:10:231287 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041288 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451289 for (size_t offset = 0; offset < response_data.length();
1290 offset += chunk_size) {
1291 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431292 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451293 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031294 packet_number++, stream_id, false,
David Benjamin9f3b62e2023-10-02 16:03:421295 std::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041296 }
1297
1298 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331299 ASYNC, ConstructServerDataPacket(
1300 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:031301 true, ConstructDataFrame("hello!")));
rchbd089ab2017-05-26 23:05:041302 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341303 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Renjie Tangaadb84b2019-08-31 01:00:231304 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341305 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3));
rchbd089ab2017-05-26 23:05:041306
1307 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1308
1309 CreateSession();
1310
1311 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421312 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1313 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041314}
1315
1316TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381317 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1318 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041319 HostPortPair::FromString("mail.example.org:443"));
1320
Ryan Hamiltonabad59e2019-06-06 04:02:591321 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231322 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021323 mock_quic_data.AddWrite(SYNCHRONOUS,
1324 ConstructInitialSettingsPacket(packet_num++));
rchbd089ab2017-05-26 23:05:041325 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231326 SYNCHRONOUS,
1327 ConstructClientRequestHeadersPacket(
1328 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031329 GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451330
Kenichi Ishibashif8634ab2021-03-16 23:41:281331 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200");
rchbd089ab2017-05-26 23:05:041332 response_headers["key1"] = std::string(30000, 'A');
1333 response_headers["key2"] = std::string(30000, 'A');
1334 response_headers["key3"] = std::string(30000, 'A');
1335 response_headers["key4"] = std::string(30000, 'A');
1336 response_headers["key5"] = std::string(30000, 'A');
1337 response_headers["key6"] = std::string(30000, 'A');
1338 response_headers["key7"] = std::string(30000, 'A');
1339 response_headers["key8"] = std::string(30000, 'A');
1340 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451341
1342 quic::QuicStreamId stream_id;
1343 std::string response_data;
Patrick Meenan885a00652023-02-15 20:07:021344 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1345 response_data = server_maker_.QpackEncodeHeaders(
1346 stream_id, std::move(response_headers), nullptr);
rchbd089ab2017-05-26 23:05:041347
Fan Yangac867502019-01-28 21:10:231348 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041349 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451350 for (size_t offset = 0; offset < response_data.length();
1351 offset += chunk_size) {
1352 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431353 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451354 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031355 packet_number++, stream_id, false,
David Benjamin9f3b62e2023-10-02 16:03:421356 std::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041357 }
1358
1359 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331360 ASYNC, ConstructServerDataPacket(
1361 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:031362 true, ConstructDataFrame("hello!")));
rchbd089ab2017-05-26 23:05:041363 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341364 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431365 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331366 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231367 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:341368 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3));
rchbd089ab2017-05-26 23:05:041369
1370 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1371
1372 CreateSession();
1373
1374 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1375 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261376 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rchbd089ab2017-05-26 23:05:041377 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1378 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1379}
1380
Kenichi Ishibashifd2d3e62022-03-01 22:54:051381TEST_P(QuicNetworkTransactionTest, RedirectMultipleLocations) {
1382 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1383 context_.params()->origins_to_force_quic_on.insert(
1384 HostPortPair::FromString("mail.example.org:443"));
1385
1386 MockQuicData mock_quic_data(version_);
1387 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021388 mock_quic_data.AddWrite(SYNCHRONOUS,
1389 ConstructInitialSettingsPacket(packet_num++));
Kenichi Ishibashifd2d3e62022-03-01 22:54:051390 mock_quic_data.AddWrite(
1391 SYNCHRONOUS,
1392 ConstructClientRequestHeadersPacket(
1393 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031394 GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashifd2d3e62022-03-01 22:54:051395
1396 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("301");
1397 response_headers.AppendValueOrAddHeader("location", "https://example1.test");
1398 response_headers.AppendValueOrAddHeader("location", "https://example2.test");
1399
Patrick Meenan885a00652023-02-15 20:07:021400 const quic::QuicStreamId stream_id =
1401 GetNthClientInitiatedBidirectionalStreamId(0);
1402 const std::string response_data = server_maker_.QpackEncodeHeaders(
1403 stream_id, std::move(response_headers), nullptr);
1404 ASSERT_LT(response_data.size(), 1200u);
1405 mock_quic_data.AddRead(
1406 ASYNC, ConstructServerDataPacket(/*packet_number=*/1, stream_id,
Patrick Meenan885a00652023-02-15 20:07:021407 /*fin=*/true, response_data));
Kenichi Ishibashifd2d3e62022-03-01 22:54:051408 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1409
1410 mock_quic_data.AddWrite(
1411 ASYNC, ConstructClientAckAndRstPacket(
1412 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1413 quic::QUIC_STREAM_CANCELLED,
1414 /*largest_received=*/1, /*smallest_received=*/1));
1415
1416 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1417
1418 CreateSession();
1419
1420 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1421 TestCompletionCallback callback;
1422 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
1423 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1424 ASSERT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1425}
1426
rcha2bd44b2016-07-02 00:42:551427TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Victor Vasilieva1e66d72019-12-05 17:55:381428 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551429
Ryan Hamilton9835e662018-08-02 05:36:271430 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551431
Ryan Hamiltonabad59e2019-06-06 04:02:591432 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231433 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021434 mock_quic_data.AddWrite(SYNCHRONOUS,
1435 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361436 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231437 SYNCHRONOUS,
1438 ConstructClientRequestHeadersPacket(
1439 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031440 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431441 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331442 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031443 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281444 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331445 mock_quic_data.AddRead(
1446 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031447 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:521448 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231449 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341450 ConstructClientAckPacket(packet_num++, 2, 1));
rcha2bd44b2016-07-02 00:42:551451 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1452
1453 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1454
1455 CreateSession();
1456
1457 SendRequestAndExpectQuicResponse("hello!");
1458 EXPECT_TRUE(
1459 test_socket_performance_watcher_factory_.rtt_notification_received());
1460}
1461
David Schinazif832cb82019-11-08 22:25:271462// Regression test for https://crbug.com/695225
1463TEST_P(QuicNetworkTransactionTest, 408Response) {
Victor Vasilieva1e66d72019-12-05 17:55:381464 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
David Schinazif832cb82019-11-08 22:25:271465
1466 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1467
1468 MockQuicData mock_quic_data(version_);
1469 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021470 mock_quic_data.AddWrite(SYNCHRONOUS,
1471 ConstructInitialSettingsPacket(packet_num++));
David Schinazif832cb82019-11-08 22:25:271472 mock_quic_data.AddWrite(
1473 SYNCHRONOUS,
1474 ConstructClientRequestHeadersPacket(
1475 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031476 GetRequestHeaders("GET", "https", "/")));
David Schinazif832cb82019-11-08 22:25:271477 mock_quic_data.AddRead(
1478 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031479 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281480 GetResponseHeaders("408")));
David Schinazif832cb82019-11-08 22:25:271481 mock_quic_data.AddRead(
1482 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031483 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:521484 ConstructDataFrame("hello!")));
David Schinazif832cb82019-11-08 22:25:271485 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341486 ConstructClientAckPacket(packet_num++, 2, 1));
David Schinazif832cb82019-11-08 22:25:271487 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1488
1489 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1490
1491 CreateSession();
1492
Kenichi Ishibashif8634ab2021-03-16 23:41:281493 SendRequestAndExpectQuicResponse("hello!", "HTTP/1.1 408");
David Schinazif832cb82019-11-08 22:25:271494}
1495
[email protected]cf3e3cd62014-02-05 16:16:161496TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411497 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561498 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:271499 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:561500 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161501
Ryan Hamiltonabad59e2019-06-06 04:02:591502 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231503 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021504 mock_quic_data.AddWrite(SYNCHRONOUS,
1505 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361506 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231507 SYNCHRONOUS,
1508 ConstructClientRequestHeadersPacket(
1509 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031510 GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431511 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331512 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031513 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281514 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331515 mock_quic_data.AddRead(
1516 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031517 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:521518 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231519 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341520 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:501521 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211522 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
[email protected]cf3e3cd62014-02-05 16:16:161523
rcha5399e02015-04-21 19:32:041524 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161525
tbansal0f56a39a2016-04-07 22:03:381526 EXPECT_FALSE(
1527 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161528 // There is no need to set up an alternate protocol job, because
1529 // no attempt will be made to speak to the proxy over TCP.
1530
rch9ae5b3b2016-02-11 00:36:291531 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161532 CreateSession();
1533
bnc62a44f022015-04-02 15:59:411534 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381535 EXPECT_TRUE(
1536 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161537}
1538
bnc313ba9c2015-06-11 15:42:311539// Regression test for https://crbug.com/492458. Test that for an HTTP
1540// connection through a QUIC proxy, the certificate exhibited by the proxy is
1541// checked against the proxy hostname, not the origin hostname.
1542TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291543 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311544 const std::string proxy_host = "www.example.org";
1545
mmenke6ddfbea2017-05-31 21:48:411546 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561547 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:271548 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:561549 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311550
Zhongyi Shi1c022d22020-03-20 19:00:161551 client_maker_->set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591552 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231553 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021554 mock_quic_data.AddWrite(SYNCHRONOUS,
1555 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361556 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231557 SYNCHRONOUS,
1558 ConstructClientRequestHeadersPacket(
1559 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031560 GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431561 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331562 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031563 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281564 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331565 mock_quic_data.AddRead(
1566 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031567 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:521568 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231569 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341570 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:501571 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211572 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc313ba9c2015-06-11 15:42:311573 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1574
1575 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291576 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311577 ASSERT_TRUE(cert.get());
1578 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241579 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1580 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311581 ProofVerifyDetailsChromium verify_details;
1582 verify_details.cert_verify_result.verified_cert = cert;
1583 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561584 ProofVerifyDetailsChromium verify_details2;
1585 verify_details2.cert_verify_result.verified_cert = cert;
1586 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311587
1588 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091589 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321590 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271591 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311592 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1593}
1594
rchbe69cb902016-02-11 01:10:481595TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Victor Vasilieva1e66d72019-12-05 17:55:381596 context_.params()->allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481597 HostPortPair origin("www.example.org", 443);
1598 HostPortPair alternative("mail.example.org", 443);
1599
1600 base::FilePath certs_dir = GetTestCertsDirectory();
1601 scoped_refptr<X509Certificate> cert(
1602 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1603 ASSERT_TRUE(cert.get());
1604 // TODO(rch): the connection should be "to" the origin, so if the cert is
1605 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241606 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1607 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481608 ProofVerifyDetailsChromium verify_details;
1609 verify_details.cert_verify_result.verified_cert = cert;
1610 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1611
Zhongyi Shi1c022d22020-03-20 19:00:161612 client_maker_->set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591613 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021614
Renjie Tangaadb84b2019-08-31 01:00:231615 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021616 mock_quic_data.AddWrite(SYNCHRONOUS,
1617 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361618 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231619 SYNCHRONOUS,
1620 ConstructClientRequestHeadersPacket(
1621 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031622 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431623 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331624 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031625 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281626 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331627 mock_quic_data.AddRead(
1628 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031629 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:521630 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231631 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341632 ConstructClientAckPacket(packet_num++, 2, 1));
rchbe69cb902016-02-11 01:10:481633 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211634 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rchbe69cb902016-02-11 01:10:481635 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1636
1637 request_.url = GURL("https://" + origin.host());
1638 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271639 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091640 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321641 CreateSession();
rchbe69cb902016-02-11 01:10:481642
1643 SendRequestAndExpectQuicResponse("hello!");
1644}
1645
zhongyief3f4ce52017-07-05 23:53:281646TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
David Schinazi84c58bb2020-06-04 20:14:331647 quic::ParsedQuicVersion unsupported_version =
1648 quic::ParsedQuicVersion::Unsupported();
Bence Békyb89104962020-01-24 00:05:171649 // Add support for another QUIC version besides |version_|. Also find an
zhongyief3f4ce52017-07-05 23:53:281650 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561651 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Dustin J. Mitchell496de812024-01-16 19:14:541652 if (version == version_) {
zhongyief3f4ce52017-07-05 23:53:281653 continue;
Dustin J. Mitchell496de812024-01-16 19:14:541654 }
zhongyief3f4ce52017-07-05 23:53:281655 if (supported_versions_.size() != 2) {
1656 supported_versions_.push_back(version);
1657 continue;
1658 }
1659 unsupported_version = version;
1660 break;
1661 }
Bence Békyb89104962020-01-24 00:05:171662 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:331663 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), unsupported_version);
zhongyief3f4ce52017-07-05 23:53:281664
1665 // Set up alternative service to use QUIC with a version that is not
1666 // supported.
1667 url::SchemeHostPort server(request_.url);
1668 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1669 443);
Peter Kastinge5a38ed2021-10-02 03:06:351670 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:491671 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:011672 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:071673 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281674
1675 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491676 http_server_properties_->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:011677 server, NetworkAnonymizationKey());
zhongyief3f4ce52017-07-05 23:53:281678 EXPECT_EQ(1u, alt_svc_info_vector.size());
1679 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1680 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1681 EXPECT_EQ(unsupported_version,
1682 alt_svc_info_vector[0].advertised_versions()[0]);
1683
1684 // First request should still be sent via TCP as the QUIC version advertised
1685 // in the stored AlternativeService is not supported by the client. However,
1686 // the response from the server will advertise new Alt-Svc with supported
1687 // versions.
David Schinazifbd4c432020-04-07 19:23:551688 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyief3f4ce52017-07-05 23:53:281689 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:171690 MockRead("HTTP/1.1 200 OK\r\n"),
1691 MockRead(altsvc_header.c_str()),
1692 MockRead("\r\n"),
zhongyief3f4ce52017-07-05 23:53:281693 MockRead("hello world"),
1694 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1695 MockRead(ASYNC, OK)};
1696
Ryan Sleevib8d7ea02018-05-07 20:01:011697 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281698 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081699 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281700 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1701
1702 // Second request should be sent via QUIC as a new list of verions supported
1703 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591704 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231705 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021706 mock_quic_data.AddWrite(SYNCHRONOUS,
1707 ConstructInitialSettingsPacket(packet_num++));
zhongyief3f4ce52017-07-05 23:53:281708 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231709 SYNCHRONOUS,
1710 ConstructClientRequestHeadersPacket(
1711 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031712 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431713 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331714 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031715 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281716 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331717 mock_quic_data.AddRead(
1718 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031719 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:521720 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231721 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341722 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyief3f4ce52017-07-05 23:53:281723 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211724 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyief3f4ce52017-07-05 23:53:281725
1726 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1727
1728 AddHangingNonAlternateProtocolSocketData();
1729
1730 CreateSession(supported_versions_);
1731
1732 SendRequestAndExpectHttpResponse("hello world");
1733 SendRequestAndExpectQuicResponse("hello!");
1734
1735 // Check alternative service list is updated with new versions.
1736 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491737 session_->http_server_properties()->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:011738 server, NetworkAnonymizationKey());
Victor Vasiliev22dd3f212022-02-11 21:57:291739 VerifyQuicVersionsInAlternativeServices(alt_svc_info_vector,
1740 supported_versions_);
zhongyief3f4ce52017-07-05 23:53:281741}
1742
bncaccd4962017-04-06 21:00:261743// Regression test for https://crbug.com/546991.
1744// The server might not be able to serve a request on an alternative connection,
1745// and might send a 421 Misdirected Request response status to indicate this.
1746// HttpNetworkTransaction should reset the request and retry without using
1747// alternative services.
1748TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1749 // Set up alternative service to use QUIC.
1750 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1751 // that overrides |enable_alternative_services|.
1752 url::SchemeHostPort server(request_.url);
1753 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1754 443);
Peter Kastinge5a38ed2021-10-02 03:06:351755 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:491756 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:011757 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:071758 supported_versions_);
bncaccd4962017-04-06 21:00:261759
davidbena4449722017-05-05 23:30:531760 // First try: The alternative job uses QUIC and reports an HTTP 421
1761 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1762 // paused at Connect(), so it will never exit the socket pool. This ensures
1763 // that the alternate job always wins the race and keeps whether the
1764 // |http_data| exits the socket pool before the main job is aborted
1765 // deterministic. The first main job gets aborted without the socket pool ever
1766 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591767 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231768 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021769 mock_quic_data.AddWrite(SYNCHRONOUS,
1770 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361771 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231772 SYNCHRONOUS,
1773 ConstructClientRequestHeadersPacket(
1774 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031775 GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331776 mock_quic_data.AddRead(
1777 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031778 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021779 GetResponseHeaders("421")));
David Schinazi395918c2021-02-05 18:56:211780 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncaccd4962017-04-06 21:00:261781 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1782
davidbena4449722017-05-05 23:30:531783 // Second try: The main job uses TCP, and there is no alternate job. Once the
1784 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1785 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261786 // Note that if there was an alternative QUIC Job created for the second try,
1787 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1788 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531789 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1790 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1791 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1792 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1793 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1794 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011795 reads, writes);
bncaccd4962017-04-06 21:00:261796 socket_factory_.AddSocketDataProvider(&http_data);
1797 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1798
bncaccd4962017-04-06 21:00:261799 CreateSession();
1800 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531801
1802 // Run until |mock_quic_data| has failed and |http_data| has paused.
1803 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261804 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
davidbena4449722017-05-05 23:30:531805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1806 base::RunLoop().RunUntilIdle();
1807
1808 // |mock_quic_data| must have run to completion.
1809 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1810 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1811
1812 // Now that the QUIC data has been consumed, unblock |http_data|.
1813 http_data.socket()->OnConnectComplete(MockConnect());
1814
1815 // The retry logic must hide the 421 status. The transaction succeeds on
1816 // |http_data|.
1817 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261818 CheckWasHttpResponse(&trans);
1819 CheckResponsePort(&trans, 443);
1820 CheckResponseData(&trans, "hello!");
1821}
1822
[email protected]1e960032013-12-20 19:00:201823TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Victor Vasilieva1e66d72019-12-05 17:55:381824 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571825 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301826
Ryan Hamiltonabad59e2019-06-06 04:02:591827 MockQuicData mock_quic_data1(version_);
Patrick Meenan885a00652023-02-15 20:07:021828 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401829 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Zhongyi Shi1c022d22020-03-20 19:00:161830 client_maker_->Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591831 MockQuicData mock_quic_data2(version_);
Patrick Meenan885a00652023-02-15 20:07:021832 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301833 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401834 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431835 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401836
1837 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1838 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301839
1840 CreateSession();
1841
tbansal0f56a39a2016-04-07 22:03:381842 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401843 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161844 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401845 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261846 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:011847 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1848 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381849 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531850
1851 NetErrorDetails details;
1852 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521853 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401854 }
[email protected]cebe3282013-05-22 23:49:301855}
1856
tbansalc8a94ea2015-11-02 23:58:511857TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1858 // Attempt to "force" quic on 443, which will not be honored.
Victor Vasilieva1e66d72019-12-05 17:55:381859 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571860 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511861
1862 MockRead http_reads[] = {
1863 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1864 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1865 MockRead(ASYNC, OK)};
1866
Ryan Sleevib8d7ea02018-05-07 20:01:011867 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511868 socket_factory_.AddSocketDataProvider(&data);
1869 SSLSocketDataProvider ssl(ASYNC, OK);
1870 socket_factory_.AddSSLSocketDataProvider(&ssl);
1871
1872 CreateSession();
1873
1874 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381875 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511876}
1877
bncc958faa2015-07-31 18:14:521878TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:351879 if (version_.AlpnDeferToRFCv1()) {
1880 // These versions currently do not support Alt-Svc.
1881 return;
1882 }
bncc958faa2015-07-31 18:14:521883 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:451884 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:561885 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521886 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1887 MockRead(ASYNC, OK)};
1888
Ryan Sleevib8d7ea02018-05-07 20:01:011889 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521890 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081891 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561892 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521893
Ryan Hamiltonabad59e2019-06-06 04:02:591894 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231895 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021896 mock_quic_data.AddWrite(SYNCHRONOUS,
1897 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361898 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231899 SYNCHRONOUS,
1900 ConstructClientRequestHeadersPacket(
1901 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031902 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431903 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331904 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031905 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281906 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331907 mock_quic_data.AddRead(
1908 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031909 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:521910 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231911 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341912 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:521913 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211914 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:521915
1916 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1917
rtennetib8e80fb2016-05-16 00:12:091918 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321919 CreateSession();
bncc958faa2015-07-31 18:14:521920
1921 SendRequestAndExpectHttpResponse("hello world");
1922 SendRequestAndExpectQuicResponse("hello!");
1923}
1924
Ryan Hamilton64f21d52019-08-31 07:10:511925TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:351926 if (version_.AlpnDeferToRFCv1()) {
1927 // These versions currently do not support Alt-Svc.
1928 return;
1929 }
Ryan Hamilton64f21d52019-08-31 07:10:511930 std::string alt_svc_header =
1931 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
1932 MockRead http_reads[] = {
1933 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
1934 MockRead("hello world"),
1935 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1936 MockRead(ASYNC, OK)};
1937
1938 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
1939 socket_factory_.AddSocketDataProvider(&http_data);
1940 AddCertificate(&ssl_data_);
1941 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1942
1943 MockQuicData mock_quic_data(version_);
1944 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021945 mock_quic_data.AddWrite(SYNCHRONOUS,
1946 ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton64f21d52019-08-31 07:10:511947 mock_quic_data.AddWrite(
1948 SYNCHRONOUS,
1949 ConstructClientRequestHeadersPacket(
1950 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031951 GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton64f21d52019-08-31 07:10:511952 mock_quic_data.AddRead(
1953 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031954 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281955 GetResponseHeaders("200")));
Ryan Hamilton64f21d52019-08-31 07:10:511956 mock_quic_data.AddRead(
1957 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031958 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:521959 ConstructDataFrame("hello!")));
Ryan Hamilton64f21d52019-08-31 07:10:511960 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341961 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton64f21d52019-08-31 07:10:511962 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211963 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamilton64f21d52019-08-31 07:10:511964
1965 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1966
1967 AddHangingNonAlternateProtocolSocketData();
1968 CreateSession();
1969
1970 SendRequestAndExpectHttpResponse("hello world");
1971 SendRequestAndExpectQuicResponse("hello!");
1972}
1973
Brianna Goldstein02cb74f2022-09-29 05:41:011974// Much like above, but makes sure NetworkAnonymizationKey is respected.
Matt Menke3233d8f22019-08-20 21:01:491975TEST_P(QuicNetworkTransactionTest,
Brianna Goldstein02cb74f2022-09-29 05:41:011976 UseAlternativeServiceForQuicWithNetworkAnonymizationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:351977 if (version_.AlpnDeferToRFCv1()) {
1978 // These versions currently do not support Alt-Svc.
1979 return;
1980 }
Matt Menke3233d8f22019-08-20 21:01:491981 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:051982 feature_list.InitWithFeatures(
1983 // enabled_features
1984 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
1985 features::kPartitionConnectionsByNetworkIsolationKey},
1986 // disabled_features
1987 {});
Matt Menke3233d8f22019-08-20 21:01:491988 // Since HttpServerProperties caches the feature value, have to create a new
1989 // one.
1990 http_server_properties_ = std::make_unique<HttpServerProperties>();
1991
Matt Menke4807a9a2020-11-21 00:14:411992 const SchemefulSite kSite1(GURL("https://foo.test/"));
1993 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Dustin J. Mitchell1d774ea2023-03-03 00:54:461994 const auto kNetworkAnonymizationKey1 =
1995 NetworkAnonymizationKey::CreateSameSite(kSite1);
Brianna Goldstein314ddf722022-09-24 02:00:521996
Matt Menke4807a9a2020-11-21 00:14:411997 const SchemefulSite kSite2(GURL("https://bar.test/"));
1998 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Dustin J. Mitchell1d774ea2023-03-03 00:54:461999 const auto kNetworkAnonymizationKey2 =
2000 NetworkAnonymizationKey::CreateSameSite(kSite2);
Matt Menke3233d8f22019-08-20 21:01:492001
2002 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452003 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Matt Menke3233d8f22019-08-20 21:01:492004 MockRead("hello world"),
2005 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2006 MockRead(ASYNC, OK)};
2007
2008 AddCertificate(&ssl_data_);
2009
Brianna Goldsteind22b0642022-10-11 16:30:502010 // Request with empty NetworkAnonymizationKey.
Matt Menke3233d8f22019-08-20 21:01:492011 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2012 socket_factory_.AddSocketDataProvider(&http_data1);
2013 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2014
2015 // First request with kNetworkIsolationKey1.
2016 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2017 socket_factory_.AddSocketDataProvider(&http_data2);
2018 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2019
2020 // Request with kNetworkIsolationKey2.
2021 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2022 socket_factory_.AddSocketDataProvider(&http_data3);
2023 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2024
2025 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2026 // alternative service infrmation has been received in this context before.
2027 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232028 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022029 mock_quic_data.AddWrite(SYNCHRONOUS,
2030 ConstructInitialSettingsPacket(packet_num++));
Matt Menke3233d8f22019-08-20 21:01:492031 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232032 SYNCHRONOUS,
2033 ConstructClientRequestHeadersPacket(
2034 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032035 GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492036 mock_quic_data.AddRead(
2037 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032038 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282039 GetResponseHeaders("200")));
Matt Menke3233d8f22019-08-20 21:01:492040 mock_quic_data.AddRead(
2041 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032042 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:522043 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232044 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342045 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menke3233d8f22019-08-20 21:01:492046 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212047 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Matt Menke3233d8f22019-08-20 21:01:492048
2049 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2050
2051 AddHangingNonAlternateProtocolSocketData();
2052 CreateSession();
2053
2054 // This is first so that the test fails if alternative service info is
Brianna Goldsteind22b0642022-10-11 16:30:502055 // written with the right NetworkAnonymizationKey, but always queried with an
Matt Menke3233d8f22019-08-20 21:01:492056 // empty one.
Brianna Goldsteind22b0642022-10-11 16:30:502057 request_.network_isolation_key = NetworkIsolationKey();
Brianna Goldstein314ddf722022-09-24 02:00:522058 request_.network_anonymization_key = NetworkAnonymizationKey();
Matt Menke3233d8f22019-08-20 21:01:492059 SendRequestAndExpectHttpResponse("hello world");
2060 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:522061 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Menke3233d8f22019-08-20 21:01:492062 SendRequestAndExpectHttpResponse("hello world");
2063 request_.network_isolation_key = kNetworkIsolationKey2;
Brianna Goldstein314ddf722022-09-24 02:00:522064 request_.network_anonymization_key = kNetworkAnonymizationKey2;
Matt Menke3233d8f22019-08-20 21:01:492065 SendRequestAndExpectHttpResponse("hello world");
2066
Brianna Goldsteind22b0642022-10-11 16:30:502067 // Only use QUIC when using a NetworkAnonymizationKey which has been used when
Matt Menke3233d8f22019-08-20 21:01:492068 // alternative service information was received.
2069 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:522070 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Menke3233d8f22019-08-20 21:01:492071 SendRequestAndExpectQuicResponse("hello!");
2072}
2073
zhongyia00ca012017-07-06 23:36:392074TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
Ryan Hamiltona51800a2022-02-12 19:34:352075 if (version_.AlpnDeferToRFCv1()) {
2076 // These versions currently do not support Alt-Svc.
2077 return;
2078 }
Victor Vasiliev22dd3f212022-02-11 21:57:292079 // Both client and server supports two QUIC versions:
2080 // Client supports |supported_versions_[0]| and |supported_versions_[1]|,
2081 // server supports |version_| and |advertised_version_2|.
2082 // Only |version_| (same as |supported_versions_[0]|) is supported by both.
zhongyia00ca012017-07-06 23:36:392083 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2084 // PacketMakers are using |version_|.
2085
Victor Vasiliev22dd3f212022-02-11 21:57:292086 // Compare ALPN strings instead of ParsedQuicVersions because QUIC v1 and v2
2087 // have the same ALPN string.
2088 ASSERT_EQ(1u, supported_versions_.size());
2089 ASSERT_EQ(supported_versions_[0], version_);
David Schinazi84c58bb2020-06-04 20:14:332090 quic::ParsedQuicVersion advertised_version_2 =
2091 quic::ParsedQuicVersion::Unsupported();
Nick Harper23290b82019-05-02 00:02:562092 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Victor Vasiliev22dd3f212022-02-11 21:57:292093 if (quic::AlpnForVersion(version) == quic::AlpnForVersion(version_)) {
zhongyia00ca012017-07-06 23:36:392094 continue;
Victor Vasiliev22dd3f212022-02-11 21:57:292095 }
zhongyia00ca012017-07-06 23:36:392096 if (supported_versions_.size() != 2) {
2097 supported_versions_.push_back(version);
2098 continue;
2099 }
Victor Vasiliev22dd3f212022-02-11 21:57:292100 if (supported_versions_.size() == 2 &&
2101 quic::AlpnForVersion(supported_versions_[1]) ==
2102 quic::AlpnForVersion(version)) {
2103 continue;
2104 }
zhongyia00ca012017-07-06 23:36:392105 advertised_version_2 = version;
2106 break;
2107 }
Bence Békyb89104962020-01-24 00:05:172108 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:332109 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), advertised_version_2);
zhongyia00ca012017-07-06 23:36:392110
Bence Békyb89104962020-01-24 00:05:172111 std::string QuicAltSvcWithVersionHeader =
2112 base::StringPrintf("Alt-Svc: %s=\":443\", %s=\":443\"\r\n\r\n",
2113 quic::AlpnForVersion(advertised_version_2).c_str(),
2114 quic::AlpnForVersion(version_).c_str());
zhongyia00ca012017-07-06 23:36:392115
2116 MockRead http_reads[] = {
2117 MockRead("HTTP/1.1 200 OK\r\n"),
2118 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2119 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2120 MockRead(ASYNC, OK)};
2121
Ryan Sleevib8d7ea02018-05-07 20:01:012122 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392123 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082124 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392125 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2126
Ryan Hamiltonabad59e2019-06-06 04:02:592127 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232128 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022129 mock_quic_data.AddWrite(SYNCHRONOUS,
2130 ConstructInitialSettingsPacket(packet_num++));
zhongyia00ca012017-07-06 23:36:392131 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232132 SYNCHRONOUS,
2133 ConstructClientRequestHeadersPacket(
2134 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032135 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432136 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332137 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032138 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282139 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332140 mock_quic_data.AddRead(
2141 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032142 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:522143 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232144 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342145 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392146 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212147 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyia00ca012017-07-06 23:36:392148
2149 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2150
2151 AddHangingNonAlternateProtocolSocketData();
2152 CreateSession(supported_versions_);
2153
2154 SendRequestAndExpectHttpResponse("hello world");
2155 SendRequestAndExpectQuicResponse("hello!");
2156}
2157
Zhongyi Shi1c022d22020-03-20 19:00:162158TEST_P(QuicNetworkTransactionTest,
2159 PickQuicVersionWhenMultipleVersionsAreSupported) {
2160 // Client and server both support more than one QUIC_VERSION.
Patrick Meenan885a00652023-02-15 20:07:022161 // Client prefers common_version_2, and then |version_|.
2162 // Server prefers |version_| common_version_2.
David Schinazifbd4c432020-04-07 19:23:552163 // We should honor the server's preference.
Zhongyi Shi1c022d22020-03-20 19:00:162164 // The picked version is verified via checking the version used by the
2165 // TestPacketMakers and the response.
Patrick Meenan885a00652023-02-15 20:07:022166 // Since Chrome only supports one ALPN-negotiated version, common_version_2
2167 // will be another version that the common library supports even though
2168 // Chrome may consider it obsolete.
Bence Békyb89104962020-01-24 00:05:172169
Zhongyi Shi1c022d22020-03-20 19:00:162170 // Find an alternative commonly supported version other than |version_|.
David Schinazi84c58bb2020-06-04 20:14:332171 quic::ParsedQuicVersion common_version_2 =
2172 quic::ParsedQuicVersion::Unsupported();
2173 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Ryan Hamiltona51800a2022-02-12 19:34:352174 if (version != version_ && !version.AlpnDeferToRFCv1()) {
Zhongyi Shi1c022d22020-03-20 19:00:162175 common_version_2 = version;
2176 break;
2177 }
zhongyia00ca012017-07-06 23:36:392178 }
David Schinazi84c58bb2020-06-04 20:14:332179 ASSERT_NE(common_version_2, quic::ParsedQuicVersion::Unsupported());
zhongyia00ca012017-07-06 23:36:392180
Zhongyi Shi1c022d22020-03-20 19:00:162181 // Setting up client's preference list: {|version_|, |common_version_2|}.
2182 supported_versions_.clear();
Zhongyi Shi1c022d22020-03-20 19:00:162183 supported_versions_.push_back(common_version_2);
Patrick Meenan885a00652023-02-15 20:07:022184 supported_versions_.push_back(version_);
zhongyia00ca012017-07-06 23:36:392185
Zhongyi Shi1c022d22020-03-20 19:00:162186 // Setting up server's Alt-Svc header in the following preference order:
Patrick Meenan885a00652023-02-15 20:07:022187 // |version_|, |common_version_2|.
Zhongyi Shi1c022d22020-03-20 19:00:162188 std::string QuicAltSvcWithVersionHeader;
David Schinazi84c58bb2020-06-04 20:14:332189 quic::ParsedQuicVersion picked_version =
2190 quic::ParsedQuicVersion::Unsupported();
2191 QuicAltSvcWithVersionHeader =
Patrick Meenan885a00652023-02-15 20:07:022192 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"; ma=3600, " +
2193 quic::AlpnForVersion(common_version_2) + "=\":443\"; ma=3600\r\n\r\n";
2194 picked_version = version_; // Use server's preference.
zhongyia00ca012017-07-06 23:36:392195
2196 MockRead http_reads[] = {
2197 MockRead("HTTP/1.1 200 OK\r\n"),
2198 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2199 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2200 MockRead(ASYNC, OK)};
2201
Ryan Sleevib8d7ea02018-05-07 20:01:012202 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392203 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082204 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392205 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2206
Zhongyi Shi1c022d22020-03-20 19:00:162207 MockQuicData mock_quic_data(picked_version);
2208
2209 // Reset QuicTestPacket makers as the version picked may not be |version_|.
Renjie Tang6ff9a9b2021-02-03 22:11:092210 client_maker_ = std::make_unique<QuicTestPacketMaker>(
Zhongyi Shi1c022d22020-03-20 19:00:162211 picked_version,
2212 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2213 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Patrick Meenan0b1b18cf2023-09-21 20:19:472214 /*client_priority_uses_incremental=*/true, /*use_priority_header=*/true);
Zhongyi Shi1c022d22020-03-20 19:00:162215 QuicTestPacketMaker server_maker(
2216 picked_version,
2217 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2218 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Patrick Meenan0b1b18cf2023-09-21 20:19:472219 /*client_priority_uses_incremental=*/false,
2220 /*use_priority_header=*/false);
Zhongyi Shi1c022d22020-03-20 19:00:162221
Renjie Tangaadb84b2019-08-31 01:00:232222 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:162223 if (VersionUsesHttp3(picked_version.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232224 mock_quic_data.AddWrite(SYNCHRONOUS,
2225 ConstructInitialSettingsPacket(packet_num++));
2226 }
Zhongyi Shi1c022d22020-03-20 19:00:162227
2228 quic::QuicStreamId client_stream_0 =
2229 quic::test::GetNthClientInitiatedBidirectionalStreamId(
2230 picked_version.transport_version, 0);
2231 mock_quic_data.AddWrite(SYNCHRONOUS,
2232 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032233 packet_num++, client_stream_0, true,
Zhongyi Shi1c022d22020-03-20 19:00:162234 GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashif8634ab2021-03-16 23:41:282235 mock_quic_data.AddRead(ASYNC,
2236 server_maker.MakeResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032237 1, client_stream_0, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282238 server_maker.GetResponseHeaders("200"), nullptr));
Fan Yang32c5a112018-12-10 20:06:332239 mock_quic_data.AddRead(
Bence Béky319388a882020-09-23 18:42:522240 ASYNC, server_maker.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032241 2, client_stream_0, true,
Bence Béky319388a882020-09-23 18:42:522242 ConstructDataFrameForVersion("hello!", picked_version)));
Renjie Tangaadb84b2019-08-31 01:00:232243 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342244 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392245 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212246 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyia00ca012017-07-06 23:36:392247
2248 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2249
2250 AddHangingNonAlternateProtocolSocketData();
2251 CreateSession(supported_versions_);
2252
2253 SendRequestAndExpectHttpResponse("hello world");
Zhongyi Shi1c022d22020-03-20 19:00:162254 SendRequestAndExpectQuicResponseMaybeFromProxy(
Kenichi Ishibashif8634ab2021-03-16 23:41:282255 "hello!", false, 443, "HTTP/1.1 200", picked_version);
zhongyia00ca012017-07-06 23:36:392256}
2257
zhongyi3d4a55e72016-04-22 20:36:462258TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
Ryan Hamiltona51800a2022-02-12 19:34:352259 if (version_.AlpnDeferToRFCv1()) {
2260 // These versions currently do not support Alt-Svc.
2261 return;
2262 }
Ryan Hamiltona2dcbae2022-02-09 19:02:452263 std::string alt_svc_header = base::StrCat(
2264 {"Alt-Svc: ",
2265 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.com", 443), ",",
2266 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
zhongyi3d4a55e72016-04-22 20:36:462267 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452268 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
zhongyi3d4a55e72016-04-22 20:36:462269 MockRead("hello world"),
2270 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2271 MockRead(ASYNC, OK)};
2272
Ryan Sleevib8d7ea02018-05-07 20:01:012273 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462274 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082275 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462276 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2277
2278 CreateSession();
bncb26024382016-06-29 02:39:452279 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462280 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452281 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462282 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402283 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462284 session_->http_server_properties();
2285 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2286 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2287 // Check alternative service is set for the correct origin.
Brianna Goldstein02cb74f2022-09-29 05:41:012288 EXPECT_EQ(2u, http_server_properties
2289 ->GetAlternativeServiceInfos(https_server,
2290 NetworkAnonymizationKey())
2291 .size());
bncb26024382016-06-29 02:39:452292 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492293 http_server_properties
Brianna Goldstein02cb74f2022-09-29 05:41:012294 ->GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
Matt Menke3233d8f22019-08-20 21:01:492295 .empty());
zhongyi3d4a55e72016-04-22 20:36:462296}
2297
2298TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
Ryan Hamiltona51800a2022-02-12 19:34:352299 if (version_.AlpnDeferToRFCv1()) {
2300 // These versions currently do not support Alt-Svc.
2301 return;
2302 }
Ryan Hamiltona2dcbae2022-02-09 19:02:452303 std::string alt_svc_header = base::StrCat(
2304 {"Alt-Svc: ",
2305 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.com", 443), ",",
2306 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
zhongyi3d4a55e72016-04-22 20:36:462307 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452308 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
zhongyi3d4a55e72016-04-22 20:36:462309 MockRead("hello world"),
2310 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2311 MockRead(ASYNC, OK)};
2312
Ryan Sleevib8d7ea02018-05-07 20:01:012313 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082314 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462315
2316 socket_factory_.AddSocketDataProvider(&http_data);
2317 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2318 socket_factory_.AddSocketDataProvider(&http_data);
2319 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2320
2321 CreateSession();
2322
2323 // Send https request and set alternative services if response header
2324 // advertises alternative service for mail.example.org.
2325 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402326 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462327 session_->http_server_properties();
2328
2329 const url::SchemeHostPort https_server(request_.url);
2330 // Check alternative service is set.
Brianna Goldstein02cb74f2022-09-29 05:41:012331 EXPECT_EQ(2u, http_server_properties
2332 ->GetAlternativeServiceInfos(https_server,
2333 NetworkAnonymizationKey())
2334 .size());
zhongyi3d4a55e72016-04-22 20:36:462335
2336 // Send http request to the same origin but with diffrent scheme, should not
2337 // use QUIC.
2338 request_.url = GURL("http://mail.example.org:443");
2339 SendRequestAndExpectHttpResponse("hello world");
2340}
2341
zhongyie537a002017-06-27 16:48:212342TEST_P(QuicNetworkTransactionTest,
2343 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442344 // Add support for another QUIC version besides |version_|.
Patrick Meenan885a00652023-02-15 20:07:022345 for (const quic::ParsedQuicVersion& version : AllSupportedQuicVersions()) {
Bence Békyb89104962020-01-24 00:05:172346 if (version != version_) {
2347 supported_versions_.push_back(version);
2348 break;
2349 }
zhongyi86838d52017-06-30 01:19:442350 }
2351
David Schinazifbd4c432020-04-07 19:23:552352 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyie537a002017-06-27 16:48:212353 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:172354 MockRead("HTTP/1.1 200 OK\r\n"),
2355 MockRead(altsvc_header.c_str()),
2356 MockRead("\r\n"),
zhongyie537a002017-06-27 16:48:212357 MockRead("hello world"),
2358 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2359 MockRead(ASYNC, OK)};
2360
Ryan Sleevib8d7ea02018-05-07 20:01:012361 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212362 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082363 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212364 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2365
Ryan Hamiltonabad59e2019-06-06 04:02:592366 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232367 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022368 mock_quic_data.AddWrite(SYNCHRONOUS,
2369 ConstructInitialSettingsPacket(packet_num++));
zhongyie537a002017-06-27 16:48:212370 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232371 SYNCHRONOUS,
2372 ConstructClientRequestHeadersPacket(
2373 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032374 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432375 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332376 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032377 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282378 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332379 mock_quic_data.AddRead(
2380 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032381 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:522382 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232383 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342384 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyie537a002017-06-27 16:48:212385 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212386 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyie537a002017-06-27 16:48:212387
2388 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2389
2390 AddHangingNonAlternateProtocolSocketData();
2391
zhongyi86838d52017-06-30 01:19:442392 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212393
2394 SendRequestAndExpectHttpResponse("hello world");
2395 SendRequestAndExpectQuicResponse("hello!");
2396
Bence Békyb89104962020-01-24 00:05:172397 // Alt-Svc header contains all possible versions, so alternative services
2398 // should contain all of |supported_versions_|.
zhongyie537a002017-06-27 16:48:212399 const url::SchemeHostPort https_server(request_.url);
2400 const AlternativeServiceInfoVector alt_svc_info_vector =
2401 session_->http_server_properties()->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:012402 https_server, NetworkAnonymizationKey());
Victor Vasiliev22dd3f212022-02-11 21:57:292403 VerifyQuicVersionsInAlternativeServices(alt_svc_info_vector,
2404 supported_versions_);
zhongyie537a002017-06-27 16:48:212405}
2406
danzh3134c2562016-08-12 14:07:522407TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Ryan Hamiltona51800a2022-02-12 19:34:352408 if (version_.AlpnDeferToRFCv1()) {
2409 // These versions currently do not support Alt-Svc.
2410 return;
2411 }
Nick Harper23290b82019-05-02 00:02:562412 std::string altsvc_header = base::StringPrintf(
Bence Békyb89104962020-01-24 00:05:172413 "Alt-Svc: %s=\":443\"\r\n\r\n", quic::AlpnForVersion(version_).c_str());
bnc8be55ebb2015-10-30 14:12:072414 MockRead http_reads[] = {
2415 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2416 MockRead("hello world"),
2417 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2418 MockRead(ASYNC, OK)};
2419
Ryan Sleevib8d7ea02018-05-07 20:01:012420 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072421 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082422 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072423 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2424
Ryan Hamiltonabad59e2019-06-06 04:02:592425 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232426 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022427 mock_quic_data.AddWrite(SYNCHRONOUS,
2428 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:362429 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232430 SYNCHRONOUS,
2431 ConstructClientRequestHeadersPacket(
2432 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032433 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432434 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332435 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032436 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282437 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332438 mock_quic_data.AddRead(
2439 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032440 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:522441 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232442 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342443 ConstructClientAckPacket(packet_num++, 2, 1));
bnc8be55ebb2015-10-30 14:12:072444 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212445 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc8be55ebb2015-10-30 14:12:072446
2447 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2448
rtennetib8e80fb2016-05-16 00:12:092449 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322450 CreateSession();
bnc8be55ebb2015-10-30 14:12:072451
2452 SendRequestAndExpectHttpResponse("hello world");
2453 SendRequestAndExpectQuicResponse("hello!");
2454}
2455
rch9ecde09b2017-04-08 00:18:232456// Verify that if a QUIC connection times out, the QuicHttpStream will
2457// return QUIC_PROTOCOL_ERROR.
2458TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:382459 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Peter Kastinge5a38ed2021-10-02 03:06:352460 context_.params()->idle_connection_timeout = base::Seconds(5);
Renjie Tangd05389fe2022-07-13 23:46:232461 // Turn off port migration to avoid dealing with unnecessary complexity in
2462 // this test.
2463 context_.params()->allow_port_migration = false;
rch9ecde09b2017-04-08 00:18:232464
2465 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592466 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:132467 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232468 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2469
Zhongyi Shi1c022d22020-03-20 19:00:162470 client_maker_->set_save_packet_frames(true);
2471 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:492472 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022473 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton0d65a8c2019-06-07 00:46:022474 quic_data.AddWrite(
2475 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162476 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:492477 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032478 priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:452479
Zhongyi Shi1c022d22020-03-20 19:00:162480 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:232481
Patrick Meenan885a00652023-02-15 20:07:022482 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2483 // sending PTO packets.
2484 packet_num++;
2485 // PTO 1
Tsuyoshi Horoea15e7a2023-05-23 00:12:032486 quic_data.AddWrite(SYNCHRONOUS,
2487 client_maker_->MakeRetransmissionPacket(1, packet_num++));
Patrick Meenan885a00652023-02-15 20:07:022488 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2489 // sending PTO packets.
2490 packet_num++;
2491 // PTO 2
Tsuyoshi Horoea15e7a2023-05-23 00:12:032492 quic_data.AddWrite(SYNCHRONOUS,
2493 client_maker_->MakeRetransmissionPacket(2, packet_num++));
Patrick Meenan885a00652023-02-15 20:07:022494 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2495 // sending PTO packets.
2496 packet_num++;
2497 // PTO 3
Tsuyoshi Horoea15e7a2023-05-23 00:12:032498 quic_data.AddWrite(SYNCHRONOUS,
2499 client_maker_->MakeRetransmissionPacket(1, packet_num++));
Nick Harper0b214c132020-10-26 20:10:232500
Patrick Meenan885a00652023-02-15 20:07:022501 quic_data.AddWrite(SYNCHRONOUS,
2502 client_maker_->MakeConnectionClosePacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032503 packet_num++, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Patrick Meenan885a00652023-02-15 20:07:022504 "No recent network activity after 4s. Timeout:4s"));
Fan Yang928f1632017-12-14 18:55:222505
rch9ecde09b2017-04-08 00:18:232506 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2507 quic_data.AddRead(ASYNC, OK);
2508 quic_data.AddSocketDataToFactory(&socket_factory_);
2509
2510 // In order for a new QUIC session to be established via alternate-protocol
2511 // without racing an HTTP connection, we need the host resolution to happen
2512 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2513 // connection to the the server, in this test we require confirmation
2514 // before encrypting so the HTTP job will still start.
2515 host_resolver_.set_synchronous_mode(true);
2516 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2517 "");
rch9ecde09b2017-04-08 00:18:232518
2519 CreateSession();
2520 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232521 QuicStreamFactoryPeer::SetAlarmFactory(
2522 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192523 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222524 context_.clock()));
rch9ecde09b2017-04-08 00:18:232525
Ryan Hamilton9835e662018-08-02 05:36:272526 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232527
2528 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2529 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262530 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch9ecde09b2017-04-08 00:18:232531 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2532
2533 // Pump the message loop to get the request started.
2534 base::RunLoop().RunUntilIdle();
2535 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:282536 crypto_client_stream_factory_.last_stream()
2537 ->NotifySessionOneRttKeyAvailable();
rch9ecde09b2017-04-08 00:18:232538
2539 // Run the QUIC session to completion.
2540 quic_task_runner_->RunUntilIdle();
2541
2542 ExpectQuicAlternateProtocolMapping();
2543 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2544 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2545}
2546
David Schinazi7e980ab2020-05-13 20:26:552547// TODO(fayang): Add time driven TOO_MANY_RTOS test.
rch9ecde09b2017-04-08 00:18:232548
rch2f2991c2017-04-13 19:28:172549// Verify that if a QUIC protocol error occurs after the handshake is confirmed
2550// the request fails with QUIC_PROTOCOL_ERROR.
2551TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:382552 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:172553 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592554 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:162555 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:492556 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022557 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Nick Harper057264a82019-09-12 23:33:492558 quic_data.AddWrite(
2559 SYNCHRONOUS,
2560 ConstructClientRequestHeadersPacket(
2561 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032562 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:162563 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:552564 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:172565 // Peer sending data from an non-existing stream causes this end to raise
2566 // error and close connection.
Tsuyoshi Horoea15e7a2023-05-23 00:12:032567 quic_data.AddRead(ASYNC,
2568 ConstructServerRstPacket(
2569 1, GetNthClientInitiatedBidirectionalStreamId(47),
2570 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:172571 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:342572 quic_data.AddWrite(
2573 SYNCHRONOUS,
2574 ConstructClientAckAndConnectionClosePacket(
Patrick Meenan885a00652023-02-15 20:07:022575 packet_num++, 1, 1, quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
2576 quic_error_details, quic::IETF_STOP_SENDING));
rch2f2991c2017-04-13 19:28:172577 quic_data.AddSocketDataToFactory(&socket_factory_);
2578
2579 // In order for a new QUIC session to be established via alternate-protocol
2580 // without racing an HTTP connection, we need the host resolution to happen
2581 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2582 // connection to the the server, in this test we require confirmation
2583 // before encrypting so the HTTP job will still start.
2584 host_resolver_.set_synchronous_mode(true);
2585 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2586 "");
rch2f2991c2017-04-13 19:28:172587
2588 CreateSession();
2589
Ryan Hamilton9835e662018-08-02 05:36:272590 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:172591
2592 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2593 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262594 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:172595 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2596
2597 // Pump the message loop to get the request started.
2598 base::RunLoop().RunUntilIdle();
2599 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:282600 crypto_client_stream_factory_.last_stream()
2601 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:172602
2603 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:552604 quic_data.Resume();
rch2f2991c2017-04-13 19:28:172605
2606 // Run the QUIC session to completion.
2607 base::RunLoop().RunUntilIdle();
2608 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2609 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2610
2611 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2612 ExpectQuicAlternateProtocolMapping();
2613 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2614}
2615
rch2f2991c2017-04-13 19:28:172616// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
2617// connection times out, then QUIC will be marked as broken and the request
2618// retried over TCP.
2619TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Ryan Hamiltona51800a2022-02-12 19:34:352620 if (version_.AlpnDeferToRFCv1()) {
2621 // These versions currently do not support Alt-Svc.
2622 return;
2623 }
Peter Kastinge5a38ed2021-10-02 03:06:352624 context_.params()->idle_connection_timeout = base::Seconds(5);
Renjie Tangd05389fe2022-07-13 23:46:232625 // Turn off port migration to avoid dealing with unnecessary complexity in
2626 // this test.
2627 context_.params()->allow_port_migration = false;
rch2f2991c2017-04-13 19:28:172628
2629 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592630 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:132631 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:172632 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2633
Zhongyi Shi1c022d22020-03-20 19:00:162634 client_maker_->set_save_packet_frames(true);
2635 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:492636 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022637 quic_data.AddWrite(SYNCHRONOUS,
2638 client_maker_->MakeInitialSettingsPacket(packet_num++));
Ryan Hamilton0d65a8c2019-06-07 00:46:022639 quic_data.AddWrite(
2640 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162641 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:492642 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032643 priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:452644
Zhongyi Shi1c022d22020-03-20 19:00:162645 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Patrick Meenan885a00652023-02-15 20:07:022646 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2647 // sending PTO packets.
2648 packet_num++;
2649 // PTO 1
Tsuyoshi Horoea15e7a2023-05-23 00:12:032650 quic_data.AddWrite(SYNCHRONOUS,
2651 client_maker_->MakeRetransmissionPacket(1, packet_num++));
Nick Harper0b214c132020-10-26 20:10:232652
Patrick Meenan885a00652023-02-15 20:07:022653 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2654 // sending PTO packets.
2655 packet_num++;
2656 // PTO 2
Tsuyoshi Horoea15e7a2023-05-23 00:12:032657 quic_data.AddWrite(SYNCHRONOUS,
2658 client_maker_->MakeRetransmissionPacket(2, packet_num++));
Nick Harper0b214c132020-10-26 20:10:232659
Patrick Meenan885a00652023-02-15 20:07:022660 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2661 // sending PTO packets.
2662 packet_num++;
2663 // PTO 3
Tsuyoshi Horoea15e7a2023-05-23 00:12:032664 quic_data.AddWrite(SYNCHRONOUS,
2665 client_maker_->MakeRetransmissionPacket(1, packet_num++));
Nick Harper0b214c132020-10-26 20:10:232666
Patrick Meenan885a00652023-02-15 20:07:022667 quic_data.AddWrite(SYNCHRONOUS,
2668 client_maker_->MakeConnectionClosePacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032669 packet_num++, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Patrick Meenan885a00652023-02-15 20:07:022670 "No recent network activity after 4s. Timeout:4s"));
Fan Yang928f1632017-12-14 18:55:222671
rch2f2991c2017-04-13 19:28:172672 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2673 quic_data.AddRead(ASYNC, OK);
2674 quic_data.AddSocketDataToFactory(&socket_factory_);
2675
2676 // After that fails, it will be resent via TCP.
2677 MockWrite http_writes[] = {
2678 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2679 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2680 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2681
Ryan Hamiltona2dcbae2022-02-09 19:02:452682 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2683 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
2684 MockRead(SYNCHRONOUS, 5, "hello world"),
2685 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:012686 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:172687 socket_factory_.AddSocketDataProvider(&http_data);
2688 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2689
2690 // In order for a new QUIC session to be established via alternate-protocol
2691 // without racing an HTTP connection, we need the host resolution to happen
2692 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2693 // connection to the the server, in this test we require confirmation
2694 // before encrypting so the HTTP job will still start.
2695 host_resolver_.set_synchronous_mode(true);
2696 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2697 "");
rch2f2991c2017-04-13 19:28:172698
2699 CreateSession();
2700 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:172701 QuicStreamFactoryPeer::SetAlarmFactory(
2702 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192703 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222704 context_.clock()));
rch2f2991c2017-04-13 19:28:172705
Ryan Hamilton9835e662018-08-02 05:36:272706 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:172707
2708 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2709 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262710 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:172711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2712
2713 // Pump the message loop to get the request started.
2714 base::RunLoop().RunUntilIdle();
2715 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:282716 crypto_client_stream_factory_.last_stream()
2717 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:172718
2719 // Run the QUIC session to completion.
2720 quic_task_runner_->RunUntilIdle();
2721 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2722
2723 ExpectQuicAlternateProtocolMapping();
2724
2725 // Let the transaction proceed which will result in QUIC being marked
2726 // as broken and the request falling back to TCP.
2727 EXPECT_THAT(callback.WaitForResult(), IsOk());
2728
2729 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2730 ASSERT_FALSE(http_data.AllReadDataConsumed());
2731
2732 // Read the response body over TCP.
2733 CheckResponseData(&trans, "hello world");
2734 ExpectBrokenAlternateProtocolMapping();
2735 ASSERT_TRUE(http_data.AllWriteDataConsumed());
2736 ASSERT_TRUE(http_data.AllReadDataConsumed());
2737}
2738
rch2f2991c2017-04-13 19:28:172739// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
2740// protocol error occurs after the handshake is confirmed, the request
2741// retried over TCP and the QUIC will be marked as broken.
2742TEST_P(QuicNetworkTransactionTest,
2743 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:352744 if (version_.AlpnDeferToRFCv1()) {
2745 // These versions currently do not support Alt-Svc.
2746 return;
2747 }
Peter Kastinge5a38ed2021-10-02 03:06:352748 context_.params()->idle_connection_timeout = base::Seconds(5);
rch2f2991c2017-04-13 19:28:172749
2750 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592751 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:162752 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:492753 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022754 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Nick Harper057264a82019-09-12 23:33:492755 quic_data.AddWrite(
2756 SYNCHRONOUS,
2757 ConstructClientRequestHeadersPacket(
2758 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032759 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:162760 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:552761 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2762
rch2f2991c2017-04-13 19:28:172763 // Peer sending data from an non-existing stream causes this end to raise
2764 // error and close connection.
Tsuyoshi Horoea15e7a2023-05-23 00:12:032765 quic_data.AddRead(ASYNC,
2766 ConstructServerRstPacket(
2767 1, GetNthClientInitiatedBidirectionalStreamId(47),
2768 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:172769 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:342770 quic_data.AddWrite(
2771 SYNCHRONOUS,
2772 ConstructClientAckAndConnectionClosePacket(
Patrick Meenan885a00652023-02-15 20:07:022773 packet_num++, 1, 1, quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
2774 quic_error_details, quic::IETF_STOP_SENDING));
rch2f2991c2017-04-13 19:28:172775 quic_data.AddSocketDataToFactory(&socket_factory_);
2776
2777 // After that fails, it will be resent via TCP.
2778 MockWrite http_writes[] = {
2779 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2780 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2781 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2782
Ryan Hamiltona2dcbae2022-02-09 19:02:452783 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2784 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
2785 MockRead(SYNCHRONOUS, 5, "hello world"),
2786 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:012787 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:172788 socket_factory_.AddSocketDataProvider(&http_data);
2789 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2790
2791 // In order for a new QUIC session to be established via alternate-protocol
2792 // without racing an HTTP connection, we need the host resolution to happen
2793 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2794 // connection to the the server, in this test we require confirmation
2795 // before encrypting so the HTTP job will still start.
2796 host_resolver_.set_synchronous_mode(true);
2797 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2798 "");
rch2f2991c2017-04-13 19:28:172799
2800 CreateSession();
2801
Ryan Hamilton9835e662018-08-02 05:36:272802 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:172803
2804 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2805 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262806 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:172807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2808
2809 // Pump the message loop to get the request started.
2810 base::RunLoop().RunUntilIdle();
2811 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:282812 crypto_client_stream_factory_.last_stream()
2813 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:552814 quic_data.Resume();
rch2f2991c2017-04-13 19:28:172815
2816 // Run the QUIC session to completion.
2817 base::RunLoop().RunUntilIdle();
2818 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2819
2820 ExpectQuicAlternateProtocolMapping();
2821
2822 // Let the transaction proceed which will result in QUIC being marked
2823 // as broken and the request falling back to TCP.
2824 EXPECT_THAT(callback.WaitForResult(), IsOk());
2825
2826 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2827 ASSERT_FALSE(http_data.AllReadDataConsumed());
2828
2829 // Read the response body over TCP.
2830 CheckResponseData(&trans, "hello world");
2831 ExpectBrokenAlternateProtocolMapping();
2832 ASSERT_TRUE(http_data.AllWriteDataConsumed());
2833 ASSERT_TRUE(http_data.AllReadDataConsumed());
2834}
2835
Brianna Goldsteind22b0642022-10-11 16:30:502836// Much like above test, but verifies that NetworkAnonymizationKey is respected.
Matt Menkeb32ba5122019-09-10 19:17:052837TEST_P(QuicNetworkTransactionTest,
2838 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:352839 if (version_.AlpnDeferToRFCv1()) {
2840 // These versions currently do not support Alt-Svc.
2841 return;
2842 }
Matt Menke4807a9a2020-11-21 00:14:412843 const SchemefulSite kSite1(GURL("https://foo.test/"));
2844 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Dustin J. Mitchell1d774ea2023-03-03 00:54:462845 const auto kNetworkAnonymizationKey1 =
2846 NetworkAnonymizationKey::CreateSameSite(kSite1);
Matt Menke4807a9a2020-11-21 00:14:412847 const SchemefulSite kSite2(GURL("https://bar.test/"));
2848 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Dustin J. Mitchell1d774ea2023-03-03 00:54:462849 const auto kNetworkAnonymizationKey2 =
2850 NetworkAnonymizationKey::CreateSameSite(kSite2);
Matt Menkeb32ba5122019-09-10 19:17:052851
2852 base::test::ScopedFeatureList feature_list;
2853 feature_list.InitWithFeatures(
2854 // enabled_features
2855 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2856 features::kPartitionConnectionsByNetworkIsolationKey},
2857 // disabled_features
2858 {});
2859 // Since HttpServerProperties caches the feature value, have to create a new
2860 // one.
2861 http_server_properties_ = std::make_unique<HttpServerProperties>();
2862
Peter Kastinge5a38ed2021-10-02 03:06:352863 context_.params()->idle_connection_timeout = base::Seconds(5);
Matt Menkeb32ba5122019-09-10 19:17:052864
2865 // The request will initially go out over QUIC.
2866 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:562867 uint64_t packet_number = 1;
Zhongyi Shi1c022d22020-03-20 19:00:162868 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:022869 quic_data.AddWrite(SYNCHRONOUS,
2870 ConstructInitialSettingsPacket(packet_number++));
Renjie Tang874398a2019-09-13 18:32:562871 quic_data.AddWrite(
2872 SYNCHRONOUS,
2873 ConstructClientRequestHeadersPacket(
2874 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032875 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:162876 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:052877 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2878
2879 // Peer sending data from an non-existing stream causes this end to raise
2880 // error and close connection.
Tsuyoshi Horoea15e7a2023-05-23 00:12:032881 quic_data.AddRead(ASYNC,
2882 ConstructServerRstPacket(
2883 1, GetNthClientInitiatedBidirectionalStreamId(47),
2884 quic::QUIC_STREAM_LAST_ERROR));
Matt Menkeb32ba5122019-09-10 19:17:052885 std::string quic_error_details = "Data for nonexistent stream";
Nick Harper1ccb0ce2020-10-07 00:28:582886 quic::QuicErrorCode quic_error_code = quic::QUIC_INVALID_STREAM_ID;
Patrick Meenan885a00652023-02-15 20:07:022887 quic_error_code = quic::QUIC_HTTP_STREAM_WRONG_DIRECTION;
2888 quic_data.AddWrite(SYNCHRONOUS,
2889 ConstructClientAckAndConnectionClosePacket(
2890 packet_number++, 1, 1, quic_error_code,
2891 quic_error_details, quic::IETF_STOP_SENDING));
Matt Menkeb32ba5122019-09-10 19:17:052892 quic_data.AddSocketDataToFactory(&socket_factory_);
2893
2894 // After that fails, it will be resent via TCP.
2895 MockWrite http_writes[] = {
2896 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2897 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2898 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2899
Ryan Hamiltona2dcbae2022-02-09 19:02:452900 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2901 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
2902 MockRead(SYNCHRONOUS, 5, "hello world"),
2903 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:052904 SequencedSocketData http_data(http_reads, http_writes);
2905 socket_factory_.AddSocketDataProvider(&http_data);
2906 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2907
2908 // In order for a new QUIC session to be established via alternate-protocol
2909 // without racing an HTTP connection, we need the host resolution to happen
2910 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2911 // connection to the the server, in this test we require confirmation
2912 // before encrypting so the HTTP job will still start.
2913 host_resolver_.set_synchronous_mode(true);
2914 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2915 "");
2916
2917 CreateSession();
2918
2919 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
Brianna Goldstein02cb74f2022-09-29 05:41:012920 kNetworkAnonymizationKey1);
Matt Menkeb32ba5122019-09-10 19:17:052921 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
Brianna Goldstein02cb74f2022-09-29 05:41:012922 kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:052923
2924 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2925 TestCompletionCallback callback;
2926 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:522927 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Reichhoff0049a0b72021-10-20 20:44:262928 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeb32ba5122019-09-10 19:17:052929 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2930
2931 // Pump the message loop to get the request started.
2932 base::RunLoop().RunUntilIdle();
2933 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:282934 crypto_client_stream_factory_.last_stream()
2935 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:052936 quic_data.Resume();
2937
2938 // Run the QUIC session to completion.
2939 base::RunLoop().RunUntilIdle();
2940 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2941
2942 // Let the transaction proceed which will result in QUIC being marked
2943 // as broken and the request falling back to TCP.
2944 EXPECT_THAT(callback.WaitForResult(), IsOk());
2945 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2946 ASSERT_FALSE(http_data.AllReadDataConsumed());
2947
2948 // Read the response body over TCP.
2949 CheckResponseData(&trans, "hello world");
2950 ASSERT_TRUE(http_data.AllWriteDataConsumed());
2951 ASSERT_TRUE(http_data.AllReadDataConsumed());
2952
2953 // The alternative service shouldhave been marked as broken under
2954 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
Brianna Goldstein02cb74f2022-09-29 05:41:012955 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
2956 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:052957
2958 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
2959 AddHttpDataAndRunRequest();
2960 // Requests using other NetworkIsolationKeys can still use QUIC.
2961 request_.network_isolation_key = kNetworkIsolationKey2;
Brianna Goldstein314ddf722022-09-24 02:00:522962 request_.network_anonymization_key = kNetworkAnonymizationKey2;
2963
Matt Menkeb32ba5122019-09-10 19:17:052964 AddQuicDataAndRunRequest();
2965
2966 // The last two requests should not have changed the alternative service
2967 // mappings.
Brianna Goldstein02cb74f2022-09-29 05:41:012968 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
2969 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:052970}
2971
Tsuyoshi Horo0f740832022-11-28 22:36:212972TEST_P(QuicNetworkTransactionTest,
2973 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithUseDnsHttpsSvcbAlpn) {
Tsuyoshi Horo94cc9fa2023-01-19 00:04:572974 session_params_.use_dns_https_svcb_alpn = true;
Tsuyoshi Horo0f740832022-11-28 22:36:212975 context_.params()->idle_connection_timeout = base::Seconds(5);
2976
2977 // The request will initially go out over QUIC.
2978 MockQuicData quic_data(version_);
2979 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
2980 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022981 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Tsuyoshi Horo0f740832022-11-28 22:36:212982 quic_data.AddWrite(
2983 SYNCHRONOUS,
2984 ConstructClientRequestHeadersPacket(
2985 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032986 GetRequestHeaders("GET", "https", "/")));
Tsuyoshi Horo0f740832022-11-28 22:36:212987 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2988 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2989
2990 // Peer sending data from an non-existing stream causes this end to raise
2991 // error and close connection.
Tsuyoshi Horoea15e7a2023-05-23 00:12:032992 quic_data.AddRead(ASYNC,
2993 ConstructServerRstPacket(
2994 1, GetNthClientInitiatedBidirectionalStreamId(47),
2995 quic::QUIC_STREAM_LAST_ERROR));
Tsuyoshi Horo0f740832022-11-28 22:36:212996 std::string quic_error_details = "Data for nonexistent stream";
2997 quic_data.AddWrite(
2998 SYNCHRONOUS,
2999 ConstructClientAckAndConnectionClosePacket(
Patrick Meenan885a00652023-02-15 20:07:023000 packet_num++, 1, 1, quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
3001 quic_error_details, quic::IETF_STOP_SENDING));
Tsuyoshi Horo0f740832022-11-28 22:36:213002 quic_data.AddSocketDataToFactory(&socket_factory_);
3003
3004 // After that fails, it will be resent via TCP.
3005 MockWrite http_writes[] = {
3006 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3007 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3008 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3009
3010 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3011 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3012 MockRead(SYNCHRONOUS, 5, "hello world"),
3013 MockRead(SYNCHRONOUS, OK, 6)};
3014 SequencedSocketData http_data(http_reads, http_writes);
3015 socket_factory_.AddSocketDataProvider(&http_data);
3016 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3017
3018 HostResolverEndpointResult endpoint_result1;
3019 endpoint_result1.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
3020 endpoint_result1.metadata.supported_protocol_alpns = {
3021 quic::QuicVersionLabelToString(quic::CreateQuicVersionLabel(version_))};
3022 HostResolverEndpointResult endpoint_result2;
3023 endpoint_result2.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
3024 std::vector<HostResolverEndpointResult> endpoints;
3025 endpoints.push_back(endpoint_result1);
3026 endpoints.push_back(endpoint_result2);
3027 host_resolver_.rules()->AddRule(
3028 "mail.example.org",
3029 MockHostResolverBase::RuleResolver::RuleResult(
3030 std::move(endpoints),
3031 /*aliases=*/std::set<std::string>{"mail.example.org"}));
3032
3033 CreateSession();
3034
3035 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
3036
3037 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3038 TestCompletionCallback callback;
3039 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
3040 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3041
3042 // Pump the message loop to get the request started.
3043 base::RunLoop().RunUntilIdle();
3044 // Explicitly confirm the handshake.
3045 crypto_client_stream_factory_.last_stream()
3046 ->NotifySessionOneRttKeyAvailable();
3047 quic_data.Resume();
3048
3049 // Run the QUIC session to completion.
3050 base::RunLoop().RunUntilIdle();
3051 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3052
3053 ExpectQuicAlternateProtocolMapping();
3054
3055 // Let the transaction proceed which will result in QUIC being marked
3056 // as broken and the request falling back to TCP.
3057 EXPECT_THAT(callback.WaitForResult(), IsOk());
3058
3059 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3060 ASSERT_FALSE(http_data.AllReadDataConsumed());
3061
3062 // Read the response body over TCP.
3063 CheckResponseData(&trans, "hello world");
3064 ExpectBrokenAlternateProtocolMapping();
3065 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3066 ASSERT_TRUE(http_data.AllReadDataConsumed());
3067}
3068
rch30943ee2017-06-12 21:28:443069// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3070// request is reset from, then QUIC will be marked as broken and the request
3071// retried over TCP.
3072TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:353073 if (version_.AlpnDeferToRFCv1()) {
3074 // These versions currently do not support Alt-Svc.
3075 return;
3076 }
rch30943ee2017-06-12 21:28:443077 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593078 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133079 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443080 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3081
Zhongyi Shi1c022d22020-03-20 19:00:163082 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493083 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023084 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton0d65a8c2019-06-07 00:46:023085 quic_data.AddWrite(
3086 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163087 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493088 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033089 priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453090
Zhongyi Shi1c022d22020-03-20 19:00:163091 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553092 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443093
Tsuyoshi Horoea15e7a2023-05-23 00:12:033094 quic_data.AddRead(ASYNC, ConstructServerRstPacket(
3095 1, GetNthClientInitiatedBidirectionalStreamId(0),
3096 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443097
Patrick Meenan885a00652023-02-15 20:07:023098 quic_data.AddWrite(
3099 SYNCHRONOUS,
3100 client_maker_->MakeAckRstAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033101 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Patrick Meenan885a00652023-02-15 20:07:023102 quic::QUIC_HEADERS_TOO_LARGE, 1, 1, GetQpackDecoderStreamId(), false,
3103 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:073104
rch30943ee2017-06-12 21:28:443105 quic_data.AddRead(ASYNC, OK);
3106 quic_data.AddSocketDataToFactory(&socket_factory_);
3107
3108 // After that fails, it will be resent via TCP.
3109 MockWrite http_writes[] = {
3110 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3111 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3112 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3113
Ryan Hamiltona2dcbae2022-02-09 19:02:453114 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3115 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3116 MockRead(SYNCHRONOUS, 5, "hello world"),
3117 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013118 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443119 socket_factory_.AddSocketDataProvider(&http_data);
3120 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3121
3122 // In order for a new QUIC session to be established via alternate-protocol
3123 // without racing an HTTP connection, we need the host resolution to happen
3124 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3125 // connection to the the server, in this test we require confirmation
3126 // before encrypting so the HTTP job will still start.
3127 host_resolver_.set_synchronous_mode(true);
3128 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3129 "");
rch30943ee2017-06-12 21:28:443130
3131 CreateSession();
3132
Ryan Hamilton9835e662018-08-02 05:36:273133 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443134
3135 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3136 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263137 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch30943ee2017-06-12 21:28:443138 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3139
3140 // Pump the message loop to get the request started.
3141 base::RunLoop().RunUntilIdle();
3142 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283143 crypto_client_stream_factory_.last_stream()
3144 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553145 quic_data.Resume();
rch30943ee2017-06-12 21:28:443146
3147 // Run the QUIC session to completion.
3148 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3149
3150 ExpectQuicAlternateProtocolMapping();
3151
3152 // Let the transaction proceed which will result in QUIC being marked
3153 // as broken and the request falling back to TCP.
3154 EXPECT_THAT(callback.WaitForResult(), IsOk());
3155
3156 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3157 ASSERT_FALSE(http_data.AllReadDataConsumed());
3158
3159 // Read the response body over TCP.
3160 CheckResponseData(&trans, "hello world");
3161 ExpectBrokenAlternateProtocolMapping();
3162 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3163 ASSERT_TRUE(http_data.AllReadDataConsumed());
3164}
3165
Ryan Hamilton6c2a2a82017-12-15 02:06:283166// Verify that when an origin has two alt-svc advertisements, one local and one
3167// remote, that when the local is broken the request will go over QUIC via
3168// the remote Alt-Svc.
3169// This is a regression test for crbug/825646.
3170TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:383171 context_.params()->allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:283172
3173 GURL origin1 = request_.url; // mail.example.org
3174 GURL origin2("https://www.example.org/");
3175 ASSERT_NE(origin1.host(), origin2.host());
3176
3177 scoped_refptr<X509Certificate> cert(
3178 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243179 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3180 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283181
3182 ProofVerifyDetailsChromium verify_details;
3183 verify_details.cert_verify_result.verified_cert = cert;
3184 verify_details.cert_verify_result.is_issued_by_known_root = true;
3185 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3186
Ryan Hamiltonabad59e2019-06-06 04:02:593187 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233188 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023189 mock_quic_data.AddWrite(SYNCHRONOUS,
3190 ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton6c2a2a82017-12-15 02:06:283191 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233192 SYNCHRONOUS,
3193 ConstructClientRequestHeadersPacket(
3194 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033195 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433196 mock_quic_data.AddRead(
3197 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033198 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283199 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433200 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333201 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033202 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:523203 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233204 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343205 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283206 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213207 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamilton6c2a2a82017-12-15 02:06:283208
3209 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:593210 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:283211 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3212 AddHangingNonAlternateProtocolSocketData();
3213
3214 CreateSession();
3215
3216 // Set up alternative service for |origin1|.
3217 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3218 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
Peter Kastinge5a38ed2021-10-02 03:06:353219 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamilton6c2a2a82017-12-15 02:06:283220 AlternativeServiceInfoVector alternative_services;
3221 alternative_services.push_back(
3222 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3223 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383224 context_.params()->supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:283225 alternative_services.push_back(
3226 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3227 remote_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383228 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:493229 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
Brianna Goldstein02cb74f2022-09-29 05:41:013230 NetworkAnonymizationKey(),
Matt Menke3233d8f22019-08-20 21:01:493231 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:283232
Brianna Goldstein02cb74f2022-09-29 05:41:013233 http_server_properties_->MarkAlternativeServiceBroken(
3234 local_alternative, NetworkAnonymizationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:283235
3236 SendRequestAndExpectQuicResponse("hello!");
3237}
3238
Ryan Hamilton899c2e082019-11-14 01:22:023239// Verify that when multiple alternatives are broken,
3240// ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
3241// This is a regression test for crbug/1024613.
3242TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
Ryan Hamiltona51800a2022-02-12 19:34:353243 if (version_.AlpnDeferToRFCv1()) {
3244 // These versions currently do not support Alt-Svc.
3245 return;
3246 }
Ryan Hamilton899c2e082019-11-14 01:22:023247 base::HistogramTester histogram_tester;
3248
3249 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453250 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Ryan Hamilton899c2e082019-11-14 01:22:023251 MockRead("hello world"),
3252 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3253 MockRead(ASYNC, OK)};
3254
3255 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
3256 socket_factory_.AddSocketDataProvider(&http_data);
3257 AddCertificate(&ssl_data_);
3258 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3259
3260 GURL origin1 = request_.url; // mail.example.org
3261
3262 scoped_refptr<X509Certificate> cert(
3263 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
3264 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
3265
3266 ProofVerifyDetailsChromium verify_details;
3267 verify_details.cert_verify_result.verified_cert = cert;
3268 verify_details.cert_verify_result.is_issued_by_known_root = true;
3269 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3270
3271 CreateSession();
3272
3273 // Set up alternative service for |origin1|.
3274 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
Peter Kastinge5a38ed2021-10-02 03:06:353275 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamilton899c2e082019-11-14 01:22:023276 AlternativeServiceInfoVector alternative_services;
3277 alternative_services.push_back(
3278 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3279 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383280 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:023281 alternative_services.push_back(
3282 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3283 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383284 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:023285 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
Brianna Goldstein02cb74f2022-09-29 05:41:013286 NetworkAnonymizationKey(),
Ryan Hamilton899c2e082019-11-14 01:22:023287 alternative_services);
3288
Brianna Goldstein02cb74f2022-09-29 05:41:013289 http_server_properties_->MarkAlternativeServiceBroken(
3290 local_alternative, NetworkAnonymizationKey());
Ryan Hamilton899c2e082019-11-14 01:22:023291
3292 SendRequestAndExpectHttpResponse("hello world");
3293
3294 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
3295 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
3296}
3297
rch30943ee2017-06-12 21:28:443298// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3299// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:053300// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:443301// connection instead of going back to the broken QUIC connection.
3302// This is a regression tests for crbug/731303.
3303TEST_P(QuicNetworkTransactionTest,
3304 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:353305 if (version_.AlpnDeferToRFCv1()) {
3306 // These versions currently do not support Alt-Svc.
3307 return;
3308 }
Victor Vasilieva1e66d72019-12-05 17:55:383309 context_.params()->allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:443310
3311 GURL origin1 = request_.url;
3312 GURL origin2("https://www.example.org/");
3313 ASSERT_NE(origin1.host(), origin2.host());
3314
Ryan Hamiltonabad59e2019-06-06 04:02:593315 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:443316
3317 scoped_refptr<X509Certificate> cert(
3318 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243319 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3320 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:443321
3322 ProofVerifyDetailsChromium verify_details;
3323 verify_details.cert_verify_result.verified_cert = cert;
3324 verify_details.cert_verify_result.is_issued_by_known_root = true;
3325 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3326
Renjie Tangaadb84b2019-08-31 01:00:233327 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023328 mock_quic_data.AddWrite(SYNCHRONOUS,
3329 ConstructInitialSettingsPacket(packet_num++));
rch30943ee2017-06-12 21:28:443330 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433331 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233332 SYNCHRONOUS,
3333 ConstructClientRequestHeadersPacket(
3334 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033335 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433336 mock_quic_data.AddRead(
3337 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033338 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283339 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433340 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333341 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033342 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:523343 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233344 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343345 ConstructClientAckPacket(packet_num++, 2, 1));
rch30943ee2017-06-12 21:28:443346
3347 // Second request will go over the pooled QUIC connection, but will be
3348 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:053349 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:223350 version_,
3351 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Bence Béky957bab12023-01-31 16:40:103352 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT, true);
David Schinazic8281052019-01-24 06:14:173353 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:223354 version_,
3355 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
3356 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:433357 mock_quic_data.AddWrite(
3358 SYNCHRONOUS,
3359 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033360 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
3361 GetRequestHeaders("GET", "https", "/", &client_maker2)));
Fan Yang32c5a112018-12-10 20:06:333362 mock_quic_data.AddRead(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033363 ASYNC,
3364 ConstructServerRstPacket(3, GetNthClientInitiatedBidirectionalStreamId(1),
3365 quic::QUIC_HEADERS_TOO_LARGE));
Bence Béky6e243aa2019-12-13 19:01:073366
Patrick Meenan885a00652023-02-15 20:07:023367 mock_quic_data.AddWrite(
3368 SYNCHRONOUS,
3369 client_maker_->MakeAckRstAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033370 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
Patrick Meenan885a00652023-02-15 20:07:023371 quic::QUIC_HEADERS_TOO_LARGE, 3, 2, GetQpackDecoderStreamId(),
3372 /*fin=*/false, StreamCancellationQpackDecoderInstruction(1)));
Bence Béky6e243aa2019-12-13 19:01:073373
rch30943ee2017-06-12 21:28:443374 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213375 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rch30943ee2017-06-12 21:28:443376
3377 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3378
3379 // After that fails, it will be resent via TCP.
3380 MockWrite http_writes[] = {
3381 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3382 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
3383 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3384
Ryan Hamiltona2dcbae2022-02-09 19:02:453385 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3386 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
3387 MockRead(SYNCHRONOUS, 5, "hello world"),
3388 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013389 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443390 socket_factory_.AddSocketDataProvider(&http_data);
3391 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3392
Ryan Hamilton6c2a2a82017-12-15 02:06:283393 // Then the next request to the second origin will be sent over TCP.
3394 socket_factory_.AddSocketDataProvider(&http_data);
3395 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:443396
3397 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563398 QuicStreamFactoryPeer::SetAlarmFactory(
3399 session_->quic_stream_factory(),
3400 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223401 context_.clock()));
rch30943ee2017-06-12 21:28:443402
3403 // Set up alternative service for |origin1|.
Peter Kastinge5a38ed2021-10-02 03:06:353404 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:243405 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:493406 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013407 url::SchemeHostPort(origin1), NetworkAnonymizationKey(), alternative1,
Matt Menke9aa86262019-08-21 15:52:073408 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:443409
3410 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:243411 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:493412 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013413 url::SchemeHostPort(origin2), NetworkAnonymizationKey(), alternative2,
Matt Menke9aa86262019-08-21 15:52:073414 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:343415
rch30943ee2017-06-12 21:28:443416 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:523417 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:443418 SendRequestAndExpectQuicResponse("hello!");
3419
3420 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:523421 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:053422 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:443423 request_.url = origin2;
3424 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:053425 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:013426 alternative1, NetworkAnonymizationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:243427 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:053428 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:013429 alternative2, NetworkAnonymizationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:243430 << alternative2.ToString();
rch30943ee2017-06-12 21:28:443431
Matt Menkeb32ba5122019-09-10 19:17:053432 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:443433 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:283434 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:443435}
3436
bnc8be55ebb2015-10-30 14:12:073437TEST_P(QuicNetworkTransactionTest,
3438 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Ryan Hamiltona51800a2022-02-12 19:34:353439 if (version_.AlpnDeferToRFCv1()) {
3440 // These versions currently do not support Alt-Svc.
3441 return;
3442 }
Nick Harper23290b82019-05-02 00:02:563443 std::string altsvc_header =
3444 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
3445 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:073446 MockRead http_reads[] = {
3447 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
3448 MockRead("hello world"),
3449 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3450 MockRead(ASYNC, OK)};
3451
Ryan Sleevib8d7ea02018-05-07 20:01:013452 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:073453 socket_factory_.AddSocketDataProvider(&http_data);
3454 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3455 socket_factory_.AddSocketDataProvider(&http_data);
3456 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3457
rch3f4b8452016-02-23 16:59:323458 CreateSession();
bnc8be55ebb2015-10-30 14:12:073459
3460 SendRequestAndExpectHttpResponse("hello world");
3461 SendRequestAndExpectHttpResponse("hello world");
3462}
3463
Xida Chen9bfe0b62018-04-24 19:52:213464// When multiple alternative services are advertised, HttpStreamFactory should
3465// select the alternative service which uses existing QUIC session if available.
3466// If no existing QUIC session can be used, use the first alternative service
3467// from the list.
zhongyi32569c62016-01-08 02:54:303468TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:353469 if (version_.AlpnDeferToRFCv1()) {
3470 // These versions currently do not support Alt-Svc.
3471 return;
3472 }
Victor Vasilieva1e66d72019-12-05 17:55:383473 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltona2dcbae2022-02-09 19:02:453474 std::string alt_svc_header = base::StrCat(
3475 {"Alt-Svc: ",
3476 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.org", 443), ",",
3477 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
bncc958faa2015-07-31 18:14:523478 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453479 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
bncc958faa2015-07-31 18:14:523480 MockRead("hello world"),
3481 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3482 MockRead(ASYNC, OK)};
3483
Ryan Sleevib8d7ea02018-05-07 20:01:013484 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:523485 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:083486 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:563487 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:523488
zhongyi32569c62016-01-08 02:54:303489 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:293490 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:303491 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:593492 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233493 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023494 mock_quic_data.AddWrite(SYNCHRONOUS,
3495 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:363496 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233497 SYNCHRONOUS,
3498 ConstructClientRequestHeadersPacket(
3499 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033500 GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:303501
Ryan Hamiltona2dcbae2022-02-09 19:02:453502 std::string alt_svc_list = base::StrCat(
3503 {GenerateQuicAltSvcHeaderValue({version_}, "mail.example.org", 444), ",",
3504 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.org", 443), ",",
3505 GenerateQuicAltSvcHeaderValue({version_}, "bar.example.org", 445)});
Zhongyi Shi32f2fd02018-04-16 18:23:433506 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:023507 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033508 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283509 GetResponseHeaders("200", alt_svc_list)));
Zhongyi Shi32f2fd02018-04-16 18:23:433510 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333511 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033512 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:523513 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233514 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343515 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:303516
3517 // Second QUIC request data.
3518 // Connection pooling, using existing session, no need to include version
3519 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:583520 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233521 SYNCHRONOUS,
3522 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033523 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
3524 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433525 mock_quic_data.AddRead(
3526 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033527 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283528 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433529 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333530 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033531 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
Bence Béky319388a882020-09-23 18:42:523532 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:473533 mock_quic_data.AddWrite(SYNCHRONOUS,
3534 ConstructClientAckPacket(packet_num++, 4, 3));
bncc958faa2015-07-31 18:14:523535 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213536 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:523537
3538 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3539
rtennetib8e80fb2016-05-16 00:12:093540 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:323541 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563542 QuicStreamFactoryPeer::SetAlarmFactory(
3543 session_->quic_stream_factory(),
3544 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223545 context_.clock()));
bncc958faa2015-07-31 18:14:523546
3547 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:303548
bnc359ed2a2016-04-29 20:43:453549 SendRequestAndExpectQuicResponse("hello!");
3550 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:303551}
3552
Ryan Hamilton8d9ee76e2018-05-29 23:52:523553// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:453554// even if alternative service destination is different.
3555TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Victor Vasilieva1e66d72019-12-05 17:55:383556 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:593557 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:453558
Renjie Tangaadb84b2019-08-31 01:00:233559 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023560 mock_quic_data.AddWrite(SYNCHRONOUS,
3561 ConstructInitialSettingsPacket(packet_num++));
bnc359ed2a2016-04-29 20:43:453562 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433563 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233564 SYNCHRONOUS,
3565 ConstructClientRequestHeadersPacket(
3566 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033567 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433568 mock_quic_data.AddRead(
3569 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033570 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283571 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433572 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333573 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033574 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:523575 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233576 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343577 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:303578
bnc359ed2a2016-04-29 20:43:453579 // Second request.
alyssar2adf3ac2016-05-03 17:12:583580 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233581 SYNCHRONOUS,
3582 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033583 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
3584 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433585 mock_quic_data.AddRead(
3586 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033587 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283588 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433589 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333590 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033591 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
Bence Béky319388a882020-09-23 18:42:523592 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:473593 mock_quic_data.AddWrite(SYNCHRONOUS,
3594 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:303595 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213596 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi32569c62016-01-08 02:54:303597
3598 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:453599
3600 AddHangingNonAlternateProtocolSocketData();
3601 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:303602
rch3f4b8452016-02-23 16:59:323603 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563604 QuicStreamFactoryPeer::SetAlarmFactory(
3605 session_->quic_stream_factory(),
3606 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223607 context_.clock()));
zhongyi32569c62016-01-08 02:54:303608
bnc359ed2a2016-04-29 20:43:453609 const char destination1[] = "first.example.com";
3610 const char destination2[] = "second.example.com";
3611
3612 // Set up alternative service entry to destination1.
3613 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:213614 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
Peter Kastinge5a38ed2021-10-02 03:06:353615 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:493616 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013617 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:073618 supported_versions_);
bnc359ed2a2016-04-29 20:43:453619 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:523620 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:453621 SendRequestAndExpectQuicResponse("hello!");
3622
3623 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:213624 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:493625 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013626 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:073627 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523628 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:453629 // even though alternative service destination is different.
3630 SendRequestAndExpectQuicResponse("hello!");
3631}
3632
3633// Pool to existing session with matching destination and matching certificate
3634// even if origin is different, and even if the alternative service with
3635// matching destination is not the first one on the list.
3636TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Victor Vasilieva1e66d72019-12-05 17:55:383637 context_.params()->allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:453638 GURL origin1 = request_.url;
3639 GURL origin2("https://www.example.org/");
3640 ASSERT_NE(origin1.host(), origin2.host());
3641
Ryan Hamiltonabad59e2019-06-06 04:02:593642 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:453643
Renjie Tangaadb84b2019-08-31 01:00:233644 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023645 mock_quic_data.AddWrite(SYNCHRONOUS,
3646 ConstructInitialSettingsPacket(packet_num++));
bnc359ed2a2016-04-29 20:43:453647 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433648 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233649 SYNCHRONOUS,
3650 ConstructClientRequestHeadersPacket(
3651 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033652 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433653 mock_quic_data.AddRead(
3654 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033655 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283656 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433657 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333658 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033659 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:523660 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233661 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343662 ConstructClientAckPacket(packet_num++, 2, 1));
bnc359ed2a2016-04-29 20:43:453663
3664 // Second request.
Yixin Wang079ad542018-01-11 04:06:053665 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:223666 version_,
3667 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Bence Béky957bab12023-01-31 16:40:103668 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT, true);
David Schinazic8281052019-01-24 06:14:173669 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:223670 version_,
3671 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
3672 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:583673 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433674 SYNCHRONOUS,
3675 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033676 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
3677 GetRequestHeaders("GET", "https", "/", &client_maker2)));
Zhongyi Shi32f2fd02018-04-16 18:23:433678 mock_quic_data.AddRead(
3679 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033680 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283681 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433682 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333683 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033684 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
Bence Béky319388a882020-09-23 18:42:523685 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:473686 mock_quic_data.AddWrite(SYNCHRONOUS,
3687 ConstructClientAckPacket(packet_num++, 4, 3));
bnc359ed2a2016-04-29 20:43:453688 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213689 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:453690
3691 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3692
3693 AddHangingNonAlternateProtocolSocketData();
3694 AddHangingNonAlternateProtocolSocketData();
3695
3696 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563697 QuicStreamFactoryPeer::SetAlarmFactory(
3698 session_->quic_stream_factory(),
3699 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223700 context_.clock()));
bnc359ed2a2016-04-29 20:43:453701
3702 const char destination1[] = "first.example.com";
3703 const char destination2[] = "second.example.com";
3704
3705 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:213706 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
Peter Kastinge5a38ed2021-10-02 03:06:353707 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:493708 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013709 url::SchemeHostPort(origin1), NetworkAnonymizationKey(),
3710 alternative_service1, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:453711
3712 // Set up multiple alternative service entries for |origin2|,
3713 // the first one with a different destination as for |origin1|,
3714 // the second one with the same. The second one should be used,
3715 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:213716 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:453717 AlternativeServiceInfoVector alternative_services;
3718 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:213719 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3720 alternative_service2, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383721 context_.params()->supported_versions));
bnc359ed2a2016-04-29 20:43:453722 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:213723 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3724 alternative_service1, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383725 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:493726 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
Brianna Goldstein02cb74f2022-09-29 05:41:013727 NetworkAnonymizationKey(),
Matt Menke3233d8f22019-08-20 21:01:493728 alternative_services);
bnc359ed2a2016-04-29 20:43:453729 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:523730 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:453731 SendRequestAndExpectQuicResponse("hello!");
3732
3733 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:523734 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:453735 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:583736
bnc359ed2a2016-04-29 20:43:453737 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:303738}
3739
3740// Multiple origins have listed the same alternative services. When there's a
3741// existing QUIC session opened by a request to other origin,
3742// if the cert is valid, should select this QUIC session to make the request
3743// if this is also the first existing QUIC session.
3744TEST_P(QuicNetworkTransactionTest,
3745 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltona51800a2022-02-12 19:34:353746 if (version_.AlpnDeferToRFCv1()) {
3747 // These versions currently do not support Alt-Svc.
3748 return;
3749 }
Victor Vasilieva1e66d72019-12-05 17:55:383750 context_.params()->allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:293751 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:303752
rch9ae5b3b2016-02-11 00:36:293753 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:303754 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453755 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rch9ae5b3b2016-02-11 00:36:293756 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:303757 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3758 MockRead(ASYNC, OK)};
3759
Ryan Sleevib8d7ea02018-05-07 20:01:013760 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:303761 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:083762 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:303763 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3764
3765 // HTTP data for request to mail.example.org.
Ryan Hamiltona2dcbae2022-02-09 19:02:453766 std::string alt_svc_header2 = base::StrCat(
3767 {"Alt-Svc: ", GenerateQuicAltSvcHeaderValue({version_}, 444), ",",
3768 GenerateQuicAltSvcHeaderValue({version_}, "www.example.org", 443),
3769 "\r\n\r\n"});
zhongyi32569c62016-01-08 02:54:303770 MockRead http_reads2[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453771 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header2.data()),
zhongyi32569c62016-01-08 02:54:303772 MockRead("hello world from mail.example.org"),
3773 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3774 MockRead(ASYNC, OK)};
3775
Ryan Sleevib8d7ea02018-05-07 20:01:013776 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:303777 socket_factory_.AddSocketDataProvider(&http_data2);
3778 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3779
Yixin Wang079ad542018-01-11 04:06:053780 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:223781 version_,
3782 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Bence Béky957bab12023-01-31 16:40:103783 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT, true);
alyssar2adf3ac2016-05-03 17:12:583784 server_maker_.set_hostname("www.example.org");
Zhongyi Shi1c022d22020-03-20 19:00:163785 client_maker_->set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:593786 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233787 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023788 mock_quic_data.AddWrite(SYNCHRONOUS,
3789 ConstructInitialSettingsPacket(packet_num++));
zhongyi32569c62016-01-08 02:54:303790 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:583791 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233792 SYNCHRONOUS,
3793 ConstructClientRequestHeadersPacket(
3794 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033795 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433796
3797 mock_quic_data.AddRead(
3798 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033799 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283800 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:333801 mock_quic_data.AddRead(
3802 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033803 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:523804 ConstructDataFrame("hello from mail QUIC!")));
Renjie Tangaadb84b2019-08-31 01:00:233805 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343806 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:433807 // Second QUIC request data.
3808 mock_quic_data.AddWrite(
3809 SYNCHRONOUS,
3810 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033811 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
3812 GetRequestHeaders("GET", "https", "/", &client_maker)));
Zhongyi Shi32f2fd02018-04-16 18:23:433813 mock_quic_data.AddRead(
3814 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033815 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283816 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:333817 mock_quic_data.AddRead(
3818 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033819 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
Bence Béky319388a882020-09-23 18:42:523820 ConstructDataFrame("hello from mail QUIC!")));
Renjie Tangb7afea82020-07-15 23:35:473821 mock_quic_data.AddWrite(SYNCHRONOUS,
3822 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:303823 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213824 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi32569c62016-01-08 02:54:303825
3826 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:303827
rtennetib8e80fb2016-05-16 00:12:093828 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:323829 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563830 QuicStreamFactoryPeer::SetAlarmFactory(
3831 session_->quic_stream_factory(),
3832 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223833 context_.clock()));
zhongyi32569c62016-01-08 02:54:303834
3835 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:293836 request_.url = GURL("https://www.example.org/");
3837 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:303838 request_.url = GURL("https://mail.example.org/");
3839 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
3840
rch9ae5b3b2016-02-11 00:36:293841 // Open a QUIC session to mail.example.org:443 when making request
3842 // to mail.example.org.
3843 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:453844 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:303845
rch9ae5b3b2016-02-11 00:36:293846 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:303847 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:453848 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:523849}
3850
3851TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
Ryan Hamiltona51800a2022-02-12 19:34:353852 if (version_.AlpnDeferToRFCv1()) {
3853 // These versions currently do not support Alt-Svc.
3854 return;
3855 }
Ryan Hamiltona2dcbae2022-02-09 19:02:453856 std::string alt_svc_header =
3857 base::StrCat({"Alt-Svc: ", GenerateQuicAltSvcHeaderValue({version_}, 137),
3858 "\r\n\r\n"});
bncc958faa2015-07-31 18:14:523859 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453860 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
bncc958faa2015-07-31 18:14:523861 MockRead("hello world"),
3862 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3863 MockRead(ASYNC, OK)};
3864
Ryan Sleevib8d7ea02018-05-07 20:01:013865 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:523866 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:083867 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:563868 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:523869
rtennetib8e80fb2016-05-16 00:12:093870 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:323871 CreateSession();
bncc958faa2015-07-31 18:14:523872
3873 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:453874
3875 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:343876 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:493877 http_server_properties_->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:013878 http_server, NetworkAnonymizationKey());
zhongyic4de03032017-05-19 04:07:343879 ASSERT_EQ(1u, alternative_service_info_vector.size());
3880 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:543881 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:343882 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
3883 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
3884 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:523885}
3886
3887TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
Ryan Hamiltona51800a2022-02-12 19:34:353888 if (version_.AlpnDeferToRFCv1()) {
3889 // These versions currently do not support Alt-Svc.
3890 return;
3891 }
bncc958faa2015-07-31 18:14:523892 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453893 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:563894 MockRead("hello world"),
bncc958faa2015-07-31 18:14:523895 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3896 MockRead(ASYNC, OK)};
3897
Ryan Sleevib8d7ea02018-05-07 20:01:013898 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:523899 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:083900 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:563901 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:523902
Ryan Hamiltonabad59e2019-06-06 04:02:593903 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233904 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023905 mock_quic_data.AddWrite(SYNCHRONOUS,
3906 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:363907 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233908 SYNCHRONOUS,
3909 ConstructClientRequestHeadersPacket(
3910 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033911 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433912 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333913 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033914 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283915 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:333916 mock_quic_data.AddRead(
3917 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033918 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:523919 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233920 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343921 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:523922 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213923 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:523924
3925 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3926
rtennetib8e80fb2016-05-16 00:12:093927 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:323928 CreateSession();
bncc958faa2015-07-31 18:14:523929
bnc3472afd2016-11-17 15:27:213930 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:523931 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:493932 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:013933 alternative_service, NetworkAnonymizationKey());
Matt Menke3233d8f22019-08-20 21:01:493934 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:013935 alternative_service, NetworkAnonymizationKey()));
bncc958faa2015-07-31 18:14:523936
3937 SendRequestAndExpectHttpResponse("hello world");
3938 SendRequestAndExpectQuicResponse("hello!");
3939
mmenkee24011922015-12-17 22:12:593940 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:523941
Matt Menke3233d8f22019-08-20 21:01:493942 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:013943 alternative_service, NetworkAnonymizationKey()));
Matt Menke19475f72019-08-21 18:57:443944 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
3945 url::SchemeHostPort("https", request_.url.host(), 443),
Brianna Goldstein02cb74f2022-09-29 05:41:013946 NetworkAnonymizationKey()));
bncc958faa2015-07-31 18:14:523947}
3948
Matt Menkeb32ba5122019-09-10 19:17:053949TEST_P(QuicNetworkTransactionTest,
3950 ConfirmAlternativeServiceWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:353951 if (version_.AlpnDeferToRFCv1()) {
3952 // These versions currently do not support Alt-Svc.
3953 return;
3954 }
Matt Menke4807a9a2020-11-21 00:14:413955 const SchemefulSite kSite1(GURL("https://foo.test/"));
3956 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Dustin J. Mitchell1d774ea2023-03-03 00:54:463957 const auto kNetworkAnonymizationKey1 =
3958 NetworkAnonymizationKey::CreateSameSite(kSite1);
Matt Menke4807a9a2020-11-21 00:14:413959 const SchemefulSite kSite2(GURL("https://bar.test/"));
3960 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Dustin J. Mitchell1d774ea2023-03-03 00:54:463961 const auto kNetworkAnonymizationKey2 =
3962 NetworkAnonymizationKey::CreateSameSite(kSite2);
Matt Menkeb32ba5122019-09-10 19:17:053963
3964 base::test::ScopedFeatureList feature_list;
3965 feature_list.InitWithFeatures(
3966 // enabled_features
3967 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3968 features::kPartitionConnectionsByNetworkIsolationKey},
3969 // disabled_features
3970 {});
3971 // Since HttpServerProperties caches the feature value, have to create a new
3972 // one.
3973 http_server_properties_ = std::make_unique<HttpServerProperties>();
3974
3975 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453976 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Matt Menkeb32ba5122019-09-10 19:17:053977 MockRead("hello world"),
3978 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3979 MockRead(ASYNC, OK)};
3980
3981 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
3982 socket_factory_.AddSocketDataProvider(&http_data);
3983 AddCertificate(&ssl_data_);
3984 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3985
3986 MockQuicData mock_quic_data(version_);
3987 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023988 mock_quic_data.AddWrite(SYNCHRONOUS,
3989 ConstructInitialSettingsPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:053990 mock_quic_data.AddWrite(
3991 SYNCHRONOUS,
3992 ConstructClientRequestHeadersPacket(
3993 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033994 GetRequestHeaders("GET", "https", "/")));
Matt Menkeb32ba5122019-09-10 19:17:053995 mock_quic_data.AddRead(
3996 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033997 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283998 GetResponseHeaders("200")));
Matt Menkeb32ba5122019-09-10 19:17:053999 mock_quic_data.AddRead(
4000 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034001 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:524002 ConstructDataFrame("hello!")));
Matt Menkeb32ba5122019-09-10 19:17:054003 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344004 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menkeb32ba5122019-09-10 19:17:054005 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214006 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Matt Menkeb32ba5122019-09-10 19:17:054007
4008 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4009
4010 CreateSession();
4011
4012 AlternativeService alternative_service(kProtoQUIC,
4013 HostPortPair::FromURL(request_.url));
4014 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014015 alternative_service, kNetworkAnonymizationKey1);
Matt Menkeb32ba5122019-09-10 19:17:054016 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014017 alternative_service, kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:054018 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014019 alternative_service, kNetworkAnonymizationKey1));
Matt Menkeb32ba5122019-09-10 19:17:054020 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014021 alternative_service, kNetworkAnonymizationKey2));
Matt Menkeb32ba5122019-09-10 19:17:054022
4023 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:524024 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Menkeb32ba5122019-09-10 19:17:054025 SendRequestAndExpectHttpResponse("hello world");
4026 SendRequestAndExpectQuicResponse("hello!");
4027
4028 mock_quic_data.Resume();
4029
4030 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014031 alternative_service, kNetworkAnonymizationKey1));
Matt Menkeb32ba5122019-09-10 19:17:054032 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4033 url::SchemeHostPort("https", request_.url.host(), 443),
Brianna Goldstein02cb74f2022-09-29 05:41:014034 kNetworkAnonymizationKey1));
Matt Menkeb32ba5122019-09-10 19:17:054035 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014036 alternative_service, kNetworkAnonymizationKey2));
Matt Menkeb32ba5122019-09-10 19:17:054037 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4038 url::SchemeHostPort("https", request_.url.host(), 443),
Brianna Goldstein02cb74f2022-09-29 05:41:014039 kNetworkAnonymizationKey2));
Matt Menkeb32ba5122019-09-10 19:17:054040}
4041
bncc958faa2015-07-31 18:14:524042TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
Ryan Hamiltona51800a2022-02-12 19:34:354043 if (version_.AlpnDeferToRFCv1()) {
4044 // These versions currently do not support Alt-Svc.
4045 return;
4046 }
bncc958faa2015-07-31 18:14:524047 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454048 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:564049 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524050 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4051 MockRead(ASYNC, OK)};
4052
Ryan Sleevib8d7ea02018-05-07 20:01:014053 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524054 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564055 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524056
Ryan Hamiltonabad59e2019-06-06 04:02:594057 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234058 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:024059 mock_quic_data.AddWrite(SYNCHRONOUS,
4060 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:364061 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234062 SYNCHRONOUS,
4063 ConstructClientRequestHeadersPacket(
4064 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034065 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434066 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334067 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034068 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284069 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334070 mock_quic_data.AddRead(
4071 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034072 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:524073 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234074 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344075 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:524076 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4077
4078 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4079
4080 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324081 CreateSession();
bncc958faa2015-07-31 18:14:524082
4083 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4084 SendRequestAndExpectHttpResponse("hello world");
4085}
4086
bnc1c196c6e2016-05-28 13:51:484087TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
Ryan Hamiltona51800a2022-02-12 19:34:354088 if (version_.AlpnDeferToRFCv1()) {
4089 // These versions currently do not support Alt-Svc.
4090 return;
4091 }
[email protected]dda75ab2013-06-22 22:43:304092 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274093 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304094
4095 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564096 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294097 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564098 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304099
Ryan Hamiltona2dcbae2022-02-09 19:02:454100 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4101 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
4102 MockRead(SYNCHRONOUS, 5, "hello world"),
4103 MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304104
Ryan Sleevib8d7ea02018-05-07 20:01:014105 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504106 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084107 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504108 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304109
4110 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454111 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304112 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454113 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304114 };
Ryan Sleevib8d7ea02018-05-07 20:01:014115 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504116 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304117
4118 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014119 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504120 socket_factory_.AddSocketDataProvider(&http_data2);
4121 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304122
bnc912a04b2016-04-20 14:19:504123 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304124
4125 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304126 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174127 ASSERT_TRUE(http_data.AllReadDataConsumed());
4128 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304129
4130 // Now run the second request in which the QUIC socket hangs,
4131 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304132 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454133 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304134
rch37de576c2015-05-17 20:28:174135 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4136 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454137 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304138}
4139
[email protected]1e960032013-12-20 19:00:204140TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594141 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164142 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494143 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:024144 mock_quic_data.AddWrite(SYNCHRONOUS,
4145 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi32f2fd02018-04-16 18:23:434146 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494147 SYNCHRONOUS,
4148 ConstructClientRequestHeadersPacket(
4149 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034150 GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:164151 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4152 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Zhongyi Shi32f2fd02018-04-16 18:23:434153 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334154 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034155 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284156 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334157 mock_quic_data.AddRead(
4158 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034159 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:524160 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:494161 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344162 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:504163 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214164 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
[email protected]8ba81212013-05-03 13:11:484165
rcha5399e02015-04-21 19:32:044166 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484167
rtennetib8e80fb2016-05-16 00:12:094168 // The non-alternate protocol job needs to hang in order to guarantee that
4169 // the alternate-protocol job will "win".
4170 AddHangingNonAlternateProtocolSocketData();
4171
rch3f4b8452016-02-23 16:59:324172 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274173 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yang1ef6dfef2021-07-24 16:20:164174 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4175 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264176 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Fan Yang1ef6dfef2021-07-24 16:20:164177 IsError(ERR_IO_PENDING));
4178 // Complete host resolution in next message loop so that QUIC job could
4179 // proceed.
4180 base::RunLoop().RunUntilIdle();
4181 // Explicitly confirm the handshake.
4182 crypto_client_stream_factory_.last_stream()
4183 ->NotifySessionOneRttKeyAvailable();
4184
4185 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
4186 mock_quic_data.Resume();
4187
4188 // Run the QUIC session to completion.
4189 base::RunLoop().RunUntilIdle();
4190
4191 EXPECT_THAT(callback.WaitForResult(), IsOk());
4192
4193 CheckWasQuicResponse(&trans);
4194 CheckResponseData(&trans, "hello!");
rchac7f35e2017-03-15 20:42:304195
Matt Menke19475f72019-08-21 18:57:444196 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4197 url::SchemeHostPort("https", request_.url.host(), 443),
Brianna Goldstein02cb74f2022-09-29 05:41:014198 NetworkAnonymizationKey()));
[email protected]8ba81212013-05-03 13:11:484199}
4200
[email protected]1e960032013-12-20 19:00:204201TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594202 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164203 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494204 int packet_number = 1;
Patrick Meenan885a00652023-02-15 20:07:024205 mock_quic_data.AddWrite(
4206 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Fan Yang32c5a112018-12-10 20:06:334207 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494208 SYNCHRONOUS,
4209 ConstructClientRequestHeadersPacket(
4210 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034211 GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:164212 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4213 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Zhongyi Shi32f2fd02018-04-16 18:23:434214 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334215 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034216 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284217 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334218 mock_quic_data.AddRead(
4219 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034220 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:524221 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:494222 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344223 ConstructClientAckPacket(packet_number++, 2, 1));
rchb27683c2015-07-29 23:53:504224 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214225 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rcha5399e02015-04-21 19:32:044226 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274227
4228 // In order for a new QUIC session to be established via alternate-protocol
4229 // without racing an HTTP connection, we need the host resolution to happen
4230 // synchronously.
4231 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294232 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564233 "");
[email protected]3a120a6b2013-06-25 01:08:274234
rtennetib8e80fb2016-05-16 00:12:094235 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324236 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274237 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yang1ef6dfef2021-07-24 16:20:164238 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4239 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264240 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Fan Yang1ef6dfef2021-07-24 16:20:164241 IsError(ERR_IO_PENDING));
4242 // Complete host resolution in next message loop so that QUIC job could
4243 // proceed.
4244 base::RunLoop().RunUntilIdle();
4245 // Explicitly confirm the handshake.
4246 crypto_client_stream_factory_.last_stream()
4247 ->NotifySessionOneRttKeyAvailable();
4248
4249 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
4250 mock_quic_data.Resume();
4251
4252 // Run the QUIC session to completion.
4253 base::RunLoop().RunUntilIdle();
4254
4255 EXPECT_THAT(callback.WaitForResult(), IsOk());
4256
4257 CheckWasQuicResponse(&trans);
4258 CheckResponseData(&trans, "hello!");
[email protected]3a120a6b2013-06-25 01:08:274259}
4260
[email protected]0fc924b2014-03-31 04:34:154261TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ryan Hamiltona51800a2022-02-12 19:34:354262 if (version_.AlpnDeferToRFCv1()) {
4263 // These versions currently do not support Alt-Svc.
4264 return;
4265 }
Nicolas Arciniegad2013f92020-02-07 23:00:564266 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:274267 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:564268 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154269
4270 // Since we are using a proxy, the QUIC job will not succeed.
4271 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294272 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4273 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564274 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154275
Ryan Hamiltona2dcbae2022-02-09 19:02:454276 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4277 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
4278 MockRead(SYNCHRONOUS, 5, "hello world"),
4279 MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154280
Ryan Sleevib8d7ea02018-05-07 20:01:014281 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154282 socket_factory_.AddSocketDataProvider(&http_data);
4283
4284 // In order for a new QUIC session to be established via alternate-protocol
4285 // without racing an HTTP connection, we need the host resolution to happen
4286 // synchronously.
4287 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294288 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564289 "");
[email protected]0fc924b2014-03-31 04:34:154290
rch9ae5b3b2016-02-11 00:36:294291 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324292 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274293 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154294 SendRequestAndExpectHttpResponse("hello world");
4295}
4296
[email protected]1e960032013-12-20 19:00:204297TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:594298 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234299 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164300 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024301 mock_quic_data.AddWrite(SYNCHRONOUS,
4302 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164303 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364304 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234305 SYNCHRONOUS,
4306 ConstructClientRequestHeadersPacket(
4307 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034308 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434309 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334310 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034311 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284312 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334313 mock_quic_data.AddRead(
4314 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034315 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:524316 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234317 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344318 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:594319 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044320 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124321
rtennetib8e80fb2016-05-16 00:12:094322 // The non-alternate protocol job needs to hang in order to guarantee that
4323 // the alternate-protocol job will "win".
4324 AddHangingNonAlternateProtocolSocketData();
4325
[email protected]11c05872013-08-20 02:04:124326 // In order for a new QUIC session to be established via alternate-protocol
4327 // without racing an HTTP connection, we need the host resolution to happen
4328 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4329 // connection to the the server, in this test we require confirmation
4330 // before encrypting so the HTTP job will still start.
4331 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294332 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564333 "");
[email protected]11c05872013-08-20 02:04:124334
rch3f4b8452016-02-23 16:59:324335 CreateSession();
Matt Menkeb566c392019-09-11 23:22:434336 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
4337 false);
Ryan Hamilton9835e662018-08-02 05:36:274338 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:124339
bnc691fda62016-08-12 00:43:164340 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:124341 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264342 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014343 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Liza Burakova80b8ebd2023-02-15 16:29:584344 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284345 crypto_client_stream_factory_.last_stream()
4346 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:014347 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:504348
bnc691fda62016-08-12 00:43:164349 CheckWasQuicResponse(&trans);
4350 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:124351}
4352
Steven Valdez58097ec32018-07-16 18:29:044353TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:014354 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594355 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164356 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024357 mock_quic_data.AddWrite(
4358 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Steven Valdez58097ec32018-07-16 18:29:044359 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014360 SYNCHRONOUS,
4361 ConstructClientRequestHeadersPacket(
4362 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034363 GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334364 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024365 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034366 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284367 GetResponseHeaders("425")));
Patrick Meenan885a00652023-02-15 20:07:024368 mock_quic_data.AddWrite(
4369 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034370 packet_number++, GetQpackDecoderStreamId(), 1, 1, false,
4371 StreamCancellationQpackDecoderInstruction(0)));
Patrick Meenan885a00652023-02-15 20:07:024372 mock_quic_data.AddWrite(
4373 SYNCHRONOUS,
4374 client_maker_->MakeRstPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034375 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Patrick Meenan885a00652023-02-15 20:07:024376 quic::QUIC_STREAM_CANCELLED));
Steven Valdez58097ec32018-07-16 18:29:044377
Zhongyi Shi1c022d22020-03-20 19:00:164378 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:044379
Steven Valdez58097ec32018-07-16 18:29:044380 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014381 SYNCHRONOUS,
4382 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034383 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), true,
4384 GetRequestHeaders("GET", "https", "/")));
Steven Valdez58097ec32018-07-16 18:29:044385 mock_quic_data.AddRead(
4386 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034387 2, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284388 GetResponseHeaders("200")));
Steven Valdez58097ec32018-07-16 18:29:044389 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334390 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034391 3, GetNthClientInitiatedBidirectionalStreamId(1), true,
Bence Béky319388a882020-09-23 18:42:524392 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474393 mock_quic_data.AddWrite(SYNCHRONOUS,
4394 ConstructClientAckPacket(packet_number++, 3, 1));
Steven Valdez58097ec32018-07-16 18:29:044395 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214396 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Steven Valdez58097ec32018-07-16 18:29:044397
4398 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4399
4400 // In order for a new QUIC session to be established via alternate-protocol
4401 // without racing an HTTP connection, we need the host resolution to happen
4402 // synchronously.
4403 host_resolver_.set_synchronous_mode(true);
4404 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4405 "");
Steven Valdez58097ec32018-07-16 18:29:044406
4407 AddHangingNonAlternateProtocolSocketData();
4408 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274409 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:564410 QuicStreamFactoryPeer::SetAlarmFactory(
4411 session_->quic_stream_factory(),
4412 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224413 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:044414
4415 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4416 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264417 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Steven Valdez58097ec32018-07-16 18:29:044418 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4419
4420 // Confirm the handshake after the 425 Too Early.
4421 base::RunLoop().RunUntilIdle();
4422
4423 // The handshake hasn't been confirmed yet, so the retry should not have
4424 // succeeded.
4425 EXPECT_FALSE(callback.have_result());
4426
Fan Yang3673cc72020-02-07 14:49:284427 crypto_client_stream_factory_.last_stream()
4428 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:044429
4430 EXPECT_THAT(callback.WaitForResult(), IsOk());
4431 CheckWasQuicResponse(&trans);
4432 CheckResponseData(&trans, "hello!");
4433}
4434
4435TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:014436 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594437 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164438 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024439 mock_quic_data.AddWrite(
4440 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Steven Valdez58097ec32018-07-16 18:29:044441 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014442 SYNCHRONOUS,
4443 ConstructClientRequestHeadersPacket(
4444 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034445 GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334446 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024447 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034448 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284449 GetResponseHeaders("425")));
Patrick Meenan885a00652023-02-15 20:07:024450 mock_quic_data.AddWrite(
4451 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034452 packet_number++, GetQpackDecoderStreamId(), 1, 1, false,
4453 StreamCancellationQpackDecoderInstruction(0)));
Patrick Meenan885a00652023-02-15 20:07:024454 mock_quic_data.AddWrite(
4455 SYNCHRONOUS,
4456 client_maker_->MakeRstPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034457 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Patrick Meenan885a00652023-02-15 20:07:024458 quic::QUIC_STREAM_CANCELLED));
Steven Valdez58097ec32018-07-16 18:29:044459
Zhongyi Shi1c022d22020-03-20 19:00:164460 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:044461
Steven Valdez58097ec32018-07-16 18:29:044462 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014463 SYNCHRONOUS,
4464 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034465 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), true,
4466 GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334467 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024468 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034469 2, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284470 GetResponseHeaders("425")));
Patrick Meenan885a00652023-02-15 20:07:024471 mock_quic_data.AddWrite(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034472 SYNCHRONOUS, ConstructClientAckAndDataPacket(
4473 packet_number++, GetQpackDecoderStreamId(), 2, 1, false,
4474 StreamCancellationQpackDecoderInstruction(1, false)));
Patrick Meenan885a00652023-02-15 20:07:024475 mock_quic_data.AddWrite(
4476 SYNCHRONOUS,
4477 client_maker_->MakeRstPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034478 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
Patrick Meenan885a00652023-02-15 20:07:024479 quic::QUIC_STREAM_CANCELLED));
Steven Valdez58097ec32018-07-16 18:29:044480 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214481 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Steven Valdez58097ec32018-07-16 18:29:044482
4483 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4484
4485 // In order for a new QUIC session to be established via alternate-protocol
4486 // without racing an HTTP connection, we need the host resolution to happen
4487 // synchronously.
4488 host_resolver_.set_synchronous_mode(true);
4489 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4490 "");
Steven Valdez58097ec32018-07-16 18:29:044491
4492 AddHangingNonAlternateProtocolSocketData();
4493 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274494 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:564495 QuicStreamFactoryPeer::SetAlarmFactory(
4496 session_->quic_stream_factory(),
4497 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224498 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:044499
4500 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4501 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264502 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Steven Valdez58097ec32018-07-16 18:29:044503 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4504
4505 // Confirm the handshake after the 425 Too Early.
4506 base::RunLoop().RunUntilIdle();
4507
4508 // The handshake hasn't been confirmed yet, so the retry should not have
4509 // succeeded.
4510 EXPECT_FALSE(callback.have_result());
4511
Fan Yang3673cc72020-02-07 14:49:284512 crypto_client_stream_factory_.last_stream()
4513 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:044514
4515 EXPECT_THAT(callback.WaitForResult(), IsOk());
4516 const HttpResponseInfo* response = trans.GetResponseInfo();
4517 ASSERT_TRUE(response != nullptr);
4518 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:284519 EXPECT_EQ("HTTP/1.1 425", response->headers->GetStatusLine());
Steven Valdez58097ec32018-07-16 18:29:044520 EXPECT_TRUE(response->was_fetched_via_spdy);
4521 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:084522 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
4523 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:044524}
4525
zhongyica364fbb2015-12-12 03:39:124526TEST_P(QuicNetworkTransactionTest,
4527 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Victor Vasilieva1e66d72019-12-05 17:55:384528 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:594529 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234530 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164531 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024532 mock_quic_data.AddWrite(SYNCHRONOUS,
4533 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164534 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364535 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234536 SYNCHRONOUS,
4537 ConstructClientRequestHeadersPacket(
4538 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034539 GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:124540 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:524541 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:434542 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:124543 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4544
4545 // The non-alternate protocol job needs to hang in order to guarantee that
4546 // the alternate-protocol job will "win".
4547 AddHangingNonAlternateProtocolSocketData();
4548
4549 // In order for a new QUIC session to be established via alternate-protocol
4550 // without racing an HTTP connection, we need the host resolution to happen
4551 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4552 // connection to the the server, in this test we require confirmation
4553 // before encrypting so the HTTP job will still start.
4554 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294555 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:124556 "");
zhongyica364fbb2015-12-12 03:39:124557
rch3f4b8452016-02-23 16:59:324558 CreateSession();
Matt Menkeb566c392019-09-11 23:22:434559 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
4560 false);
Ryan Hamilton9835e662018-08-02 05:36:274561 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:124562
bnc691fda62016-08-12 00:43:164563 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:124564 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264565 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014566 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Liza Burakova80b8ebd2023-02-15 16:29:584567 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284568 crypto_client_stream_factory_.last_stream()
4569 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:014570 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:124571
4572 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524573 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124574
bnc691fda62016-08-12 00:43:164575 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:124576 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:524577 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
4578 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124579}
4580
4581TEST_P(QuicNetworkTransactionTest,
4582 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Victor Vasilieva1e66d72019-12-05 17:55:384583 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:594584 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234585 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164586 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024587 mock_quic_data.AddWrite(SYNCHRONOUS,
4588 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164589 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364590 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234591 SYNCHRONOUS,
4592 ConstructClientRequestHeadersPacket(
4593 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034594 GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:214595 // Peer sending data from an non-existing stream causes this end to raise
4596 // error and close connection.
Tsuyoshi Horoea15e7a2023-05-23 00:12:034597 mock_quic_data.AddRead(ASYNC,
4598 ConstructServerRstPacket(
4599 1, GetNthClientInitiatedBidirectionalStreamId(47),
4600 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:214601 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:374602 mock_quic_data.AddWrite(
Renjie Tang248e36ea2020-06-26 00:12:344603 SYNCHRONOUS,
4604 ConstructClientAckAndConnectionClosePacket(
Patrick Meenan885a00652023-02-15 20:07:024605 packet_num++, 1, 1, quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
4606 quic_error_details, quic::IETF_STOP_SENDING));
zhongyica364fbb2015-12-12 03:39:124607 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4608
4609 // The non-alternate protocol job needs to hang in order to guarantee that
4610 // the alternate-protocol job will "win".
4611 AddHangingNonAlternateProtocolSocketData();
4612
4613 // In order for a new QUIC session to be established via alternate-protocol
4614 // without racing an HTTP connection, we need the host resolution to happen
4615 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4616 // connection to the the server, in this test we require confirmation
4617 // before encrypting so the HTTP job will still start.
4618 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294619 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:124620 "");
zhongyica364fbb2015-12-12 03:39:124621
rch3f4b8452016-02-23 16:59:324622 CreateSession();
Matt Menkeb566c392019-09-11 23:22:434623 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
4624 false);
Ryan Hamilton9835e662018-08-02 05:36:274625 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:124626
bnc691fda62016-08-12 00:43:164627 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:124628 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264629 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014630 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Liza Burakova80b8ebd2023-02-15 16:29:584631 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284632 crypto_client_stream_factory_.last_stream()
4633 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:014634 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:124635 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524636 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124637
bnc691fda62016-08-12 00:43:164638 trans.PopulateNetErrorDetails(&details);
Patrick Meenan885a00652023-02-15 20:07:024639 EXPECT_EQ(quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
Renjie Tang248e36ea2020-06-26 00:12:344640 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124641}
4642
Nick Harper057264a82019-09-12 23:33:494643TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:594644 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234645 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164646 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024647 mock_quic_data.AddWrite(SYNCHRONOUS,
4648 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164649 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364650 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234651 SYNCHRONOUS,
4652 ConstructClientRequestHeadersPacket(
4653 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034654 GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:484655 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:334656 mock_quic_data.AddRead(
4657 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034658 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284659 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334660 mock_quic_data.AddRead(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034661 ASYNC,
4662 ConstructServerRstPacket(2, GetNthClientInitiatedBidirectionalStreamId(0),
4663 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:074664
Patrick Meenan885a00652023-02-15 20:07:024665 mock_quic_data.AddWrite(
4666 SYNCHRONOUS,
4667 client_maker_->MakeAckRstAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034668 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Patrick Meenan885a00652023-02-15 20:07:024669 quic::QUIC_STREAM_CANCELLED, 2, 1, GetQpackDecoderStreamId(), false,
4670 StreamCancellationQpackDecoderInstruction(0)));
rchcd5f1c62016-06-23 02:43:484671 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
4672 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4673
4674 // The non-alternate protocol job needs to hang in order to guarantee that
4675 // the alternate-protocol job will "win".
4676 AddHangingNonAlternateProtocolSocketData();
4677
4678 // In order for a new QUIC session to be established via alternate-protocol
4679 // without racing an HTTP connection, we need the host resolution to happen
4680 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4681 // connection to the the server, in this test we require confirmation
4682 // before encrypting so the HTTP job will still start.
4683 host_resolver_.set_synchronous_mode(true);
4684 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4685 "");
rchcd5f1c62016-06-23 02:43:484686
4687 CreateSession();
Matt Menkeb566c392019-09-11 23:22:434688 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
4689 false);
Ryan Hamilton9835e662018-08-02 05:36:274690 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:484691
bnc691fda62016-08-12 00:43:164692 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:484693 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264694 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014695 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:484696
Liza Burakova80b8ebd2023-02-15 16:29:584697 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284698 crypto_client_stream_factory_.last_stream()
4699 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:484700 // Read the headers.
robpercival214763f2016-07-01 23:27:014701 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:484702
bnc691fda62016-08-12 00:43:164703 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:484704 ASSERT_TRUE(response != nullptr);
4705 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:284706 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
rchcd5f1c62016-06-23 02:43:484707 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:524708 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:084709 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
4710 response->connection_info);
rchcd5f1c62016-06-23 02:43:484711
4712 std::string response_data;
bnc691fda62016-08-12 00:43:164713 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:484714}
4715
Nick Harper057264a82019-09-12 23:33:494716TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:384717 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:594718 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234719 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164720 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024721 mock_quic_data.AddWrite(SYNCHRONOUS,
4722 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164723 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364724 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234725 SYNCHRONOUS,
4726 ConstructClientRequestHeadersPacket(
4727 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034728 GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334729 mock_quic_data.AddRead(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034730 ASYNC,
4731 ConstructServerRstPacket(1, GetNthClientInitiatedBidirectionalStreamId(0),
4732 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:074733
Patrick Meenan885a00652023-02-15 20:07:024734 mock_quic_data.AddWrite(
4735 SYNCHRONOUS,
4736 client_maker_->MakeAckRstAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034737 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Patrick Meenan885a00652023-02-15 20:07:024738 quic::QUIC_STREAM_CANCELLED, 1, 1, GetQpackDecoderStreamId(), false,
4739 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:074740
rchcd5f1c62016-06-23 02:43:484741 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
4742 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4743
4744 // The non-alternate protocol job needs to hang in order to guarantee that
4745 // the alternate-protocol job will "win".
4746 AddHangingNonAlternateProtocolSocketData();
4747
4748 // In order for a new QUIC session to be established via alternate-protocol
4749 // without racing an HTTP connection, we need the host resolution to happen
4750 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4751 // connection to the the server, in this test we require confirmation
4752 // before encrypting so the HTTP job will still start.
4753 host_resolver_.set_synchronous_mode(true);
4754 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4755 "");
rchcd5f1c62016-06-23 02:43:484756
4757 CreateSession();
Matt Menkeb566c392019-09-11 23:22:434758 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
4759 false);
Ryan Hamilton9835e662018-08-02 05:36:274760 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:484761
bnc691fda62016-08-12 00:43:164762 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:484763 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264764 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014765 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:484766
Liza Burakova80b8ebd2023-02-15 16:29:584767 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284768 crypto_client_stream_factory_.last_stream()
4769 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:484770 // Read the headers.
robpercival214763f2016-07-01 23:27:014771 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:484772}
4773
[email protected]1e960032013-12-20 19:00:204774TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:304775 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:524776 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:584777 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:304778 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:504779 MockRead(ASYNC, close->data(), close->length()),
4780 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
4781 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:304782 };
Ryan Sleevib8d7ea02018-05-07 20:01:014783 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:304784 socket_factory_.AddSocketDataProvider(&quic_data);
4785
4786 // Main job which will succeed even though the alternate job fails.
4787 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:024788 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
4789 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4790 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:304791
Ryan Sleevib8d7ea02018-05-07 20:01:014792 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:304793 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564794 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:304795
rch3f4b8452016-02-23 16:59:324796 CreateSession();
David Schinazic8281052019-01-24 06:14:174797 AddQuicAlternateProtocolMapping(
4798 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:194799 SendRequestAndExpectHttpResponse("hello from http");
4800 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:304801}
4802
Matt Menkeb32ba5122019-09-10 19:17:054803TEST_P(QuicNetworkTransactionTest,
4804 BrokenAlternateProtocolWithNetworkIsolationKey) {
Matt Menke4807a9a2020-11-21 00:14:414805 const SchemefulSite kSite1(GURL("https://foo.test/"));
4806 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Dustin J. Mitchell1d774ea2023-03-03 00:54:464807 const auto kNetworkAnonymizationKey1 =
4808 NetworkAnonymizationKey::CreateSameSite(kSite1);
Matt Menke4807a9a2020-11-21 00:14:414809 const SchemefulSite kSite2(GURL("https://bar.test/"));
4810 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Dustin J. Mitchell1d774ea2023-03-03 00:54:464811 const auto kNetworkAnonymizationKey2 =
4812 NetworkAnonymizationKey::CreateSameSite(kSite2);
Matt Menkeb32ba5122019-09-10 19:17:054813
4814 base::test::ScopedFeatureList feature_list;
4815 feature_list.InitWithFeatures(
4816 // enabled_features
4817 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4818 features::kPartitionConnectionsByNetworkIsolationKey},
4819 // disabled_features
4820 {});
4821 // Since HttpServerProperties caches the feature value, have to create a new
4822 // one.
4823 http_server_properties_ = std::make_unique<HttpServerProperties>();
4824
4825 // Alternate-protocol job
4826 std::unique_ptr<quic::QuicEncryptedPacket> close(
4827 ConstructServerConnectionClosePacket(1));
4828 MockRead quic_reads[] = {
4829 MockRead(ASYNC, close->data(), close->length()),
4830 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
4831 MockRead(ASYNC, OK), // EOF
4832 };
4833 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
4834 socket_factory_.AddSocketDataProvider(&quic_data);
4835
4836 // Main job which will succeed even though the alternate job fails.
4837 MockRead http_reads[] = {
4838 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
4839 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4840 MockRead(ASYNC, OK)};
4841
4842 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4843 socket_factory_.AddSocketDataProvider(&http_data);
4844 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4845
4846 CreateSession();
4847 AddQuicAlternateProtocolMapping(
Brianna Goldstein02cb74f2022-09-29 05:41:014848 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT,
4849 kNetworkAnonymizationKey1);
Matt Menkeb32ba5122019-09-10 19:17:054850 AddQuicAlternateProtocolMapping(
Brianna Goldstein02cb74f2022-09-29 05:41:014851 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT,
4852 kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:054853 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:524854 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Menkeb32ba5122019-09-10 19:17:054855 SendRequestAndExpectHttpResponse("hello from http");
4856
Brianna Goldstein02cb74f2022-09-29 05:41:014857 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
4858 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:054859}
4860
[email protected]1e960032013-12-20 19:00:204861TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:594862 // Alternate-protocol job
4863 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:024864 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:594865 };
Ryan Sleevib8d7ea02018-05-07 20:01:014866 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:594867 socket_factory_.AddSocketDataProvider(&quic_data);
4868
4869 // Main job which will succeed even though the alternate job fails.
4870 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:024871 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
4872 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4873 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:594874
Ryan Sleevib8d7ea02018-05-07 20:01:014875 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:594876 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564877 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:594878
rch3f4b8452016-02-23 16:59:324879 CreateSession();
[email protected]d03a66d2013-05-06 12:55:594880
Ryan Hamilton9835e662018-08-02 05:36:274881 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:194882 SendRequestAndExpectHttpResponse("hello from http");
4883 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:594884}
4885
[email protected]00c159f2014-05-21 22:38:164886TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:534887 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:164888 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:024889 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:164890 };
Ryan Sleevib8d7ea02018-05-07 20:01:014891 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:164892 socket_factory_.AddSocketDataProvider(&quic_data);
4893
[email protected]eb71ab62014-05-23 07:57:534894 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:164895 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:024896 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:164897 };
4898
Ryan Sleevib8d7ea02018-05-07 20:01:014899 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:164900 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
4901 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564902 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:164903
rtennetib8e80fb2016-05-16 00:12:094904 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324905 CreateSession();
[email protected]00c159f2014-05-21 22:38:164906
Ryan Hamilton9835e662018-08-02 05:36:274907 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:164908 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:164909 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264910 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014911 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4912 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:164913 ExpectQuicAlternateProtocolMapping();
4914}
4915
Zhongyi Shia0cef1082017-08-25 01:49:504916TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
4917 // Tests that TCP job is delayed and QUIC job does not require confirmation
4918 // if QUIC was recently supported on the same IP on start.
4919
4920 // Set QUIC support on the last IP address, which is same with the local IP
4921 // address. Require confirmation mode will be turned off immediately when
4922 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:434923 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
4924 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:504925
Ryan Hamiltonabad59e2019-06-06 04:02:594926 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164927 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494928 int packet_number = 1;
Patrick Meenan885a00652023-02-15 20:07:024929 mock_quic_data.AddWrite(SYNCHRONOUS,
4930 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:434931 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494932 SYNCHRONOUS,
4933 ConstructClientRequestHeadersPacket(
4934 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034935 GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:164936 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4937 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
Zhongyi Shi32f2fd02018-04-16 18:23:434938 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334939 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034940 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284941 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334942 mock_quic_data.AddRead(
4943 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034944 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:524945 ConstructDataFrame("hello!")));
Nick Harper057264a82019-09-12 23:33:494946 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344947 ConstructClientAckPacket(packet_number++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:504948 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214949 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Zhongyi Shia0cef1082017-08-25 01:49:504950
4951 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4952 // No HTTP data is mocked as TCP job never starts in this case.
4953
4954 CreateSession();
4955 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:434956 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
4957 false);
Zhongyi Shia0cef1082017-08-25 01:49:504958
Ryan Hamilton9835e662018-08-02 05:36:274959 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:504960
4961 // Stall host resolution so that QUIC job will not succeed synchronously.
4962 // Socket will not be configured immediately and QUIC support is not sorted
4963 // out, TCP job will still be delayed as server properties indicates QUIC
4964 // support on last IP address.
4965 host_resolver_.set_synchronous_mode(false);
4966
4967 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4968 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264969 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Zhongyi Shia0cef1082017-08-25 01:49:504970 IsError(ERR_IO_PENDING));
4971 // Complete host resolution in next message loop so that QUIC job could
4972 // proceed.
4973 base::RunLoop().RunUntilIdle();
Fan Yang1ef6dfef2021-07-24 16:20:164974 // Explicitly confirm the handshake.
4975 crypto_client_stream_factory_.last_stream()
4976 ->NotifySessionOneRttKeyAvailable();
4977
4978 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
4979 mock_quic_data.Resume();
4980
4981 // Run the QUIC session to completion.
4982 base::RunLoop().RunUntilIdle();
Zhongyi Shia0cef1082017-08-25 01:49:504983 EXPECT_THAT(callback.WaitForResult(), IsOk());
4984
4985 CheckWasQuicResponse(&trans);
4986 CheckResponseData(&trans, "hello!");
4987}
4988
4989TEST_P(QuicNetworkTransactionTest,
4990 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
4991 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
4992 // was recently supported on a different IP address on start.
4993
4994 // Set QUIC support on the last IP address, which is different with the local
4995 // IP address. Require confirmation mode will remain when local IP address is
4996 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:434997 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
4998 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:504999
Ryan Hamiltonabad59e2019-06-06 04:02:595000 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235001 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165002 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:025003 mock_quic_data.AddWrite(SYNCHRONOUS,
5004 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:165005 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:505006 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235007 SYNCHRONOUS,
5008 ConstructClientRequestHeadersPacket(
5009 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035010 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435011 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335012 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035013 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285014 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335015 mock_quic_data.AddRead(
5016 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035017 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:525018 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235019 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345020 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505021 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5022 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5023 // No HTTP data is mocked as TCP job will be delayed and never starts.
5024
5025 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435026 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5027 false);
Ryan Hamilton9835e662018-08-02 05:36:275028 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505029
5030 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5031 // Socket will not be configured immediately and QUIC support is not sorted
5032 // out, TCP job will still be delayed as server properties indicates QUIC
5033 // support on last IP address.
5034 host_resolver_.set_synchronous_mode(false);
5035
5036 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5037 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265038 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Zhongyi Shia0cef1082017-08-25 01:49:505039 IsError(ERR_IO_PENDING));
5040
5041 // Complete host resolution in next message loop so that QUIC job could
5042 // proceed.
5043 base::RunLoop().RunUntilIdle();
5044 // Explicitly confirm the handshake so that QUIC job could succeed.
Fan Yang3673cc72020-02-07 14:49:285045 crypto_client_stream_factory_.last_stream()
5046 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia0cef1082017-08-25 01:49:505047 EXPECT_THAT(callback.WaitForResult(), IsOk());
5048
5049 CheckWasQuicResponse(&trans);
5050 CheckResponseData(&trans, "hello!");
5051}
5052
Ryan Hamilton75f197262017-08-17 14:00:075053TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5054 // Test that NetErrorDetails is correctly populated, even if the
5055 // handshake has not yet been confirmed and no stream has been created.
5056
5057 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595058 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075059 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5060 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5061 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5062
5063 // Main job will also fail.
5064 MockRead http_reads[] = {
5065 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5066 };
5067
Ryan Sleevib8d7ea02018-05-07 20:01:015068 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075069 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5070 socket_factory_.AddSocketDataProvider(&http_data);
5071 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5072
5073 AddHangingNonAlternateProtocolSocketData();
5074 CreateSession();
5075 // Require handshake confirmation to ensure that no QUIC streams are
5076 // created, and to ensure that the TCP job does not wait for the QUIC
5077 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:435078 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5079 false);
Ryan Hamilton75f197262017-08-17 14:00:075080
Ryan Hamilton9835e662018-08-02 05:36:275081 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075082 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5083 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265084 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton75f197262017-08-17 14:00:075085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5086 // Allow the TCP job to fail.
5087 base::RunLoop().RunUntilIdle();
5088 // Now let the QUIC job fail.
5089 mock_quic_data.Resume();
5090 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5091 ExpectQuicAlternateProtocolMapping();
5092 NetErrorDetails details;
5093 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525094 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075095}
5096
[email protected]1e960032013-12-20 19:00:205097TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455098 // Alternate-protocol job
5099 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025100 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455101 };
Ryan Sleevib8d7ea02018-05-07 20:01:015102 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455103 socket_factory_.AddSocketDataProvider(&quic_data);
5104
[email protected]c92c1b52014-05-31 04:16:065105 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015106 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065107 socket_factory_.AddSocketDataProvider(&quic_data2);
5108
[email protected]4d283b32013-10-17 12:57:275109 // Final job that will proceed when the QUIC job fails.
5110 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025111 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5112 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5113 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275114
Ryan Sleevib8d7ea02018-05-07 20:01:015115 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275116 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565117 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275118
rch3f4b8452016-02-23 16:59:325119 CreateSession();
[email protected]77c6c162013-08-17 02:57:455120
Ryan Hamilton9835e662018-08-02 05:36:275121 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455122
[email protected]4d283b32013-10-17 12:57:275123 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455124
5125 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275126
rch37de576c2015-05-17 20:28:175127 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5128 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455129}
5130
Matt Menkeb32ba5122019-09-10 19:17:055131TEST_P(QuicNetworkTransactionTest,
5132 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
5133 base::test::ScopedFeatureList feature_list;
5134 feature_list.InitWithFeatures(
5135 // enabled_features
5136 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5137 features::kPartitionConnectionsByNetworkIsolationKey},
5138 // disabled_features
5139 {});
5140 // Since HttpServerProperties caches the feature value, have to create a new
5141 // one.
5142 http_server_properties_ = std::make_unique<HttpServerProperties>();
5143
Matt Menke4807a9a2020-11-21 00:14:415144 const SchemefulSite kSite1(GURL("https://foo.test/"));
5145 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Dustin J. Mitchell1d774ea2023-03-03 00:54:465146 const auto kNetworkAnonymizationKey1 =
5147 NetworkAnonymizationKey::CreateSameSite(kSite1);
Matt Menke4807a9a2020-11-21 00:14:415148 const SchemefulSite kSite2(GURL("https://bar.test/"));
5149 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Dustin J. Mitchell1d774ea2023-03-03 00:54:465150 const auto kNetworkAnonymizationKey2 =
5151 NetworkAnonymizationKey::CreateSameSite(kSite2);
Matt Menkeb32ba5122019-09-10 19:17:055152
5153 // Alternate-protocol job
5154 MockRead quic_reads[] = {
5155 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5156 };
5157 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5158 socket_factory_.AddSocketDataProvider(&quic_data);
5159
5160 // Second Alternate-protocol job which will race with the TCP job.
5161 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
5162 socket_factory_.AddSocketDataProvider(&quic_data2);
5163
5164 // Final job that will proceed when the QUIC job fails.
5165 MockRead http_reads[] = {
5166 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5167 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5168 MockRead(ASYNC, OK)};
5169
5170 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5171 socket_factory_.AddSocketDataProvider(&http_data);
5172 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5173
5174 CreateSession();
5175
5176 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
Brianna Goldstein02cb74f2022-09-29 05:41:015177 kNetworkAnonymizationKey1);
Matt Menkeb32ba5122019-09-10 19:17:055178 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
Brianna Goldstein02cb74f2022-09-29 05:41:015179 kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:055180
5181 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:525182 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Menkeb32ba5122019-09-10 19:17:055183 SendRequestAndExpectHttpResponse("hello from http");
5184 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5185 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
5186
Brianna Goldstein02cb74f2022-09-29 05:41:015187 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
5188 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:055189
5190 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
5191 AddHttpDataAndRunRequest();
5192 // Requests using other NetworkIsolationKeys can still use QUIC.
5193 request_.network_isolation_key = kNetworkIsolationKey2;
Brianna Goldstein314ddf722022-09-24 02:00:525194 request_.network_anonymization_key = kNetworkAnonymizationKey2;
5195
Matt Menkeb32ba5122019-09-10 19:17:055196 AddQuicDataAndRunRequest();
5197
5198 // The last two requests should not have changed the alternative service
5199 // mappings.
Brianna Goldstein02cb74f2022-09-29 05:41:015200 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
5201 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:055202}
5203
[email protected]eb71ab62014-05-23 07:57:535204TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335205 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015206 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495207 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335208 socket_factory_.AddSocketDataProvider(&quic_data);
5209
5210 // Main job which will succeed even though the alternate job fails.
5211 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025212 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5213 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5214 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335215
Ryan Sleevib8d7ea02018-05-07 20:01:015216 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335217 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565218 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335219
rch3f4b8452016-02-23 16:59:325220 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275221 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335222 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535223
5224 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335225}
5226
Kenichi Ishibashi6fc20b82023-08-01 21:43:595227TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
5228 FLAGS_quic_enable_chaos_protection = false;
Ryan Hamiltona51800a2022-02-12 19:34:355229 if (version_.AlpnDeferToRFCv1()) {
5230 // These versions currently do not support Alt-Svc.
5231 return;
5232 }
Ryan Hamiltonabad59e2019-06-06 04:02:595233 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165234 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:175235 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045236 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155237
5238 // When the QUIC connection fails, we will try the request again over HTTP.
5239 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:455240 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
rchf114d982015-10-21 01:34:565241 MockRead("hello world"),
5242 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5243 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155244
Ryan Sleevib8d7ea02018-05-07 20:01:015245 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155246 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565247 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155248
5249 // In order for a new QUIC session to be established via alternate-protocol
5250 // without racing an HTTP connection, we need the host resolution to happen
5251 // synchronously.
5252 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295253 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565254 "");
[email protected]4fee9672014-01-08 14:47:155255
rch3f4b8452016-02-23 16:59:325256 CreateSession();
David Schinazic8281052019-01-24 06:14:175257 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5258 AddQuicAlternateProtocolMapping(
5259 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155260 SendRequestAndExpectHttpResponse("hello world");
5261}
5262
tbansalc3308d72016-08-27 10:25:045263TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltona51800a2022-02-12 19:34:355264 if (version_.AlpnDeferToRFCv1()) {
5265 // These versions currently do not support Alt-Svc.
5266 return;
5267 }
Ryan Hamiltonabad59e2019-06-06 04:02:595268 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165269 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:175270 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335271 mock_quic_data.AddWrite(
5272 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5273 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035274 GetRequestHeaders("GET", "https", "/")));
Renjie Tangcd594f32020-07-11 20:18:345275 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1));
tbansalc3308d72016-08-27 10:25:045276 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5277
5278 // When the QUIC connection fails, we will try the request again over HTTP.
5279 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:455280 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
tbansalc3308d72016-08-27 10:25:045281 MockRead("hello world"),
5282 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5283 MockRead(ASYNC, OK)};
5284
Ryan Sleevib8d7ea02018-05-07 20:01:015285 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045286 socket_factory_.AddSocketDataProvider(&http_data);
5287 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5288
tbansalc3308d72016-08-27 10:25:045289 const HostPortPair host_port_pair("myproxy.org", 443);
tbansalc3308d72016-08-27 10:25:045290
Nicolas Arciniegad2013f92020-02-07 23:00:565291 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:275292 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Matt Menke7bc4def2020-07-29 20:54:515293 "QUIC myproxy.org:443; HTTPS myproxy.org:443",
5294 TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045295 request_.url = GURL("http://mail.example.org/");
5296
5297 // In order for a new QUIC session to be established via alternate-protocol
5298 // without racing an HTTP connection, we need the host resolution to happen
5299 // synchronously.
5300 host_resolver_.set_synchronous_mode(true);
5301 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045302
5303 CreateSession();
David Schinazic8281052019-01-24 06:14:175304 crypto_client_stream_factory_.set_handshake_mode(
5305 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045306 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595307 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Ciara McMullin4672e2d2023-10-31 19:14:115308 ElementsAre(Key(ProxyUriToProxyChain("quic://myproxy.org:443",
5309 ProxyServer::SCHEME_QUIC))));
tbansalc3308d72016-08-27 10:25:045310}
5311
bnc508835902015-05-12 20:10:295312TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
Zhongyi Shi1c022d22020-03-20 19:00:165313 client_maker_->set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385314 EXPECT_FALSE(
5315 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:595316 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235317 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025318 mock_quic_data.AddWrite(SYNCHRONOUS,
5319 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:365320 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235321 SYNCHRONOUS,
5322 ConstructClientRequestHeadersPacket(
5323 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035324 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435325 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335326 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035327 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285328 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335329 mock_quic_data.AddRead(
5330 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035331 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:525332 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235333 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345334 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:505335 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295336 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5337
bncb07c05532015-05-14 19:07:205338 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095339 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325340 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275341 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295342 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385343 EXPECT_TRUE(
5344 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295345}
5346
rtenneti56977812016-01-15 19:26:565347TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Victor Vasilieva1e66d72019-12-05 17:55:385348 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575349 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565350
Renjie Tangaadb84b2019-08-31 01:00:235351 MockQuicData mock_quic_data(version_);
Patrick Meenan885a00652023-02-15 20:07:025352 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:235353 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5354 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5355
5356 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5357 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
5358 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:015359 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:235360 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:565361
rtennetib8e80fb2016-05-16 00:12:095362 // The non-alternate protocol job needs to hang in order to guarantee that
5363 // the alternate-protocol job will "win".
5364 AddHangingNonAlternateProtocolSocketData();
5365
rtenneti56977812016-01-15 19:26:565366 CreateSession();
5367 request_.method = "POST";
5368 ChunkedUploadDataStream upload_data(0);
5369 upload_data.AppendData("1", 1, true);
5370
5371 request_.upload_data_stream = &upload_data;
5372
bnc691fda62016-08-12 00:43:165373 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:565374 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265375 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015376 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:565377 EXPECT_NE(OK, callback.WaitForResult());
5378}
5379
rche11300ef2016-09-02 01:44:285380TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Victor Vasilieva1e66d72019-12-05 17:55:385381 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:285382 ScopedMockNetworkChangeNotifier network_change_notifier;
5383 MockNetworkChangeNotifier* mock_ncn =
5384 network_change_notifier.mock_network_change_notifier();
5385 mock_ncn->ForceNetworkHandlesSupported();
5386 mock_ncn->SetConnectedNetworksList(
5387 {kDefaultNetworkForTests, kNewNetworkForTests});
5388
Victor Vasilieva1e66d72019-12-05 17:55:385389 context_.params()->origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:285390 HostPortPair::FromString("mail.example.org:443"));
Victor Vasilieva1e66d72019-12-05 17:55:385391 context_.params()->migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:285392
Ryan Hamiltonabad59e2019-06-06 04:02:595393 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:285394 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:235395 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025396 socket_data.AddWrite(SYNCHRONOUS,
5397 ConstructInitialSettingsPacket(packet_num++));
Fan Yang32c5a112018-12-10 20:06:335398 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235399 SYNCHRONOUS,
5400 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035401 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
5402 GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:285403 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5404 socket_data.AddSocketDataToFactory(&socket_factory_);
5405
Ryan Hamiltonabad59e2019-06-06 04:02:595406 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:285407 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
5408 socket_data2.AddSocketDataToFactory(&socket_factory_);
5409
5410 // The non-alternate protocol job needs to hang in order to guarantee that
5411 // the alternate-protocol job will "win".
5412 AddHangingNonAlternateProtocolSocketData();
5413
5414 CreateSession();
5415 request_.method = "POST";
5416 ChunkedUploadDataStream upload_data(0);
5417
5418 request_.upload_data_stream = &upload_data;
5419
Tsuyoshi Horof8861cb2022-07-05 23:50:205420 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5421 session_.get());
rche11300ef2016-09-02 01:44:285422 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265423 int rv = trans->Start(&request_, callback.callback(), net_log_with_source_);
rche11300ef2016-09-02 01:44:285424 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5425
5426 base::RunLoop().RunUntilIdle();
5427 upload_data.AppendData("1", 1, true);
5428 base::RunLoop().RunUntilIdle();
5429
5430 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:505431 trans.reset();
rche11300ef2016-09-02 01:44:285432 session_.reset();
5433}
5434
Ryan Hamilton4b3574532017-10-30 20:17:255435TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:385436 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255437 HostPortPair::FromString("mail.example.org:443"));
5438
Ryan Hamiltonabad59e2019-06-06 04:02:595439 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235440 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025441 socket_data.AddWrite(SYNCHRONOUS,
5442 ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton4b3574532017-10-30 20:17:255443 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:335444 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235445 SYNCHRONOUS,
5446 ConstructClientRequestHeadersPacket(
5447 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035448 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435449 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335450 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035451 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285452 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335453 socket_data.AddRead(
5454 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035455 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:525456 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235457 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345458 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:255459 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Tsuyoshi Horoea15e7a2023-05-23 00:12:035460 socket_data.AddWrite(
5461 SYNCHRONOUS,
5462 client_maker_->MakeAckAndConnectionClosePacket(
5463 packet_num++, 2, 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:255464
5465 socket_data.AddSocketDataToFactory(&socket_factory_);
5466
5467 CreateSession();
5468
5469 SendRequestAndExpectQuicResponse("hello!");
5470 session_.reset();
5471}
5472
5473TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:385474 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255475 HostPortPair::FromString("mail.example.org:443"));
5476
Ryan Hamiltonabad59e2019-06-06 04:02:595477 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235478 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025479 socket_data.AddWrite(SYNCHRONOUS,
5480 ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton4b3574532017-10-30 20:17:255481 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:335482 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235483 SYNCHRONOUS,
5484 ConstructClientRequestHeadersPacket(
5485 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035486 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435487 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335488 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035489 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285490 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335491 socket_data.AddRead(
5492 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035493 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:525494 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235495 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345496 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:255497 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Tsuyoshi Horoea15e7a2023-05-23 00:12:035498 socket_data.AddWrite(
5499 SYNCHRONOUS,
5500 client_maker_->MakeAckAndConnectionClosePacket(
5501 packet_num++, 2, 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:255502
5503 socket_data.AddSocketDataToFactory(&socket_factory_);
5504
5505 CreateSession();
5506
5507 SendRequestAndExpectQuicResponse("hello!");
5508 session_.reset();
5509}
5510
Ryan Hamilton9edcf1a2017-11-22 05:55:175511TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:385512 context_.params()->retry_without_alt_svc_on_quic_errors = false;
5513 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255514 HostPortPair::FromString("mail.example.org:443"));
5515
Ryan Hamiltonabad59e2019-06-06 04:02:595516 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:255517 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Patrick Meenan885a00652023-02-15 20:07:025518 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:175519 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:255520 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
5521 }
5522 socket_data.AddSocketDataToFactory(&socket_factory_);
5523
5524 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:175525 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:175526 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
5527 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:255528
Victor Vasiliev7752898d2019-11-14 21:30:225529 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:255530 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5531 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265532 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton4b3574532017-10-30 20:17:255533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:175534 while (!callback.have_result()) {
5535 base::RunLoop().RunUntilIdle();
5536 quic_task_runner_->RunUntilIdle();
5537 }
5538 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:255539 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:175540 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5541 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5542 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:225543 EXPECT_TRUE(context_.clock()->Now() - start >
5544 quic::QuicTime::Delta::FromSeconds(4));
5545 EXPECT_TRUE(context_.clock()->Now() - start <
5546 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:255547}
5548
Ryan Hamilton9edcf1a2017-11-22 05:55:175549TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:385550 context_.params()->retry_without_alt_svc_on_quic_errors = false;
5551 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255552 HostPortPair::FromString("mail.example.org:443"));
5553
Ryan Hamiltonabad59e2019-06-06 04:02:595554 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:255555 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Patrick Meenan885a00652023-02-15 20:07:025556 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:175557 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:255558 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
5559 }
5560 socket_data.AddSocketDataToFactory(&socket_factory_);
5561
5562 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:175563 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:175564 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
5565 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:255566
Victor Vasiliev7752898d2019-11-14 21:30:225567 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:255568 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5569 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265570 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton4b3574532017-10-30 20:17:255571 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:175572 while (!callback.have_result()) {
5573 base::RunLoop().RunUntilIdle();
5574 quic_task_runner_->RunUntilIdle();
5575 }
5576 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:255577 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:175578 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5579 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5580 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:225581 EXPECT_TRUE(context_.clock()->Now() - start >
5582 quic::QuicTime::Delta::FromSeconds(4));
5583 EXPECT_TRUE(context_.clock()->Now() - start <
5584 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:255585}
5586
Cherie Shi7596de632018-02-22 07:28:185587TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Victor Vasilieva1e66d72019-12-05 17:55:385588 context_.params()->retry_without_alt_svc_on_quic_errors = false;
5589 context_.params()->origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:185590 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev62c09dc2020-11-06 18:18:295591 const std::string error_details = base::StrCat(
5592 {"Write failed with error: ", base::NumberToString(ERR_MSG_TOO_BIG), " (",
5593 strerror(ERR_MSG_TOO_BIG), ")"});
Cherie Shi7596de632018-02-22 07:28:185594
Ryan Hamiltonabad59e2019-06-06 04:02:595595 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:185596 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:235597 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025598 socket_data.AddWrite(SYNCHRONOUS,
5599 ConstructInitialSettingsPacket(packet_num++));
Cherie Shi7596de632018-02-22 07:28:185600 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
5601 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525602 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235603 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165604 client_maker_->MakeConnectionClosePacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035605 packet_num + 1, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:185606 socket_data.AddSocketDataToFactory(&socket_factory_);
5607
5608 CreateSession();
5609
5610 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5611 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265612 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Cherie Shi7596de632018-02-22 07:28:185613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5614 base::RunLoop().RunUntilIdle();
5615 ASSERT_TRUE(callback.have_result());
5616 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5617 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5618 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5619}
5620
ckrasicda193a82016-07-09 00:39:365621TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Victor Vasilieva1e66d72019-12-05 17:55:385622 context_.params()->origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:365623 HostPortPair::FromString("mail.example.org:443"));
5624
Ryan Hamiltonabad59e2019-06-06 04:02:595625 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:365626
Renjief49758b2019-01-11 23:32:415627 int write_packet_index = 1;
Patrick Meenan885a00652023-02-15 20:07:025628 mock_quic_data.AddWrite(SYNCHRONOUS,
5629 ConstructInitialSettingsPacket(write_packet_index++));
ckrasicda193a82016-07-09 00:39:365630
Bence Béky319388a882020-09-23 18:42:525631 mock_quic_data.AddWrite(
5632 SYNCHRONOUS,
5633 ConstructClientRequestHeadersAndDataFramesPacket(
5634 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:035635 true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
Bence Béky957bab12023-01-31 16:40:105636 nullptr, {ConstructDataFrame("1")}));
ckrasicda193a82016-07-09 00:39:365637
Zhongyi Shi32f2fd02018-04-16 18:23:435638 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335639 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035640 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285641 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335642
5643 mock_quic_data.AddRead(
5644 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035645 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:525646 ConstructDataFrame("hello!")));
ckrasicda193a82016-07-09 00:39:365647
Renjie Tangcd594f32020-07-11 20:18:345648 mock_quic_data.AddWrite(SYNCHRONOUS,
5649 ConstructClientAckPacket(write_packet_index++, 2, 1));
ckrasicda193a82016-07-09 00:39:365650
5651 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215652 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
ckrasicda193a82016-07-09 00:39:365653 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5654
5655 // The non-alternate protocol job needs to hang in order to guarantee that
5656 // the alternate-protocol job will "win".
5657 AddHangingNonAlternateProtocolSocketData();
5658
5659 CreateSession();
5660 request_.method = "POST";
5661 ChunkedUploadDataStream upload_data(0);
5662 upload_data.AppendData("1", 1, true);
5663
5664 request_.upload_data_stream = &upload_data;
5665
5666 SendRequestAndExpectQuicResponse("hello!");
5667}
5668
Ryan Sleevia9d6aa62019-07-26 13:32:185669TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
Ryan Hamiltona51800a2022-02-12 19:34:355670 if (version_.AlpnDeferToRFCv1()) {
5671 // These versions currently do not support Alt-Svc.
5672 return;
5673 }
Ryan Sleevia9d6aa62019-07-26 13:32:185674 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:205675
5676 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:455677 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yixin Wang10f477ed2017-11-21 04:20:205678 MockRead("hello world"),
5679 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5680 MockRead(ASYNC, OK)};
5681
Ryan Sleevib8d7ea02018-05-07 20:01:015682 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:205683 socket_factory_.AddSocketDataProvider(&http_data);
5684 AddCertificate(&ssl_data_);
5685 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5686
Ryan Hamiltonabad59e2019-06-06 04:02:595687 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235688 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025689 mock_quic_data.AddWrite(SYNCHRONOUS,
5690 ConstructInitialSettingsPacket(packet_num++));
Yixin Wang10f477ed2017-11-21 04:20:205691 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235692 SYNCHRONOUS,
5693 ConstructClientRequestHeadersPacket(
5694 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035695 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435696 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335697 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035698 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285699 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335700 mock_quic_data.AddRead(
5701 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035702 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:525703 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235704 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345705 ConstructClientAckPacket(packet_num++, 2, 1));
Yixin Wang10f477ed2017-11-21 04:20:205706 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215707 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang10f477ed2017-11-21 04:20:205708
5709 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5710
5711 AddHangingNonAlternateProtocolSocketData();
5712 CreateSession();
5713
5714 SendRequestAndExpectHttpResponse("hello world");
5715 SendRequestAndExpectQuicResponse("hello!");
5716}
5717
Ryan Sleevia9d6aa62019-07-26 13:32:185718TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
Ryan Hamiltona51800a2022-02-12 19:34:355719 if (version_.AlpnDeferToRFCv1()) {
5720 // These versions currently do not support Alt-Svc.
5721 return;
5722 }
Ryan Sleevia9d6aa62019-07-26 13:32:185723 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:205724
5725 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:455726 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yixin Wang10f477ed2017-11-21 04:20:205727 MockRead("hello world"),
5728 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5729 MockRead(ASYNC, OK)};
5730
Ryan Sleevib8d7ea02018-05-07 20:01:015731 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:205732 socket_factory_.AddSocketDataProvider(&http_data);
5733 AddCertificate(&ssl_data_);
5734 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5735 socket_factory_.AddSocketDataProvider(&http_data);
5736 AddCertificate(&ssl_data_);
5737 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5738
5739 AddHangingNonAlternateProtocolSocketData();
5740 CreateSession();
5741
5742 SendRequestAndExpectHttpResponse("hello world");
5743 SendRequestAndExpectHttpResponse("hello world");
5744}
5745
bnc359ed2a2016-04-29 20:43:455746class QuicNetworkTransactionWithDestinationTest
5747 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:015748 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:055749 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:455750 protected:
5751 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:555752 : version_(GetParam().version),
Nick Harper23290b82019-05-02 00:02:565753 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:455754 destination_type_(GetParam().destination_type),
Tsuyoshi Horof8861cb2022-07-05 23:50:205755 ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()),
Nicolas Arciniegad2013f92020-02-07 23:00:565756 proxy_resolution_service_(
5757 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:115758 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Ryan Hamiltonf9a421f2020-01-31 21:09:525759 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:195760 FLAGS_quic_enable_http3_grease_randomness = false;
Ryan Hamiltonf9a421f2020-01-31 21:09:525761 }
bnc359ed2a2016-04-29 20:43:455762
5763 void SetUp() override {
5764 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:555765 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:455766
Matt Menke30a878c2021-07-20 22:25:095767 HttpNetworkSessionParams session_params;
mmenke6ddfbea2017-05-31 21:48:415768 session_params.enable_quic = true;
Tsuyoshi Horo76b96592023-08-28 09:09:495769 // To simplefy tests, we disable UseDnsHttpsSvcbAlpn feature. If this is
5770 // enabled, we need to prepare mock sockets for `dns_alpn_h3_job_`. Also
5771 // AsyncQuicSession feature makes it more complecated because it changes the
5772 // socket call order.
5773 session_params.use_dns_https_svcb_alpn = false;
5774
Victor Vasilieva1e66d72019-12-05 17:55:385775 context_.params()->allow_remote_alt_svc = true;
5776 context_.params()->supported_versions = supported_versions_;
mmenke6ddfbea2017-05-31 21:48:415777
Matt Menke30a878c2021-07-20 22:25:095778 HttpNetworkSessionContext session_context;
bnc359ed2a2016-04-29 20:43:455779
Victor Vasiliev7752898d2019-11-14 21:30:225780 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
bnc359ed2a2016-04-29 20:43:455781
5782 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:275783 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:415784 session_context.quic_crypto_client_stream_factory =
5785 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:455786
Victor Vasiliev7752898d2019-11-14 21:30:225787 session_context.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:415788 session_context.client_socket_factory = &socket_factory_;
5789 session_context.host_resolver = &host_resolver_;
5790 session_context.cert_verifier = &cert_verifier_;
5791 session_context.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:415792 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:455793 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:415794 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:595795 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:415796 session_context.http_auth_handler_factory = auth_handler_factory_.get();
5797 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:455798
Renjie Tang6ff9a9b2021-02-03 22:11:095799 session_ =
5800 std::make_unique<HttpNetworkSession>(session_params, session_context);
Matt Menkeb566c392019-09-11 23:22:435801 session_->quic_stream_factory()
5802 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:455803 }
5804
5805 void TearDown() override {
5806 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
5807 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:555808 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:455809 PlatformTest::TearDown();
5810 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:555811 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:405812 session_.reset();
bnc359ed2a2016-04-29 20:43:455813 }
5814
zhongyie537a002017-06-27 16:48:215815 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:455816 HostPortPair destination;
5817 switch (destination_type_) {
5818 case SAME_AS_FIRST:
5819 destination = HostPortPair(origin1_, 443);
5820 break;
5821 case SAME_AS_SECOND:
5822 destination = HostPortPair(origin2_, 443);
5823 break;
5824 case DIFFERENT:
5825 destination = HostPortPair(kDifferentHostname, 443);
5826 break;
5827 }
bnc3472afd2016-11-17 15:27:215828 AlternativeService alternative_service(kProtoQUIC, destination);
Peter Kastinge5a38ed2021-10-02 03:06:355829 base::Time expiration = base::Time::Now() + base::Days(1);
zhongyie537a002017-06-27 16:48:215830 http_server_properties_.SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:015831 url::SchemeHostPort("https", origin, 443), NetworkAnonymizationKey(),
Matt Menke9aa86262019-08-21 15:52:075832 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:455833 }
5834
Ryan Hamilton8d9ee76e2018-05-29 23:52:525835 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:235836 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:525837 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:525838 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:135839 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:455840 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Bence Béky4c325e52020-10-22 20:48:015841 spdy::Http2HeaderBlock headers(
Ryan Hamilton0239aac2018-05-19 00:03:135842 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:025843 return maker->MakeRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035844 packet_number, stream_id, true, priority, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:455845 }
5846
Ryan Hamilton8d9ee76e2018-05-29 23:52:525847 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:235848 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:525849 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:525850 QuicTestPacketMaker* maker) {
Kenichi Ishibashif8634ab2021-03-16 23:41:285851 spdy::Http2HeaderBlock headers(maker->GetResponseHeaders("200"));
Ryan Hamilton0d65a8c2019-06-07 00:46:025852 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035853 std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:455854 }
5855
Ryan Hamilton8d9ee76e2018-05-29 23:52:525856 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:235857 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:525858 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:455859 QuicTestPacketMaker* maker) {
Bence Béky319388a882020-09-23 18:42:525860 return maker->MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035861 packet_number, stream_id, true,
Bence Béky319388a882020-09-23 18:42:525862 ConstructDataFrameForVersion("hello", version_));
bnc359ed2a2016-04-29 20:43:455863 }
5864
Ryan Hamilton8d9ee76e2018-05-29 23:52:525865 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:235866 uint64_t packet_number,
5867 uint64_t largest_received,
5868 uint64_t smallest_received,
bnc359ed2a2016-04-29 20:43:455869 QuicTestPacketMaker* maker) {
5870 return maker->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:345871 smallest_received);
bnc359ed2a2016-04-29 20:43:455872 }
5873
Ryan Hamilton8d9ee76e2018-05-29 23:52:525874 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:235875 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:375876 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:025877 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:375878 }
5879
bnc359ed2a2016-04-29 20:43:455880 void AddRefusedSocketData() {
Tsuyoshi Horof8861cb2022-07-05 23:50:205881 auto refused_data = std::make_unique<StaticSocketDataProvider>();
bnc359ed2a2016-04-29 20:43:455882 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
5883 refused_data->set_connect_data(refused_connect);
5884 socket_factory_.AddSocketDataProvider(refused_data.get());
5885 static_socket_data_provider_vector_.push_back(std::move(refused_data));
5886 }
5887
5888 void AddHangingSocketData() {
Tsuyoshi Horof8861cb2022-07-05 23:50:205889 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
bnc359ed2a2016-04-29 20:43:455890 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
5891 hanging_data->set_connect_data(hanging_connect);
5892 socket_factory_.AddSocketDataProvider(hanging_data.get());
5893 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
5894 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5895 }
5896
5897 bool AllDataConsumed() {
5898 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
5899 if (!socket_data_ptr->AllReadDataConsumed() ||
5900 !socket_data_ptr->AllWriteDataConsumed()) {
5901 return false;
5902 }
5903 }
5904 return true;
5905 }
5906
5907 void SendRequestAndExpectQuicResponse(const std::string& host) {
5908 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5909 HttpRequestInfo request;
5910 std::string url("https://");
5911 url.append(host);
5912 request.url = GURL(url);
5913 request.load_flags = 0;
5914 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:105915 request.traffic_annotation =
5916 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:455917 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265918 int rv = trans.Start(&request, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015919 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:455920
5921 std::string response_data;
robpercival214763f2016-07-01 23:27:015922 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:455923 EXPECT_EQ("hello", response_data);
5924
5925 const HttpResponseInfo* response = trans.GetResponseInfo();
5926 ASSERT_TRUE(response != nullptr);
5927 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:285928 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
bnc359ed2a2016-04-29 20:43:455929 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525930 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085931 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:455932 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:375933 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:455934 }
5935
Fan Yang32c5a112018-12-10 20:06:335936 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:565937 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
5938 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:365939 }
5940
Patrick Meenan0041f332022-05-19 23:48:355941 quic::test::QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Nick Harper23290b82019-05-02 00:02:565942 const quic::ParsedQuicVersion version_;
Nick Harper23290b82019-05-02 00:02:565943 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:455944 DestinationType destination_type_;
5945 std::string origin1_;
5946 std::string origin2_;
Victor Vasiliev7752898d2019-11-14 21:30:225947 MockQuicContext context_;
bnc359ed2a2016-04-29 20:43:455948 std::unique_ptr<HttpNetworkSession> session_;
5949 MockClientSocketFactory socket_factory_;
Eric Orthbe86fee2021-10-28 22:31:115950 MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
5951 RuleResolver::GetLocalhostResult()};
bnc359ed2a2016-04-29 20:43:455952 MockCertVerifier cert_verifier_;
5953 TransportSecurityState transport_security_state_;
bnc359ed2a2016-04-29 20:43:455954 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:075955 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:265956 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:455957 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:265958 HttpServerProperties http_server_properties_;
Matt Reichhoff0049a0b72021-10-20 20:44:265959 NetLogWithSource net_log_with_source_{
5960 NetLogWithSource::Make(NetLogSourceType::NONE)};
bnc359ed2a2016-04-29 20:43:455961 MockCryptoClientStreamFactory crypto_client_stream_factory_;
5962 std::vector<std::unique_ptr<StaticSocketDataProvider>>
5963 static_socket_data_provider_vector_;
5964 SSLSocketDataProvider ssl_data_;
5965};
5966
Victor Costane635086f2019-01-27 05:20:305967INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
5968 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:575969 ::testing::ValuesIn(GetPoolingTestParams()),
5970 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:455971
5972// A single QUIC request fails because the certificate does not match the origin
5973// hostname, regardless of whether it matches the alternative service hostname.
5974TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
Dustin J. Mitchell496de812024-01-16 19:14:545975 if (destination_type_ == DIFFERENT) {
bnc359ed2a2016-04-29 20:43:455976 return;
Dustin J. Mitchell496de812024-01-16 19:14:545977 }
bnc359ed2a2016-04-29 20:43:455978
5979 GURL url("https://mail.example.com/");
5980 origin1_ = url.host();
5981
5982 // Not used for requests, but this provides a test case where the certificate
5983 // is valid for the hostname of the alternative service.
5984 origin2_ = "mail.example.org";
5985
zhongyie537a002017-06-27 16:48:215986 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:455987
5988 scoped_refptr<X509Certificate> cert(
5989 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:245990 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
5991 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:455992
5993 ProofVerifyDetailsChromium verify_details;
5994 verify_details.cert_verify_result.verified_cert = cert;
5995 verify_details.cert_verify_result.is_issued_by_known_root = true;
5996 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5997
Ryan Hamiltonabad59e2019-06-06 04:02:595998 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:455999 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
David Schinazi395918c2021-02-05 18:56:216000 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:456001
6002 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6003
6004 AddRefusedSocketData();
6005
6006 HttpRequestInfo request;
6007 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:106008 request.traffic_annotation =
6009 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456010
6011 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6012 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266013 int rv = trans.Start(&request, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:016014 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:456015
6016 EXPECT_TRUE(AllDataConsumed());
6017}
6018
6019// First request opens QUIC session to alternative service. Second request
6020// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:526021// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:456022TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
6023 origin1_ = "mail.example.org";
6024 origin2_ = "news.example.org";
6025
zhongyie537a002017-06-27 16:48:216026 SetQuicAlternativeService(origin1_);
6027 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:456028
6029 scoped_refptr<X509Certificate> cert(
6030 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246031 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
6032 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
6033 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456034
6035 ProofVerifyDetailsChromium verify_details;
6036 verify_details.cert_verify_result.verified_cert = cert;
6037 verify_details.cert_verify_result.is_issued_by_known_root = true;
6038 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6039
Yixin Wang079ad542018-01-11 04:06:056040 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:226041 version_,
6042 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Patrick Meenan0b1b18cf2023-09-21 20:19:476043 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
6044 /*client_priority_uses_incremental=*/true, /*use_priority_header=*/true);
David Schinazic8281052019-01-24 06:14:176045 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:226046 version_,
6047 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Patrick Meenan0b1b18cf2023-09-21 20:19:476048 context_.clock(), origin1_, quic::Perspective::IS_SERVER,
6049 /*client_priority_uses_incremental=*/false,
6050 /*use_priority_header=*/false);
bnc359ed2a2016-04-29 20:43:456051
Ryan Hamiltonabad59e2019-06-06 04:02:596052 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236053 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026054 mock_quic_data.AddWrite(
6055 SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++, &client_maker));
Fan Yang32c5a112018-12-10 20:06:336056 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236057 SYNCHRONOUS,
6058 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036059 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangaadb84b2019-08-31 01:00:236060 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:026061 mock_quic_data.AddRead(
6062 ASYNC,
6063 ConstructServerResponseHeadersPacket(
6064 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:436065 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336066 ASYNC,
6067 ConstructServerDataPacket(
6068 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:236069 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346070 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:456071
Yixin Wang079ad542018-01-11 04:06:056072 client_maker.set_hostname(origin2_);
6073 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:456074
Zhongyi Shi32f2fd02018-04-16 18:23:436075 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026076 SYNCHRONOUS,
6077 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036078 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
Bence Béky957bab12023-01-31 16:40:106079 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:026080 mock_quic_data.AddRead(
6081 ASYNC,
6082 ConstructServerResponseHeadersPacket(
6083 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:436084 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336085 ASYNC,
6086 ConstructServerDataPacket(
6087 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:236088 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346089 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3, &client_maker));
bnc359ed2a2016-04-29 20:43:456090 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216091 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:456092
6093 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6094
6095 AddHangingSocketData();
6096 AddHangingSocketData();
6097
Tsuyoshi Horo2c0a5042022-07-06 05:53:076098 auto quic_task_runner =
6099 base::MakeRefCounted<TestTaskRunner>(context_.mock_clock());
Fan Yangc9e00dc2018-10-09 14:17:566100 QuicStreamFactoryPeer::SetAlarmFactory(
6101 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:096102 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Victor Vasiliev7752898d2019-11-14 21:30:226103 context_.clock()));
Fan Yangc9e00dc2018-10-09 14:17:566104
bnc359ed2a2016-04-29 20:43:456105 SendRequestAndExpectQuicResponse(origin1_);
6106 SendRequestAndExpectQuicResponse(origin2_);
6107
6108 EXPECT_TRUE(AllDataConsumed());
6109}
6110
6111// First request opens QUIC session to alternative service. Second request does
6112// not pool to it, even though destination matches, because certificate is not
6113// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:526114// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:456115TEST_P(QuicNetworkTransactionWithDestinationTest,
6116 DoNotPoolIfCertificateInvalid) {
6117 origin1_ = "news.example.org";
6118 origin2_ = "mail.example.com";
6119
zhongyie537a002017-06-27 16:48:216120 SetQuicAlternativeService(origin1_);
6121 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:456122
6123 scoped_refptr<X509Certificate> cert1(
6124 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246125 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
6126 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
6127 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456128
6129 scoped_refptr<X509Certificate> cert2(
6130 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246131 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
6132 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456133
6134 ProofVerifyDetailsChromium verify_details1;
6135 verify_details1.cert_verify_result.verified_cert = cert1;
6136 verify_details1.cert_verify_result.is_issued_by_known_root = true;
6137 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
6138
6139 ProofVerifyDetailsChromium verify_details2;
6140 verify_details2.cert_verify_result.verified_cert = cert2;
6141 verify_details2.cert_verify_result.is_issued_by_known_root = true;
6142 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
6143
Yixin Wang079ad542018-01-11 04:06:056144 QuicTestPacketMaker client_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:226145 version_,
6146 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Patrick Meenan0b1b18cf2023-09-21 20:19:476147 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
6148 /*client_priority_uses_incremental=*/true, /*use_priority_header=*/true);
David Schinazic8281052019-01-24 06:14:176149 QuicTestPacketMaker server_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:226150 version_,
6151 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Patrick Meenan0b1b18cf2023-09-21 20:19:476152 context_.clock(), origin1_, quic::Perspective::IS_SERVER,
6153 /*client_priority_uses_incremental=*/false,
6154 /*use_priority_header=*/false);
bnc359ed2a2016-04-29 20:43:456155
Ryan Hamiltonabad59e2019-06-06 04:02:596156 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:236157 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026158 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6159 packet_num++, &client_maker1));
Fan Yang32c5a112018-12-10 20:06:336160 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236161 SYNCHRONOUS,
6162 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036163 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangaadb84b2019-08-31 01:00:236164 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:436165 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336166 ASYNC,
6167 ConstructServerResponseHeadersPacket(
6168 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:436169 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336170 ASYNC,
6171 ConstructServerDataPacket(
6172 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:436173 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236174 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346175 ConstructClientAckPacket(packet_num++, 2, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:456176 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6177 mock_quic_data1.AddRead(ASYNC, 0); // EOF
6178
6179 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
6180
Yixin Wang079ad542018-01-11 04:06:056181 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:226182 version_,
6183 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Patrick Meenan0b1b18cf2023-09-21 20:19:476184 context_.clock(), origin2_, quic::Perspective::IS_CLIENT,
6185 /*client_priority_uses_incremental=*/true, /*use_priority_header=*/true);
David Schinazic8281052019-01-24 06:14:176186 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:226187 version_,
6188 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Patrick Meenan0b1b18cf2023-09-21 20:19:476189 context_.clock(), origin2_, quic::Perspective::IS_SERVER,
6190 /*client_priority_uses_incremental=*/false,
6191 /*use_priority_header=*/false);
bnc359ed2a2016-04-29 20:43:456192
Ryan Hamiltonabad59e2019-06-06 04:02:596193 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:236194 int packet_num2 = 1;
Patrick Meenan885a00652023-02-15 20:07:026195 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6196 packet_num2++, &client_maker2));
Fan Yang32c5a112018-12-10 20:06:336197 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236198 SYNCHRONOUS,
6199 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036200 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangaadb84b2019-08-31 01:00:236201 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:436202 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:336203 ASYNC,
6204 ConstructServerResponseHeadersPacket(
6205 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:436206 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:336207 ASYNC,
6208 ConstructServerDataPacket(
6209 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:436210 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236211 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346212 ConstructClientAckPacket(packet_num2++, 2, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:456213 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6214 mock_quic_data2.AddRead(ASYNC, 0); // EOF
6215
6216 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
6217
bnc359ed2a2016-04-29 20:43:456218 SendRequestAndExpectQuicResponse(origin1_);
6219 SendRequestAndExpectQuicResponse(origin2_);
6220
6221 EXPECT_TRUE(AllDataConsumed());
6222}
6223
Yixin Wang46a273ec302018-01-23 17:59:566224// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:146225TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Patrick Meenan0b1b18cf2023-09-21 20:19:476226 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:566227 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146228 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566229 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276230 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566231 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566232
Ryan Hamiltonabad59e2019-06-06 04:02:596233 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236234 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026235 mock_quic_data.AddWrite(SYNCHRONOUS,
6236 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:436237
Patrick Meenan8f8c8352023-07-06 17:20:196238 mock_quic_data.AddWrite(
6239 SYNCHRONOUS,
6240 ConstructClientPriorityPacket(
6241 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6242 DEFAULT_PRIORITY));
Fan Yang32c5a112018-12-10 20:06:336243 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236244 SYNCHRONOUS,
6245 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036246 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
6247 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
6248 false));
Fan Yang32c5a112018-12-10 20:06:336249 mock_quic_data.AddRead(
6250 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036251 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286252 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566253
6254 const char get_request[] =
6255 "GET / HTTP/1.1\r\n"
6256 "Host: mail.example.org\r\n"
6257 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526258 mock_quic_data.AddWrite(
6259 SYNCHRONOUS,
6260 ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036261 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
6262 false, ConstructDataFrame(get_request)));
Renjief49758b2019-01-11 23:32:416263
Yixin Wang46a273ec302018-01-23 17:59:566264 const char get_response[] =
6265 "HTTP/1.1 200 OK\r\n"
6266 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:436267 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336268 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036269 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:526270 ConstructDataFrame(get_response)));
Fan Yang32c5a112018-12-10 20:06:336271 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:416272 SYNCHRONOUS, ConstructServerDataPacket(
6273 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:036274 ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:236275 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346276 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:566277 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6278
Patrick Meenan885a00652023-02-15 20:07:026279 mock_quic_data.AddWrite(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036280 SYNCHRONOUS,
6281 ConstructClientDataPacket(packet_num++, GetQpackDecoderStreamId(), false,
6282 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:076283
Yixin Wang46a273ec302018-01-23 17:59:566284 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:416285 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236286 ConstructClientRstPacket(packet_num++,
6287 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416288 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566289
6290 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6291
6292 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6293
6294 CreateSession();
6295
6296 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:096297 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:566298 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566299 RunTransaction(&trans);
6300 CheckWasHttpResponse(&trans);
6301 CheckResponsePort(&trans, 70);
6302 CheckResponseData(&trans, "0123456789");
Andrew Williams13e652b2024-01-02 16:49:126303 CheckUsedQuicProxyServer(&trans);
Yixin Wang46a273ec302018-01-23 17:59:566304
Cammie Smith Barnesbf91e2a2020-12-23 20:49:046305 // DNS aliases should be empty when using a proxy.
6306 EXPECT_TRUE(trans.GetResponseInfo()->dns_aliases.empty());
6307
Yixin Wang46a273ec302018-01-23 17:59:566308 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
6309 // proxy socket to disconnect.
6310 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6311
6312 base::RunLoop().RunUntilIdle();
6313 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6314 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6315}
6316
6317// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:146318TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Patrick Meenan0b1b18cf2023-09-21 20:19:476319 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:566320 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146321 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566322 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276323 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566324 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566325
Ryan Hamiltonabad59e2019-06-06 04:02:596326 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236327 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026328 mock_quic_data.AddWrite(SYNCHRONOUS,
6329 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:436330
Patrick Meenan8f8c8352023-07-06 17:20:196331 mock_quic_data.AddWrite(
6332 SYNCHRONOUS,
6333 ConstructClientPriorityPacket(
6334 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6335 DEFAULT_PRIORITY));
Fan Yang32c5a112018-12-10 20:06:336336 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236337 SYNCHRONOUS,
6338 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036339 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
6340 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
6341 false));
Fan Yang32c5a112018-12-10 20:06:336342 mock_quic_data.AddRead(
6343 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036344 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286345 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566346
Patrick Meenan0b1b18cf2023-09-21 20:19:476347 SpdyTestUtil spdy_util(/*use_priority_header=*/true);
Yixin Wang46a273ec302018-01-23 17:59:566348
Ryan Hamilton0239aac2018-05-19 00:03:136349 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:566350 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:526351 mock_quic_data.AddWrite(
6352 SYNCHRONOUS,
6353 ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036354 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
6355 false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Ryan Hamilton0239aac2018-05-19 00:03:136356 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:566357 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:436358 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:176359 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036360 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:526361 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:566362
Ryan Hamilton0239aac2018-05-19 00:03:136363 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:196364 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Zhongyi Shi32f2fd02018-04-16 18:23:436365 mock_quic_data.AddRead(
6366 SYNCHRONOUS,
6367 ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036368 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:526369 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Renjie Tangaadb84b2019-08-31 01:00:236370 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346371 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:566372 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6373
Patrick Meenan885a00652023-02-15 20:07:026374 mock_quic_data.AddWrite(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036375 SYNCHRONOUS,
6376 ConstructClientDataPacket(packet_num++, GetQpackDecoderStreamId(), false,
6377 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:076378
Yixin Wang46a273ec302018-01-23 17:59:566379 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436380 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236381 ConstructClientRstPacket(packet_num++,
6382 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416383 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566384
6385 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6386
6387 SSLSocketDataProvider ssl_data(ASYNC, OK);
6388 ssl_data.next_proto = kProtoHTTP2;
6389 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
6390
6391 CreateSession();
6392
6393 request_.url = GURL("https://mail.example.org/");
6394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566395 RunTransaction(&trans);
6396 CheckWasSpdyResponse(&trans);
6397 CheckResponsePort(&trans, 70);
6398 CheckResponseData(&trans, "0123456789");
Andrew Williams13e652b2024-01-02 16:49:126399 CheckUsedQuicProxyServer(&trans);
Yixin Wang46a273ec302018-01-23 17:59:566400
Wez0e717112018-06-18 23:09:226401 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
6402 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:566403 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6404
6405 base::RunLoop().RunUntilIdle();
6406 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6407 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6408}
6409
6410// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
6411// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:146412TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Patrick Meenan0b1b18cf2023-09-21 20:19:476413 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:566414 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146415 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566416 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276417 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566418 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566419
Ryan Hamiltonabad59e2019-06-06 04:02:596420 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:416421 int write_packet_index = 1;
Patrick Meenan885a00652023-02-15 20:07:026422 mock_quic_data.AddWrite(SYNCHRONOUS,
6423 ConstructInitialSettingsPacket(write_packet_index++));
Patrick Meenanf741c6082023-01-03 18:06:436424
Patrick Meenan8f8c8352023-07-06 17:20:196425 mock_quic_data.AddWrite(
6426 SYNCHRONOUS,
6427 ConstructClientPriorityPacket(
6428 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6429 DEFAULT_PRIORITY));
Fan Yang32c5a112018-12-10 20:06:336430 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:416431 SYNCHRONOUS,
6432 ConstructClientRequestHeadersPacket(
6433 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:036434 false, DEFAULT_PRIORITY,
Bence Béky957bab12023-01-31 16:40:106435 ConnectRequestHeaders("mail.example.org:443"), false));
Fan Yang32c5a112018-12-10 20:06:336436 mock_quic_data.AddRead(
6437 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036438 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286439 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566440
Yixin Wang46a273ec302018-01-23 17:59:566441 const char get_request_1[] =
6442 "GET / HTTP/1.1\r\n"
6443 "Host: mail.example.org\r\n"
6444 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526445 mock_quic_data.AddWrite(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036446 SYNCHRONOUS,
6447 ConstructClientAckAndDataPacket(
6448 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6449 1, 1, false, ConstructDataFrame(get_request_1)));
Renjief49758b2019-01-11 23:32:416450
Yixin Wang46a273ec302018-01-23 17:59:566451 const char get_response_1[] =
6452 "HTTP/1.1 200 OK\r\n"
6453 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:436454 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:436455 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036456 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:526457 ConstructDataFrame(get_response_1)));
Yixin Wang46a273ec302018-01-23 17:59:566458
Fan Yang32c5a112018-12-10 20:06:336459 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:176460 SYNCHRONOUS, ConstructServerDataPacket(
6461 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:036462 ConstructDataFrame("0123456789")));
Yixin Wang46a273ec302018-01-23 17:59:566463
Renjie Tangcd594f32020-07-11 20:18:346464 mock_quic_data.AddWrite(SYNCHRONOUS,
6465 ConstructClientAckPacket(write_packet_index++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:566466
6467 const char get_request_2[] =
6468 "GET /2 HTTP/1.1\r\n"
6469 "Host: mail.example.org\r\n"
6470 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526471 mock_quic_data.AddWrite(
6472 SYNCHRONOUS,
Tsuyoshi Horoea15e7a2023-05-23 00:12:036473 ConstructClientDataPacket(write_packet_index++,
6474 GetNthClientInitiatedBidirectionalStreamId(0),
6475 false, ConstructDataFrame(get_request_2)));
Yixin Wang46a273ec302018-01-23 17:59:566476
6477 const char get_response_2[] =
6478 "HTTP/1.1 200 OK\r\n"
6479 "Content-Length: 7\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:436480 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:436481 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036482 4, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:526483 ConstructDataFrame(get_response_2)));
Yixin Wang46a273ec302018-01-23 17:59:566484
Ryan Hamilton8d9ee76e2018-05-29 23:52:526485 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:176486 SYNCHRONOUS, ConstructServerDataPacket(
6487 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:036488 ConstructDataFrame("0123456")));
Yixin Wang46a273ec302018-01-23 17:59:566489
Renjie Tangcd594f32020-07-11 20:18:346490 mock_quic_data.AddWrite(SYNCHRONOUS,
6491 ConstructClientAckPacket(write_packet_index++, 5, 4));
Yixin Wang46a273ec302018-01-23 17:59:566492 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6493
Patrick Meenan885a00652023-02-15 20:07:026494 mock_quic_data.AddWrite(
6495 SYNCHRONOUS, ConstructClientDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036496 write_packet_index++, GetQpackDecoderStreamId(), false,
6497 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:076498
Renjief49758b2019-01-11 23:32:416499 mock_quic_data.AddWrite(
6500 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416501 ConstructClientRstPacket(write_packet_index++,
6502 GetNthClientInitiatedBidirectionalStreamId(0),
6503 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566504
6505 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6506
6507 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6508
6509 CreateSession();
6510
6511 request_.url = GURL("https://mail.example.org/");
6512 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566513 RunTransaction(&trans_1);
6514 CheckWasHttpResponse(&trans_1);
6515 CheckResponsePort(&trans_1, 70);
6516 CheckResponseData(&trans_1, "0123456789");
Andrew Williams13e652b2024-01-02 16:49:126517 CheckUsedQuicProxyServer(&trans_1);
Yixin Wang46a273ec302018-01-23 17:59:566518
6519 request_.url = GURL("https://mail.example.org/2");
6520 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566521 RunTransaction(&trans_2);
6522 CheckWasHttpResponse(&trans_2);
6523 CheckResponsePort(&trans_2, 70);
6524 CheckResponseData(&trans_2, "0123456");
Andrew Williams13e652b2024-01-02 16:49:126525 CheckUsedQuicProxyServer(&trans_2);
Yixin Wang46a273ec302018-01-23 17:59:566526
6527 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
6528 // proxy socket to disconnect.
6529 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6530
6531 base::RunLoop().RunUntilIdle();
6532 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6533 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6534}
6535
6536// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
6537// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
6538// server is reused for the second request.
Bence Békyf6bb6b22020-04-17 20:22:116539TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Patrick Meenan0b1b18cf2023-09-21 20:19:476540 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:566541 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146542 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566543 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276544 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566545 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566546
Ryan Hamiltonabad59e2019-06-06 04:02:596547 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236548 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026549 mock_quic_data.AddWrite(SYNCHRONOUS,
6550 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:436551
Patrick Meenan8f8c8352023-07-06 17:20:196552 mock_quic_data.AddWrite(
6553 SYNCHRONOUS,
6554 ConstructClientPriorityPacket(
6555 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6556 DEFAULT_PRIORITY));
Yixin Wang46a273ec302018-01-23 17:59:566557
6558 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:336559 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236560 SYNCHRONOUS,
6561 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036562 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
6563 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
6564 false));
Zhongyi Shi32f2fd02018-04-16 18:23:436565 mock_quic_data.AddRead(
6566 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036567 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286568 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566569
6570 // GET request, response, and data over QUIC tunnel for first request
6571 const char get_request[] =
6572 "GET / HTTP/1.1\r\n"
6573 "Host: mail.example.org\r\n"
6574 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526575 mock_quic_data.AddWrite(
6576 SYNCHRONOUS,
6577 ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036578 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
6579 false, ConstructDataFrame(get_request)));
Renjief49758b2019-01-11 23:32:416580
Yixin Wang46a273ec302018-01-23 17:59:566581 const char get_response[] =
6582 "HTTP/1.1 200 OK\r\n"
6583 "Content-Length: 10\r\n\r\n";
6584 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336585 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036586 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:526587 ConstructDataFrame(get_response)));
Fan Yang32c5a112018-12-10 20:06:336588 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:416589 SYNCHRONOUS, ConstructServerDataPacket(
6590 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:036591 ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:236592 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346593 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:566594
6595 // CONNECT request and response for second request
Patrick Meenan8f8c8352023-07-06 17:20:196596 mock_quic_data.AddWrite(
6597 SYNCHRONOUS,
6598 ConstructClientPriorityPacket(
6599 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
6600 DEFAULT_PRIORITY));
Zhongyi Shi32f2fd02018-04-16 18:23:436601 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236602 SYNCHRONOUS,
6603 ConstructClientRequestHeadersPacket(
6604 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:036605 DEFAULT_PRIORITY, ConnectRequestHeaders("different.example.org:443"),
6606 false));
Zhongyi Shi32f2fd02018-04-16 18:23:436607 mock_quic_data.AddRead(
6608 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036609 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286610 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566611
6612 // GET request, response, and data over QUIC tunnel for second request
Patrick Meenan0b1b18cf2023-09-21 20:19:476613 SpdyTestUtil spdy_util(/*use_priority_header=*/true);
Ryan Hamilton0239aac2018-05-19 00:03:136614 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:566615 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:526616 mock_quic_data.AddWrite(
6617 SYNCHRONOUS,
6618 ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036619 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4,
6620 false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:566621
Ryan Hamilton0239aac2018-05-19 00:03:136622 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:566623 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:436624 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:176625 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036626 5, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:526627 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:566628
Ryan Hamilton0239aac2018-05-19 00:03:136629 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:196630 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Zhongyi Shi32f2fd02018-04-16 18:23:436631 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:436632 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036633 6, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:526634 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:566635
Renjie Tangaadb84b2019-08-31 01:00:236636 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346637 ConstructClientAckPacket(packet_num++, 6, 5));
Yixin Wang46a273ec302018-01-23 17:59:566638 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Patrick Meenan885a00652023-02-15 20:07:026639 mock_quic_data.AddWrite(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036640 SYNCHRONOUS,
6641 ConstructClientDataPacket(packet_num++, GetQpackDecoderStreamId(), false,
6642 StreamCancellationQpackDecoderInstruction(0)));
Yixin Wang46a273ec302018-01-23 17:59:566643 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:416644 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236645 ConstructClientRstPacket(packet_num++,
6646 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416647 quic::QUIC_STREAM_CANCELLED));
Patrick Meenan885a00652023-02-15 20:07:026648 mock_quic_data.AddWrite(
6649 SYNCHRONOUS, ConstructClientDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036650 packet_num++, GetQpackDecoderStreamId(), false,
Patrick Meenan885a00652023-02-15 20:07:026651 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:076652
Yixin Wang46a273ec302018-01-23 17:59:566653 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436654 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236655 ConstructClientRstPacket(packet_num++,
6656 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416657 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566658
6659 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6660
6661 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6662
6663 SSLSocketDataProvider ssl_data(ASYNC, OK);
6664 ssl_data.next_proto = kProtoHTTP2;
6665 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
6666
6667 CreateSession();
6668
6669 request_.url = GURL("https://mail.example.org/");
6670 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566671 RunTransaction(&trans_1);
6672 CheckWasHttpResponse(&trans_1);
6673 CheckResponsePort(&trans_1, 70);
6674 CheckResponseData(&trans_1, "0123456789");
Andrew Williams13e652b2024-01-02 16:49:126675 CheckUsedQuicProxyServer(&trans_1);
Yixin Wang46a273ec302018-01-23 17:59:566676
6677 request_.url = GURL("https://different.example.org/");
6678 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566679 RunTransaction(&trans_2);
6680 CheckWasSpdyResponse(&trans_2);
6681 CheckResponsePort(&trans_2, 70);
6682 CheckResponseData(&trans_2, "0123456");
Andrew Williams13e652b2024-01-02 16:49:126683 CheckUsedQuicProxyServer(&trans_2);
Yixin Wang46a273ec302018-01-23 17:59:566684
6685 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
6686 // proxy socket to disconnect.
6687 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6688
6689 base::RunLoop().RunUntilIdle();
6690 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6691 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6692}
6693
6694// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:146695TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Patrick Meenan0b1b18cf2023-09-21 20:19:476696 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:566697 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146698 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566699 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276700 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566701 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566702
Ryan Hamiltonabad59e2019-06-06 04:02:596703 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236704 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026705 mock_quic_data.AddWrite(SYNCHRONOUS,
6706 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:436707
Patrick Meenan8f8c8352023-07-06 17:20:196708 mock_quic_data.AddWrite(
6709 SYNCHRONOUS,
6710 ConstructClientPriorityPacket(
6711 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6712 DEFAULT_PRIORITY));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526713 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236714 SYNCHRONOUS,
6715 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036716 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
6717 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
6718 false));
Fan Yang32c5a112018-12-10 20:06:336719 mock_quic_data.AddRead(
6720 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036721 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
Fan Yang32c5a112018-12-10 20:06:336722 GetResponseHeaders("500")));
6723 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:236724 mock_quic_data.AddWrite(
6725 SYNCHRONOUS,
6726 ConstructClientAckAndRstPacket(
6727 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:346728 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:566729
6730 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6731
6732 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6733
6734 CreateSession();
6735
6736 request_.url = GURL("https://mail.example.org/");
6737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566738 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266739 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:566740 EXPECT_EQ(ERR_IO_PENDING, rv);
6741 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
Yixin Wang46a273ec302018-01-23 17:59:566742
6743 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6744 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6745}
6746
6747// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:146748TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Patrick Meenan0b1b18cf2023-09-21 20:19:476749 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:566750 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146751 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566752 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276753 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566754 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566755
Ryan Hamiltonabad59e2019-06-06 04:02:596756 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236757 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026758 mock_quic_data.AddWrite(SYNCHRONOUS,
6759 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenan8f8c8352023-07-06 17:20:196760 mock_quic_data.AddWrite(
6761 SYNCHRONOUS,
6762 ConstructClientPriorityPacket(
6763 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6764 DEFAULT_PRIORITY));
Fan Yang32c5a112018-12-10 20:06:336765 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236766 SYNCHRONOUS,
6767 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036768 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
6769 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
6770 false));
Yixin Wang46a273ec302018-01-23 17:59:566771 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
6772
6773 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6774
6775 CreateSession();
6776
6777 request_.url = GURL("https://mail.example.org/");
6778 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566779 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266780 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:566781 EXPECT_EQ(ERR_IO_PENDING, rv);
6782 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
6783
6784 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6785 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6786}
6787
6788// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
6789// host. Retries request and succeeds.
Bence Békyf6bb6b22020-04-17 20:22:116790TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Patrick Meenan0b1b18cf2023-09-21 20:19:476791 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:566792 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146793 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566794 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276795 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566796 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566797
Ryan Hamiltonabad59e2019-06-06 04:02:596798 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236799 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026800 mock_quic_data.AddWrite(SYNCHRONOUS,
6801 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:436802
Patrick Meenan8f8c8352023-07-06 17:20:196803 mock_quic_data.AddWrite(
6804 SYNCHRONOUS,
6805 ConstructClientPriorityPacket(
6806 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6807 DEFAULT_PRIORITY));
Fan Yang32c5a112018-12-10 20:06:336808 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236809 SYNCHRONOUS,
6810 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036811 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
6812 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
6813 false));
Zhongyi Shi32f2fd02018-04-16 18:23:436814 mock_quic_data.AddRead(
6815 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036816 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286817 GetResponseHeaders("200")));
Patrick Meenan885a00652023-02-15 20:07:026818 mock_quic_data.AddWrite(
6819 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036820 packet_num++, GetQpackDecoderStreamId(), 1, 1, false,
6821 StreamCancellationQpackDecoderInstruction(0)));
Patrick Meenan885a00652023-02-15 20:07:026822 mock_quic_data.AddWrite(
6823 SYNCHRONOUS,
6824 ConstructClientRstPacket(packet_num++,
6825 GetNthClientInitiatedBidirectionalStreamId(0),
6826 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566827
Patrick Meenan8f8c8352023-07-06 17:20:196828 mock_quic_data.AddWrite(
6829 SYNCHRONOUS,
6830 ConstructClientPriorityPacket(
6831 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
6832 DEFAULT_PRIORITY));
Zhongyi Shi32f2fd02018-04-16 18:23:436833 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236834 SYNCHRONOUS,
6835 ConstructClientRequestHeadersPacket(
6836 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:036837 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
6838 false));
Zhongyi Shi32f2fd02018-04-16 18:23:436839 mock_quic_data.AddRead(
6840 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036841 2, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286842 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566843
6844 const char get_request[] =
6845 "GET / HTTP/1.1\r\n"
6846 "Host: mail.example.org\r\n"
6847 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526848 mock_quic_data.AddWrite(
6849 SYNCHRONOUS,
6850 ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036851 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2,
6852 false, ConstructDataFrame(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:566853 const char get_response[] =
6854 "HTTP/1.1 200 OK\r\n"
6855 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:436856 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336857 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036858 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:526859 ConstructDataFrame(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526860
Fan Yang32c5a112018-12-10 20:06:336861 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:416862 SYNCHRONOUS, ConstructServerDataPacket(
6863 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:036864 ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:236865 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346866 ConstructClientAckPacket(packet_num++, 4, 3));
Yixin Wang46a273ec302018-01-23 17:59:566867 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6868
Patrick Meenan885a00652023-02-15 20:07:026869 mock_quic_data.AddWrite(
6870 SYNCHRONOUS, ConstructClientDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036871 packet_num++, GetQpackDecoderStreamId(), false,
Patrick Meenan885a00652023-02-15 20:07:026872 StreamCancellationQpackDecoderInstruction(1, false)));
Yixin Wang46a273ec302018-01-23 17:59:566873 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:416874 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236875 ConstructClientRstPacket(packet_num++,
6876 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416877 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566878
6879 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6880
6881 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6882 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
6883
6884 SSLSocketDataProvider ssl_data(ASYNC, OK);
6885 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
6886
6887 CreateSession();
6888
6889 request_.url = GURL("https://mail.example.org/");
6890 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566891 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266892 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:566893 EXPECT_EQ(ERR_IO_PENDING, rv);
6894 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
6895
6896 rv = trans.RestartIgnoringLastError(callback.callback());
6897 EXPECT_EQ(ERR_IO_PENDING, rv);
6898 EXPECT_EQ(OK, callback.WaitForResult());
6899
6900 CheckWasHttpResponse(&trans);
6901 CheckResponsePort(&trans, 70);
6902 CheckResponseData(&trans, "0123456789");
Andrew Williams13e652b2024-01-02 16:49:126903 CheckUsedQuicProxyServer(&trans);
Yixin Wang46a273ec302018-01-23 17:59:566904
6905 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
6906 // proxy socket to disconnect.
6907 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6908
6909 base::RunLoop().RunUntilIdle();
6910 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6911 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6912}
6913
6914// Checks if a request's specified "user-agent" header shows up correctly in the
6915// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:146916TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Patrick Meenan0b1b18cf2023-09-21 20:19:476917 DisablePriorityHeader();
Matt Menked732ea42019-03-08 12:05:006918 const char kConfiguredUserAgent[] = "Configured User-Agent";
6919 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:566920 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146921 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566922 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276923 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566924 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566925
Ryan Hamiltonabad59e2019-06-06 04:02:596926 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236927 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026928 mock_quic_data.AddWrite(SYNCHRONOUS,
6929 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenan8f8c8352023-07-06 17:20:196930 mock_quic_data.AddWrite(
6931 SYNCHRONOUS,
6932 ConstructClientPriorityPacket(
6933 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6934 DEFAULT_PRIORITY));
Yixin Wang46a273ec302018-01-23 17:59:566935
Bence Béky4c325e52020-10-22 20:48:016936 spdy::Http2HeaderBlock headers =
6937 ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:006938 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:336939 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026940 SYNCHRONOUS,
6941 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036942 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
6943 DEFAULT_PRIORITY, std::move(headers), false));
Yixin Wang46a273ec302018-01-23 17:59:566944 // Return an error, so the transaction stops here (this test isn't interested
6945 // in the rest).
6946 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
6947
6948 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6949
Matt Menked732ea42019-03-08 12:05:006950 StaticHttpUserAgentSettings http_user_agent_settings(
6951 std::string() /* accept_language */, kConfiguredUserAgent);
6952 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:566953 CreateSession();
6954
6955 request_.url = GURL("https://mail.example.org/");
6956 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:006957 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:566958 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:566959 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266960 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:566961 EXPECT_EQ(ERR_IO_PENDING, rv);
6962 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
6963
6964 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6965 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6966}
6967
Yixin Wang00fc44c2018-01-23 21:12:206968// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
6969// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:146970TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Patrick Meenan0b1b18cf2023-09-21 20:19:476971 DisablePriorityHeader();
Yixin Wang00fc44c2018-01-23 21:12:206972 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146973 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:566974 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:276975 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:566976 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:206977
6978 const RequestPriority request_priority = MEDIUM;
6979
Ryan Hamiltonabad59e2019-06-06 04:02:596980 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236981 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026982 mock_quic_data.AddWrite(SYNCHRONOUS,
6983 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenan8f8c8352023-07-06 17:20:196984 mock_quic_data.AddWrite(
6985 SYNCHRONOUS,
6986 ConstructClientPriorityPacket(
6987 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6988 DEFAULT_PRIORITY));
Zhongyi Shi32f2fd02018-04-16 18:23:436989 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236990 SYNCHRONOUS,
6991 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036992 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
6993 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
6994 false));
Yixin Wang00fc44c2018-01-23 21:12:206995 // Return an error, so the transaction stops here (this test isn't interested
6996 // in the rest).
6997 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
6998
6999 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7000
7001 CreateSession();
7002
7003 request_.url = GURL("https://mail.example.org/");
7004 HttpNetworkTransaction trans(request_priority, session_.get());
7005 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267006 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang00fc44c2018-01-23 21:12:207007 EXPECT_EQ(ERR_IO_PENDING, rv);
7008 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7009
7010 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7011 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7012}
7013
Matt Menkeedaf3b82019-03-14 21:39:447014// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
7015// HTTP/2 stream dependency and weights given the request priority.
7016TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
7017 session_params_.enable_quic = true;
7018 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567019 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:277020 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:567021 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeedaf3b82019-03-14 21:39:447022
7023 const RequestPriority kRequestPriority = MEDIUM;
7024 const RequestPriority kRequestPriority2 = LOWEST;
7025
Ryan Hamiltonabad59e2019-06-06 04:02:597026 MockQuicData mock_quic_data(version_);
Patrick Meenan885a00652023-02-15 20:07:027027 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
7028 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
Matt Menkeedaf3b82019-03-14 21:39:447029 // This should never be reached.
7030 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7031 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7032
7033 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:597034 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:447035 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
7036 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7037
7038 int original_max_sockets_per_group =
7039 ClientSocketPoolManager::max_sockets_per_group(
7040 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
7041 ClientSocketPoolManager::set_max_sockets_per_group(
7042 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
7043 int original_max_sockets_per_pool =
7044 ClientSocketPoolManager::max_sockets_per_pool(
7045 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
7046 ClientSocketPoolManager::set_max_sockets_per_pool(
7047 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
7048 CreateSession();
7049
7050 request_.url = GURL("https://mail.example.org/");
7051 HttpNetworkTransaction trans(kRequestPriority, session_.get());
7052 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267053 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeedaf3b82019-03-14 21:39:447054 EXPECT_EQ(ERR_IO_PENDING, rv);
7055
7056 HttpRequestInfo request2;
7057 request2.url = GURL("https://mail.example.org/some/other/path/");
7058 request2.traffic_annotation =
7059 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7060
7061 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
7062 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:267063 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
Matt Menkeedaf3b82019-03-14 21:39:447064 EXPECT_EQ(ERR_IO_PENDING, rv2);
7065
7066 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7067 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7068
7069 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
7070
7071 ClientSocketPoolManager::set_max_sockets_per_pool(
7072 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
7073 original_max_sockets_per_pool);
7074 ClientSocketPoolManager::set_max_sockets_per_group(
7075 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
7076 original_max_sockets_per_group);
7077}
7078
Yixin Wang46a273ec302018-01-23 17:59:567079// Test the request-challenge-retry sequence for basic auth, over a QUIC
7080// connection when setting up a QUIC proxy tunnel.
Bence Békyf6bb6b22020-04-17 20:22:117081TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Jan Wilken Dörriec92a6d7242021-03-23 17:43:487082 const std::u16string kBaz(u"baz");
7083 const std::u16string kFoo(u"foo");
Yixin Wang46a273ec302018-01-23 17:59:567084
Yixin Wang46a273ec302018-01-23 17:59:567085 // On the second pass, the body read of the auth challenge is synchronous, so
7086 // IsConnectedAndIdle returns false. The socket should still be drained and
7087 // reused. See http://crbug.com/544255.
7088 for (int i = 0; i < 2; ++i) {
Bence Béky6e243aa2019-12-13 19:01:077089 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227090 version_,
7091 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7092 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky957bab12023-01-31 16:40:107093 true);
Bence Béky6e243aa2019-12-13 19:01:077094 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227095 version_,
7096 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7097 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Bence Béky6e243aa2019-12-13 19:01:077098 false);
Yixin Wang46a273ec302018-01-23 17:59:567099
7100 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147101 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567102 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:277103 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Ramin Halavatica8d5252018-03-12 05:33:497104 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567105
Ryan Hamiltonabad59e2019-06-06 04:02:597106 MockQuicData mock_quic_data(version_);
Yixin Wang46a273ec302018-01-23 17:59:567107
Renjie Tangaadb84b2019-08-31 01:00:237108 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:027109 mock_quic_data.AddWrite(
7110 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:437111
Patrick Meenan8f8c8352023-07-06 17:20:197112 mock_quic_data.AddWrite(
7113 SYNCHRONOUS,
7114 client_maker.MakePriorityPacket(
7115 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
7116 quic::HttpStreamPriority::kDefaultUrgency));
Yixin Wang46a273ec302018-01-23 17:59:567117
7118 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437119 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:077120 client_maker.MakeRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037121 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
7122 quic::HttpStreamPriority::kDefaultUrgency,
Bence Béky957bab12023-01-31 16:40:107123 client_maker.ConnectRequestHeaders("mail.example.org:443"), nullptr,
7124 false));
Yixin Wang46a273ec302018-01-23 17:59:567125
Kenichi Ishibashif8634ab2021-03-16 23:41:287126 spdy::Http2HeaderBlock headers = server_maker.GetResponseHeaders("407");
Yixin Wang46a273ec302018-01-23 17:59:567127 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
7128 headers["content-length"] = "10";
7129 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:077130 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337131 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037132 std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:567133
7134 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:437135 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:077136 ASYNC, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:337137 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037138 "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:567139 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:437140 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:077141 SYNCHRONOUS, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:337142 2, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:037143 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:567144 }
Yixin Wang46a273ec302018-01-23 17:59:567145
Bence Béky7a45d4d2020-05-08 01:59:237146 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347147 client_maker.MakeAckPacket(packet_num++, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:077148
Patrick Meenan885a00652023-02-15 20:07:027149 mock_quic_data.AddWrite(
7150 SYNCHRONOUS,
7151 client_maker.MakeDataPacket(
7152 packet_num++, GetQpackDecoderStreamId(),
Patrick Meenan885a00652023-02-15 20:07:027153 /* fin = */ false, StreamCancellationQpackDecoderInstruction(0)));
Yixin Wang46a273ec302018-01-23 17:59:567154
7155 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337156 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:077157 client_maker.MakeRstPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037158 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417159 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:187160 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:567161
Patrick Meenan8f8c8352023-07-06 17:20:197162 mock_quic_data.AddWrite(
7163 SYNCHRONOUS,
7164 client_maker.MakePriorityPacket(
7165 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
7166 quic::HttpStreamPriority::kDefaultUrgency));
Patrick Meenanf741c6082023-01-03 18:06:437167
Bence Béky6e243aa2019-12-13 19:01:077168 headers = client_maker.ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:567169 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
7170 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:047171 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:077172 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237173 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037174 quic::HttpStreamPriority::kDefaultUrgency, std::move(headers),
7175 nullptr, false));
Yixin Wang46a273ec302018-01-23 17:59:567176
7177 // Response to wrong password
Kenichi Ishibashif8634ab2021-03-16 23:41:287178 headers = server_maker.GetResponseHeaders("407");
Yixin Wang46a273ec302018-01-23 17:59:567179 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
7180 headers["content-length"] = "10";
7181 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:077182 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337183 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037184 std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:567185 mock_quic_data.AddRead(SYNCHRONOUS,
7186 ERR_IO_PENDING); // No more data to read
7187
Patrick Meenan885a00652023-02-15 20:07:027188 mock_quic_data.AddWrite(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037189 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
7190 packet_num++, GetQpackDecoderStreamId(), 3, 3, false,
7191 StreamCancellationQpackDecoderInstruction(1, false)));
Patrick Meenan885a00652023-02-15 20:07:027192 mock_quic_data.AddWrite(
7193 SYNCHRONOUS,
7194 client_maker.MakeRstPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037195 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
Patrick Meenan885a00652023-02-15 20:07:027196 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567197
7198 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7199 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
7200
7201 CreateSession();
7202
7203 request_.url = GURL("https://mail.example.org/");
7204 // Ensure that proxy authentication is attempted even
Matt Menke25eaa432020-08-25 00:10:007205 // when privacy mode is enabled.
7206 request_.privacy_mode = PRIVACY_MODE_ENABLED;
Yixin Wang46a273ec302018-01-23 17:59:567207 {
7208 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567209 RunTransaction(&trans);
7210
7211 const HttpResponseInfo* response = trans.GetResponseInfo();
7212 ASSERT_TRUE(response != nullptr);
7213 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:287214 EXPECT_EQ("HTTP/1.1 407", response->headers->GetStatusLine());
Yixin Wang46a273ec302018-01-23 17:59:567215 EXPECT_TRUE(response->headers->IsKeepAlive());
7216 EXPECT_EQ(407, response->headers->response_code());
7217 EXPECT_EQ(10, response->headers->GetContentLength());
7218 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Anton Bikineev068d2912021-05-15 20:43:527219 absl::optional<AuthChallengeInfo> auth_challenge =
Emily Starkf2c9bbd2019-04-09 17:08:587220 response->auth_challenge;
7221 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:567222 EXPECT_TRUE(auth_challenge->is_proxy);
7223 EXPECT_EQ("https://proxy.example.org:70",
7224 auth_challenge->challenger.Serialize());
7225 EXPECT_EQ("MyRealm1", auth_challenge->realm);
7226 EXPECT_EQ("basic", auth_challenge->scheme);
7227
7228 TestCompletionCallback callback;
7229 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
7230 callback.callback());
7231 EXPECT_EQ(ERR_IO_PENDING, rv);
7232 EXPECT_EQ(OK, callback.WaitForResult());
7233
7234 response = trans.GetResponseInfo();
7235 ASSERT_TRUE(response != nullptr);
7236 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:287237 EXPECT_EQ("HTTP/1.1 407", response->headers->GetStatusLine());
Yixin Wang46a273ec302018-01-23 17:59:567238 EXPECT_TRUE(response->headers->IsKeepAlive());
7239 EXPECT_EQ(407, response->headers->response_code());
7240 EXPECT_EQ(10, response->headers->GetContentLength());
7241 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:587242 auth_challenge = response->auth_challenge;
7243 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:567244 EXPECT_TRUE(auth_challenge->is_proxy);
7245 EXPECT_EQ("https://proxy.example.org:70",
7246 auth_challenge->challenger.Serialize());
7247 EXPECT_EQ("MyRealm1", auth_challenge->realm);
7248 EXPECT_EQ("basic", auth_challenge->scheme);
7249 }
7250 // HttpNetworkTransaction is torn down now that it's out of scope, causing
7251 // the QUIC stream to be cleaned up (since the proxy socket cannot be
7252 // reused because it's not connected).
7253 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7254 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7255 }
7256}
7257
Brianna Goldsteind22b0642022-10-11 16:30:507258// Test that NetworkAnonymizationKey is respected by QUIC connections, when
Matt Menke26e41542019-06-05 01:09:517259// kPartitionConnectionsByNetworkIsolationKey is enabled.
7260TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Matt Menke4807a9a2020-11-21 00:14:417261 const SchemefulSite kSite1(GURL("http://origin1/"));
7262 const SchemefulSite kSite2(GURL("http://origin2/"));
7263 NetworkIsolationKey network_isolation_key1(kSite1, kSite1);
7264 NetworkIsolationKey network_isolation_key2(kSite2, kSite2);
Dustin J. Mitchell1d774ea2023-03-03 00:54:467265 const auto network_anonymization_key1 =
7266 NetworkAnonymizationKey::CreateSameSite(kSite1);
7267 const auto network_anonymization_key2 =
7268 NetworkAnonymizationKey::CreateSameSite(kSite2);
Matt Menke26e41542019-06-05 01:09:517269
Victor Vasilieva1e66d72019-12-05 17:55:387270 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:517271 HostPortPair::FromString("mail.example.org:443"));
7272
7273 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
7274 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
7275 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
7276 // the same way as the HTTP over H2 proxy case.
7277 for (bool use_proxy : {false, true}) {
7278 SCOPED_TRACE(use_proxy);
7279
7280 if (use_proxy) {
7281 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:277282 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Matt Menke26e41542019-06-05 01:09:517283 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
7284 } else {
Nicolas Arciniegad2013f92020-02-07 23:00:567285 proxy_resolution_service_ =
7286 ConfiguredProxyResolutionService::CreateDirect();
Matt Menke26e41542019-06-05 01:09:517287 }
7288
7289 GURL url1;
7290 GURL url2;
7291 GURL url3;
7292 if (use_proxy) {
7293 url1 = GURL("http://mail.example.org/1");
7294 url2 = GURL("http://mail.example.org/2");
7295 url3 = GURL("http://mail.example.org/3");
7296 } else {
7297 url1 = GURL("https://mail.example.org/1");
7298 url2 = GURL("https://mail.example.org/2");
7299 url3 = GURL("https://mail.example.org/3");
7300 }
7301
7302 for (bool partition_connections : {false, true}) {
7303 SCOPED_TRACE(partition_connections);
7304
7305 base::test::ScopedFeatureList feature_list;
7306 if (partition_connections) {
7307 feature_list.InitAndEnableFeature(
7308 features::kPartitionConnectionsByNetworkIsolationKey);
7309 } else {
7310 feature_list.InitAndDisableFeature(
7311 features::kPartitionConnectionsByNetworkIsolationKey);
7312 }
7313
7314 // Reads and writes for the unpartitioned case, where only one socket is
7315 // used.
7316
Victor Vasilieva1e66d72019-12-05 17:55:387317 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:517318 HostPortPair::FromString("mail.example.org:443"));
7319
Ryan Hamiltonabad59e2019-06-06 04:02:597320 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:517321 QuicTestPacketMaker client_maker1(
7322 version_,
Victor Vasiliev7752898d2019-11-14 21:30:227323 quic::QuicUtils::CreateRandomConnectionId(
7324 context_.random_generator()),
7325 context_.clock(), kDefaultServerHostName,
Patrick Meenan0b1b18cf2023-09-21 20:19:477326 quic::Perspective::IS_CLIENT,
7327 /*client_priority_uses_incremental=*/true,
7328 /*use_priority_header=*/true);
Matt Menke26e41542019-06-05 01:09:517329 QuicTestPacketMaker server_maker1(
7330 version_,
Victor Vasiliev7752898d2019-11-14 21:30:227331 quic::QuicUtils::CreateRandomConnectionId(
7332 context_.random_generator()),
7333 context_.clock(), kDefaultServerHostName,
Patrick Meenan0b1b18cf2023-09-21 20:19:477334 quic::Perspective::IS_SERVER,
7335 /*client_priority_uses_incremental=*/false,
7336 /*use_priority_header=*/false);
Matt Menke26e41542019-06-05 01:09:517337
Renjie Tangaadb84b2019-08-31 01:00:237338 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:027339 unpartitioned_mock_quic_data.AddWrite(
7340 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
Matt Menke26e41542019-06-05 01:09:517341
7342 unpartitioned_mock_quic_data.AddWrite(
7343 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027344 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237345 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037346 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:107347 GetRequestHeaders("GET", url1.scheme(), "/1"), nullptr));
Matt Menke26e41542019-06-05 01:09:517348 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027349 ASYNC, server_maker1.MakeResponseHeadersPacket(
7350 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037351 GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517352 unpartitioned_mock_quic_data.AddRead(
7353 ASYNC, server_maker1.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037354 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7355 ConstructDataFrame("1")));
Matt Menke26e41542019-06-05 01:09:517356 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347357 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menke26e41542019-06-05 01:09:517358
7359 unpartitioned_mock_quic_data.AddWrite(
7360 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027361 client_maker1.MakeRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037362 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
Matt Menke26e41542019-06-05 01:09:517363 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:107364 GetRequestHeaders("GET", url2.scheme(), "/2"), nullptr));
Matt Menke26e41542019-06-05 01:09:517365 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027366 ASYNC, server_maker1.MakeResponseHeadersPacket(
7367 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037368 GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517369 unpartitioned_mock_quic_data.AddRead(
7370 ASYNC, server_maker1.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037371 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
7372 ConstructDataFrame("2")));
Matt Menke26e41542019-06-05 01:09:517373 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangb7afea82020-07-15 23:35:477374 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3));
Matt Menke26e41542019-06-05 01:09:517375
7376 unpartitioned_mock_quic_data.AddWrite(
7377 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027378 client_maker1.MakeRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037379 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2), true,
Matt Menke26e41542019-06-05 01:09:517380 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:107381 GetRequestHeaders("GET", url3.scheme(), "/3"), nullptr));
Matt Menke26e41542019-06-05 01:09:517382 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027383 ASYNC, server_maker1.MakeResponseHeadersPacket(
7384 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037385 GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517386 unpartitioned_mock_quic_data.AddRead(
7387 ASYNC, server_maker1.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037388 6, GetNthClientInitiatedBidirectionalStreamId(2), true,
7389 ConstructDataFrame("3")));
Matt Menke26e41542019-06-05 01:09:517390 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangb7afea82020-07-15 23:35:477391 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 6, 5));
Matt Menke26e41542019-06-05 01:09:517392
7393 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
7394
7395 // Reads and writes for the partitioned case, where two sockets are used.
7396
Ryan Hamiltonabad59e2019-06-06 04:02:597397 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:517398 QuicTestPacketMaker client_maker2(
7399 version_,
Victor Vasiliev7752898d2019-11-14 21:30:227400 quic::QuicUtils::CreateRandomConnectionId(
7401 context_.random_generator()),
7402 context_.clock(), kDefaultServerHostName,
Patrick Meenan0b1b18cf2023-09-21 20:19:477403 quic::Perspective::IS_CLIENT,
7404 /*client_priority_uses_incremental=*/true,
7405 /*use_priority_header=*/true);
Matt Menke26e41542019-06-05 01:09:517406 QuicTestPacketMaker server_maker2(
7407 version_,
Victor Vasiliev7752898d2019-11-14 21:30:227408 quic::QuicUtils::CreateRandomConnectionId(
7409 context_.random_generator()),
7410 context_.clock(), kDefaultServerHostName,
Patrick Meenan0b1b18cf2023-09-21 20:19:477411 quic::Perspective::IS_SERVER,
7412 /*client_priority_uses_incremental=*/false,
7413 /*use_priority_header=*/false);
Matt Menke26e41542019-06-05 01:09:517414
Renjie Tangaadb84b2019-08-31 01:00:237415 int packet_num2 = 1;
Patrick Meenan885a00652023-02-15 20:07:027416 partitioned_mock_quic_data1.AddWrite(
7417 SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(packet_num2++));
Matt Menke26e41542019-06-05 01:09:517418
7419 partitioned_mock_quic_data1.AddWrite(
7420 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027421 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237422 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:037423 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:107424 GetRequestHeaders("GET", url1.scheme(), "/1"), nullptr));
Matt Menke26e41542019-06-05 01:09:517425 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027426 ASYNC, server_maker2.MakeResponseHeadersPacket(
7427 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037428 GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517429 partitioned_mock_quic_data1.AddRead(
7430 ASYNC, server_maker2.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037431 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7432 ConstructDataFrame("1")));
Matt Menke26e41542019-06-05 01:09:517433 partitioned_mock_quic_data1.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347434 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 2, 1));
Matt Menke26e41542019-06-05 01:09:517435
7436 partitioned_mock_quic_data1.AddWrite(
7437 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027438 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237439 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
Tsuyoshi Horoea15e7a2023-05-23 00:12:037440 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:107441 GetRequestHeaders("GET", url3.scheme(), "/3"), nullptr));
Matt Menke26e41542019-06-05 01:09:517442 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027443 ASYNC, server_maker2.MakeResponseHeadersPacket(
7444 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037445 GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517446 partitioned_mock_quic_data1.AddRead(
7447 ASYNC, server_maker2.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037448 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
7449 ConstructDataFrame("3")));
Matt Menke26e41542019-06-05 01:09:517450 partitioned_mock_quic_data1.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347451 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 4, 3));
Matt Menke26e41542019-06-05 01:09:517452
7453 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
7454
Ryan Hamiltonabad59e2019-06-06 04:02:597455 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:517456 QuicTestPacketMaker client_maker3(
7457 version_,
Victor Vasiliev7752898d2019-11-14 21:30:227458 quic::QuicUtils::CreateRandomConnectionId(
7459 context_.random_generator()),
7460 context_.clock(), kDefaultServerHostName,
Patrick Meenan0b1b18cf2023-09-21 20:19:477461 quic::Perspective::IS_CLIENT,
7462 /*client_priority_uses_incremental=*/true,
7463 /*use_priority_header=*/true);
Matt Menke26e41542019-06-05 01:09:517464 QuicTestPacketMaker server_maker3(
7465 version_,
Victor Vasiliev7752898d2019-11-14 21:30:227466 quic::QuicUtils::CreateRandomConnectionId(
7467 context_.random_generator()),
7468 context_.clock(), kDefaultServerHostName,
Patrick Meenan0b1b18cf2023-09-21 20:19:477469 quic::Perspective::IS_SERVER,
7470 /*client_priority_uses_incremental=*/false,
7471 /*use_priority_header=*/false);
Matt Menke26e41542019-06-05 01:09:517472
Renjie Tangaadb84b2019-08-31 01:00:237473 int packet_num3 = 1;
Patrick Meenan885a00652023-02-15 20:07:027474 partitioned_mock_quic_data2.AddWrite(
7475 SYNCHRONOUS, client_maker3.MakeInitialSettingsPacket(packet_num3++));
Matt Menke26e41542019-06-05 01:09:517476
7477 partitioned_mock_quic_data2.AddWrite(
7478 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027479 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237480 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:037481 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:107482 GetRequestHeaders("GET", url2.scheme(), "/2"), nullptr));
Matt Menke26e41542019-06-05 01:09:517483 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027484 ASYNC, server_maker3.MakeResponseHeadersPacket(
7485 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037486 GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517487 partitioned_mock_quic_data2.AddRead(
7488 ASYNC, server_maker3.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037489 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7490 ConstructDataFrame("2")));
Matt Menke26e41542019-06-05 01:09:517491 partitioned_mock_quic_data2.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347492 SYNCHRONOUS, client_maker3.MakeAckPacket(packet_num3++, 2, 1));
Matt Menke26e41542019-06-05 01:09:517493
7494 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
7495
7496 if (partition_connections) {
7497 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7498 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7499 } else {
7500 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7501 }
7502
7503 CreateSession();
7504
7505 TestCompletionCallback callback;
7506 HttpRequestInfo request1;
7507 request1.method = "GET";
7508 request1.url = GURL(url1);
7509 request1.traffic_annotation =
7510 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7511 request1.network_isolation_key = network_isolation_key1;
Brianna Goldstein314ddf722022-09-24 02:00:527512 request1.network_anonymization_key = network_anonymization_key1;
Matt Menke26e41542019-06-05 01:09:517513 HttpNetworkTransaction trans1(LOWEST, session_.get());
7514 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
7515 EXPECT_THAT(callback.GetResult(rv), IsOk());
7516 std::string response_data1;
7517 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
7518 EXPECT_EQ("1", response_data1);
7519
7520 HttpRequestInfo request2;
7521 request2.method = "GET";
7522 request2.url = GURL(url2);
7523 request2.traffic_annotation =
7524 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7525 request2.network_isolation_key = network_isolation_key2;
Brianna Goldstein314ddf722022-09-24 02:00:527526 request2.network_anonymization_key = network_anonymization_key2;
Matt Menke26e41542019-06-05 01:09:517527 HttpNetworkTransaction trans2(LOWEST, session_.get());
7528 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
7529 EXPECT_THAT(callback.GetResult(rv), IsOk());
7530 std::string response_data2;
7531 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
7532 EXPECT_EQ("2", response_data2);
7533
7534 HttpRequestInfo request3;
7535 request3.method = "GET";
7536 request3.url = GURL(url3);
7537 request3.traffic_annotation =
7538 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7539 request3.network_isolation_key = network_isolation_key1;
Brianna Goldstein314ddf722022-09-24 02:00:527540 request3.network_anonymization_key = network_anonymization_key1;
7541
Matt Menke26e41542019-06-05 01:09:517542 HttpNetworkTransaction trans3(LOWEST, session_.get());
7543 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
7544 EXPECT_THAT(callback.GetResult(rv), IsOk());
7545 std::string response_data3;
7546 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
7547 EXPECT_EQ("3", response_data3);
7548
7549 if (partition_connections) {
7550 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
7551 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
7552 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
7553 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
7554 } else {
7555 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
7556 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
7557 }
7558 }
7559 }
7560}
7561
7562// Test that two requests to the same origin over QUIC tunnels use different
7563// QUIC sessions if their NetworkIsolationKeys don't match, and
7564// kPartitionConnectionsByNetworkIsolationKey is enabled.
7565TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
7566 base::test::ScopedFeatureList feature_list;
7567 feature_list.InitAndEnableFeature(
7568 features::kPartitionConnectionsByNetworkIsolationKey);
7569
7570 session_params_.enable_quic = true;
7571 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567572 proxy_resolution_service_ =
Yoichi Osato9775d5642022-07-20 08:38:277573 ConfiguredProxyResolutionService::CreateFixedFromPacResultForTest(
Nicolas Arciniegad2013f92020-02-07 23:00:567574 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menke26e41542019-06-05 01:09:517575
7576 const char kGetRequest[] =
7577 "GET / HTTP/1.1\r\n"
7578 "Host: mail.example.org\r\n"
7579 "Connection: keep-alive\r\n\r\n";
7580 const char kGetResponse[] =
7581 "HTTP/1.1 200 OK\r\n"
7582 "Content-Length: 10\r\n\r\n";
7583
Ryan Hamiltonabad59e2019-06-06 04:02:597584 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
7585 std::make_unique<MockQuicData>(version_),
7586 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:517587
7588 for (int index : {0, 1}) {
7589 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227590 version_,
7591 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7592 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky957bab12023-01-31 16:40:107593 true);
Matt Menke26e41542019-06-05 01:09:517594 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227595 version_,
7596 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7597 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
7598 false);
Matt Menke26e41542019-06-05 01:09:517599
Renjie Tangaadb84b2019-08-31 01:00:237600 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:027601 mock_quic_data[index]->AddWrite(
7602 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:437603
Patrick Meenan8f8c8352023-07-06 17:20:197604 mock_quic_data[index]->AddWrite(
7605 SYNCHRONOUS,
7606 client_maker.MakePriorityPacket(
7607 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
7608 quic::HttpStreamPriority::kDefaultUrgency));
Matt Menke26e41542019-06-05 01:09:517609
Patrick Meenanf741c6082023-01-03 18:06:437610 std::cout << "MakeRequestHeadersPacket\n";
Ryan Hamiltonabad59e2019-06-06 04:02:597611 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:517612 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027613 client_maker.MakeRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037614 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
7615 quic::HttpStreamPriority::kDefaultUrgency,
Bence Béky957bab12023-01-31 16:40:107616 ConnectRequestHeaders("mail.example.org:443"), nullptr, false));
Ryan Hamiltonabad59e2019-06-06 04:02:597617 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027618 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:517619 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037620 GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:517621
Bence Béky319388a882020-09-23 18:42:527622 mock_quic_data[index]->AddWrite(
7623 SYNCHRONOUS,
7624 client_maker.MakeAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037625 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
7626 false, ConstructDataFrame(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:517627
Ryan Hamiltonabad59e2019-06-06 04:02:597628 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:517629 ASYNC, server_maker.MakeDataPacket(
7630 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037631 ConstructDataFrame(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:597632 mock_quic_data[index]->AddRead(
Bence Béky319388a882020-09-23 18:42:527633 SYNCHRONOUS, server_maker.MakeDataPacket(
7634 3, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:037635 false, ConstructDataFrame("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:597636 mock_quic_data[index]->AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347637 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2));
Ryan Hamiltonabad59e2019-06-06 04:02:597638 mock_quic_data[index]->AddRead(SYNCHRONOUS,
7639 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:517640
Ryan Hamiltonabad59e2019-06-06 04:02:597641 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:517642 }
7643
7644 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7645 SSLSocketDataProvider ssl_data2(ASYNC, OK);
7646 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
7647
7648 CreateSession();
7649
7650 request_.url = GURL("https://mail.example.org/");
7651 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
7652 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7653 RunTransaction(&trans);
7654 CheckResponseData(&trans, "0123456789");
7655
7656 HttpRequestInfo request2;
Matt Menke4807a9a2020-11-21 00:14:417657 const SchemefulSite kSite1(GURL("http://origin1/"));
7658 request_.network_isolation_key = NetworkIsolationKey(kSite1, kSite1);
Dustin J. Mitchell1d774ea2023-03-03 00:54:467659 request_.network_anonymization_key =
7660 NetworkAnonymizationKey::CreateSameSite(kSite1);
Matt Menke26e41542019-06-05 01:09:517661 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
7662 RunTransaction(&trans2);
7663 CheckResponseData(&trans2, "0123456789");
7664
Ryan Hamiltonabad59e2019-06-06 04:02:597665 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
7666 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
7667 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
7668 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:517669}
7670
Yoichi Osato4c75c0c2020-06-24 08:03:577671TEST_P(QuicNetworkTransactionTest, AllowHTTP1FalseProhibitsH1) {
7672 MockRead http_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING),
7673 MockRead(ASYNC, OK)};
7674 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
7675 socket_factory_.AddSocketDataProvider(&http_data);
7676 AddCertificate(&ssl_data_);
7677 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7678
7679 CreateSession();
7680
7681 request_.method = "POST";
7682 UploadDataStreamNotAllowHTTP1 upload_data("");
7683 request_.upload_data_stream = &upload_data;
7684
7685 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7686 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267687 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:577688 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7689 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_H2_OR_QUIC_REQUIRED));
7690}
7691
7692// Confirm mock class UploadDataStreamNotAllowHTTP1 can upload content over
7693// QUIC.
7694TEST_P(QuicNetworkTransactionTest, AllowHTTP1MockTest) {
7695 context_.params()->origins_to_force_quic_on.insert(
7696 HostPortPair::FromString("mail.example.org:443"));
7697
7698 MockQuicData mock_quic_data(version_);
7699 int write_packet_index = 1;
Patrick Meenan885a00652023-02-15 20:07:027700 mock_quic_data.AddWrite(SYNCHRONOUS,
7701 ConstructInitialSettingsPacket(write_packet_index++));
Yoichi Osato4c75c0c2020-06-24 08:03:577702 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:527703 mock_quic_data.AddWrite(
7704 SYNCHRONOUS,
7705 ConstructClientRequestHeadersAndDataFramesPacket(
7706 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:037707 true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
Bence Béky957bab12023-01-31 16:40:107708 nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:577709 mock_quic_data.AddRead(
7710 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037711 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287712 GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:577713
Yoichi Osato4c75c0c2020-06-24 08:03:577714 mock_quic_data.AddRead(
7715 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037716 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:527717 ConstructDataFrame("hello!")));
Yoichi Osato4c75c0c2020-06-24 08:03:577718
Renjie Tangcd594f32020-07-11 20:18:347719 mock_quic_data.AddWrite(SYNCHRONOUS,
7720 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:577721
7722 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:217723 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:577724 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7725
7726 // The non-alternate protocol job needs to hang in order to guarantee that
7727 // the alternate-protocol job will "win".
7728 AddHangingNonAlternateProtocolSocketData();
7729
7730 CreateSession();
7731 request_.method = "POST";
7732 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
7733 request_.upload_data_stream = &upload_data;
7734
7735 SendRequestAndExpectQuicResponse("hello!");
7736}
7737
Kenichi Ishibashi6fc20b82023-08-01 21:43:597738TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadPauseAndResume) {
7739 FLAGS_quic_enable_chaos_protection = false;
Yoichi Osato4c75c0c2020-06-24 08:03:577740 context_.params()->origins_to_force_quic_on.insert(
7741 HostPortPair::FromString("mail.example.org:443"));
7742
7743 MockQuicData mock_quic_data(version_);
7744 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
7745 int write_packet_index = 1;
7746 mock_quic_data.AddWrite(
7747 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
7748 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Patrick Meenan885a00652023-02-15 20:07:027749 mock_quic_data.AddWrite(SYNCHRONOUS,
7750 ConstructInitialSettingsPacket(write_packet_index++));
Yoichi Osato4c75c0c2020-06-24 08:03:577751 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:527752 mock_quic_data.AddWrite(
7753 SYNCHRONOUS,
7754 ConstructClientRequestHeadersAndDataFramesPacket(
7755 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:037756 true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
Bence Béky957bab12023-01-31 16:40:107757 nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:577758 mock_quic_data.AddRead(
7759 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
7760 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037761 GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:577762 mock_quic_data.AddRead(
7763 SYNCHRONOUS, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037764 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7765 ConstructDataFrame("hello!")));
Yoichi Osato4c75c0c2020-06-24 08:03:577766
Renjie Tangcd594f32020-07-11 20:18:347767 mock_quic_data.AddWrite(SYNCHRONOUS,
7768 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:577769 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:217770 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:577771 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7772 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
7773
7774 CreateSession();
7775
7776 AddQuicAlternateProtocolMapping(
7777 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
7778
7779 // Set up request.
7780 request_.method = "POST";
7781 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
7782 request_.upload_data_stream = &upload_data;
7783
7784 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7785 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267786 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:577787 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7788 base::RunLoop().RunUntilIdle();
7789 // Resume QUIC job
7790 crypto_client_stream_factory_.last_stream()
7791 ->NotifySessionOneRttKeyAvailable();
7792 socket_data->Resume();
7793
7794 base::RunLoop().RunUntilIdle();
7795 CheckResponseData(&trans, "hello!");
7796}
7797
Kenichi Ishibashi6fc20b82023-08-01 21:43:597798TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadFailH1AndResumeQuic) {
7799 FLAGS_quic_enable_chaos_protection = false;
Ryan Hamiltona51800a2022-02-12 19:34:357800 if (version_.AlpnDeferToRFCv1()) {
7801 // These versions currently do not support Alt-Svc.
7802 return;
7803 }
Yoichi Osato4c75c0c2020-06-24 08:03:577804 // This test confirms failed main job should not bother quic job.
7805 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:457806 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yoichi Osato4c75c0c2020-06-24 08:03:577807 MockRead("1.1 Body"),
7808 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7809 MockRead(ASYNC, OK)};
7810 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
7811 socket_factory_.AddSocketDataProvider(&http_data);
7812 AddCertificate(&ssl_data_);
7813 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7814
7815 MockQuicData mock_quic_data(version_);
7816 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
7817 int write_packet_index = 1;
7818 mock_quic_data.AddWrite(
7819 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
7820 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Patrick Meenan885a00652023-02-15 20:07:027821 mock_quic_data.AddWrite(SYNCHRONOUS,
7822 ConstructInitialSettingsPacket(write_packet_index++));
Yoichi Osato4c75c0c2020-06-24 08:03:577823 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:527824 mock_quic_data.AddWrite(
7825 SYNCHRONOUS,
7826 ConstructClientRequestHeadersAndDataFramesPacket(
7827 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:037828 true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
Bence Béky957bab12023-01-31 16:40:107829 nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:577830 mock_quic_data.AddRead(
7831 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
7832 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037833 GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:577834 mock_quic_data.AddRead(
7835 SYNCHRONOUS, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037836 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7837 ConstructDataFrame("hello!")));
Renjie Tangcd594f32020-07-11 20:18:347838 mock_quic_data.AddWrite(SYNCHRONOUS,
7839 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:577840 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:217841 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:577842 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7843 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
7844
7845 // This packet won't be read because AllowHTTP1:false doesn't allow H/1
7846 // connection.
7847 MockRead http_reads2[] = {MockRead("HTTP/1.1 200 OK\r\n")};
7848 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
7849 socket_factory_.AddSocketDataProvider(&http_data2);
7850 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7851
7852 CreateSession();
7853
7854 // Send the first request via TCP and set up alternative service (QUIC) for
7855 // the origin.
7856 SendRequestAndExpectHttpResponse("1.1 Body");
7857
7858 // Settings to resume main H/1 job quickly while pausing quic job.
7859 AddQuicAlternateProtocolMapping(
7860 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
7861 ServerNetworkStats stats1;
Peter Kastinge5a38ed2021-10-02 03:06:357862 stats1.srtt = base::Microseconds(10);
Yoichi Osato4c75c0c2020-06-24 08:03:577863 http_server_properties_->SetServerNetworkStats(
Brianna Goldstein02cb74f2022-09-29 05:41:017864 url::SchemeHostPort(request_.url), NetworkAnonymizationKey(), stats1);
Yoichi Osato4c75c0c2020-06-24 08:03:577865
7866 // Set up request.
7867 request_.method = "POST";
7868 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
7869 request_.upload_data_stream = &upload_data;
7870
7871 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7872 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267873 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:577874 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7875 // Confirm TCP job was resumed.
7876 // We can not check its failure because HttpStreamFactory::JobController.
7877 // main_job_net_error is not exposed.
Dustin J. Mitchell496de812024-01-16 19:14:547878 while (socket_factory_.mock_data().next_index() < 3u) {
Yoichi Osato4c75c0c2020-06-24 08:03:577879 base::RunLoop().RunUntilIdle();
Dustin J. Mitchell496de812024-01-16 19:14:547880 }
Yoichi Osato4c75c0c2020-06-24 08:03:577881 // Resume QUIC job.
7882 crypto_client_stream_factory_.last_stream()
7883 ->NotifySessionOneRttKeyAvailable();
7884 socket_data->Resume();
7885 base::RunLoop().RunUntilIdle();
7886 CheckResponseData(&trans, "hello!");
7887}
7888
Bence Békyc164e0d22020-09-22 20:08:597889TEST_P(QuicNetworkTransactionTest, IncorrectHttp3GoAway) {
Bence Békyc164e0d22020-09-22 20:08:597890 context_.params()->retry_without_alt_svc_on_quic_errors = false;
7891
7892 MockQuicData mock_quic_data(version_);
7893 int write_packet_number = 1;
7894 mock_quic_data.AddWrite(
7895 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number++));
7896 mock_quic_data.AddWrite(
7897 SYNCHRONOUS,
7898 ConstructClientRequestHeadersPacket(
7899 write_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:037900 true, GetRequestHeaders("GET", "https", "/")));
Bence Békyc164e0d22020-09-22 20:08:597901
7902 int read_packet_number = 1;
7903 mock_quic_data.AddRead(
7904 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number++));
7905 // The GOAWAY frame sent by the server MUST have a stream ID corresponding to
7906 // a client-initiated bidirectional stream. Any other kind of stream ID
7907 // should cause the client to close the connection.
7908 quic::GoAwayFrame goaway{3};
Nidhi Jaju391105a2022-07-28 02:09:517909 auto goaway_buffer = quic::HttpEncoder::SerializeGoAwayFrame(goaway);
Bence Békyc164e0d22020-09-22 20:08:597910 const quic::QuicStreamId control_stream_id =
7911 quic::QuicUtils::GetFirstUnidirectionalStreamId(
7912 version_.transport_version, quic::Perspective::IS_SERVER);
7913 mock_quic_data.AddRead(
Nidhi Jaju391105a2022-07-28 02:09:517914 ASYNC, ConstructServerDataPacket(read_packet_number++, control_stream_id,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037915 false, goaway_buffer));
Bence Békyc164e0d22020-09-22 20:08:597916 mock_quic_data.AddWrite(
7917 SYNCHRONOUS,
7918 ConstructClientAckAndConnectionClosePacket(
7919 write_packet_number++, 2, 4, quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
7920 "GOAWAY with invalid stream ID", 0));
7921 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7922
7923 // In order for a new QUIC session to be established via alternate-protocol
7924 // without racing an HTTP connection, we need the host resolution to happen
7925 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
7926 // connection to the the server, in this test we require confirmation
7927 // before encrypting so the HTTP job will still start.
7928 host_resolver_.set_synchronous_mode(true);
7929 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
7930 "");
7931
7932 CreateSession();
Liza Burakova80b8ebd2023-02-15 16:29:587933 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ASYNC_ZERO_RTT);
Bence Békyc164e0d22020-09-22 20:08:597934
7935 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7936 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267937 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Bence Békyc164e0d22020-09-22 20:08:597938 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Liza Burakova80b8ebd2023-02-15 16:29:587939 base::RunLoop().RunUntilIdle();
Bence Békyc164e0d22020-09-22 20:08:597940 crypto_client_stream_factory_.last_stream()
7941 ->NotifySessionOneRttKeyAvailable();
7942 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
7943
7944 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7945 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7946
7947 NetErrorDetails details;
7948 trans.PopulateNetErrorDetails(&details);
7949 EXPECT_THAT(details.quic_connection_error,
7950 quic::test::IsError(quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID));
7951}
7952
Bence Béky2ee18922020-09-25 12:11:327953TEST_P(QuicNetworkTransactionTest, RetryOnHttp3GoAway) {
Bence Béky2ee18922020-09-25 12:11:327954 MockQuicData mock_quic_data1(version_);
7955 int write_packet_number1 = 1;
7956 mock_quic_data1.AddWrite(
7957 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number1++));
7958 const quic::QuicStreamId stream_id1 =
7959 GetNthClientInitiatedBidirectionalStreamId(0);
7960 mock_quic_data1.AddWrite(SYNCHRONOUS,
7961 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037962 write_packet_number1++, stream_id1, true,
Bence Béky2ee18922020-09-25 12:11:327963 GetRequestHeaders("GET", "https", "/")));
7964 const quic::QuicStreamId stream_id2 =
7965 GetNthClientInitiatedBidirectionalStreamId(1);
7966 mock_quic_data1.AddWrite(SYNCHRONOUS,
7967 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037968 write_packet_number1++, stream_id2, true,
Bence Béky2ee18922020-09-25 12:11:327969 GetRequestHeaders("GET", "https", "/foo")));
7970
7971 int read_packet_number1 = 1;
7972 mock_quic_data1.AddRead(
7973 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number1++));
7974
7975 // GOAWAY with stream_id2 informs the client that stream_id2 (and streams with
7976 // larger IDs) have not been processed and can safely be retried.
7977 quic::GoAwayFrame goaway{stream_id2};
Nidhi Jaju391105a2022-07-28 02:09:517978 auto goaway_buffer = quic::HttpEncoder::SerializeGoAwayFrame(goaway);
Bence Béky2ee18922020-09-25 12:11:327979 const quic::QuicStreamId control_stream_id =
7980 quic::QuicUtils::GetFirstUnidirectionalStreamId(
7981 version_.transport_version, quic::Perspective::IS_SERVER);
7982 mock_quic_data1.AddRead(
Nidhi Jaju391105a2022-07-28 02:09:517983 ASYNC, ConstructServerDataPacket(read_packet_number1++, control_stream_id,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037984 false, goaway_buffer));
Bence Béky2ee18922020-09-25 12:11:327985 mock_quic_data1.AddWrite(
7986 ASYNC, ConstructClientAckPacket(write_packet_number1++, 2, 1));
7987
7988 // Response to first request is accepted after GOAWAY.
7989 mock_quic_data1.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
7990 read_packet_number1++, stream_id1, false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037991 GetResponseHeaders("200")));
Bence Béky2ee18922020-09-25 12:11:327992 mock_quic_data1.AddRead(
7993 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037994 read_packet_number1++, stream_id1, true,
Bence Béky2ee18922020-09-25 12:11:327995 ConstructDataFrame("response on the first connection")));
7996 mock_quic_data1.AddWrite(
7997 ASYNC, ConstructClientAckPacket(write_packet_number1++, 4, 1));
Bence Békye7426ec2021-02-02 18:18:197998 // Make socket hang to make sure connection stays in connection pool.
7999 // This should not prevent the retry from opening a new connection.
8000 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING);
David Schinazi395918c2021-02-05 18:56:218001 mock_quic_data1.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Bence Béky2ee18922020-09-25 12:11:328002 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
8003
8004 // Second request is retried on a new connection.
8005 MockQuicData mock_quic_data2(version_);
8006 QuicTestPacketMaker client_maker2(
8007 version_,
8008 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8009 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Patrick Meenan0b1b18cf2023-09-21 20:19:478010 /*client_priority_uses_incremental=*/true, /*use_priority_header=*/true);
Bence Béky2ee18922020-09-25 12:11:328011 int write_packet_number2 = 1;
8012 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(
8013 write_packet_number2++));
8014 spdy::SpdyPriority priority =
8015 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8016 mock_quic_data2.AddWrite(
8017 SYNCHRONOUS, client_maker2.MakeRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038018 write_packet_number2++, stream_id1, true, priority,
Bence Béky957bab12023-01-31 16:40:108019 GetRequestHeaders("GET", "https", "/foo"), nullptr));
Bence Béky2ee18922020-09-25 12:11:328020
8021 QuicTestPacketMaker server_maker2(
8022 version_,
8023 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8024 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Patrick Meenan0b1b18cf2023-09-21 20:19:478025 /*client_priority_uses_incremental=*/false,
8026 /*use_priority_header=*/false);
Bence Béky2ee18922020-09-25 12:11:328027 int read_packet_number2 = 1;
Tsuyoshi Horoea15e7a2023-05-23 00:12:038028 mock_quic_data2.AddRead(ASYNC, server_maker2.MakeResponseHeadersPacket(
8029 read_packet_number2++, stream_id1, false,
8030 GetResponseHeaders("200"), nullptr));
Bence Béky2ee18922020-09-25 12:11:328031 mock_quic_data2.AddRead(
8032 ASYNC, server_maker2.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038033 read_packet_number2++, stream_id1, true,
Bence Béky2ee18922020-09-25 12:11:328034 ConstructDataFrame("response on the second connection")));
8035 mock_quic_data2.AddWrite(
8036 ASYNC, client_maker2.MakeAckPacket(write_packet_number2++, 2, 1));
8037 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8038 mock_quic_data2.AddRead(ASYNC, 0); // EOF
8039 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8040
8041 AddHangingNonAlternateProtocolSocketData();
8042 CreateSession();
8043 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
8044
8045 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
8046 TestCompletionCallback callback1;
Matt Reichhoff0049a0b72021-10-20 20:44:268047 int rv = trans1.Start(&request_, callback1.callback(), net_log_with_source_);
Bence Béky2ee18922020-09-25 12:11:328048 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8049 base::RunLoop().RunUntilIdle();
8050
8051 HttpRequestInfo request2;
8052 request2.method = "GET";
8053 std::string url("https://");
8054 url.append(kDefaultServerHostName);
8055 url.append("/foo");
8056 request2.url = GURL(url);
8057 request2.load_flags = 0;
8058 request2.traffic_annotation =
8059 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8060 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8061 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:268062 rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
Bence Béky2ee18922020-09-25 12:11:328063 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8064
8065 EXPECT_THAT(callback1.WaitForResult(), IsOk());
8066 CheckResponseData(&trans1, "response on the first connection");
8067
8068 EXPECT_THAT(callback2.WaitForResult(), IsOk());
8069 CheckResponseData(&trans2, "response on the second connection");
8070
Bence Békye7426ec2021-02-02 18:18:198071 mock_quic_data1.Resume();
Bence Béky2ee18922020-09-25 12:11:328072 mock_quic_data2.Resume();
8073 EXPECT_TRUE(mock_quic_data1.AllWriteDataConsumed());
8074 EXPECT_TRUE(mock_quic_data1.AllReadDataConsumed());
8075 EXPECT_TRUE(mock_quic_data2.AllWriteDataConsumed());
8076 EXPECT_TRUE(mock_quic_data2.AllReadDataConsumed());
8077}
8078
Yoichi Osato4c75c0c2020-06-24 08:03:578079// TODO(yoichio): Add the TCP job reuse case. See crrev.com/c/2174099.
8080
Momoka Yamamotoff688972022-11-02 03:37:468081#if BUILDFLAG(ENABLE_WEBSOCKETS)
8082
8083// This test verifies that when there is an HTTP/3 connection open to a server,
8084// a WebSocket request does not use it, but instead opens a new connection with
8085// HTTP/1.
8086TEST_P(QuicNetworkTransactionTest, WebsocketOpensNewConnectionWithHttp1) {
8087 context_.params()->origins_to_force_quic_on.insert(
8088 HostPortPair::FromString("mail.example.org:443"));
8089 context_.params()->retry_without_alt_svc_on_quic_errors = false;
8090
8091 MockQuicData mock_quic_data(version_);
8092
8093 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
8094
8095 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:028096 mock_quic_data.AddWrite(SYNCHRONOUS,
8097 ConstructInitialSettingsPacket(packet_num++));
Momoka Yamamotoff688972022-11-02 03:37:468098
8099 spdy::SpdyPriority priority =
8100 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8101
8102 // The request will initially go out over HTTP/3.
8103 mock_quic_data.AddWrite(
8104 SYNCHRONOUS,
8105 client_maker_->MakeRequestHeadersPacket(
8106 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:038107 priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Momoka Yamamotoff688972022-11-02 03:37:468108 mock_quic_data.AddRead(
8109 ASYNC, server_maker_.MakeResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038110 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Momoka Yamamotoff688972022-11-02 03:37:468111 server_maker_.GetResponseHeaders("200"), nullptr));
8112 mock_quic_data.AddRead(
8113 ASYNC, server_maker_.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038114 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Momoka Yamamotoff688972022-11-02 03:37:468115 ConstructDataFrame("hello!")));
8116 mock_quic_data.AddWrite(SYNCHRONOUS,
8117 ConstructClientAckPacket(packet_num++, 2, 1));
8118 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read.
8119 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
8120
8121 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8122 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8123
8124 MockWrite http_writes[] = {
8125 MockWrite(SYNCHRONOUS, 0,
8126 "GET / HTTP/1.1\r\n"
8127 "Host: mail.example.org\r\n"
8128 "Connection: Upgrade\r\n"
8129 "Upgrade: websocket\r\n"
8130 "Origin: http://mail.example.org\r\n"
8131 "Sec-WebSocket-Version: 13\r\n"
8132 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
8133 "Sec-WebSocket-Extensions: permessage-deflate; "
8134 "client_max_window_bits\r\n\r\n")};
8135
8136 MockRead http_reads[] = {
8137 MockRead(SYNCHRONOUS, 1,
8138 "HTTP/1.1 101 Switching Protocols\r\n"
8139 "Upgrade: websocket\r\n"
8140 "Connection: Upgrade\r\n"
8141 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
8142
8143 SequencedSocketData http_data(http_reads, http_writes);
8144 socket_factory_.AddSocketDataProvider(&http_data);
8145
8146 CreateSession();
8147
8148 TestCompletionCallback callback1;
8149 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
8150 int rv = trans1.Start(&request_, callback1.callback(), net_log_with_source_);
8151 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8152 rv = callback1.WaitForResult();
8153 ASSERT_THAT(rv, IsOk());
8154
8155 const HttpResponseInfo* response = trans1.GetResponseInfo();
8156 ASSERT_TRUE(response->headers);
8157 EXPECT_TRUE(response->was_fetched_via_spdy);
8158 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
8159
8160 std::string response_data;
8161 rv = ReadTransaction(&trans1, &response_data);
8162 EXPECT_THAT(rv, IsOk());
8163 EXPECT_EQ("hello!", response_data);
8164
8165 HttpRequestInfo request2;
8166 request2.method = "GET";
8167 request2.url = GURL("wss://mail.example.org/");
8168 request2.traffic_annotation =
8169 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8170 EXPECT_TRUE(HostPortPair::FromURL(request_.url)
8171 .Equals(HostPortPair::FromURL(request2.url)));
8172 request2.extra_headers.SetHeader("Connection", "Upgrade");
8173 request2.extra_headers.SetHeader("Upgrade", "websocket");
8174 request2.extra_headers.SetHeader("Origin", "http://mail.example.org");
8175 request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
8176
8177 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
8178
8179 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8180 trans2.SetWebSocketHandshakeStreamCreateHelper(
8181 &websocket_stream_create_helper);
8182
8183 TestCompletionCallback callback2;
8184 rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
8185 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8186 rv = callback2.WaitForResult();
8187 ASSERT_THAT(rv, IsOk());
8188
8189 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
8190 mock_quic_data.Resume();
8191 // Run the QUIC session to completion.
8192 base::RunLoop().RunUntilIdle();
8193
8194 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8195 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8196}
Momoka Yamamoto751ecf72022-11-11 14:38:348197
8198// Much like above, but for Alt-Svc QUIC.
8199TEST_P(QuicNetworkTransactionTest,
8200 WebsocketOpensNewConnectionWithHttp1AfterAltSvcQuic) {
8201 if (version_.AlpnDeferToRFCv1()) {
8202 // These versions currently do not support Alt-Svc.
8203 return;
8204 }
8205 MockRead http_reads[] = {
8206 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
8207 MockRead("hello world"),
8208 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8209 MockRead(ASYNC, OK)};
8210
8211 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
8212 socket_factory_.AddSocketDataProvider(&http_data);
8213 AddCertificate(&ssl_data_);
8214 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8215
8216 MockQuicData mock_quic_data(version_);
8217 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:028218 mock_quic_data.AddWrite(SYNCHRONOUS,
8219 ConstructInitialSettingsPacket(packet_num++));
Momoka Yamamoto751ecf72022-11-11 14:38:348220 mock_quic_data.AddWrite(
8221 SYNCHRONOUS,
8222 ConstructClientRequestHeadersPacket(
8223 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:038224 GetRequestHeaders("GET", "https", "/")));
Momoka Yamamoto751ecf72022-11-11 14:38:348225 mock_quic_data.AddRead(
8226 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038227 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Momoka Yamamoto751ecf72022-11-11 14:38:348228 GetResponseHeaders("200")));
8229 mock_quic_data.AddRead(
8230 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038231 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Momoka Yamamoto751ecf72022-11-11 14:38:348232 ConstructDataFrame("hello!")));
8233 mock_quic_data.AddWrite(SYNCHRONOUS,
8234 ConstructClientAckPacket(packet_num++, 2, 1));
8235 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8236 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
8237
8238 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8239 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8240
8241 MockWrite http_writes2[] = {
8242 MockWrite(SYNCHRONOUS, 0,
8243 "GET / HTTP/1.1\r\n"
8244 "Host: mail.example.org\r\n"
8245 "Connection: Upgrade\r\n"
8246 "Upgrade: websocket\r\n"
8247 "Origin: http://mail.example.org\r\n"
8248 "Sec-WebSocket-Version: 13\r\n"
8249 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
8250 "Sec-WebSocket-Extensions: permessage-deflate; "
8251 "client_max_window_bits\r\n\r\n")};
8252
8253 MockRead http_reads2[] = {
8254 MockRead(SYNCHRONOUS, 1,
8255 "HTTP/1.1 101 Switching Protocols\r\n"
8256 "Upgrade: websocket\r\n"
8257 "Connection: Upgrade\r\n"
8258 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
8259
8260 SequencedSocketData http_data2(http_reads2, http_writes2);
8261 socket_factory_.AddSocketDataProvider(&http_data2);
8262 AddCertificate(&ssl_data_);
8263 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8264
8265 CreateSession();
8266
8267 SendRequestAndExpectHttpResponse("hello world");
8268 SendRequestAndExpectQuicResponse("hello!");
8269
8270 HttpRequestInfo request2;
8271 request2.method = "GET";
8272 request2.url = GURL("wss://mail.example.org/");
8273 request2.traffic_annotation =
8274 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8275 EXPECT_TRUE(HostPortPair::FromURL(request_.url)
8276 .Equals(HostPortPair::FromURL(request2.url)));
8277 request2.extra_headers.SetHeader("Connection", "Upgrade");
8278 request2.extra_headers.SetHeader("Upgrade", "websocket");
8279 request2.extra_headers.SetHeader("Origin", "http://mail.example.org");
8280 request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
8281
8282 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
8283
8284 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8285 trans2.SetWebSocketHandshakeStreamCreateHelper(
8286 &websocket_stream_create_helper);
8287
8288 TestCompletionCallback callback2;
8289 int rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
8290 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8291 rv = callback2.WaitForResult();
8292 ASSERT_THAT(rv, IsOk());
8293 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
8294 mock_quic_data.Resume();
8295 // Run the QUIC session to completion.
8296 base::RunLoop().RunUntilIdle();
8297
8298 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8299 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8300}
Momoka Yamamotoff688972022-11-02 03:37:468301
Momoka Yamamoto8d36ce22023-01-19 02:56:498302// Much like above, but for DnsHttpsSvcbAlpn QUIC.
8303TEST_P(QuicNetworkTransactionTest,
8304 WebsocketOpensNewConnectionWithHttp1AfterDnsHttpsSvcbAlpn) {
8305 session_params_.use_dns_https_svcb_alpn = true;
8306
8307 MockQuicData mock_quic_data(version_);
8308
8309 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:028310 mock_quic_data.AddWrite(SYNCHRONOUS,
8311 ConstructInitialSettingsPacket(packet_num++));
Momoka Yamamoto8d36ce22023-01-19 02:56:498312
8313 spdy::SpdyPriority priority =
8314 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8315
8316 // The request will initially go out over HTTP/3.
8317 mock_quic_data.AddWrite(
8318 SYNCHRONOUS,
8319 client_maker_->MakeRequestHeadersPacket(
8320 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:038321 priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Momoka Yamamoto8d36ce22023-01-19 02:56:498322 mock_quic_data.AddRead(
8323 ASYNC, server_maker_.MakeResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038324 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Momoka Yamamoto8d36ce22023-01-19 02:56:498325 server_maker_.GetResponseHeaders("200"), nullptr));
8326 mock_quic_data.AddRead(
8327 ASYNC, server_maker_.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038328 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Momoka Yamamoto8d36ce22023-01-19 02:56:498329 ConstructDataFrame("hello!")));
8330 mock_quic_data.AddWrite(SYNCHRONOUS,
8331 ConstructClientAckPacket(packet_num++, 2, 1));
8332 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read.
8333 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
8334
8335 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8336
8337 MockWrite http_writes[] = {
8338 MockWrite(SYNCHRONOUS, 0,
8339 "GET / HTTP/1.1\r\n"
8340 "Host: mail.example.org\r\n"
8341 "Connection: Upgrade\r\n"
8342 "Upgrade: websocket\r\n"
8343 "Origin: http://mail.example.org\r\n"
8344 "Sec-WebSocket-Version: 13\r\n"
8345 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
8346 "Sec-WebSocket-Extensions: permessage-deflate; "
8347 "client_max_window_bits\r\n\r\n")};
8348
8349 MockRead http_reads[] = {
8350 MockRead(SYNCHRONOUS, 1,
8351 "HTTP/1.1 101 Switching Protocols\r\n"
8352 "Upgrade: websocket\r\n"
8353 "Connection: Upgrade\r\n"
8354 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
8355
8356 SequencedSocketData http_data(http_reads, http_writes);
8357 socket_factory_.AddSocketDataProvider(&http_data);
8358 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8359
8360 HostResolverEndpointResult endpoint_result1;
8361 endpoint_result1.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
8362 endpoint_result1.metadata.supported_protocol_alpns = {
8363 quic::QuicVersionLabelToString(quic::CreateQuicVersionLabel(version_))};
8364 HostResolverEndpointResult endpoint_result2;
8365 endpoint_result2.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
8366 std::vector<HostResolverEndpointResult> endpoints;
8367 endpoints.push_back(endpoint_result1);
8368 endpoints.push_back(endpoint_result2);
8369 host_resolver_.rules()->AddRule(
8370 "mail.example.org",
8371 MockHostResolverBase::RuleResolver::RuleResult(
8372 std::move(endpoints),
8373 /*aliases=*/std::set<std::string>{"mail.example.org"}));
8374
8375 CreateSession();
8376 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
8377 TestCompletionCallback callback1;
8378 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
8379 int rv = trans1.Start(&request_, callback1.callback(), net_log_with_source_);
8380 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8381 rv = callback1.WaitForResult();
8382 ASSERT_THAT(rv, IsOk());
8383
8384 const HttpResponseInfo* response = trans1.GetResponseInfo();
8385 ASSERT_TRUE(response->headers);
8386 EXPECT_TRUE(response->was_fetched_via_spdy);
8387 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
8388
8389 std::string response_data;
8390 rv = ReadTransaction(&trans1, &response_data);
8391 EXPECT_THAT(rv, IsOk());
8392 EXPECT_EQ("hello!", response_data);
8393
8394 HttpRequestInfo request2;
8395 request2.method = "GET";
8396 request2.url = GURL("wss://mail.example.org/");
8397 request2.traffic_annotation =
8398 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8399 EXPECT_TRUE(HostPortPair::FromURL(request_.url)
8400 .Equals(HostPortPair::FromURL(request2.url)));
8401 request2.extra_headers.SetHeader("Connection", "Upgrade");
8402 request2.extra_headers.SetHeader("Upgrade", "websocket");
8403 request2.extra_headers.SetHeader("Origin", "http://mail.example.org");
8404 request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
8405
8406 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
8407
8408 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8409 trans2.SetWebSocketHandshakeStreamCreateHelper(
8410 &websocket_stream_create_helper);
8411
8412 TestCompletionCallback callback2;
8413 rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
8414 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8415 rv = callback2.WaitForResult();
8416 ASSERT_THAT(rv, IsOk());
8417
8418 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
8419 mock_quic_data.Resume();
8420 // Run the QUIC session to completion.
8421 base::RunLoop().RunUntilIdle();
8422
8423 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8424 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8425}
8426
Momoka Yamamotoff688972022-11-02 03:37:468427#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
8428
Tsuyoshi Horo4f516be2022-06-14 11:53:138429} // namespace net::test