blob: c17472c4f7a114d798f841984f6e3117635cc85a [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>
Andrew Williams826d8742024-01-31 19:39:198#include <string_view>
bnc912a04b2016-04-20 14:19:509#include <utility>
[email protected]1e960032013-12-20 19:00:2010#include <vector>
11
[email protected]61a527782013-02-21 03:58:0012#include "base/compiler_specific.h"
Avi Drissman41c4a412023-01-11 22:45:3713#include "base/functional/bind.h"
Keishi Hattori0e45c022021-11-27 09:25:5214#include "base/memory/raw_ptr.h"
mmenke651bae7f2015-12-18 21:26:4515#include "base/run_loop.h"
Bence Béky319388a882020-09-23 18:42:5216#include "base/strings/strcat.h"
zhongyie537a002017-06-27 16:48:2117#include "base/strings/string_number_conversions.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"
Andrew Williams5fcff8e2024-01-23 21:22:4132#include "net/base/test_proxy_delegate.h"
[email protected]6e7845ae2013-03-29 21:48:1133#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5334#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0035#include "net/http/http_auth_handler_factory.h"
Tsuyoshi Horo3023b5d2023-11-28 21:40:3136#include "net/http/http_connection_info.h"
[email protected]61a527782013-02-21 03:58:0037#include "net/http/http_network_session.h"
38#include "net/http/http_network_transaction.h"
Matt Menke6e879bd2019-03-18 17:26:0439#include "net/http/http_proxy_connect_job.h"
Matt Menke609160742019-08-02 18:47:2640#include "net/http/http_server_properties.h"
[email protected]61a527782013-02-21 03:58:0041#include "net/http/http_stream.h"
42#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1943#include "net/http/http_transaction_test_util.h"
Yoichi Osato4c75c0c2020-06-24 08:03:5744#include "net/http/test_upload_data_stream_not_allow_http1.h"
[email protected]b1c988b2013-06-13 06:48:1145#include "net/http/transport_security_state.h"
Matt Reichhoff0049a0b72021-10-20 20:44:2646#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0047#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5148#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4649#include "net/log/test_net_log_util.h"
Nicolas Arciniegad2013f92020-02-07 23:00:5650#include "net/proxy_resolution/configured_proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4051#include "net/proxy_resolution/proxy_config_service_fixed.h"
52#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0853#include "net/quic/crypto/proof_verifier_chromium.h"
54#include "net/quic/mock_crypto_client_stream_factory.h"
Victor Vasiliev7752898d2019-11-14 21:30:2255#include "net/quic/mock_quic_context.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0856#include "net/quic/mock_quic_data.h"
57#include "net/quic/quic_chromium_alarm_factory.h"
Patrick Meenan885a00652023-02-15 20:07:0258#include "net/quic/quic_context.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0859#include "net/quic/quic_http_stream.h"
60#include "net/quic/quic_http_utils.h"
Dustin J. Mitchell795c7362024-01-18 16:50:5261#include "net/quic/quic_session_pool_peer.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0862#include "net/quic/quic_test_packet_maker.h"
63#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0064#include "net/socket/client_socket_factory.h"
65#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2166#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2867#include "net/socket/socket_performance_watcher.h"
68#include "net/socket/socket_performance_watcher_factory.h"
Andrew Williams5fcff8e2024-01-23 21:22:4169#include "net/socket/socket_tag.h"
[email protected]61a527782013-02-21 03:58:0070#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5871#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5772#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2973#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0174#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4375#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4076#include "net/test/test_with_task_environment.h"
Ryan Hamiltonea4fa192022-04-12 18:30:4977#include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_decrypter.h"
78#include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_encrypter.h"
79#include "net/third_party/quiche/src/quiche/quic/core/quic_framer.h"
80#include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
81#include "net/third_party/quiche/src/quiche/quic/platform/api/quic_test.h"
82#include "net/third_party/quiche/src/quiche/quic/test_tools/crypto_test_utils.h"
83#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_clock.h"
84#include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
85#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_session_peer.h"
86#include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
87#include "net/third_party/quiche/src/quiche/spdy/core/spdy_frame_builder.h"
88#include "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2989#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0090#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4891#include "net/url_request/url_request.h"
Matt Menkea9606a0eb2020-09-11 20:36:3892#include "net/url_request/url_request_job_factory.h"
allada71b2efb2016-09-09 04:57:4893#include "net/url_request/url_request_test_util.h"
Momoka Yamamotoff688972022-11-02 03:37:4694#include "net/websockets/websocket_test_util.h"
robpercival214763f2016-07-01 23:27:0195#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0096#include "testing/gtest/include/gtest/gtest.h"
97#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4698#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0099
Reilly Grant89a7e512018-01-20 01:57:16100using ::testing::ElementsAre;
101using ::testing::Key;
102
Tsuyoshi Horo4f516be2022-06-14 11:53:13103namespace net::test {
[email protected]61a527782013-02-21 03:58:00104
105namespace {
106
bnc359ed2a2016-04-29 20:43:45107enum DestinationType {
108 // In pooling tests with two requests for different origins to the same
109 // destination, the destination should be
110 SAME_AS_FIRST, // the same as the first origin,
111 SAME_AS_SECOND, // the same as the second origin, or
112 DIFFERENT, // different from both.
113};
114
rch9ae5b3b2016-02-11 00:36:29115const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45116const char kDifferentHostname[] = "different.example.com";
117
Andrew Williams826d8742024-01-31 19:39:19118constexpr std::string_view kQuic200RespStatusLine = "HTTP/1.1 200";
119
120// Response data used for QUIC requests in multiple tests.
121constexpr std::string_view kQuicRespData = "hello!";
122// Response data used for HTTP requests in multiple tests.
Alison Gale923a33e2024-04-22 23:34:28123// TODO(crbug.com/41496581): Once MockReadWrite accepts a
Andrew Williams826d8742024-01-31 19:39:19124// std::string_view parameter, we can use "constexpr std::string_view" for this.
125const char kHttpRespData[] = "hello world";
126
David Schinazi09e9a6012019-10-03 17:37:57127struct TestParams {
128 quic::ParsedQuicVersion version;
Patrick Meenan0b1b18cf2023-09-21 20:19:47129 bool priority_header_enabled;
David Schinazi09e9a6012019-10-03 17:37:57130};
131
132// Used by ::testing::PrintToStringParamName().
133std::string PrintToString(const TestParams& p) {
Patrick Meenan0b1b18cf2023-09-21 20:19:47134 return base::StrCat({ParsedQuicVersionToString(p.version), "_",
135 p.priority_header_enabled ? "PriorityHeaderEnabled"
136 : "PriorityHeaderDisabled"});
David Schinazi09e9a6012019-10-03 17:37:57137}
138
bnc359ed2a2016-04-29 20:43:45139// Run QuicNetworkTransactionWithDestinationTest instances with all value
140// combinations of version and destination_type.
141struct PoolingTestParams {
Nick Harper23290b82019-05-02 00:02:56142 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45143 DestinationType destination_type;
144};
145
David Schinazi09e9a6012019-10-03 17:37:57146// Used by ::testing::PrintToStringParamName().
147std::string PrintToString(const PoolingTestParams& p) {
148 const char* destination_string = "";
149 switch (p.destination_type) {
150 case SAME_AS_FIRST:
151 destination_string = "SAME_AS_FIRST";
152 break;
153 case SAME_AS_SECOND:
154 destination_string = "SAME_AS_SECOND";
155 break;
156 case DIFFERENT:
157 destination_string = "DIFFERENT";
158 break;
159 }
Victor Vasiliev62c09dc2020-11-06 18:18:29160 return base::StrCat(
Bence Béky957bab12023-01-31 16:40:10161 {ParsedQuicVersionToString(p.version), "_", destination_string});
David Schinazi09e9a6012019-10-03 17:37:57162}
163
Ryan Hamiltona2dcbae2022-02-09 19:02:45164std::string GenerateQuicAltSvcHeaderValue(
165 const quic::ParsedQuicVersionVector& versions,
166 std::string host,
167 uint16_t port) {
168 std::string value;
Bence Békyb89104962020-01-24 00:05:17169 std::string version_string;
David Schinazifbd4c432020-04-07 19:23:55170 bool first_version = true;
171 for (const auto& version : versions) {
172 if (first_version) {
173 first_version = false;
Bence Békyb89104962020-01-24 00:05:17174 } else {
Ryan Hamiltona2dcbae2022-02-09 19:02:45175 value.append(", ");
David Schinazifbd4c432020-04-07 19:23:55176 }
Ryan Hamiltona2dcbae2022-02-09 19:02:45177 value.append(base::StrCat({quic::AlpnForVersion(version), "=\"", host, ":",
178 base::NumberToString(port), "\""}));
zhongyie537a002017-06-27 16:48:21179 }
Ryan Hamiltona2dcbae2022-02-09 19:02:45180 return value;
181}
Bence Békyb89104962020-01-24 00:05:17182
Ryan Hamiltona2dcbae2022-02-09 19:02:45183std::string GenerateQuicAltSvcHeaderValue(
184 const quic::ParsedQuicVersionVector& versions,
185 uint16_t port) {
186 return GenerateQuicAltSvcHeaderValue(versions, "", port);
187}
188
189std::string GenerateQuicAltSvcHeader(
190 const quic::ParsedQuicVersionVector& versions) {
191 std::string altsvc_header = "Alt-Svc: ";
192 altsvc_header.append(GenerateQuicAltSvcHeaderValue(versions, 443));
193 altsvc_header.append("\r\n");
Bence Békyb89104962020-01-24 00:05:17194 return altsvc_header;
zhongyie537a002017-06-27 16:48:21195}
196
David Schinazi09e9a6012019-10-03 17:37:57197std::vector<TestParams> GetTestParams() {
198 std::vector<TestParams> params;
199 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) {
Patrick Meenan0b1b18cf2023-09-21 20:19:47202 params.push_back(TestParams{version, true});
203 params.push_back(TestParams{version, false});
David Schinazi09e9a6012019-10-03 17:37:57204 }
205 return params;
206}
207
bnc359ed2a2016-04-29 20:43:45208std::vector<PoolingTestParams> GetPoolingTestParams() {
209 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56210 quic::ParsedQuicVersionVector all_supported_versions =
Patrick Meenan885a00652023-02-15 20:07:02211 AllSupportedQuicVersions();
Nico Weber6dcde5b2020-02-22 20:49:20212 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
Bence Béky957bab12023-01-31 16:40:10213 params.push_back(PoolingTestParams{version, SAME_AS_FIRST});
214 params.push_back(PoolingTestParams{version, SAME_AS_SECOND});
215 params.push_back(PoolingTestParams{version, DIFFERENT});
bnc359ed2a2016-04-29 20:43:45216 }
217 return params;
218}
bncb07c05532015-05-14 19:07:20219
Andrew Williams826d8742024-01-31 19:39:19220std::string ConstructDataFrameForVersion(std::string_view body,
Bence Béky319388a882020-09-23 18:42:52221 quic::ParsedQuicVersion version) {
Victor Vasilievc617d452022-03-07 15:54:25222 quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
223 body.size(), quiche::SimpleBufferAllocator::Get());
Andrew Williams826d8742024-01-31 19:39:19224 return base::StrCat({std::string_view(buffer.data(), buffer.size()), body});
Bence Béky319388a882020-09-23 18:42:52225}
226
[email protected]61a527782013-02-21 03:58:00227} // namespace
228
tbansal0f56a39a2016-04-07 22:03:38229class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40230 public:
tbansal180587c2017-02-16 15:13:23231 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
232 bool* rtt_notification_received)
233 : should_notify_updated_rtt_(should_notify_updated_rtt),
234 rtt_notification_received_(rtt_notification_received) {}
Peter Boström293b1342021-09-22 17:31:43235
236 TestSocketPerformanceWatcher(const TestSocketPerformanceWatcher&) = delete;
237 TestSocketPerformanceWatcher& operator=(const TestSocketPerformanceWatcher&) =
238 delete;
239
Tsuyoshi Horo07c3f0e2022-06-16 07:30:47240 ~TestSocketPerformanceWatcher() override = default;
tbansalfdf5665b2015-09-21 22:46:40241
tbansal180587c2017-02-16 15:13:23242 bool ShouldNotifyUpdatedRTT() const override {
243 return *should_notify_updated_rtt_;
244 }
tbansalfdf5665b2015-09-21 22:46:40245
tbansal0f56a39a2016-04-07 22:03:38246 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
247 *rtt_notification_received_ = true;
248 }
249
250 void OnConnectionChanged() override {}
251
252 private:
Keishi Hattori0e45c022021-11-27 09:25:52253 raw_ptr<bool> should_notify_updated_rtt_;
254 raw_ptr<bool> rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38255};
256
257class TestSocketPerformanceWatcherFactory
258 : public SocketPerformanceWatcherFactory {
259 public:
Tsuyoshi Horo4478fd32022-06-09 01:41:25260 TestSocketPerformanceWatcherFactory() = default;
Peter Boström293b1342021-09-22 17:31:43261
262 TestSocketPerformanceWatcherFactory(
263 const TestSocketPerformanceWatcherFactory&) = delete;
264 TestSocketPerformanceWatcherFactory& operator=(
265 const TestSocketPerformanceWatcherFactory&) = delete;
266
Tsuyoshi Horo07c3f0e2022-06-16 07:30:47267 ~TestSocketPerformanceWatcherFactory() override = default;
tbansal0f56a39a2016-04-07 22:03:38268
269 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42270 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41271 const Protocol protocol,
David Benjamin5241b582023-02-17 03:51:51272 const IPAddress& /* address */) override {
tbansalc8a94ea2015-11-02 23:58:51273 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38274 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51275 }
276 ++watcher_count_;
Tsuyoshi Horof8861cb2022-07-05 23:50:20277 return std::make_unique<TestSocketPerformanceWatcher>(
278 &should_notify_updated_rtt_, &rtt_notification_received_);
tbansalfdf5665b2015-09-21 22:46:40279 }
280
tbansalc8a94ea2015-11-02 23:58:51281 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40282
tbansalc8a94ea2015-11-02 23:58:51283 bool rtt_notification_received() const { return rtt_notification_received_; }
284
tbansal180587c2017-02-16 15:13:23285 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
286 should_notify_updated_rtt_ = should_notify_updated_rtt;
287 }
288
tbansalc8a94ea2015-11-02 23:58:51289 private:
Tsuyoshi Horo4478fd32022-06-09 01:41:25290 size_t watcher_count_ = 0u;
291 bool should_notify_updated_rtt_ = true;
292 bool rtt_notification_received_ = false;
tbansalc8a94ea2015-11-02 23:58:51293};
294
Ryan Hamilton8d9ee76e2018-05-29 23:52:52295class QuicNetworkTransactionTest
296 : public PlatformTest,
David Schinazi09e9a6012019-10-03 17:37:57297 public ::testing::WithParamInterface<TestParams>,
Gabriel Charette694c3c332019-08-19 14:53:05298 public WithTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00299 protected:
[email protected]1c04f9522013-02-21 20:32:43300 QuicNetworkTransactionTest()
David Schinazi09e9a6012019-10-03 17:37:57301 : version_(GetParam().version),
Nick Harper23290b82019-05-02 00:02:56302 supported_versions_(quic::test::SupportedVersions(version_)),
Tsuyoshi Horof8861cb2022-07-05 23:50:20303 client_maker_(std::make_unique<QuicTestPacketMaker>(
Zhongyi Shi1c022d22020-03-20 19:00:16304 version_,
305 quic::QuicUtils::CreateRandomConnectionId(
306 context_.random_generator()),
307 context_.clock(),
308 kDefaultServerHostName,
309 quic::Perspective::IS_CLIENT,
Patrick Meenan0b1b18cf2023-09-21 20:19:47310 /*client_priority_uses_incremental=*/true,
311 /*use_priority_header=*/true)),
Victor Vasiliev7752898d2019-11-14 21:30:22312 server_maker_(version_,
313 quic::QuicUtils::CreateRandomConnectionId(
314 context_.random_generator()),
315 context_.clock(),
316 kDefaultServerHostName,
317 quic::Perspective::IS_SERVER,
Patrick Meenan0b1b18cf2023-09-21 20:19:47318 /*client_priority_uses_incremental=*/false,
319 /*use_priority_header=*/false),
Tsuyoshi Horo2c0a5042022-07-06 05:53:07320 quic_task_runner_(
321 base::MakeRefCounted<TestTaskRunner>(context_.mock_clock())),
Tsuyoshi Horof8861cb2022-07-05 23:50:20322 ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()),
Nicolas Arciniegad2013f92020-02-07 23:00:56323 proxy_resolution_service_(
324 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11325 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke3233d8f22019-08-20 21:01:49326 http_server_properties_(std::make_unique<HttpServerProperties>()),
rchf114d982015-10-21 01:34:56327 ssl_data_(ASYNC, OK) {
Patrick Meenan0b1b18cf2023-09-21 20:19:47328 if (GetParam().priority_header_enabled) {
329 feature_list_.InitAndEnableFeature(net::features::kPriorityHeader);
330 } else {
331 feature_list_.InitAndDisableFeature(net::features::kPriorityHeader);
332 }
Renjie Tang98b4d512020-02-08 01:24:19333 FLAGS_quic_enable_http3_grease_randomness = false;
[email protected]aa9b14d2013-05-10 23:45:19334 request_.method = "GET";
rchf114d982015-10-21 01:34:56335 std::string url("https://");
bncb07c05532015-05-14 19:07:20336 url.append(kDefaultServerHostName);
337 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19338 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10339 request_.traffic_annotation =
340 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Victor Vasiliev7752898d2019-11-14 21:30:22341 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56342
343 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29344 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56345 verify_details_.cert_verify_result.verified_cert = cert;
346 verify_details_.cert_verify_result.is_issued_by_known_root = true;
347 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43348 }
[email protected]61a527782013-02-21 03:58:00349
dcheng67be2b1f2014-10-27 21:47:29350 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00351 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55352 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00353 }
354
dcheng67be2b1f2014-10-27 21:47:29355 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00356 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
357 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55358 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00359 PlatformTest::TearDown();
360 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55361 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40362 session_.reset();
[email protected]61a527782013-02-21 03:58:00363 }
364
Patrick Meenan0b1b18cf2023-09-21 20:19:47365 void DisablePriorityHeader() {
366 // switch client_maker_ to a version that does not add priority headers.
367 client_maker_ = std::make_unique<QuicTestPacketMaker>(
368 version_,
369 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
370 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
371 /*client_priority_uses_incremental=*/true,
372 /*use_priority_header=*/false);
373 }
374
Ryan Hamilton8d9ee76e2018-05-29 23:52:52375 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23376 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03377 return server_maker_.MakeConnectionClosePacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03378 num, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58379 }
380
Ryan Hamilton8d9ee76e2018-05-29 23:52:52381 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23382 uint64_t packet_number,
383 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34384 uint64_t smallest_received) {
Zhongyi Shi1c022d22020-03-20 19:00:16385 return client_maker_->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34386 smallest_received);
fayang3bcb8b502016-12-07 21:44:37387 }
388
Ryan Hamilton8d9ee76e2018-05-29 23:52:52389 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23390 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52391 quic::QuicStreamId stream_id,
392 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23393 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34394 uint64_t smallest_received) {
395 return client_maker_->MakeAckAndRstPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03396 num, stream_id, error_code, largest_received, smallest_received);
zhongyi6b5a3892016-03-12 04:46:20397 }
398
Ryan Hamilton8d9ee76e2018-05-29 23:52:52399 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23400 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52401 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41402 quic::QuicRstStreamErrorCode error_code) {
Tsuyoshi Horoea15e7a2023-05-23 00:12:03403 return client_maker_->MakeRstPacket(num, stream_id, error_code,
Zhongyi Shi1c022d22020-03-20 19:00:16404 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56405 }
406
Ryan Hamilton8d9ee76e2018-05-29 23:52:52407 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58408 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23409 uint64_t num,
Fan Yangac867502019-01-28 21:10:23410 uint64_t largest_received,
411 uint64_t smallest_received,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52412 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29413 const std::string& quic_error_details,
414 uint64_t frame_type) {
Zhongyi Shi1c022d22020-03-20 19:00:16415 return client_maker_->MakeAckAndConnectionClosePacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03416 num, largest_received, smallest_received, quic_error,
Renjie Tangcd594f32020-07-11 20:18:34417 quic_error_details, frame_type);
zhongyica364fbb2015-12-12 03:39:12418 }
419
Ryan Hamilton8d9ee76e2018-05-29 23:52:52420 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23421 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52422 quic::QuicStreamId stream_id,
423 quic::QuicRstStreamErrorCode error_code) {
Tsuyoshi Horoea15e7a2023-05-23 00:12:03424 return server_maker_.MakeRstPacket(num, stream_id, error_code);
zhongyica364fbb2015-12-12 03:39:12425 }
426
Ryan Hamilton8d9ee76e2018-05-29 23:52:52427 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02428 uint64_t packet_number) {
Zhongyi Shi1c022d22020-03-20 19:00:16429 return client_maker_->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37430 }
431
zhongyi32569c62016-01-08 02:54:30432 // Uses default QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01433 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
434 const std::string& scheme,
435 const std::string& path) {
Zhongyi Shi1c022d22020-03-20 19:00:16436 return GetRequestHeaders(method, scheme, path, client_maker_.get());
zhongyi32569c62016-01-08 02:54:30437 }
438
439 // Uses customized QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01440 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
441 const std::string& scheme,
442 const std::string& path,
443 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50444 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00445 }
446
Bence Béky4c325e52020-10-22 20:48:01447 spdy::Http2HeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Zhongyi Shi1c022d22020-03-20 19:00:16448 return client_maker_->ConnectRequestHeaders(host_port);
Yixin Wang46a273ec302018-01-23 17:59:56449 }
450
Bence Béky4c325e52020-10-22 20:48:01451 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58452 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00453 }
454
zhongyi32569c62016-01-08 02:54:30455 // Appends alt_svc headers in the response headers.
Bence Béky4c325e52020-10-22 20:48:01456 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status,
457 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58458 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30459 }
460
Ryan Hamilton8d9ee76e2018-05-29 23:52:52461 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23462 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52463 quic::QuicStreamId stream_id,
[email protected]61a527782013-02-21 03:58:00464 bool fin,
David Benjamin9f3b62e2023-10-02 16:03:42465 std::string_view data) {
Tsuyoshi Horoea15e7a2023-05-23 00:12:03466 return server_maker_.MakeDataPacket(packet_number, stream_id, fin, data);
[email protected]61a527782013-02-21 03:58:00467 }
468
Ryan Hamilton8d9ee76e2018-05-29 23:52:52469 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23470 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52471 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36472 bool fin,
David Benjamin9f3b62e2023-10-02 16:03:42473 std::string_view data) {
Tsuyoshi Horoea15e7a2023-05-23 00:12:03474 return client_maker_->MakeDataPacket(packet_number, stream_id, fin, data);
ckrasicda193a82016-07-09 00:39:36475 }
476
Ryan Hamilton8d9ee76e2018-05-29 23:52:52477 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23478 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52479 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23480 uint64_t largest_received,
481 uint64_t smallest_received,
Yixin Wang46a273ec302018-01-23 17:59:56482 bool fin,
David Benjamin9f3b62e2023-10-02 16:03:42483 std::string_view data) {
Tsuyoshi Horoea15e7a2023-05-23 00:12:03484 return client_maker_->MakeAckAndDataPacket(packet_number, stream_id,
485 largest_received,
Renjie Tangcd594f32020-07-11 20:18:34486 smallest_received, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56487 }
488
Kenichi Ishibashi10111e82021-03-23 02:19:06489 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckDataAndRst(
490 uint64_t packet_number,
Kenichi Ishibashi10111e82021-03-23 02:19:06491 quic::QuicStreamId stream_id,
492 quic::QuicRstStreamErrorCode error_code,
493 uint64_t largest_received,
494 uint64_t smallest_received,
495 quic::QuicStreamId data_id,
496 bool fin,
David Benjamin9f3b62e2023-10-02 16:03:42497 std::string_view data) {
Kenichi Ishibashi10111e82021-03-23 02:19:06498 return client_maker_->MakeAckDataAndRst(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03499 packet_number, stream_id, error_code, largest_received,
Kenichi Ishibashi10111e82021-03-23 02:19:06500 smallest_received, data_id, fin, data);
501 }
502
Ryan Hamilton8d9ee76e2018-05-29 23:52:52503 std::unique_ptr<quic::QuicEncryptedPacket>
Patrick Meenanf741c6082023-01-03 18:06:43504 ConstructClientRequestHeadersPacket(
505 uint64_t packet_number,
506 quic::QuicStreamId stream_id,
Patrick Meenanf741c6082023-01-03 18:06:43507 bool fin,
508 spdy::Http2HeaderBlock headers,
509 bool should_include_priority_frame = true) {
510 return ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03511 packet_number, stream_id, fin, DEFAULT_PRIORITY, std::move(headers),
512 should_include_priority_frame);
zhongyi32569c62016-01-08 02:54:30513 }
514
Ryan Hamilton8d9ee76e2018-05-29 23:52:52515 std::unique_ptr<quic::QuicEncryptedPacket>
Patrick Meenanf741c6082023-01-03 18:06:43516 ConstructClientRequestHeadersPacket(
517 uint64_t packet_number,
518 quic::QuicStreamId stream_id,
Patrick Meenanf741c6082023-01-03 18:06:43519 bool fin,
520 RequestPriority request_priority,
521 spdy::Http2HeaderBlock headers,
Patrick Meenanf741c6082023-01-03 18:06:43522 bool should_include_priority_frame = true) {
Ryan Hamilton0239aac2018-05-19 00:03:13523 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56524 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16525 return client_maker_->MakeRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03526 packet_number, stream_id, fin, priority, std::move(headers), nullptr,
527 should_include_priority_frame);
Patrick Meenanf741c6082023-01-03 18:06:43528 }
529
530 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
531 uint64_t packet_number,
532 quic::QuicStreamId id,
533 RequestPriority request_priority) {
534 spdy::SpdyPriority spdy_priority =
535 ConvertRequestPriorityToQuicPriority(request_priority);
Tsuyoshi Horoea15e7a2023-05-23 00:12:03536 return client_maker_->MakePriorityPacket(packet_number, id, spdy_priority);
[email protected]61a527782013-02-21 03:58:00537 }
538
Ryan Hamilton8d9ee76e2018-05-29 23:52:52539 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25540 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23541 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52542 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25543 bool fin,
544 RequestPriority request_priority,
Bence Béky4c325e52020-10-22 20:48:01545 spdy::Http2HeaderBlock headers,
Yixin Wange7ecc472018-03-06 19:00:25546 size_t* spdy_headers_frame_length,
547 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13548 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25549 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16550 return client_maker_->MakeRequestHeadersAndMultipleDataFramesPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03551 packet_number, stream_id, fin, priority, std::move(headers),
552 spdy_headers_frame_length, data_writes);
Yixin Wange7ecc472018-03-06 19:00:25553 }
554
Ryan Hamilton8d9ee76e2018-05-29 23:52:52555 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23556 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52557 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52558 bool fin,
Bence Béky4c325e52020-10-22 20:48:01559 spdy::Http2HeaderBlock headers) {
Tsuyoshi Horoea15e7a2023-05-23 00:12:03560 return server_maker_.MakeResponseHeadersPacket(
561 packet_number, stream_id, fin, std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30562 }
563
Andrew Williams826d8742024-01-31 19:39:19564 std::string ConstructDataFrame(std::string_view body) {
Bence Béky319388a882020-09-23 18:42:52565 return ConstructDataFrameForVersion(body, version_);
Renjief49758b2019-01-11 23:32:41566 }
567
Nick Harper23290b82019-05-02 00:02:56568 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41569 session_params_.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:38570 context_.params()->supported_versions = supported_versions;
[email protected]61a527782013-02-21 03:58:00571
Victor Vasiliev7752898d2019-11-14 21:30:22572 session_context_.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:41573 session_context_.client_socket_factory = &socket_factory_;
574 session_context_.quic_crypto_client_stream_factory =
575 &crypto_client_stream_factory_;
576 session_context_.host_resolver = &host_resolver_;
577 session_context_.cert_verifier = &cert_verifier_;
578 session_context_.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:41579 session_context_.socket_performance_watcher_factory =
580 &test_socket_performance_watcher_factory_;
Andrew Williams5fcff8e2024-01-23 21:22:41581 session_context_.proxy_delegate = proxy_delegate_.get();
Lily Houghton8c2f97d2018-01-22 05:06:59582 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41583 session_context_.ssl_config_service = ssl_config_service_.get();
584 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49585 session_context_.http_server_properties = http_server_properties_.get();
Matt Reichhoff0049a0b72021-10-20 20:44:26586 session_context_.net_log = NetLog::Get();
mmenke6ddfbea2017-05-31 21:48:41587
Renjie Tang6ff9a9b2021-02-03 22:11:09588 session_ =
589 std::make_unique<HttpNetworkSession>(session_params_, session_context_);
Dustin J. Mitchell795c7362024-01-18 16:50:52590 session_->quic_session_pool()->set_is_quic_known_to_work_on_current_network(
591 true);
Yixin Wang46a273ec302018-01-23 17:59:56592 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
593 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00594 }
595
zhongyi86838d52017-06-30 01:19:44596 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21597
David Schinazif832cb82019-11-08 22:25:27598 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
Andrew Williams826d8742024-01-31 19:39:19599 std::string_view status_line,
Zhongyi Shi1c022d22020-03-20 19:00:16600 const quic::ParsedQuicVersion& version) {
[email protected]aa9b14d2013-05-10 23:45:19601 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42602 ASSERT_TRUE(response != nullptr);
603 ASSERT_TRUE(response->headers.get() != nullptr);
David Schinazif832cb82019-11-08 22:25:27604 EXPECT_EQ(status_line, response->headers->GetStatusLine());
[email protected]aa9b14d2013-05-10 23:45:19605 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52606 EXPECT_TRUE(response->was_alpn_negotiated);
Victor Vasiliev22dd3f212022-02-11 21:57:29607 auto connection_info =
608 QuicHttpStream::ConnectionInfoFromQuicVersion(version);
609 if (connection_info == response->connection_info) {
610 return;
611 }
612 // QUIC v1 and QUIC v2 are considered a match, because they have the same
613 // ALPN token.
Tsuyoshi Horo3023b5d2023-11-28 21:40:31614 if ((connection_info == HttpConnectionInfo::kQUIC_RFC_V1 ||
615 connection_info == HttpConnectionInfo::kQUIC_2_DRAFT_8) &&
616 (response->connection_info == HttpConnectionInfo::kQUIC_RFC_V1 ||
617 response->connection_info == HttpConnectionInfo::kQUIC_2_DRAFT_8)) {
Victor Vasiliev22dd3f212022-02-11 21:57:29618 return;
619 }
620
621 // They do not match. This EXPECT_EQ will fail and print useful
622 // information.
623 EXPECT_EQ(connection_info, response->connection_info);
[email protected]aa9b14d2013-05-10 23:45:19624 }
625
Zhongyi Shi1c022d22020-03-20 19:00:16626 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
Andrew Williams826d8742024-01-31 19:39:19627 std::string_view status_line) {
Zhongyi Shi1c022d22020-03-20 19:00:16628 CheckWasQuicResponse(trans, status_line, version_);
629 }
630
David Schinazif832cb82019-11-08 22:25:27631 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
Andrew Williams826d8742024-01-31 19:39:19632 CheckWasQuicResponse(trans, kQuic200RespStatusLine, version_);
David Schinazif832cb82019-11-08 22:25:27633 }
634
bnc691fda62016-08-12 00:43:16635 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41636 const HttpResponseInfo* response = trans->GetResponseInfo();
637 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37638 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41639 }
640
bnc691fda62016-08-12 00:43:16641 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19642 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42643 ASSERT_TRUE(response != nullptr);
644 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19645 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
646 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52647 EXPECT_FALSE(response->was_alpn_negotiated);
Tsuyoshi Horo3023b5d2023-11-28 21:40:31648 EXPECT_EQ(HttpConnectionInfo::kHTTP1_1, response->connection_info);
[email protected]aa9b14d2013-05-10 23:45:19649 }
650
Yixin Wang46a273ec302018-01-23 17:59:56651 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
652 const HttpResponseInfo* response = trans->GetResponseInfo();
653 ASSERT_TRUE(response != nullptr);
654 ASSERT_TRUE(response->headers.get() != nullptr);
Andrew Williams826d8742024-01-31 19:39:19655 // SPDY and QUIC use the same 200 response format.
656 EXPECT_EQ(kQuic200RespStatusLine, response->headers->GetStatusLine());
Yixin Wang46a273ec302018-01-23 17:59:56657 EXPECT_TRUE(response->was_fetched_via_spdy);
658 EXPECT_TRUE(response->was_alpn_negotiated);
Tsuyoshi Horo3023b5d2023-11-28 21:40:31659 EXPECT_EQ(HttpConnectionInfo::kHTTP2, response->connection_info);
Yixin Wang46a273ec302018-01-23 17:59:56660 }
661
bnc691fda62016-08-12 00:43:16662 void CheckResponseData(HttpNetworkTransaction* trans,
Andrew Williams826d8742024-01-31 19:39:19663 std::string_view expected) {
[email protected]aa9b14d2013-05-10 23:45:19664 std::string response_data;
bnc691fda62016-08-12 00:43:16665 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19666 EXPECT_EQ(expected, response_data);
667 }
668
bnc691fda62016-08-12 00:43:16669 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19670 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:26671 int rv = trans->Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:01672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
673 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19674 }
675
Andrew Williams826d8742024-01-31 19:39:19676 void SendRequestAndExpectHttpResponse(std::string_view expected) {
bnc691fda62016-08-12 00:43:16677 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
678 RunTransaction(&trans);
679 CheckWasHttpResponse(&trans);
680 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19681 }
682
Andrew Williams826d8742024-01-31 19:39:19683 void SendRequestAndExpectHttpResponseFromProxy(
684 std::string_view expected,
685 uint16_t port,
686 const ProxyChain& proxy_chain) {
tbansalc3308d72016-08-27 10:25:04687 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalc3308d72016-08-27 10:25:04688 RunTransaction(&trans);
689 CheckWasHttpResponse(&trans);
690 CheckResponsePort(&trans, port);
691 CheckResponseData(&trans, expected);
Andrew Williams826d8742024-01-31 19:39:19692 EXPECT_EQ(trans.GetResponseInfo()->proxy_chain, proxy_chain);
693 ASSERT_TRUE(proxy_chain.IsValid());
694 ASSERT_FALSE(proxy_chain.is_direct());
David Schinazif832cb82019-11-08 22:25:27695 }
tbansalc3308d72016-08-27 10:25:04696
Andrew Williams826d8742024-01-31 19:39:19697 void SendRequestAndExpectSpdyResponseFromProxy(
698 std::string_view expected,
699 uint16_t port,
700 const ProxyChain& proxy_chain) {
701 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
702 RunTransaction(&trans);
703 CheckWasSpdyResponse(&trans);
704 CheckResponsePort(&trans, port);
705 CheckResponseData(&trans, expected);
706 EXPECT_EQ(trans.GetResponseInfo()->proxy_chain, proxy_chain);
707 ASSERT_TRUE(proxy_chain.IsValid());
708 ASSERT_FALSE(proxy_chain.is_direct());
709 }
710
711 void SendRequestAndExpectQuicResponse(std::string_view expected,
712 std::string_view status_line) {
713 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, 443, status_line,
714 version_, std::nullopt);
715 }
716
717 void SendRequestAndExpectQuicResponse(std::string_view expected) {
718 SendRequestAndExpectQuicResponseMaybeFromProxy(
719 expected, 443, kQuic200RespStatusLine, version_, std::nullopt);
tbansal7cec3812015-02-05 21:25:12720 }
721
[email protected]aa9b14d2013-05-10 23:45:19722 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05723 MockCryptoClientStream::HandshakeMode handshake_mode,
Brianna Goldstein02cb74f2022-09-29 05:41:01724 const NetworkAnonymizationKey& network_anonymization_key =
725 NetworkAnonymizationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19726 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, server.host(), 443);
Peter Kastinge5a38ed2021-10-02 03:06:35729 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:49730 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:01731 server, network_anonymization_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07732 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19733 }
734
rchbe69cb902016-02-11 01:10:48735 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27736 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48737 const HostPortPair& alternative) {
738 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46739 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21740 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48741 alternative.port());
Peter Kastinge5a38ed2021-10-02 03:06:35742 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:49743 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:01744 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07745 supported_versions_);
rchbe69cb902016-02-11 01:10:48746 }
747
Matt Menkeb32ba5122019-09-10 19:17:05748 void ExpectBrokenAlternateProtocolMapping(
Brianna Goldstein02cb74f2022-09-29 05:41:01749 const NetworkAnonymizationKey& network_anonymization_key =
750 NetworkAnonymizationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46751 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34752 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49753 http_server_properties_->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:01754 server, network_anonymization_key);
zhongyic4de03032017-05-19 04:07:34755 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49756 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05757 alternative_service_info_vector[0].alternative_service(),
Brianna Goldstein02cb74f2022-09-29 05:41:01758 network_anonymization_key));
[email protected]aa9b14d2013-05-10 23:45:19759 }
760
Matt Menkeb32ba5122019-09-10 19:17:05761 void ExpectQuicAlternateProtocolMapping(
Brianna Goldstein02cb74f2022-09-29 05:41:01762 const NetworkAnonymizationKey& network_anonymization_key =
763 NetworkAnonymizationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46764 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34765 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49766 http_server_properties_->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:01767 server, network_anonymization_key);
zhongyic4de03032017-05-19 04:07:34768 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54769 EXPECT_EQ(
770 kProtoQUIC,
771 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49772 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05773 alternative_service_info_vector[0].alternative_service(),
Brianna Goldstein02cb74f2022-09-29 05:41:01774 network_anonymization_key));
[email protected]4d590c9c2014-05-02 05:14:33775 }
776
[email protected]aa9b14d2013-05-10 23:45:19777 void AddHangingNonAlternateProtocolSocketData() {
Lei Zhange00db752021-04-17 00:48:46778 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
[email protected]dda75ab2013-06-22 22:43:30779 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30780 hanging_data->set_connect_data(hanging_connect);
781 hanging_data_.push_back(std::move(hanging_data));
782 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
[email protected]aa9b14d2013-05-10 23:45:19783 }
784
Matt Menkeb32ba5122019-09-10 19:17:05785 // Adds a new socket data provider for an HTTP request, and runs a request,
786 // expecting it to be used.
787 void AddHttpDataAndRunRequest() {
788 MockWrite http_writes[] = {
789 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
790 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
791 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
792
Ryan Hamiltona2dcbae2022-02-09 19:02:45793 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
794 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
795 MockRead(SYNCHRONOUS, 5, "http used"),
796 // Connection closed.
797 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:05798 SequencedSocketData http_data(http_reads, http_writes);
799 socket_factory_.AddSocketDataProvider(&http_data);
800 SSLSocketDataProvider ssl_data(ASYNC, OK);
801 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
802 SendRequestAndExpectHttpResponse("http used");
803 EXPECT_TRUE(http_data.AllWriteDataConsumed());
804 EXPECT_TRUE(http_data.AllReadDataConsumed());
805 }
806
807 // Adds a new socket data provider for a QUIC request, and runs a request,
808 // expecting it to be used. The new QUIC session is not closed.
809 void AddQuicDataAndRunRequest() {
810 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22811 version_,
812 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
813 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Patrick Meenan0b1b18cf2023-09-21 20:19:47814 /*client_priority_uses_incremental=*/true,
815 /*use_priority_header=*/true);
Matt Menkeb32ba5122019-09-10 19:17:05816 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22817 version_,
818 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
819 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Patrick Meenan0b1b18cf2023-09-21 20:19:47820 /*client_priority_uses_incremental=*/false,
821 /*use_priority_header=*/false);
Matt Menkeb32ba5122019-09-10 19:17:05822 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56823 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05824 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:02825 quic_data.AddWrite(SYNCHRONOUS,
826 client_maker.MakeInitialSettingsPacket(packet_number++));
Matt Menkeb32ba5122019-09-10 19:17:05827 quic_data.AddWrite(
828 SYNCHRONOUS,
829 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56830 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:03831 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Bence Béky957bab12023-01-31 16:40:10832 GetRequestHeaders("GET", "https", "/", &client_maker), nullptr));
Matt Menkeb32ba5122019-09-10 19:17:05833 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Fan Yang1ef6dfef2021-07-24 16:20:16834 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Matt Menkeb32ba5122019-09-10 19:17:05835 quic_data.AddRead(
836 ASYNC, server_maker.MakeResponseHeadersPacket(
837 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:03838 server_maker.GetResponseHeaders("200"), nullptr));
Matt Menkeb32ba5122019-09-10 19:17:05839 quic_data.AddRead(
840 ASYNC, server_maker.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:03841 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
842 ConstructDataFrame("quic used")));
Matt Menkeb32ba5122019-09-10 19:17:05843 // Don't care about the final ack.
844 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
845 // No more data to read.
846 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
847 quic_data.AddSocketDataToFactory(&socket_factory_);
Fan Yang1ef6dfef2021-07-24 16:20:16848
849 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
850 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:26851 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Fan Yang1ef6dfef2021-07-24 16:20:16852 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
853
854 // Pump the message loop to get the request started.
855 base::RunLoop().RunUntilIdle();
856 // Explicitly confirm the handshake.
857 crypto_client_stream_factory_.last_stream()
858 ->NotifySessionOneRttKeyAvailable();
859
860 ASSERT_FALSE(quic_data.AllReadDataConsumed());
861 quic_data.Resume();
862
863 // Run the QUIC session to completion.
864 base::RunLoop().RunUntilIdle();
Matt Menkeb32ba5122019-09-10 19:17:05865
866 EXPECT_TRUE(quic_data.AllReadDataConsumed());
867 }
868
Bence Béky6e243aa2019-12-13 19:01:07869 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56870 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
871 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36872 }
873
Bence Béky6e243aa2019-12-13 19:01:07874 quic::QuicStreamId GetQpackDecoderStreamId() const {
875 return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
876 version_.transport_version, 1);
877 }
878
879 std::string StreamCancellationQpackDecoderInstruction(int n) const {
Ian Swettb70d9f8f2020-04-10 23:38:43880 return StreamCancellationQpackDecoderInstruction(n, true);
881 }
882
883 std::string StreamCancellationQpackDecoderInstruction(
884 int n,
885 bool create_stream) const {
Bence Béky6e243aa2019-12-13 19:01:07886 const quic::QuicStreamId cancelled_stream_id =
887 GetNthClientInitiatedBidirectionalStreamId(n);
888 EXPECT_LT(cancelled_stream_id, 63u);
889
Peter Kasting241e6d22021-06-09 17:24:58890 const char opcode = 0x40;
Ian Swettb70d9f8f2020-04-10 23:38:43891 if (create_stream) {
Peter Kasting241e6d22021-06-09 17:24:58892 return {0x03, static_cast<char>(opcode | cancelled_stream_id)};
Ian Swettb70d9f8f2020-04-10 23:38:43893 } else {
Peter Kasting241e6d22021-06-09 17:24:58894 return {static_cast<char>(opcode | cancelled_stream_id)};
Ian Swettb70d9f8f2020-04-10 23:38:43895 }
Bence Béky6e243aa2019-12-13 19:01:07896 }
897
Bence Béky230ac612017-08-30 19:17:08898 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49899 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08900 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49901 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08902 }
903
Zhongyi Shi1c022d22020-03-20 19:00:16904 void SendRequestAndExpectQuicResponseMaybeFromProxy(
Andrew Williams826d8742024-01-31 19:39:19905 std::string_view expected,
Zhongyi Shi1c022d22020-03-20 19:00:16906 uint16_t port,
Andrew Williams826d8742024-01-31 19:39:19907 std::string_view status_line,
908 const quic::ParsedQuicVersion& version,
909 std::optional<ProxyChain> proxy_chain) {
Zhongyi Shi1c022d22020-03-20 19:00:16910 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Zhongyi Shi1c022d22020-03-20 19:00:16911 RunTransaction(&trans);
912 CheckWasQuicResponse(&trans, status_line, version);
913 CheckResponsePort(&trans, port);
914 CheckResponseData(&trans, expected);
Andrew Williams826d8742024-01-31 19:39:19915 if (proxy_chain.has_value()) {
916 EXPECT_EQ(trans.GetResponseInfo()->proxy_chain, *proxy_chain);
917 ASSERT_TRUE(proxy_chain->IsValid());
918 ASSERT_FALSE(proxy_chain->is_direct());
Cammie Smith Barnesbf91e2a2020-12-23 20:49:04919 // DNS aliases should be empty when using a proxy.
920 EXPECT_TRUE(trans.GetResponseInfo()->dns_aliases.empty());
Zhongyi Shi1c022d22020-03-20 19:00:16921 } else {
Andrew Williamsc3ea3b5d2023-10-25 14:32:46922 EXPECT_TRUE(trans.GetResponseInfo()->proxy_chain.is_direct());
Zhongyi Shi1c022d22020-03-20 19:00:16923 }
924 }
925
Victor Vasiliev22dd3f212022-02-11 21:57:29926 // Verify that the set of QUIC protocols in `alt_svc_info_vector` and
927 // `supported_versions` is the same. Since QUICv1 and QUICv2 have the same
928 // ALPN token "h3", they cannot be distinguished when parsing ALPN, so
929 // consider them equal. This is accomplished by comparing the set of ALPN
930 // strings (instead of comparing the set of ParsedQuicVersion entities).
931 static void VerifyQuicVersionsInAlternativeServices(
932 const AlternativeServiceInfoVector& alt_svc_info_vector,
933 const quic::ParsedQuicVersionVector& supported_versions) {
934 // Process supported versions.
935 std::set<std::string> supported_alpn;
936 for (const auto& version : supported_versions) {
937 if (version.AlpnDeferToRFCv1()) {
938 // These versions currently do not support Alt-Svc.
939 return;
940 }
941 supported_alpn.insert(quic::ParsedQuicVersionToString(version));
942 }
943
944 // Versions that support the legacy Google-specific Alt-Svc format are sent
945 // in a single Alt-Svc entry, therefore they are accumulated in a single
946 // AlternativeServiceInfo, whereas more recent versions all have their own
947 // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
948 std::set<std::string> alt_svc_negotiated_alpn;
949 for (const auto& alt_svc_info : alt_svc_info_vector) {
950 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
951 for (const auto& version : alt_svc_info.advertised_versions()) {
952 alt_svc_negotiated_alpn.insert(
953 quic::ParsedQuicVersionToString(version));
954 }
955 }
956
957 // Compare.
958 EXPECT_EQ(alt_svc_negotiated_alpn, supported_alpn);
959 }
960
Nick Harper23290b82019-05-02 00:02:56961 const quic::ParsedQuicVersion version_;
Ryan Hamiltona2dcbae2022-02-09 19:02:45962 const std::string alt_svc_header_ =
963 GenerateQuicAltSvcHeader({version_}) + "\r\n";
Nick Harper23290b82019-05-02 00:02:56964 quic::ParsedQuicVersionVector supported_versions_;
Patrick Meenan0041f332022-05-19 23:48:35965 quic::test::QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Victor Vasiliev7752898d2019-11-14 21:30:22966 MockQuicContext context_;
Zhongyi Shi1c022d22020-03-20 19:00:16967 std::unique_ptr<QuicTestPacketMaker> client_maker_;
alyssar2adf3ac2016-05-03 17:12:58968 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:09969 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:42970 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00971 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56972 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05973 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Eric Orthbe86fee2021-10-28 22:31:11974 MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
975 RuleResolver::GetLocalhostResult()};
[email protected]1c04f9522013-02-21 20:32:43976 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11977 TransportSecurityState transport_security_state_;
tbansal0f56a39a2016-04-07 22:03:38978 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07979 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Andrew Williams5fcff8e2024-01-23 21:22:41980 // `proxy_resolution_service_` may store a pointer to `proxy_delegate_`, so
981 // ensure that the latter outlives the former.
982 std::unique_ptr<TestProxyDelegate> proxy_delegate_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:26983 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42984 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:49985 std::unique_ptr<HttpServerProperties> http_server_properties_;
Matt Menke30a878c2021-07-20 22:25:09986 HttpNetworkSessionParams session_params_;
987 HttpNetworkSessionContext session_context_;
[email protected]aa9b14d2013-05-10 23:45:19988 HttpRequestInfo request_;
Matt Reichhoff0049a0b72021-10-20 20:44:26989 NetLogWithSource net_log_with_source_{
990 NetLogWithSource::Make(NetLogSourceType::NONE)};
991 RecordingNetLogObserver net_log_observer_;
danakjad1777e2016-04-16 00:56:42992 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56993 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03994 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
Patrick Meenan0b1b18cf2023-09-21 20:19:47995 base::test::ScopedFeatureList feature_list_;
[email protected]61a527782013-02-21 03:58:00996};
997
David Schinazi09e9a6012019-10-03 17:37:57998INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
999 QuicNetworkTransactionTest,
1000 ::testing::ValuesIn(GetTestParams()),
1001 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201002
Ryan Hamilton409e838c2024-04-03 22:08:071003TEST_P(QuicNetworkTransactionTest, BasicRequestAndResponse) {
1004 context_.params()->origins_to_force_quic_on.insert(
1005 HostPortPair::FromString("mail.example.org:443"));
1006
1007 MockQuicData quic_data(version_);
Ryan Hamiltona4f632d2024-04-03 22:27:421008 int sent_packet_num = 0;
1009 int received_packet_num = 0;
1010 const quic::QuicStreamId stream_id =
1011 GetNthClientInitiatedBidirectionalStreamId(0);
Ryan Hamilton409e838c2024-04-03 22:08:071012 // HTTP/3 SETTINGS are always the first thing sent on a connection
Ryan Hamiltona4f632d2024-04-03 22:27:421013 quic_data.AddWrite(SYNCHRONOUS,
1014 ConstructInitialSettingsPacket(++sent_packet_num));
Ryan Hamilton409e838c2024-04-03 22:08:071015 // The GET request with no body is sent next.
Ryan Hamiltona4f632d2024-04-03 22:27:421016 quic_data.AddWrite(SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1017 ++sent_packet_num, stream_id, true,
1018 GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton409e838c2024-04-03 22:08:071019 // Read the response headers.
1020 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamiltona4f632d2024-04-03 22:27:421021 ++received_packet_num, stream_id, false,
1022 GetResponseHeaders("200")));
Ryan Hamilton409e838c2024-04-03 22:08:071023 // Read the response body.
Ryan Hamiltona4f632d2024-04-03 22:27:421024 quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
1025 ++received_packet_num, stream_id, true,
1026 ConstructDataFrame(kQuicRespData)));
Ryan Hamilton409e838c2024-04-03 22:08:071027 // Acknowledge the previous two received packets.
Ryan Hamiltona4f632d2024-04-03 22:27:421028 quic_data.AddWrite(
1029 SYNCHRONOUS,
1030 ConstructClientAckPacket(++sent_packet_num, received_packet_num, 1));
Ryan Hamilton409e838c2024-04-03 22:08:071031 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1032 // Connection close on shutdown.
Ryan Hamiltona4f632d2024-04-03 22:27:421033 quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
1034 ++sent_packet_num, received_packet_num, 1,
1035 quic::QUIC_CONNECTION_CANCELLED,
1036 "net error", quic::NO_IETF_QUIC_ERROR));
Ryan Hamilton409e838c2024-04-03 22:08:071037
1038 quic_data.AddSocketDataToFactory(&socket_factory_);
1039
1040 CreateSession();
1041
1042 SendRequestAndExpectQuicResponse(kQuicRespData);
1043
1044 // Delete the session while the MockQuicData is still in scope.
1045 session_.reset();
1046}
1047
1048TEST_P(QuicNetworkTransactionTest, BasicRequestAndResponseWithAsycWrites) {
1049 context_.params()->origins_to_force_quic_on.insert(
1050 HostPortPair::FromString("mail.example.org:443"));
1051
1052 MockQuicData quic_data(version_);
Ryan Hamiltona4f632d2024-04-03 22:27:421053 int sent_packet_num = 0;
1054 int received_packet_num = 0;
1055 const quic::QuicStreamId stream_id =
1056 GetNthClientInitiatedBidirectionalStreamId(0);
Ryan Hamilton409e838c2024-04-03 22:08:071057 // HTTP/3 SETTINGS are always the first thing sent on a connection
Ryan Hamiltona4f632d2024-04-03 22:27:421058 quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(++sent_packet_num));
Ryan Hamilton409e838c2024-04-03 22:08:071059 // The GET request with no body is sent next.
Ryan Hamiltona4f632d2024-04-03 22:27:421060 quic_data.AddWrite(ASYNC, ConstructClientRequestHeadersPacket(
1061 ++sent_packet_num, stream_id, true,
1062 GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton409e838c2024-04-03 22:08:071063 // Read the response headers.
1064 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamiltona4f632d2024-04-03 22:27:421065 ++received_packet_num, stream_id, false,
1066 GetResponseHeaders("200")));
Ryan Hamilton409e838c2024-04-03 22:08:071067 // Read the response body.
Ryan Hamiltona4f632d2024-04-03 22:27:421068 quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
1069 ++received_packet_num, stream_id, true,
1070 ConstructDataFrame(kQuicRespData)));
Ryan Hamilton409e838c2024-04-03 22:08:071071 // Acknowledge the previous two received packets.
Ryan Hamiltona4f632d2024-04-03 22:27:421072 quic_data.AddWrite(ASYNC, ConstructClientAckPacket(++sent_packet_num,
1073 received_packet_num, 1));
Ryan Hamilton409e838c2024-04-03 22:08:071074 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1075 // Connection close on shutdown.
Ryan Hamiltona4f632d2024-04-03 22:27:421076 quic_data.AddWrite(ASYNC, ConstructClientAckAndConnectionClosePacket(
1077 ++sent_packet_num, received_packet_num, 1,
1078 quic::QUIC_CONNECTION_CANCELLED, "net error",
1079 quic::NO_IETF_QUIC_ERROR));
Ryan Hamilton409e838c2024-04-03 22:08:071080
1081 quic_data.AddSocketDataToFactory(&socket_factory_);
1082
1083 CreateSession();
1084
1085 SendRequestAndExpectQuicResponse(kQuicRespData);
1086
1087 // Delete the session while the MockQuicData is still in scope.
1088 session_.reset();
1089}
1090
1091TEST_P(QuicNetworkTransactionTest, BasicRequestAndResponseWithTrailers) {
1092 context_.params()->origins_to_force_quic_on.insert(
1093 HostPortPair::FromString("mail.example.org:443"));
1094
1095 MockQuicData quic_data(version_);
Ryan Hamiltona4f632d2024-04-03 22:27:421096 int sent_packet_num = 0;
1097 int received_packet_num = 0;
1098 const quic::QuicStreamId stream_id =
1099 GetNthClientInitiatedBidirectionalStreamId(0);
Ryan Hamilton409e838c2024-04-03 22:08:071100 // HTTP/3 SETTINGS are always the first thing sent on a connection
Ryan Hamiltona4f632d2024-04-03 22:27:421101 quic_data.AddWrite(SYNCHRONOUS,
1102 ConstructInitialSettingsPacket(++sent_packet_num));
Ryan Hamilton409e838c2024-04-03 22:08:071103 // The GET request with no body is sent next.
Ryan Hamiltona4f632d2024-04-03 22:27:421104 quic_data.AddWrite(SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1105 ++sent_packet_num, stream_id, true,
1106 GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton409e838c2024-04-03 22:08:071107 // Read the response headers.
1108 quic_data.AddRead(ASYNC, server_maker_.MakeResponseHeadersPacket(
Ryan Hamiltona4f632d2024-04-03 22:27:421109 ++received_packet_num, stream_id, false,
1110 GetResponseHeaders("200"), nullptr));
Ryan Hamilton409e838c2024-04-03 22:08:071111 // Read the response body.
Ryan Hamiltona4f632d2024-04-03 22:27:421112 quic_data.AddRead(
1113 ASYNC, ConstructServerDataPacket(++received_packet_num, stream_id, false,
1114 ConstructDataFrame(kQuicRespData)));
Ryan Hamilton409e838c2024-04-03 22:08:071115 // Acknowledge the previous two received packets.
Ryan Hamiltona4f632d2024-04-03 22:27:421116 quic_data.AddWrite(
1117 SYNCHRONOUS,
1118 ConstructClientAckPacket(++sent_packet_num, received_packet_num, 1));
Ryan Hamilton409e838c2024-04-03 22:08:071119 // Read the response trailers.
1120 spdy::Http2HeaderBlock trailers;
1121 trailers.AppendValueOrAddHeader("foo", "bar");
1122 quic_data.AddRead(ASYNC, server_maker_.MakeResponseHeadersPacket(
Ryan Hamiltona4f632d2024-04-03 22:27:421123 ++received_packet_num, stream_id, true,
1124 std::move(trailers), nullptr));
Ryan Hamilton409e838c2024-04-03 22:08:071125 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1126 // Connection close on shutdown.
Ryan Hamiltona4f632d2024-04-03 22:27:421127 quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
1128 ++sent_packet_num, received_packet_num, 1,
1129 quic::QUIC_CONNECTION_CANCELLED,
1130 "net error", quic::NO_IETF_QUIC_ERROR));
Ryan Hamilton409e838c2024-04-03 22:08:071131
1132 quic_data.AddSocketDataToFactory(&socket_factory_);
1133
1134 CreateSession();
1135
1136 SendRequestAndExpectQuicResponse(kQuicRespData);
1137
1138 // Delete the session while the MockQuicData is still in scope.
1139 session_.reset();
1140}
1141
Ryan Hamilton08765a72024-04-03 22:59:361142// Regression test for crbug.com/332587381
1143TEST_P(QuicNetworkTransactionTest, BasicRequestAndResponseWithEmptyTrailers) {
1144 context_.params()->origins_to_force_quic_on.insert(
1145 HostPortPair::FromString("mail.example.org:443"));
1146
1147 MockQuicData quic_data(version_);
1148 int sent_packet_num = 0;
1149 int received_packet_num = 0;
1150 const quic::QuicStreamId stream_id =
1151 GetNthClientInitiatedBidirectionalStreamId(0);
1152 // HTTP/3 SETTINGS are always the first thing sent on a connection
1153 quic_data.AddWrite(SYNCHRONOUS,
1154 ConstructInitialSettingsPacket(++sent_packet_num));
1155 // The GET request with no body is sent next.
1156 quic_data.AddWrite(SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1157 ++sent_packet_num, stream_id, true,
1158 GetRequestHeaders("GET", "https", "/")));
1159 // Read the response headers.
1160 quic_data.AddRead(ASYNC, server_maker_.MakeResponseHeadersPacket(
1161 ++received_packet_num, stream_id, false,
1162 GetResponseHeaders("200"), nullptr));
1163 // Read the response body.
1164 quic_data.AddRead(
1165 ASYNC, ConstructServerDataPacket(++received_packet_num, stream_id, false,
1166 ConstructDataFrame(kQuicRespData)));
1167 // Acknowledge the previous two received packets.
1168 quic_data.AddWrite(
1169 SYNCHRONOUS,
1170 ConstructClientAckPacket(++sent_packet_num, received_packet_num, 1));
1171 // Read the empty response trailers.
1172 quic_data.AddRead(ASYNC, server_maker_.MakeResponseHeadersPacket(
1173 ++received_packet_num, stream_id, true,
1174 spdy::Http2HeaderBlock(), nullptr));
1175 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1176 // Connection close on shutdown.
1177 quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
1178 ++sent_packet_num, received_packet_num, 1,
1179 quic::QUIC_CONNECTION_CANCELLED,
1180 "net error", quic::NO_IETF_QUIC_ERROR));
1181
1182 quic_data.AddSocketDataToFactory(&socket_factory_);
1183
1184 CreateSession();
1185
1186 SendRequestAndExpectQuicResponse(kQuicRespData);
1187
1188 // Delete the session while the MockQuicData is still in scope.
1189 session_.reset();
1190}
1191
Ryan Hamiltona64a5bcf2017-11-30 07:35:281192TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:381193 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281194 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381195 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281196 HostPortPair::FromString("mail.example.org:443"));
1197 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271198 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281199
Ryan Hamiltonabad59e2019-06-06 04:02:591200 MockQuicData mock_quic_data(version_);
Patrick Meenan885a00652023-02-15 20:07:021201 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281202 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1203 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211204 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281205
1206 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1207
1208 CreateSession();
1209
1210 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1211 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261212 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281213 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1214 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1215
1216 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1217 -ERR_INTERNET_DISCONNECTED, 1);
1218 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1219 -ERR_INTERNET_DISCONNECTED, 1);
1220}
1221
1222TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Victor Vasilieva1e66d72019-12-05 17:55:381223 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281224 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381225 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281226 HostPortPair::FromString("mail.example.org:443"));
1227 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271228 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281229
Ryan Hamiltonabad59e2019-06-06 04:02:591230 MockQuicData mock_quic_data(version_);
Patrick Meenan885a00652023-02-15 20:07:021231 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281232 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1233 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
David Schinazi395918c2021-02-05 18:56:211234 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281235
1236 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1237
1238 CreateSession();
1239
1240 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1241 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261242 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281243 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1244 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1245
1246 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1247 -ERR_INTERNET_DISCONNECTED, 1);
1248 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1249 -ERR_INTERNET_DISCONNECTED, 1);
1250}
1251
tbansal180587c2017-02-16 15:13:231252TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381253 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231254 HostPortPair::FromString("mail.example.org:443"));
1255
Ryan Hamiltonabad59e2019-06-06 04:02:591256 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231257 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021258 mock_quic_data.AddWrite(SYNCHRONOUS,
1259 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361260 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231261 SYNCHRONOUS,
1262 ConstructClientRequestHeadersPacket(
1263 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031264 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431265 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331266 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031267 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281268 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331269 mock_quic_data.AddRead(
1270 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031271 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:191272 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:231273 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341274 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231275 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1276
1277 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1278
1279 CreateSession();
1280 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1281
1282 EXPECT_FALSE(
1283 test_socket_performance_watcher_factory_.rtt_notification_received());
Andrew Williams826d8742024-01-31 19:39:191284 SendRequestAndExpectQuicResponse(kQuicRespData);
tbansal180587c2017-02-16 15:13:231285 EXPECT_TRUE(
1286 test_socket_performance_watcher_factory_.rtt_notification_received());
1287}
1288
1289TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381290 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231291 HostPortPair::FromString("mail.example.org:443"));
1292
Ryan Hamiltonabad59e2019-06-06 04:02:591293 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231294 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021295 mock_quic_data.AddWrite(SYNCHRONOUS,
1296 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361297 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231298 SYNCHRONOUS,
1299 ConstructClientRequestHeadersPacket(
1300 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031301 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431302 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331303 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031304 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281305 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331306 mock_quic_data.AddRead(
1307 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031308 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:191309 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:231310 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341311 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231312 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1313
1314 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1315
1316 CreateSession();
1317 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1318
1319 EXPECT_FALSE(
1320 test_socket_performance_watcher_factory_.rtt_notification_received());
Andrew Williams826d8742024-01-31 19:39:191321 SendRequestAndExpectQuicResponse(kQuicRespData);
tbansal180587c2017-02-16 15:13:231322 EXPECT_FALSE(
1323 test_socket_performance_watcher_factory_.rtt_notification_received());
1324}
1325
[email protected]1e960032013-12-20 19:00:201326TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:381327 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571328 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471329
Ryan Hamiltonabad59e2019-06-06 04:02:591330 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231331 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021332 mock_quic_data.AddWrite(SYNCHRONOUS,
1333 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361334 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231335 SYNCHRONOUS,
1336 ConstructClientRequestHeadersPacket(
1337 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031338 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431339 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331340 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031341 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281342 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331343 mock_quic_data.AddRead(
1344 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031345 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:191346 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:231347 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341348 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:591349 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471350
rcha5399e02015-04-21 19:32:041351 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471352
[email protected]4dca587c2013-03-07 16:54:471353 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471354
Andrew Williams826d8742024-01-31 19:39:191355 SendRequestAndExpectQuicResponse(kQuicRespData);
[email protected]4dca587c2013-03-07 16:54:471356
[email protected]98b20ce2013-05-10 05:55:261357 // Check that the NetLog was filled reasonably.
Matt Reichhoff0049a0b72021-10-20 20:44:261358 auto entries = net_log_observer_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261359 EXPECT_LT(0u, entries.size());
1360
1361 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291362 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001363 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1364 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261365 EXPECT_LT(0, pos);
1366
David Schinazi24bfaa02020-10-22 19:54:381367 // ... and also a TYPE_QUIC_SESSION_PACKET_SENT.
1368 pos = ExpectLogContainsSomewhere(entries, 0,
1369 NetLogEventType::QUIC_SESSION_PACKET_SENT,
1370 NetLogEventPhase::NONE);
1371 EXPECT_LT(0, pos);
1372
rchfd527212015-08-25 00:41:261373 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291374 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261375 entries, 0,
mikecirone8b85c432016-09-08 19:11:001376 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1377 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261378 EXPECT_LT(0, pos);
1379
Eric Roman79cc7552019-07-19 02:17:541380 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261381
rchfd527212015-08-25 00:41:261382 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1383 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001384 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1385 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261386 EXPECT_LT(0, pos);
1387
[email protected]98b20ce2013-05-10 05:55:261388 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291389 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001390 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1391 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261392 EXPECT_LT(0, pos);
1393
Eric Roman79cc7552019-07-19 02:17:541394 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Patrick Meenan885a00652023-02-15 20:07:021395 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1396 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471397}
1398
Bence Békyb6300042020-01-28 21:18:201399// Regression test for https://crbug.com/1043531.
1400TEST_P(QuicNetworkTransactionTest, ResetOnEmptyResponseHeaders) {
Kenichi Ishibashi10111e82021-03-23 02:19:061401 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Bence Békyb6300042020-01-28 21:18:201402 context_.params()->origins_to_force_quic_on.insert(
1403 HostPortPair::FromString("mail.example.org:443"));
1404
1405 MockQuicData mock_quic_data(version_);
1406 int write_packet_num = 1;
1407 mock_quic_data.AddWrite(SYNCHRONOUS,
1408 ConstructInitialSettingsPacket(write_packet_num++));
1409 mock_quic_data.AddWrite(
1410 SYNCHRONOUS,
1411 ConstructClientRequestHeadersPacket(
1412 write_packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:031413 true, GetRequestHeaders("GET", "https", "/")));
Bence Békyb6300042020-01-28 21:18:201414
1415 const quic::QuicStreamId request_stream_id =
1416 GetNthClientInitiatedBidirectionalStreamId(0);
Bence Béky4c325e52020-10-22 20:48:011417 spdy::Http2HeaderBlock empty_response_headers;
Bence Békyb6300042020-01-28 21:18:201418 const std::string response_data = server_maker_.QpackEncodeHeaders(
1419 request_stream_id, std::move(empty_response_headers), nullptr);
1420 uint64_t read_packet_num = 1;
1421 mock_quic_data.AddRead(
1422 ASYNC, ConstructServerDataPacket(read_packet_num++, request_stream_id,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031423 false, response_data));
Bence Békyb6300042020-01-28 21:18:201424 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1425
1426 mock_quic_data.AddWrite(
Kenichi Ishibashi10111e82021-03-23 02:19:061427 ASYNC, ConstructClientAckDataAndRst(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031428 write_packet_num++, request_stream_id,
Kenichi Ishibashi10111e82021-03-23 02:19:061429 quic::QUIC_STREAM_GENERAL_PROTOCOL_ERROR, 1, 1,
1430 GetQpackDecoderStreamId(), false,
1431 StreamCancellationQpackDecoderInstruction(request_stream_id)));
Bence Békyb6300042020-01-28 21:18:201432
1433 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1434
1435 CreateSession();
1436
1437 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1438 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261439 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Bence Békyb6300042020-01-28 21:18:201440 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Kenichi Ishibashi10111e82021-03-23 02:19:061441 EXPECT_THAT(callback.WaitForResult(), IsError(net::ERR_QUIC_PROTOCOL_ERROR));
1442 base::RunLoop().RunUntilIdle();
1443 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1444 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
Bence Békyb6300042020-01-28 21:18:201445}
1446
rchbd089ab2017-05-26 23:05:041447TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381448 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041449 HostPortPair::FromString("mail.example.org:443"));
1450
Ryan Hamiltonabad59e2019-06-06 04:02:591451 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231452 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021453 mock_quic_data.AddWrite(SYNCHRONOUS,
1454 ConstructInitialSettingsPacket(packet_num++));
rchbd089ab2017-05-26 23:05:041455 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231456 SYNCHRONOUS,
1457 ConstructClientRequestHeadersPacket(
1458 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031459 GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashif8634ab2021-03-16 23:41:281460 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200");
rchbd089ab2017-05-26 23:05:041461 response_headers["key1"] = std::string(30000, 'A');
1462 response_headers["key2"] = std::string(30000, 'A');
1463 response_headers["key3"] = std::string(30000, 'A');
1464 response_headers["key4"] = std::string(30000, 'A');
1465 response_headers["key5"] = std::string(30000, 'A');
1466 response_headers["key6"] = std::string(30000, 'A');
1467 response_headers["key7"] = std::string(30000, 'A');
1468 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451469 quic::QuicStreamId stream_id;
1470 std::string response_data;
Patrick Meenan885a00652023-02-15 20:07:021471 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1472 response_data = server_maker_.QpackEncodeHeaders(
1473 stream_id, std::move(response_headers), nullptr);
rchbd089ab2017-05-26 23:05:041474
Fan Yangac867502019-01-28 21:10:231475 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041476 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451477 for (size_t offset = 0; offset < response_data.length();
1478 offset += chunk_size) {
1479 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431480 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451481 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031482 packet_number++, stream_id, false,
David Benjamin9f3b62e2023-10-02 16:03:421483 std::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041484 }
1485
1486 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331487 ASYNC, ConstructServerDataPacket(
1488 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Andrew Williams826d8742024-01-31 19:39:191489 true, ConstructDataFrame(kQuicRespData)));
rchbd089ab2017-05-26 23:05:041490 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341491 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Renjie Tangaadb84b2019-08-31 01:00:231492 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341493 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3));
rchbd089ab2017-05-26 23:05:041494
1495 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1496
1497 CreateSession();
1498
Andrew Williams826d8742024-01-31 19:39:191499 SendRequestAndExpectQuicResponse(kQuicRespData);
Zhongyi Shi99d0cdd2019-05-21 01:18:421500 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1501 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041502}
1503
1504TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381505 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1506 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041507 HostPortPair::FromString("mail.example.org:443"));
1508
Ryan Hamiltonabad59e2019-06-06 04:02:591509 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231510 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021511 mock_quic_data.AddWrite(SYNCHRONOUS,
1512 ConstructInitialSettingsPacket(packet_num++));
rchbd089ab2017-05-26 23:05:041513 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231514 SYNCHRONOUS,
1515 ConstructClientRequestHeadersPacket(
1516 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031517 GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451518
Kenichi Ishibashif8634ab2021-03-16 23:41:281519 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200");
rchbd089ab2017-05-26 23:05:041520 response_headers["key1"] = std::string(30000, 'A');
1521 response_headers["key2"] = std::string(30000, 'A');
1522 response_headers["key3"] = std::string(30000, 'A');
1523 response_headers["key4"] = std::string(30000, 'A');
1524 response_headers["key5"] = std::string(30000, 'A');
1525 response_headers["key6"] = std::string(30000, 'A');
1526 response_headers["key7"] = std::string(30000, 'A');
1527 response_headers["key8"] = std::string(30000, 'A');
1528 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451529
1530 quic::QuicStreamId stream_id;
1531 std::string response_data;
Patrick Meenan885a00652023-02-15 20:07:021532 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1533 response_data = server_maker_.QpackEncodeHeaders(
1534 stream_id, std::move(response_headers), nullptr);
rchbd089ab2017-05-26 23:05:041535
Fan Yangac867502019-01-28 21:10:231536 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041537 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451538 for (size_t offset = 0; offset < response_data.length();
1539 offset += chunk_size) {
1540 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431541 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451542 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031543 packet_number++, stream_id, false,
David Benjamin9f3b62e2023-10-02 16:03:421544 std::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041545 }
1546
1547 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331548 ASYNC, ConstructServerDataPacket(
1549 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:031550 true, ConstructDataFrame("hello!")));
rchbd089ab2017-05-26 23:05:041551 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341552 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431553 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331554 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231555 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:341556 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3));
rchbd089ab2017-05-26 23:05:041557
1558 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1559
1560 CreateSession();
1561
1562 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1563 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:261564 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rchbd089ab2017-05-26 23:05:041565 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1566 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1567}
1568
Kenichi Ishibashifd2d3e62022-03-01 22:54:051569TEST_P(QuicNetworkTransactionTest, RedirectMultipleLocations) {
1570 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1571 context_.params()->origins_to_force_quic_on.insert(
1572 HostPortPair::FromString("mail.example.org:443"));
1573
1574 MockQuicData mock_quic_data(version_);
1575 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021576 mock_quic_data.AddWrite(SYNCHRONOUS,
1577 ConstructInitialSettingsPacket(packet_num++));
Kenichi Ishibashifd2d3e62022-03-01 22:54:051578 mock_quic_data.AddWrite(
1579 SYNCHRONOUS,
1580 ConstructClientRequestHeadersPacket(
1581 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031582 GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashifd2d3e62022-03-01 22:54:051583
1584 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("301");
1585 response_headers.AppendValueOrAddHeader("location", "https://example1.test");
1586 response_headers.AppendValueOrAddHeader("location", "https://example2.test");
1587
Patrick Meenan885a00652023-02-15 20:07:021588 const quic::QuicStreamId stream_id =
1589 GetNthClientInitiatedBidirectionalStreamId(0);
1590 const std::string response_data = server_maker_.QpackEncodeHeaders(
1591 stream_id, std::move(response_headers), nullptr);
1592 ASSERT_LT(response_data.size(), 1200u);
1593 mock_quic_data.AddRead(
1594 ASYNC, ConstructServerDataPacket(/*packet_number=*/1, stream_id,
Patrick Meenan885a00652023-02-15 20:07:021595 /*fin=*/true, response_data));
Kenichi Ishibashifd2d3e62022-03-01 22:54:051596 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1597
1598 mock_quic_data.AddWrite(
1599 ASYNC, ConstructClientAckAndRstPacket(
1600 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1601 quic::QUIC_STREAM_CANCELLED,
1602 /*largest_received=*/1, /*smallest_received=*/1));
1603
1604 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1605
1606 CreateSession();
1607
1608 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1609 TestCompletionCallback callback;
1610 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
1611 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
1612 ASSERT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1613}
1614
rcha2bd44b2016-07-02 00:42:551615TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Victor Vasilieva1e66d72019-12-05 17:55:381616 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551617
Ryan Hamilton9835e662018-08-02 05:36:271618 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551619
Ryan Hamiltonabad59e2019-06-06 04:02:591620 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231621 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021622 mock_quic_data.AddWrite(SYNCHRONOUS,
1623 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361624 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231625 SYNCHRONOUS,
1626 ConstructClientRequestHeadersPacket(
1627 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031628 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431629 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331630 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031631 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281632 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331633 mock_quic_data.AddRead(
1634 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031635 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:191636 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:231637 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341638 ConstructClientAckPacket(packet_num++, 2, 1));
rcha2bd44b2016-07-02 00:42:551639 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1640
1641 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1642
1643 CreateSession();
1644
Andrew Williams826d8742024-01-31 19:39:191645 SendRequestAndExpectQuicResponse(kQuicRespData);
rcha2bd44b2016-07-02 00:42:551646 EXPECT_TRUE(
1647 test_socket_performance_watcher_factory_.rtt_notification_received());
1648}
1649
David Schinazif832cb82019-11-08 22:25:271650// Regression test for https://crbug.com/695225
1651TEST_P(QuicNetworkTransactionTest, 408Response) {
Victor Vasilieva1e66d72019-12-05 17:55:381652 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
David Schinazif832cb82019-11-08 22:25:271653
1654 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1655
1656 MockQuicData mock_quic_data(version_);
1657 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021658 mock_quic_data.AddWrite(SYNCHRONOUS,
1659 ConstructInitialSettingsPacket(packet_num++));
David Schinazif832cb82019-11-08 22:25:271660 mock_quic_data.AddWrite(
1661 SYNCHRONOUS,
1662 ConstructClientRequestHeadersPacket(
1663 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031664 GetRequestHeaders("GET", "https", "/")));
David Schinazif832cb82019-11-08 22:25:271665 mock_quic_data.AddRead(
1666 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031667 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281668 GetResponseHeaders("408")));
David Schinazif832cb82019-11-08 22:25:271669 mock_quic_data.AddRead(
1670 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031671 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:191672 ConstructDataFrame(kQuicRespData)));
David Schinazif832cb82019-11-08 22:25:271673 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341674 ConstructClientAckPacket(packet_num++, 2, 1));
David Schinazif832cb82019-11-08 22:25:271675 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1676
1677 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1678
1679 CreateSession();
1680
Andrew Williams826d8742024-01-31 19:39:191681 SendRequestAndExpectQuicResponse(kQuicRespData, "HTTP/1.1 408");
David Schinazif832cb82019-11-08 22:25:271682}
1683
[email protected]cf3e3cd62014-02-05 16:16:161684TEST_P(QuicNetworkTransactionTest, QuicProxy) {
Dustin J. Mitchelldfd537d2024-03-13 13:09:311685 DisablePriorityHeader();
mmenke6ddfbea2017-05-31 21:48:411686 session_params_.enable_quic = true;
Andrew Williams826d8742024-01-31 19:39:191687
1688 const auto kQuicProxyChain =
1689 ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
Dustin J. Mitchelldfd537d2024-03-13 13:09:311690 ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)});
Nicolas Arciniegad2013f92020-02-07 23:00:561691 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:001692 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Andrew Williams826d8742024-01-31 19:39:191693 {kQuicProxyChain}, TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161694
Ryan Hamiltonabad59e2019-06-06 04:02:591695 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231696 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021697 mock_quic_data.AddWrite(SYNCHRONOUS,
1698 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361699 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231700 SYNCHRONOUS,
Dustin J. Mitchelldfd537d2024-03-13 13:09:311701 ConstructClientPriorityPacket(
1702 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1703 DEFAULT_PRIORITY));
1704 mock_quic_data.AddWrite(
1705 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:231706 ConstructClientRequestHeadersPacket(
Dustin J. Mitchelldfd537d2024-03-13 13:09:311707 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
1708 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:80"),
1709 false));
Zhongyi Shi32f2fd02018-04-16 18:23:431710 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331711 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031712 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281713 GetResponseHeaders("200")));
Dustin J. Mitchelldfd537d2024-03-13 13:09:311714
1715 const char kGetRequest[] =
1716 "GET / HTTP/1.1\r\n"
1717 "Host: mail.example.org\r\n"
1718 "Connection: keep-alive\r\n\r\n";
1719 mock_quic_data.AddWrite(
1720 SYNCHRONOUS,
1721 ConstructClientAckAndDataPacket(
1722 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
1723 false, ConstructDataFrame(kGetRequest)));
1724
1725 const char kGetResponse[] =
1726 "HTTP/1.1 200 OK\r\n"
1727 "Content-Length: 11\r\n\r\n";
1728 ASSERT_EQ(strlen(kHttpRespData), 11u);
1729
Fan Yang32c5a112018-12-10 20:06:331730 mock_quic_data.AddRead(
1731 ASYNC, ConstructServerDataPacket(
Dustin J. Mitchelldfd537d2024-03-13 13:09:311732 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
1733 ConstructDataFrame(kGetResponse)));
1734
1735 mock_quic_data.AddRead(
1736 ASYNC, ConstructServerDataPacket(
1737 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
1738 ConstructDataFrame(kHttpRespData)));
Renjie Tangaadb84b2019-08-31 01:00:231739 mock_quic_data.AddWrite(SYNCHRONOUS,
Dustin J. Mitchelldfd537d2024-03-13 13:09:311740 ConstructClientAckPacket(packet_num++, 3, 2));
1741 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1742
1743 mock_quic_data.AddWrite(
1744 SYNCHRONOUS,
1745 ConstructClientDataPacket(packet_num++, GetQpackDecoderStreamId(), false,
1746 StreamCancellationQpackDecoderInstruction(0)));
1747
1748 mock_quic_data.AddWrite(
1749 SYNCHRONOUS,
1750 ConstructClientRstPacket(packet_num++,
1751 GetNthClientInitiatedBidirectionalStreamId(0),
1752 quic::QUIC_STREAM_CANCELLED));
[email protected]cf3e3cd62014-02-05 16:16:161753
rcha5399e02015-04-21 19:32:041754 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161755
tbansal0f56a39a2016-04-07 22:03:381756 EXPECT_FALSE(
1757 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161758 // There is no need to set up an alternate protocol job, because
1759 // no attempt will be made to speak to the proxy over TCP.
1760
rch9ae5b3b2016-02-11 00:36:291761 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161762 CreateSession();
Dustin J. Mitchelldfd537d2024-03-13 13:09:311763 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1764 SendRequestAndExpectHttpResponseFromProxy(
1765 kHttpRespData, kQuicProxyChain.First().GetPort(), kQuicProxyChain);
Andrew Williamsa5adfb632024-02-02 01:07:351766
Dustin J. Mitchelldfd537d2024-03-13 13:09:311767 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
1768 // proxy socket to disconnect.
1769 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
1770
1771 base::RunLoop().RunUntilIdle();
1772 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1773 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1774
tbansal0f56a39a2016-04-07 22:03:381775 EXPECT_TRUE(
1776 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161777}
1778
bnc313ba9c2015-06-11 15:42:311779// Regression test for https://crbug.com/492458. Test that for an HTTP
1780// connection through a QUIC proxy, the certificate exhibited by the proxy is
1781// checked against the proxy hostname, not the origin hostname.
1782TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
Dustin J. Mitchelldfd537d2024-03-13 13:09:311783 DisablePriorityHeader();
Andrew Williams826d8742024-01-31 19:39:191784 const std::string kOriginHost = "mail.example.com";
1785 const std::string kProxyHost = "proxy.example.org";
bnc313ba9c2015-06-11 15:42:311786
mmenke6ddfbea2017-05-31 21:48:411787 session_params_.enable_quic = true;
Andrew Williams826d8742024-01-31 19:39:191788 const auto kQuicProxyChain =
1789 ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
1790 ProxyServer::SCHEME_QUIC, kProxyHost, 70)});
Nicolas Arciniegad2013f92020-02-07 23:00:561791 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:001792 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Andrew Williams826d8742024-01-31 19:39:191793 {kQuicProxyChain}, TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311794
Andrew Williams826d8742024-01-31 19:39:191795 client_maker_->set_hostname(kOriginHost);
1796
Ryan Hamiltonabad59e2019-06-06 04:02:591797 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231798 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021799 mock_quic_data.AddWrite(SYNCHRONOUS,
1800 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361801 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231802 SYNCHRONOUS,
Dustin J. Mitchelldfd537d2024-03-13 13:09:311803 ConstructClientPriorityPacket(
1804 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1805 DEFAULT_PRIORITY));
1806 mock_quic_data.AddWrite(
1807 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:231808 ConstructClientRequestHeadersPacket(
Dustin J. Mitchelldfd537d2024-03-13 13:09:311809 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
1810 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.com:80"),
1811 false));
Zhongyi Shi32f2fd02018-04-16 18:23:431812 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331813 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031814 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281815 GetResponseHeaders("200")));
Dustin J. Mitchelldfd537d2024-03-13 13:09:311816
1817 const char kGetRequest[] =
1818 "GET / HTTP/1.1\r\n"
1819 "Host: mail.example.com\r\n"
1820 "Connection: keep-alive\r\n\r\n";
1821 mock_quic_data.AddWrite(
1822 SYNCHRONOUS,
1823 ConstructClientAckAndDataPacket(
1824 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
1825 false, ConstructDataFrame(kGetRequest)));
1826
1827 const char kGetResponse[] =
1828 "HTTP/1.1 200 OK\r\n"
1829 "Content-Length: 11\r\n\r\n";
1830 ASSERT_EQ(strlen(kHttpRespData), 11u);
1831
Fan Yang32c5a112018-12-10 20:06:331832 mock_quic_data.AddRead(
1833 ASYNC, ConstructServerDataPacket(
Dustin J. Mitchelldfd537d2024-03-13 13:09:311834 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
1835 ConstructDataFrame(kGetResponse)));
1836
1837 mock_quic_data.AddRead(
1838 ASYNC, ConstructServerDataPacket(
1839 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
1840 ConstructDataFrame(kHttpRespData)));
Renjie Tangaadb84b2019-08-31 01:00:231841 mock_quic_data.AddWrite(SYNCHRONOUS,
Dustin J. Mitchelldfd537d2024-03-13 13:09:311842 ConstructClientAckPacket(packet_num++, 3, 2));
1843 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1844
1845 mock_quic_data.AddWrite(
1846 SYNCHRONOUS,
1847 ConstructClientDataPacket(packet_num++, GetQpackDecoderStreamId(), false,
1848 StreamCancellationQpackDecoderInstruction(0)));
1849
1850 mock_quic_data.AddWrite(
1851 SYNCHRONOUS,
1852 ConstructClientRstPacket(packet_num++,
1853 GetNthClientInitiatedBidirectionalStreamId(0),
1854 quic::QUIC_STREAM_CANCELLED));
1855
bnc313ba9c2015-06-11 15:42:311856 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1857
1858 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291859 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311860 ASSERT_TRUE(cert.get());
1861 // This certificate is valid for the proxy, but not for the origin.
Andrew Williams826d8742024-01-31 19:39:191862 EXPECT_TRUE(cert->VerifyNameMatch(kProxyHost));
1863 EXPECT_FALSE(cert->VerifyNameMatch(kOriginHost));
bnc313ba9c2015-06-11 15:42:311864 ProofVerifyDetailsChromium verify_details;
1865 verify_details.cert_verify_result.verified_cert = cert;
1866 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561867 ProofVerifyDetailsChromium verify_details2;
1868 verify_details2.cert_verify_result.verified_cert = cert;
1869 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311870
Andrew Williams826d8742024-01-31 19:39:191871 request_.url = GURL("http://" + kOriginHost);
rtennetib8e80fb2016-05-16 00:12:091872 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321873 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271874 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Dustin J. Mitchelldfd537d2024-03-13 13:09:311875 SendRequestAndExpectHttpResponseFromProxy(
1876 kHttpRespData, kQuicProxyChain.First().GetPort(), kQuicProxyChain);
bnc313ba9c2015-06-11 15:42:311877}
1878
rchbe69cb902016-02-11 01:10:481879TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Victor Vasilieva1e66d72019-12-05 17:55:381880 context_.params()->allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481881 HostPortPair origin("www.example.org", 443);
1882 HostPortPair alternative("mail.example.org", 443);
1883
1884 base::FilePath certs_dir = GetTestCertsDirectory();
1885 scoped_refptr<X509Certificate> cert(
1886 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1887 ASSERT_TRUE(cert.get());
1888 // TODO(rch): the connection should be "to" the origin, so if the cert is
1889 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241890 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1891 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481892 ProofVerifyDetailsChromium verify_details;
1893 verify_details.cert_verify_result.verified_cert = cert;
1894 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1895
Zhongyi Shi1c022d22020-03-20 19:00:161896 client_maker_->set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591897 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021898
Renjie Tangaadb84b2019-08-31 01:00:231899 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021900 mock_quic_data.AddWrite(SYNCHRONOUS,
1901 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:361902 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231903 SYNCHRONOUS,
1904 ConstructClientRequestHeadersPacket(
1905 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031906 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431907 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331908 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031909 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:281910 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:331911 mock_quic_data.AddRead(
1912 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031913 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:191914 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:231915 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341916 ConstructClientAckPacket(packet_num++, 2, 1));
rchbe69cb902016-02-11 01:10:481917 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:211918 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rchbe69cb902016-02-11 01:10:481919 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1920
1921 request_.url = GURL("https://" + origin.host());
1922 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271923 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091924 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321925 CreateSession();
rchbe69cb902016-02-11 01:10:481926
Andrew Williams826d8742024-01-31 19:39:191927 SendRequestAndExpectQuicResponse(kQuicRespData);
rchbe69cb902016-02-11 01:10:481928}
1929
zhongyief3f4ce52017-07-05 23:53:281930TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
David Schinazi84c58bb2020-06-04 20:14:331931 quic::ParsedQuicVersion unsupported_version =
1932 quic::ParsedQuicVersion::Unsupported();
Bence Békyb89104962020-01-24 00:05:171933 // Add support for another QUIC version besides |version_|. Also find an
zhongyief3f4ce52017-07-05 23:53:281934 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561935 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Dustin J. Mitchell496de812024-01-16 19:14:541936 if (version == version_) {
zhongyief3f4ce52017-07-05 23:53:281937 continue;
Dustin J. Mitchell496de812024-01-16 19:14:541938 }
zhongyief3f4ce52017-07-05 23:53:281939 if (supported_versions_.size() != 2) {
1940 supported_versions_.push_back(version);
1941 continue;
1942 }
1943 unsupported_version = version;
1944 break;
1945 }
Bence Békyb89104962020-01-24 00:05:171946 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:331947 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), unsupported_version);
zhongyief3f4ce52017-07-05 23:53:281948
1949 // Set up alternative service to use QUIC with a version that is not
1950 // supported.
1951 url::SchemeHostPort server(request_.url);
1952 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1953 443);
Peter Kastinge5a38ed2021-10-02 03:06:351954 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:491955 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:011956 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:071957 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281958
1959 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491960 http_server_properties_->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:011961 server, NetworkAnonymizationKey());
zhongyief3f4ce52017-07-05 23:53:281962 EXPECT_EQ(1u, alt_svc_info_vector.size());
1963 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1964 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1965 EXPECT_EQ(unsupported_version,
1966 alt_svc_info_vector[0].advertised_versions()[0]);
1967
1968 // First request should still be sent via TCP as the QUIC version advertised
1969 // in the stored AlternativeService is not supported by the client. However,
1970 // the response from the server will advertise new Alt-Svc with supported
1971 // versions.
David Schinazifbd4c432020-04-07 19:23:551972 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyief3f4ce52017-07-05 23:53:281973 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:171974 MockRead("HTTP/1.1 200 OK\r\n"),
1975 MockRead(altsvc_header.c_str()),
1976 MockRead("\r\n"),
Andrew Williams826d8742024-01-31 19:39:191977 MockRead(kHttpRespData),
zhongyief3f4ce52017-07-05 23:53:281978 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1979 MockRead(ASYNC, OK)};
1980
Ryan Sleevib8d7ea02018-05-07 20:01:011981 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281982 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081983 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281984 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1985
1986 // Second request should be sent via QUIC as a new list of verions supported
1987 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591988 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231989 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:021990 mock_quic_data.AddWrite(SYNCHRONOUS,
1991 ConstructInitialSettingsPacket(packet_num++));
zhongyief3f4ce52017-07-05 23:53:281992 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231993 SYNCHRONOUS,
1994 ConstructClientRequestHeadersPacket(
1995 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:031996 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431997 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331998 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:031999 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282000 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332001 mock_quic_data.AddRead(
2002 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032003 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:192004 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:232005 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342006 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyief3f4ce52017-07-05 23:53:282007 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212008 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyief3f4ce52017-07-05 23:53:282009
2010 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2011
2012 AddHangingNonAlternateProtocolSocketData();
2013
2014 CreateSession(supported_versions_);
2015
Andrew Williams826d8742024-01-31 19:39:192016 SendRequestAndExpectHttpResponse(kHttpRespData);
2017 SendRequestAndExpectQuicResponse(kQuicRespData);
zhongyief3f4ce52017-07-05 23:53:282018
2019 // Check alternative service list is updated with new versions.
2020 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:492021 session_->http_server_properties()->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:012022 server, NetworkAnonymizationKey());
Victor Vasiliev22dd3f212022-02-11 21:57:292023 VerifyQuicVersionsInAlternativeServices(alt_svc_info_vector,
2024 supported_versions_);
zhongyief3f4ce52017-07-05 23:53:282025}
2026
bncaccd4962017-04-06 21:00:262027// Regression test for https://crbug.com/546991.
2028// The server might not be able to serve a request on an alternative connection,
2029// and might send a 421 Misdirected Request response status to indicate this.
2030// HttpNetworkTransaction should reset the request and retry without using
2031// alternative services.
2032TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
2033 // Set up alternative service to use QUIC.
2034 // Note that |origins_to_force_quic_on| cannot be used in this test, because
2035 // that overrides |enable_alternative_services|.
2036 url::SchemeHostPort server(request_.url);
2037 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
2038 443);
Peter Kastinge5a38ed2021-10-02 03:06:352039 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:492040 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:012041 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:072042 supported_versions_);
bncaccd4962017-04-06 21:00:262043
davidbena4449722017-05-05 23:30:532044 // First try: The alternative job uses QUIC and reports an HTTP 421
2045 // Misdirected Request error. The main job uses TCP, but |http_data| below is
2046 // paused at Connect(), so it will never exit the socket pool. This ensures
2047 // that the alternate job always wins the race and keeps whether the
2048 // |http_data| exits the socket pool before the main job is aborted
2049 // deterministic. The first main job gets aborted without the socket pool ever
2050 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:592051 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232052 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022053 mock_quic_data.AddWrite(SYNCHRONOUS,
2054 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:362055 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232056 SYNCHRONOUS,
2057 ConstructClientRequestHeadersPacket(
2058 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032059 GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332060 mock_quic_data.AddRead(
2061 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032062 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
Ryan Hamilton0d65a8c2019-06-07 00:46:022063 GetResponseHeaders("421")));
David Schinazi395918c2021-02-05 18:56:212064 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncaccd4962017-04-06 21:00:262065 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2066
davidbena4449722017-05-05 23:30:532067 // Second try: The main job uses TCP, and there is no alternate job. Once the
2068 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
2069 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:262070 // Note that if there was an alternative QUIC Job created for the second try,
2071 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
2072 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:532073 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
2074 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
2075 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
2076 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
Andrew Williams826d8742024-01-31 19:39:192077 MockRead(ASYNC, 4, kHttpRespData),
2078 MockRead(ASYNC, OK, 5)};
davidbena4449722017-05-05 23:30:532079 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:012080 reads, writes);
bncaccd4962017-04-06 21:00:262081 socket_factory_.AddSocketDataProvider(&http_data);
2082 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2083
bncaccd4962017-04-06 21:00:262084 CreateSession();
2085 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:532086
2087 // Run until |mock_quic_data| has failed and |http_data| has paused.
2088 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262089 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
davidbena4449722017-05-05 23:30:532090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2091 base::RunLoop().RunUntilIdle();
2092
2093 // |mock_quic_data| must have run to completion.
2094 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
2095 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
2096
2097 // Now that the QUIC data has been consumed, unblock |http_data|.
2098 http_data.socket()->OnConnectComplete(MockConnect());
2099
2100 // The retry logic must hide the 421 status. The transaction succeeds on
2101 // |http_data|.
2102 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:262103 CheckWasHttpResponse(&trans);
2104 CheckResponsePort(&trans, 443);
Andrew Williams826d8742024-01-31 19:39:192105 CheckResponseData(&trans, kHttpRespData);
bncaccd4962017-04-06 21:00:262106}
2107
[email protected]1e960032013-12-20 19:00:202108TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Victor Vasilieva1e66d72019-12-05 17:55:382109 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:572110 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:302111
Ryan Hamiltonabad59e2019-06-06 04:02:592112 MockQuicData mock_quic_data1(version_);
Patrick Meenan885a00652023-02-15 20:07:022113 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:402114 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Zhongyi Shi1c022d22020-03-20 19:00:162115 client_maker_->Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:592116 MockQuicData mock_quic_data2(version_);
Patrick Meenan885a00652023-02-15 20:07:022117 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:302118 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:402119 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:432120 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:402121
2122 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
2123 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:302124
2125 CreateSession();
2126
tbansal0f56a39a2016-04-07 22:03:382127 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:402128 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:162129 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:402130 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262131 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:012132 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2133 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:382134 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:532135
2136 NetErrorDetails details;
2137 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522138 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:402139 }
[email protected]cebe3282013-05-22 23:49:302140}
2141
tbansalc8a94ea2015-11-02 23:58:512142TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
2143 // Attempt to "force" quic on 443, which will not be honored.
Victor Vasilieva1e66d72019-12-05 17:55:382144 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:572145 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:512146
2147 MockRead http_reads[] = {
Andrew Williams826d8742024-01-31 19:39:192148 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead(kHttpRespData),
tbansalc8a94ea2015-11-02 23:58:512149 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2150 MockRead(ASYNC, OK)};
2151
Ryan Sleevib8d7ea02018-05-07 20:01:012152 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:512153 socket_factory_.AddSocketDataProvider(&data);
2154 SSLSocketDataProvider ssl(ASYNC, OK);
2155 socket_factory_.AddSSLSocketDataProvider(&ssl);
2156
2157 CreateSession();
2158
Andrew Williams826d8742024-01-31 19:39:192159 SendRequestAndExpectHttpResponse(kHttpRespData);
tbansal0f56a39a2016-04-07 22:03:382160 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:512161}
2162
bncc958faa2015-07-31 18:14:522163TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:352164 if (version_.AlpnDeferToRFCv1()) {
2165 // These versions currently do not support Alt-Svc.
2166 return;
2167 }
bncc958faa2015-07-31 18:14:522168 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452169 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:192170 MockRead(kHttpRespData),
bncc958faa2015-07-31 18:14:522171 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2172 MockRead(ASYNC, OK)};
2173
Ryan Sleevib8d7ea02018-05-07 20:01:012174 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:522175 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082176 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:562177 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:522178
Ryan Hamiltonabad59e2019-06-06 04:02:592179 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232180 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022181 mock_quic_data.AddWrite(SYNCHRONOUS,
2182 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:362183 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232184 SYNCHRONOUS,
2185 ConstructClientRequestHeadersPacket(
2186 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032187 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432188 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332189 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032190 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282191 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332192 mock_quic_data.AddRead(
2193 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032194 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:192195 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:232196 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342197 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:522198 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212199 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:522200
2201 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2202
rtennetib8e80fb2016-05-16 00:12:092203 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322204 CreateSession();
bncc958faa2015-07-31 18:14:522205
Andrew Williams826d8742024-01-31 19:39:192206 SendRequestAndExpectHttpResponse(kHttpRespData);
2207 SendRequestAndExpectQuicResponse(kQuicRespData);
bncc958faa2015-07-31 18:14:522208}
2209
Ryan Hamilton64f21d52019-08-31 07:10:512210TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:352211 if (version_.AlpnDeferToRFCv1()) {
2212 // These versions currently do not support Alt-Svc.
2213 return;
2214 }
Ryan Hamilton64f21d52019-08-31 07:10:512215 std::string alt_svc_header =
2216 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
2217 MockRead http_reads[] = {
2218 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
Andrew Williams826d8742024-01-31 19:39:192219 MockRead(kHttpRespData),
Ryan Hamilton64f21d52019-08-31 07:10:512220 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2221 MockRead(ASYNC, OK)};
2222
2223 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2224 socket_factory_.AddSocketDataProvider(&http_data);
2225 AddCertificate(&ssl_data_);
2226 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2227
2228 MockQuicData mock_quic_data(version_);
2229 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022230 mock_quic_data.AddWrite(SYNCHRONOUS,
2231 ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton64f21d52019-08-31 07:10:512232 mock_quic_data.AddWrite(
2233 SYNCHRONOUS,
2234 ConstructClientRequestHeadersPacket(
2235 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032236 GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton64f21d52019-08-31 07:10:512237 mock_quic_data.AddRead(
2238 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032239 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282240 GetResponseHeaders("200")));
Ryan Hamilton64f21d52019-08-31 07:10:512241 mock_quic_data.AddRead(
2242 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032243 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:192244 ConstructDataFrame(kQuicRespData)));
Ryan Hamilton64f21d52019-08-31 07:10:512245 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342246 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton64f21d52019-08-31 07:10:512247 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212248 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamilton64f21d52019-08-31 07:10:512249
2250 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2251
2252 AddHangingNonAlternateProtocolSocketData();
2253 CreateSession();
2254
Andrew Williams826d8742024-01-31 19:39:192255 SendRequestAndExpectHttpResponse(kHttpRespData);
2256 SendRequestAndExpectQuicResponse(kQuicRespData);
Ryan Hamilton64f21d52019-08-31 07:10:512257}
2258
Brianna Goldstein02cb74f2022-09-29 05:41:012259// Much like above, but makes sure NetworkAnonymizationKey is respected.
Matt Menke3233d8f22019-08-20 21:01:492260TEST_P(QuicNetworkTransactionTest,
Brianna Goldstein02cb74f2022-09-29 05:41:012261 UseAlternativeServiceForQuicWithNetworkAnonymizationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:352262 if (version_.AlpnDeferToRFCv1()) {
2263 // These versions currently do not support Alt-Svc.
2264 return;
2265 }
Matt Menke3233d8f22019-08-20 21:01:492266 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:052267 feature_list.InitWithFeatures(
2268 // enabled_features
2269 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2270 features::kPartitionConnectionsByNetworkIsolationKey},
2271 // disabled_features
2272 {});
Matt Menke3233d8f22019-08-20 21:01:492273 // Since HttpServerProperties caches the feature value, have to create a new
2274 // one.
2275 http_server_properties_ = std::make_unique<HttpServerProperties>();
2276
Matt Menke4807a9a2020-11-21 00:14:412277 const SchemefulSite kSite1(GURL("https://foo.test/"));
2278 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Dustin J. Mitchell1d774ea2023-03-03 00:54:462279 const auto kNetworkAnonymizationKey1 =
2280 NetworkAnonymizationKey::CreateSameSite(kSite1);
Brianna Goldstein314ddf722022-09-24 02:00:522281
Matt Menke4807a9a2020-11-21 00:14:412282 const SchemefulSite kSite2(GURL("https://bar.test/"));
2283 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Dustin J. Mitchell1d774ea2023-03-03 00:54:462284 const auto kNetworkAnonymizationKey2 =
2285 NetworkAnonymizationKey::CreateSameSite(kSite2);
Matt Menke3233d8f22019-08-20 21:01:492286
2287 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452288 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:192289 MockRead(kHttpRespData),
Matt Menke3233d8f22019-08-20 21:01:492290 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2291 MockRead(ASYNC, OK)};
2292
2293 AddCertificate(&ssl_data_);
2294
Brianna Goldsteind22b0642022-10-11 16:30:502295 // Request with empty NetworkAnonymizationKey.
Matt Menke3233d8f22019-08-20 21:01:492296 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2297 socket_factory_.AddSocketDataProvider(&http_data1);
2298 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2299
2300 // First request with kNetworkIsolationKey1.
2301 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2302 socket_factory_.AddSocketDataProvider(&http_data2);
2303 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2304
2305 // Request with kNetworkIsolationKey2.
2306 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2307 socket_factory_.AddSocketDataProvider(&http_data3);
2308 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2309
2310 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2311 // alternative service infrmation has been received in this context before.
2312 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232313 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022314 mock_quic_data.AddWrite(SYNCHRONOUS,
2315 ConstructInitialSettingsPacket(packet_num++));
Matt Menke3233d8f22019-08-20 21:01:492316 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232317 SYNCHRONOUS,
2318 ConstructClientRequestHeadersPacket(
2319 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032320 GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492321 mock_quic_data.AddRead(
2322 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032323 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282324 GetResponseHeaders("200")));
Matt Menke3233d8f22019-08-20 21:01:492325 mock_quic_data.AddRead(
2326 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032327 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:192328 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:232329 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342330 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menke3233d8f22019-08-20 21:01:492331 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212332 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Matt Menke3233d8f22019-08-20 21:01:492333
2334 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2335
2336 AddHangingNonAlternateProtocolSocketData();
2337 CreateSession();
2338
2339 // This is first so that the test fails if alternative service info is
Brianna Goldsteind22b0642022-10-11 16:30:502340 // written with the right NetworkAnonymizationKey, but always queried with an
Matt Menke3233d8f22019-08-20 21:01:492341 // empty one.
Brianna Goldsteind22b0642022-10-11 16:30:502342 request_.network_isolation_key = NetworkIsolationKey();
Brianna Goldstein314ddf722022-09-24 02:00:522343 request_.network_anonymization_key = NetworkAnonymizationKey();
Andrew Williams826d8742024-01-31 19:39:192344 SendRequestAndExpectHttpResponse(kHttpRespData);
Matt Menke3233d8f22019-08-20 21:01:492345 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:522346 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Andrew Williams826d8742024-01-31 19:39:192347 SendRequestAndExpectHttpResponse(kHttpRespData);
Matt Menke3233d8f22019-08-20 21:01:492348 request_.network_isolation_key = kNetworkIsolationKey2;
Brianna Goldstein314ddf722022-09-24 02:00:522349 request_.network_anonymization_key = kNetworkAnonymizationKey2;
Andrew Williams826d8742024-01-31 19:39:192350 SendRequestAndExpectHttpResponse(kHttpRespData);
Matt Menke3233d8f22019-08-20 21:01:492351
Brianna Goldsteind22b0642022-10-11 16:30:502352 // Only use QUIC when using a NetworkAnonymizationKey which has been used when
Matt Menke3233d8f22019-08-20 21:01:492353 // alternative service information was received.
2354 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:522355 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Andrew Williams826d8742024-01-31 19:39:192356 SendRequestAndExpectQuicResponse(kQuicRespData);
Matt Menke3233d8f22019-08-20 21:01:492357}
2358
zhongyia00ca012017-07-06 23:36:392359TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
Ryan Hamiltona51800a2022-02-12 19:34:352360 if (version_.AlpnDeferToRFCv1()) {
2361 // These versions currently do not support Alt-Svc.
2362 return;
2363 }
Victor Vasiliev22dd3f212022-02-11 21:57:292364 // Both client and server supports two QUIC versions:
2365 // Client supports |supported_versions_[0]| and |supported_versions_[1]|,
2366 // server supports |version_| and |advertised_version_2|.
2367 // Only |version_| (same as |supported_versions_[0]|) is supported by both.
zhongyia00ca012017-07-06 23:36:392368 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2369 // PacketMakers are using |version_|.
2370
Victor Vasiliev22dd3f212022-02-11 21:57:292371 // Compare ALPN strings instead of ParsedQuicVersions because QUIC v1 and v2
2372 // have the same ALPN string.
2373 ASSERT_EQ(1u, supported_versions_.size());
2374 ASSERT_EQ(supported_versions_[0], version_);
David Schinazi84c58bb2020-06-04 20:14:332375 quic::ParsedQuicVersion advertised_version_2 =
2376 quic::ParsedQuicVersion::Unsupported();
Nick Harper23290b82019-05-02 00:02:562377 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Victor Vasiliev22dd3f212022-02-11 21:57:292378 if (quic::AlpnForVersion(version) == quic::AlpnForVersion(version_)) {
zhongyia00ca012017-07-06 23:36:392379 continue;
Victor Vasiliev22dd3f212022-02-11 21:57:292380 }
zhongyia00ca012017-07-06 23:36:392381 if (supported_versions_.size() != 2) {
2382 supported_versions_.push_back(version);
2383 continue;
2384 }
Victor Vasiliev22dd3f212022-02-11 21:57:292385 if (supported_versions_.size() == 2 &&
2386 quic::AlpnForVersion(supported_versions_[1]) ==
2387 quic::AlpnForVersion(version)) {
2388 continue;
2389 }
zhongyia00ca012017-07-06 23:36:392390 advertised_version_2 = version;
2391 break;
2392 }
Bence Békyb89104962020-01-24 00:05:172393 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:332394 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), advertised_version_2);
zhongyia00ca012017-07-06 23:36:392395
Bence Békyb89104962020-01-24 00:05:172396 std::string QuicAltSvcWithVersionHeader =
2397 base::StringPrintf("Alt-Svc: %s=\":443\", %s=\":443\"\r\n\r\n",
2398 quic::AlpnForVersion(advertised_version_2).c_str(),
2399 quic::AlpnForVersion(version_).c_str());
zhongyia00ca012017-07-06 23:36:392400
2401 MockRead http_reads[] = {
2402 MockRead("HTTP/1.1 200 OK\r\n"),
Andrew Williams826d8742024-01-31 19:39:192403 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead(kHttpRespData),
zhongyia00ca012017-07-06 23:36:392404 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2405 MockRead(ASYNC, OK)};
2406
Ryan Sleevib8d7ea02018-05-07 20:01:012407 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392408 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082409 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392410 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2411
Ryan Hamiltonabad59e2019-06-06 04:02:592412 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232413 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022414 mock_quic_data.AddWrite(SYNCHRONOUS,
2415 ConstructInitialSettingsPacket(packet_num++));
zhongyia00ca012017-07-06 23:36:392416 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232417 SYNCHRONOUS,
2418 ConstructClientRequestHeadersPacket(
2419 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032420 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432421 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332422 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032423 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282424 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332425 mock_quic_data.AddRead(
2426 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032427 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:192428 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:232429 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342430 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392431 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212432 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyia00ca012017-07-06 23:36:392433
2434 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2435
2436 AddHangingNonAlternateProtocolSocketData();
2437 CreateSession(supported_versions_);
2438
Andrew Williams826d8742024-01-31 19:39:192439 SendRequestAndExpectHttpResponse(kHttpRespData);
2440 SendRequestAndExpectQuicResponse(kQuicRespData);
zhongyia00ca012017-07-06 23:36:392441}
2442
Zhongyi Shi1c022d22020-03-20 19:00:162443TEST_P(QuicNetworkTransactionTest,
2444 PickQuicVersionWhenMultipleVersionsAreSupported) {
2445 // Client and server both support more than one QUIC_VERSION.
Patrick Meenan885a00652023-02-15 20:07:022446 // Client prefers common_version_2, and then |version_|.
2447 // Server prefers |version_| common_version_2.
David Schinazifbd4c432020-04-07 19:23:552448 // We should honor the server's preference.
Zhongyi Shi1c022d22020-03-20 19:00:162449 // The picked version is verified via checking the version used by the
2450 // TestPacketMakers and the response.
Patrick Meenan885a00652023-02-15 20:07:022451 // Since Chrome only supports one ALPN-negotiated version, common_version_2
2452 // will be another version that the common library supports even though
2453 // Chrome may consider it obsolete.
Bence Békyb89104962020-01-24 00:05:172454
Zhongyi Shi1c022d22020-03-20 19:00:162455 // Find an alternative commonly supported version other than |version_|.
David Schinazi84c58bb2020-06-04 20:14:332456 quic::ParsedQuicVersion common_version_2 =
2457 quic::ParsedQuicVersion::Unsupported();
2458 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Ryan Hamiltona51800a2022-02-12 19:34:352459 if (version != version_ && !version.AlpnDeferToRFCv1()) {
Zhongyi Shi1c022d22020-03-20 19:00:162460 common_version_2 = version;
2461 break;
2462 }
zhongyia00ca012017-07-06 23:36:392463 }
David Schinazi84c58bb2020-06-04 20:14:332464 ASSERT_NE(common_version_2, quic::ParsedQuicVersion::Unsupported());
zhongyia00ca012017-07-06 23:36:392465
Zhongyi Shi1c022d22020-03-20 19:00:162466 // Setting up client's preference list: {|version_|, |common_version_2|}.
2467 supported_versions_.clear();
Zhongyi Shi1c022d22020-03-20 19:00:162468 supported_versions_.push_back(common_version_2);
Patrick Meenan885a00652023-02-15 20:07:022469 supported_versions_.push_back(version_);
zhongyia00ca012017-07-06 23:36:392470
Zhongyi Shi1c022d22020-03-20 19:00:162471 // Setting up server's Alt-Svc header in the following preference order:
Patrick Meenan885a00652023-02-15 20:07:022472 // |version_|, |common_version_2|.
Zhongyi Shi1c022d22020-03-20 19:00:162473 std::string QuicAltSvcWithVersionHeader;
David Schinazi84c58bb2020-06-04 20:14:332474 quic::ParsedQuicVersion picked_version =
2475 quic::ParsedQuicVersion::Unsupported();
2476 QuicAltSvcWithVersionHeader =
Patrick Meenan885a00652023-02-15 20:07:022477 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"; ma=3600, " +
2478 quic::AlpnForVersion(common_version_2) + "=\":443\"; ma=3600\r\n\r\n";
2479 picked_version = version_; // Use server's preference.
zhongyia00ca012017-07-06 23:36:392480
2481 MockRead http_reads[] = {
2482 MockRead("HTTP/1.1 200 OK\r\n"),
Andrew Williams826d8742024-01-31 19:39:192483 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead(kHttpRespData),
zhongyia00ca012017-07-06 23:36:392484 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2485 MockRead(ASYNC, OK)};
2486
Ryan Sleevib8d7ea02018-05-07 20:01:012487 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392488 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082489 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392490 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2491
Zhongyi Shi1c022d22020-03-20 19:00:162492 MockQuicData mock_quic_data(picked_version);
2493
2494 // Reset QuicTestPacket makers as the version picked may not be |version_|.
Renjie Tang6ff9a9b2021-02-03 22:11:092495 client_maker_ = std::make_unique<QuicTestPacketMaker>(
Zhongyi Shi1c022d22020-03-20 19:00:162496 picked_version,
2497 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2498 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Patrick Meenan0b1b18cf2023-09-21 20:19:472499 /*client_priority_uses_incremental=*/true, /*use_priority_header=*/true);
Zhongyi Shi1c022d22020-03-20 19:00:162500 QuicTestPacketMaker server_maker(
2501 picked_version,
2502 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2503 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Patrick Meenan0b1b18cf2023-09-21 20:19:472504 /*client_priority_uses_incremental=*/false,
2505 /*use_priority_header=*/false);
Zhongyi Shi1c022d22020-03-20 19:00:162506
Renjie Tangaadb84b2019-08-31 01:00:232507 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:162508 if (VersionUsesHttp3(picked_version.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232509 mock_quic_data.AddWrite(SYNCHRONOUS,
2510 ConstructInitialSettingsPacket(packet_num++));
2511 }
Zhongyi Shi1c022d22020-03-20 19:00:162512
2513 quic::QuicStreamId client_stream_0 =
2514 quic::test::GetNthClientInitiatedBidirectionalStreamId(
2515 picked_version.transport_version, 0);
2516 mock_quic_data.AddWrite(SYNCHRONOUS,
2517 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032518 packet_num++, client_stream_0, true,
Zhongyi Shi1c022d22020-03-20 19:00:162519 GetRequestHeaders("GET", "https", "/")));
Kenichi Ishibashif8634ab2021-03-16 23:41:282520 mock_quic_data.AddRead(ASYNC,
2521 server_maker.MakeResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032522 1, client_stream_0, false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282523 server_maker.GetResponseHeaders("200"), nullptr));
Fan Yang32c5a112018-12-10 20:06:332524 mock_quic_data.AddRead(
Bence Béky319388a882020-09-23 18:42:522525 ASYNC, server_maker.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032526 2, client_stream_0, true,
Andrew Williams826d8742024-01-31 19:39:192527 ConstructDataFrameForVersion(kQuicRespData, picked_version)));
Renjie Tangaadb84b2019-08-31 01:00:232528 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342529 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392530 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212531 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyia00ca012017-07-06 23:36:392532
2533 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2534
2535 AddHangingNonAlternateProtocolSocketData();
2536 CreateSession(supported_versions_);
2537
Andrew Williams826d8742024-01-31 19:39:192538 SendRequestAndExpectHttpResponse(kHttpRespData);
Zhongyi Shi1c022d22020-03-20 19:00:162539 SendRequestAndExpectQuicResponseMaybeFromProxy(
Andrew Williams826d8742024-01-31 19:39:192540 kQuicRespData, 443, kQuic200RespStatusLine, picked_version, std::nullopt);
zhongyia00ca012017-07-06 23:36:392541}
2542
zhongyi3d4a55e72016-04-22 20:36:462543TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
Ryan Hamiltona51800a2022-02-12 19:34:352544 if (version_.AlpnDeferToRFCv1()) {
2545 // These versions currently do not support Alt-Svc.
2546 return;
2547 }
Ryan Hamiltona2dcbae2022-02-09 19:02:452548 std::string alt_svc_header = base::StrCat(
2549 {"Alt-Svc: ",
2550 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.com", 443), ",",
2551 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
zhongyi3d4a55e72016-04-22 20:36:462552 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452553 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
Andrew Williams826d8742024-01-31 19:39:192554 MockRead(kHttpRespData),
zhongyi3d4a55e72016-04-22 20:36:462555 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2556 MockRead(ASYNC, OK)};
2557
Ryan Sleevib8d7ea02018-05-07 20:01:012558 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462559 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082560 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462561 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2562
2563 CreateSession();
bncb26024382016-06-29 02:39:452564 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462565 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452566 request_.url = GURL("https://mail.example.org:443");
Andrew Williams826d8742024-01-31 19:39:192567 SendRequestAndExpectHttpResponse(kHttpRespData);
bnc525e175a2016-06-20 12:36:402568 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462569 session_->http_server_properties();
2570 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2571 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2572 // Check alternative service is set for the correct origin.
Brianna Goldstein02cb74f2022-09-29 05:41:012573 EXPECT_EQ(2u, http_server_properties
2574 ->GetAlternativeServiceInfos(https_server,
2575 NetworkAnonymizationKey())
2576 .size());
bncb26024382016-06-29 02:39:452577 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492578 http_server_properties
Brianna Goldstein02cb74f2022-09-29 05:41:012579 ->GetAlternativeServiceInfos(http_server, NetworkAnonymizationKey())
Matt Menke3233d8f22019-08-20 21:01:492580 .empty());
zhongyi3d4a55e72016-04-22 20:36:462581}
2582
2583TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
Ryan Hamiltona51800a2022-02-12 19:34:352584 if (version_.AlpnDeferToRFCv1()) {
2585 // These versions currently do not support Alt-Svc.
2586 return;
2587 }
Ryan Hamiltona2dcbae2022-02-09 19:02:452588 std::string alt_svc_header = base::StrCat(
2589 {"Alt-Svc: ",
2590 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.com", 443), ",",
2591 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
zhongyi3d4a55e72016-04-22 20:36:462592 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:452593 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
Andrew Williams826d8742024-01-31 19:39:192594 MockRead(kHttpRespData),
zhongyi3d4a55e72016-04-22 20:36:462595 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2596 MockRead(ASYNC, OK)};
2597
Ryan Sleevib8d7ea02018-05-07 20:01:012598 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082599 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462600
2601 socket_factory_.AddSocketDataProvider(&http_data);
2602 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2603 socket_factory_.AddSocketDataProvider(&http_data);
2604 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2605
2606 CreateSession();
2607
2608 // Send https request and set alternative services if response header
2609 // advertises alternative service for mail.example.org.
Andrew Williams826d8742024-01-31 19:39:192610 SendRequestAndExpectHttpResponse(kHttpRespData);
bnc525e175a2016-06-20 12:36:402611 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462612 session_->http_server_properties();
2613
2614 const url::SchemeHostPort https_server(request_.url);
2615 // Check alternative service is set.
Brianna Goldstein02cb74f2022-09-29 05:41:012616 EXPECT_EQ(2u, http_server_properties
2617 ->GetAlternativeServiceInfos(https_server,
2618 NetworkAnonymizationKey())
2619 .size());
zhongyi3d4a55e72016-04-22 20:36:462620
2621 // Send http request to the same origin but with diffrent scheme, should not
2622 // use QUIC.
2623 request_.url = GURL("http://mail.example.org:443");
Andrew Williams826d8742024-01-31 19:39:192624 SendRequestAndExpectHttpResponse(kHttpRespData);
zhongyi3d4a55e72016-04-22 20:36:462625}
2626
zhongyie537a002017-06-27 16:48:212627TEST_P(QuicNetworkTransactionTest,
2628 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442629 // Add support for another QUIC version besides |version_|.
Patrick Meenan885a00652023-02-15 20:07:022630 for (const quic::ParsedQuicVersion& version : AllSupportedQuicVersions()) {
Bence Békyb89104962020-01-24 00:05:172631 if (version != version_) {
2632 supported_versions_.push_back(version);
2633 break;
2634 }
zhongyi86838d52017-06-30 01:19:442635 }
2636
David Schinazifbd4c432020-04-07 19:23:552637 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyie537a002017-06-27 16:48:212638 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:172639 MockRead("HTTP/1.1 200 OK\r\n"),
2640 MockRead(altsvc_header.c_str()),
2641 MockRead("\r\n"),
Andrew Williams826d8742024-01-31 19:39:192642 MockRead(kHttpRespData),
zhongyie537a002017-06-27 16:48:212643 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2644 MockRead(ASYNC, OK)};
2645
Ryan Sleevib8d7ea02018-05-07 20:01:012646 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212647 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082648 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212649 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2650
Ryan Hamiltonabad59e2019-06-06 04:02:592651 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232652 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022653 mock_quic_data.AddWrite(SYNCHRONOUS,
2654 ConstructInitialSettingsPacket(packet_num++));
zhongyie537a002017-06-27 16:48:212655 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232656 SYNCHRONOUS,
2657 ConstructClientRequestHeadersPacket(
2658 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032659 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432660 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332661 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032662 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282663 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332664 mock_quic_data.AddRead(
2665 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032666 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:192667 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:232668 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342669 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyie537a002017-06-27 16:48:212670 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212671 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyie537a002017-06-27 16:48:212672
2673 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2674
2675 AddHangingNonAlternateProtocolSocketData();
2676
zhongyi86838d52017-06-30 01:19:442677 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212678
Andrew Williams826d8742024-01-31 19:39:192679 SendRequestAndExpectHttpResponse(kHttpRespData);
2680 SendRequestAndExpectQuicResponse(kQuicRespData);
zhongyie537a002017-06-27 16:48:212681
Bence Békyb89104962020-01-24 00:05:172682 // Alt-Svc header contains all possible versions, so alternative services
2683 // should contain all of |supported_versions_|.
zhongyie537a002017-06-27 16:48:212684 const url::SchemeHostPort https_server(request_.url);
2685 const AlternativeServiceInfoVector alt_svc_info_vector =
2686 session_->http_server_properties()->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:012687 https_server, NetworkAnonymizationKey());
Victor Vasiliev22dd3f212022-02-11 21:57:292688 VerifyQuicVersionsInAlternativeServices(alt_svc_info_vector,
2689 supported_versions_);
zhongyie537a002017-06-27 16:48:212690}
2691
danzh3134c2562016-08-12 14:07:522692TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Ryan Hamiltona51800a2022-02-12 19:34:352693 if (version_.AlpnDeferToRFCv1()) {
2694 // These versions currently do not support Alt-Svc.
2695 return;
2696 }
Nick Harper23290b82019-05-02 00:02:562697 std::string altsvc_header = base::StringPrintf(
Bence Békyb89104962020-01-24 00:05:172698 "Alt-Svc: %s=\":443\"\r\n\r\n", quic::AlpnForVersion(version_).c_str());
bnc8be55ebb2015-10-30 14:12:072699 MockRead http_reads[] = {
2700 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
Andrew Williams826d8742024-01-31 19:39:192701 MockRead(kHttpRespData),
bnc8be55ebb2015-10-30 14:12:072702 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2703 MockRead(ASYNC, OK)};
2704
Ryan Sleevib8d7ea02018-05-07 20:01:012705 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072706 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082707 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072708 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2709
Ryan Hamiltonabad59e2019-06-06 04:02:592710 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232711 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022712 mock_quic_data.AddWrite(SYNCHRONOUS,
2713 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:362714 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232715 SYNCHRONOUS,
2716 ConstructClientRequestHeadersPacket(
2717 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032718 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432719 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332720 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032721 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:282722 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:332723 mock_quic_data.AddRead(
2724 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032725 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:192726 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:232727 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342728 ConstructClientAckPacket(packet_num++, 2, 1));
bnc8be55ebb2015-10-30 14:12:072729 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:212730 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc8be55ebb2015-10-30 14:12:072731
2732 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2733
rtennetib8e80fb2016-05-16 00:12:092734 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322735 CreateSession();
bnc8be55ebb2015-10-30 14:12:072736
Andrew Williams826d8742024-01-31 19:39:192737 SendRequestAndExpectHttpResponse(kHttpRespData);
2738 SendRequestAndExpectQuicResponse(kQuicRespData);
bnc8be55ebb2015-10-30 14:12:072739}
2740
rch9ecde09b2017-04-08 00:18:232741// Verify that if a QUIC connection times out, the QuicHttpStream will
2742// return QUIC_PROTOCOL_ERROR.
2743TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:382744 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Peter Kastinge5a38ed2021-10-02 03:06:352745 context_.params()->idle_connection_timeout = base::Seconds(5);
Renjie Tangd05389fe2022-07-13 23:46:232746 // Turn off port migration to avoid dealing with unnecessary complexity in
2747 // this test.
2748 context_.params()->allow_port_migration = false;
rch9ecde09b2017-04-08 00:18:232749
2750 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592751 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:132752 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232753 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2754
Zhongyi Shi1c022d22020-03-20 19:00:162755 client_maker_->set_save_packet_frames(true);
2756 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:492757 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022758 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton0d65a8c2019-06-07 00:46:022759 quic_data.AddWrite(
2760 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162761 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:492762 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032763 priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:452764
Zhongyi Shi1c022d22020-03-20 19:00:162765 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:232766
Patrick Meenan885a00652023-02-15 20:07:022767 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2768 // sending PTO packets.
2769 packet_num++;
2770 // PTO 1
Tsuyoshi Horoea15e7a2023-05-23 00:12:032771 quic_data.AddWrite(SYNCHRONOUS,
2772 client_maker_->MakeRetransmissionPacket(1, packet_num++));
Patrick Meenan885a00652023-02-15 20:07:022773 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2774 // sending PTO packets.
2775 packet_num++;
2776 // PTO 2
Tsuyoshi Horoea15e7a2023-05-23 00:12:032777 quic_data.AddWrite(SYNCHRONOUS,
2778 client_maker_->MakeRetransmissionPacket(2, packet_num++));
Patrick Meenan885a00652023-02-15 20:07:022779 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2780 // sending PTO packets.
2781 packet_num++;
2782 // PTO 3
Tsuyoshi Horoea15e7a2023-05-23 00:12:032783 quic_data.AddWrite(SYNCHRONOUS,
2784 client_maker_->MakeRetransmissionPacket(1, packet_num++));
Nick Harper0b214c132020-10-26 20:10:232785
Patrick Meenan885a00652023-02-15 20:07:022786 quic_data.AddWrite(SYNCHRONOUS,
2787 client_maker_->MakeConnectionClosePacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032788 packet_num++, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Patrick Meenan885a00652023-02-15 20:07:022789 "No recent network activity after 4s. Timeout:4s"));
Fan Yang928f1632017-12-14 18:55:222790
rch9ecde09b2017-04-08 00:18:232791 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2792 quic_data.AddRead(ASYNC, OK);
2793 quic_data.AddSocketDataToFactory(&socket_factory_);
2794
2795 // In order for a new QUIC session to be established via alternate-protocol
2796 // without racing an HTTP connection, we need the host resolution to happen
2797 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2798 // connection to the the server, in this test we require confirmation
2799 // before encrypting so the HTTP job will still start.
2800 host_resolver_.set_synchronous_mode(true);
2801 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2802 "");
rch9ecde09b2017-04-08 00:18:232803
2804 CreateSession();
2805 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Dustin J. Mitchell795c7362024-01-18 16:50:522806 QuicSessionPoolPeer::SetAlarmFactory(
2807 session_->quic_session_pool(),
Jeremy Roman0579ed62017-08-29 15:56:192808 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222809 context_.clock()));
rch9ecde09b2017-04-08 00:18:232810
Ryan Hamilton9835e662018-08-02 05:36:272811 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232812
2813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2814 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262815 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch9ecde09b2017-04-08 00:18:232816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2817
2818 // Pump the message loop to get the request started.
2819 base::RunLoop().RunUntilIdle();
2820 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:282821 crypto_client_stream_factory_.last_stream()
2822 ->NotifySessionOneRttKeyAvailable();
rch9ecde09b2017-04-08 00:18:232823
2824 // Run the QUIC session to completion.
2825 quic_task_runner_->RunUntilIdle();
2826
2827 ExpectQuicAlternateProtocolMapping();
2828 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2829 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2830}
2831
David Schinazi7e980ab2020-05-13 20:26:552832// TODO(fayang): Add time driven TOO_MANY_RTOS test.
rch9ecde09b2017-04-08 00:18:232833
rch2f2991c2017-04-13 19:28:172834// Verify that if a QUIC protocol error occurs after the handshake is confirmed
2835// the request fails with QUIC_PROTOCOL_ERROR.
2836TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:382837 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:172838 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592839 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:162840 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:492841 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022842 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Nick Harper057264a82019-09-12 23:33:492843 quic_data.AddWrite(
2844 SYNCHRONOUS,
2845 ConstructClientRequestHeadersPacket(
2846 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032847 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:162848 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:552849 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:172850 // Peer sending data from an non-existing stream causes this end to raise
2851 // error and close connection.
Tsuyoshi Horoea15e7a2023-05-23 00:12:032852 quic_data.AddRead(ASYNC,
2853 ConstructServerRstPacket(
2854 1, GetNthClientInitiatedBidirectionalStreamId(47),
2855 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:172856 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:342857 quic_data.AddWrite(
2858 SYNCHRONOUS,
2859 ConstructClientAckAndConnectionClosePacket(
Patrick Meenan885a00652023-02-15 20:07:022860 packet_num++, 1, 1, quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
2861 quic_error_details, quic::IETF_STOP_SENDING));
rch2f2991c2017-04-13 19:28:172862 quic_data.AddSocketDataToFactory(&socket_factory_);
2863
2864 // In order for a new QUIC session to be established via alternate-protocol
2865 // without racing an HTTP connection, we need the host resolution to happen
2866 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2867 // connection to the the server, in this test we require confirmation
2868 // before encrypting so the HTTP job will still start.
2869 host_resolver_.set_synchronous_mode(true);
2870 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2871 "");
rch2f2991c2017-04-13 19:28:172872
2873 CreateSession();
2874
Ryan Hamilton9835e662018-08-02 05:36:272875 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:172876
2877 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2878 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262879 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:172880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2881
2882 // Pump the message loop to get the request started.
2883 base::RunLoop().RunUntilIdle();
2884 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:282885 crypto_client_stream_factory_.last_stream()
2886 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:172887
2888 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:552889 quic_data.Resume();
rch2f2991c2017-04-13 19:28:172890
2891 // Run the QUIC session to completion.
2892 base::RunLoop().RunUntilIdle();
2893 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2894 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2895
2896 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2897 ExpectQuicAlternateProtocolMapping();
2898 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2899}
2900
rch2f2991c2017-04-13 19:28:172901// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
2902// connection times out, then QUIC will be marked as broken and the request
2903// retried over TCP.
2904TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Ryan Hamiltona51800a2022-02-12 19:34:352905 if (version_.AlpnDeferToRFCv1()) {
2906 // These versions currently do not support Alt-Svc.
2907 return;
2908 }
Peter Kastinge5a38ed2021-10-02 03:06:352909 context_.params()->idle_connection_timeout = base::Seconds(5);
Renjie Tangd05389fe2022-07-13 23:46:232910 // Turn off port migration to avoid dealing with unnecessary complexity in
2911 // this test.
2912 context_.params()->allow_port_migration = false;
rch2f2991c2017-04-13 19:28:172913
2914 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592915 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:132916 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:172917 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2918
Zhongyi Shi1c022d22020-03-20 19:00:162919 client_maker_->set_save_packet_frames(true);
2920 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:492921 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:022922 quic_data.AddWrite(SYNCHRONOUS,
2923 client_maker_->MakeInitialSettingsPacket(packet_num++));
Ryan Hamilton0d65a8c2019-06-07 00:46:022924 quic_data.AddWrite(
2925 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162926 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:492927 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:032928 priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:452929
Zhongyi Shi1c022d22020-03-20 19:00:162930 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Patrick Meenan885a00652023-02-15 20:07:022931 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2932 // sending PTO packets.
2933 packet_num++;
2934 // PTO 1
Tsuyoshi Horoea15e7a2023-05-23 00:12:032935 quic_data.AddWrite(SYNCHRONOUS,
2936 client_maker_->MakeRetransmissionPacket(1, packet_num++));
Nick Harper0b214c132020-10-26 20:10:232937
Patrick Meenan885a00652023-02-15 20:07:022938 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2939 // sending PTO packets.
2940 packet_num++;
2941 // PTO 2
Tsuyoshi Horoea15e7a2023-05-23 00:12:032942 quic_data.AddWrite(SYNCHRONOUS,
2943 client_maker_->MakeRetransmissionPacket(2, packet_num++));
Nick Harper0b214c132020-10-26 20:10:232944
Patrick Meenan885a00652023-02-15 20:07:022945 // QuicConnection::OnRetransmissionTimeout skips a packet number when
2946 // sending PTO packets.
2947 packet_num++;
2948 // PTO 3
Tsuyoshi Horoea15e7a2023-05-23 00:12:032949 quic_data.AddWrite(SYNCHRONOUS,
2950 client_maker_->MakeRetransmissionPacket(1, packet_num++));
Nick Harper0b214c132020-10-26 20:10:232951
Patrick Meenan885a00652023-02-15 20:07:022952 quic_data.AddWrite(SYNCHRONOUS,
2953 client_maker_->MakeConnectionClosePacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:032954 packet_num++, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Patrick Meenan885a00652023-02-15 20:07:022955 "No recent network activity after 4s. Timeout:4s"));
Fan Yang928f1632017-12-14 18:55:222956
rch2f2991c2017-04-13 19:28:172957 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2958 quic_data.AddRead(ASYNC, OK);
2959 quic_data.AddSocketDataToFactory(&socket_factory_);
2960
2961 // After that fails, it will be resent via TCP.
2962 MockWrite http_writes[] = {
2963 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2964 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2965 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2966
Ryan Hamiltona2dcbae2022-02-09 19:02:452967 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2968 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:192969 MockRead(SYNCHRONOUS, 5, kHttpRespData),
Ryan Hamiltona2dcbae2022-02-09 19:02:452970 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:012971 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:172972 socket_factory_.AddSocketDataProvider(&http_data);
2973 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2974
2975 // In order for a new QUIC session to be established via alternate-protocol
2976 // without racing an HTTP connection, we need the host resolution to happen
2977 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2978 // connection to the the server, in this test we require confirmation
2979 // before encrypting so the HTTP job will still start.
2980 host_resolver_.set_synchronous_mode(true);
2981 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2982 "");
rch2f2991c2017-04-13 19:28:172983
2984 CreateSession();
2985 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Dustin J. Mitchell795c7362024-01-18 16:50:522986 QuicSessionPoolPeer::SetAlarmFactory(
2987 session_->quic_session_pool(),
Jeremy Roman0579ed62017-08-29 15:56:192988 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222989 context_.clock()));
rch2f2991c2017-04-13 19:28:172990
Ryan Hamilton9835e662018-08-02 05:36:272991 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:172992
2993 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2994 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:262995 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:172996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2997
2998 // Pump the message loop to get the request started.
2999 base::RunLoop().RunUntilIdle();
3000 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283001 crypto_client_stream_factory_.last_stream()
3002 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:173003
3004 // Run the QUIC session to completion.
3005 quic_task_runner_->RunUntilIdle();
3006 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3007
3008 ExpectQuicAlternateProtocolMapping();
3009
3010 // Let the transaction proceed which will result in QUIC being marked
3011 // as broken and the request falling back to TCP.
3012 EXPECT_THAT(callback.WaitForResult(), IsOk());
3013
3014 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3015 ASSERT_FALSE(http_data.AllReadDataConsumed());
3016
3017 // Read the response body over TCP.
Andrew Williams826d8742024-01-31 19:39:193018 CheckResponseData(&trans, kHttpRespData);
rch2f2991c2017-04-13 19:28:173019 ExpectBrokenAlternateProtocolMapping();
3020 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3021 ASSERT_TRUE(http_data.AllReadDataConsumed());
3022}
3023
rch2f2991c2017-04-13 19:28:173024// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3025// protocol error occurs after the handshake is confirmed, the request
3026// retried over TCP and the QUIC will be marked as broken.
3027TEST_P(QuicNetworkTransactionTest,
3028 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:353029 if (version_.AlpnDeferToRFCv1()) {
3030 // These versions currently do not support Alt-Svc.
3031 return;
3032 }
Peter Kastinge5a38ed2021-10-02 03:06:353033 context_.params()->idle_connection_timeout = base::Seconds(5);
rch2f2991c2017-04-13 19:28:173034
3035 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593036 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:163037 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493038 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023039 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Nick Harper057264a82019-09-12 23:33:493040 quic_data.AddWrite(
3041 SYNCHRONOUS,
3042 ConstructClientRequestHeadersPacket(
3043 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033044 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163045 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553046 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3047
rch2f2991c2017-04-13 19:28:173048 // Peer sending data from an non-existing stream causes this end to raise
3049 // error and close connection.
Tsuyoshi Horoea15e7a2023-05-23 00:12:033050 quic_data.AddRead(ASYNC,
3051 ConstructServerRstPacket(
3052 1, GetNthClientInitiatedBidirectionalStreamId(47),
3053 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173054 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:343055 quic_data.AddWrite(
3056 SYNCHRONOUS,
3057 ConstructClientAckAndConnectionClosePacket(
Patrick Meenan885a00652023-02-15 20:07:023058 packet_num++, 1, 1, quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
3059 quic_error_details, quic::IETF_STOP_SENDING));
rch2f2991c2017-04-13 19:28:173060 quic_data.AddSocketDataToFactory(&socket_factory_);
3061
3062 // After that fails, it will be resent via TCP.
3063 MockWrite http_writes[] = {
3064 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3065 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3066 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3067
Ryan Hamiltona2dcbae2022-02-09 19:02:453068 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3069 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:193070 MockRead(SYNCHRONOUS, 5, kHttpRespData),
Ryan Hamiltona2dcbae2022-02-09 19:02:453071 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013072 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173073 socket_factory_.AddSocketDataProvider(&http_data);
3074 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3075
3076 // In order for a new QUIC session to be established via alternate-protocol
3077 // without racing an HTTP connection, we need the host resolution to happen
3078 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3079 // connection to the the server, in this test we require confirmation
3080 // before encrypting so the HTTP job will still start.
3081 host_resolver_.set_synchronous_mode(true);
3082 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3083 "");
rch2f2991c2017-04-13 19:28:173084
3085 CreateSession();
3086
Ryan Hamilton9835e662018-08-02 05:36:273087 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173088
3089 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3090 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263091 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch2f2991c2017-04-13 19:28:173092 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3093
3094 // Pump the message loop to get the request started.
3095 base::RunLoop().RunUntilIdle();
3096 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283097 crypto_client_stream_factory_.last_stream()
3098 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553099 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173100
3101 // Run the QUIC session to completion.
3102 base::RunLoop().RunUntilIdle();
3103 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3104
3105 ExpectQuicAlternateProtocolMapping();
3106
3107 // Let the transaction proceed which will result in QUIC being marked
3108 // as broken and the request falling back to TCP.
3109 EXPECT_THAT(callback.WaitForResult(), IsOk());
3110
3111 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3112 ASSERT_FALSE(http_data.AllReadDataConsumed());
3113
3114 // Read the response body over TCP.
Andrew Williams826d8742024-01-31 19:39:193115 CheckResponseData(&trans, kHttpRespData);
rch2f2991c2017-04-13 19:28:173116 ExpectBrokenAlternateProtocolMapping();
3117 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3118 ASSERT_TRUE(http_data.AllReadDataConsumed());
3119}
3120
Brianna Goldsteind22b0642022-10-11 16:30:503121// Much like above test, but verifies that NetworkAnonymizationKey is respected.
Matt Menkeb32ba5122019-09-10 19:17:053122TEST_P(QuicNetworkTransactionTest,
3123 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:353124 if (version_.AlpnDeferToRFCv1()) {
3125 // These versions currently do not support Alt-Svc.
3126 return;
3127 }
Matt Menke4807a9a2020-11-21 00:14:413128 const SchemefulSite kSite1(GURL("https://foo.test/"));
3129 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Dustin J. Mitchell1d774ea2023-03-03 00:54:463130 const auto kNetworkAnonymizationKey1 =
3131 NetworkAnonymizationKey::CreateSameSite(kSite1);
Matt Menke4807a9a2020-11-21 00:14:413132 const SchemefulSite kSite2(GURL("https://bar.test/"));
3133 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Dustin J. Mitchell1d774ea2023-03-03 00:54:463134 const auto kNetworkAnonymizationKey2 =
3135 NetworkAnonymizationKey::CreateSameSite(kSite2);
Matt Menkeb32ba5122019-09-10 19:17:053136
3137 base::test::ScopedFeatureList feature_list;
3138 feature_list.InitWithFeatures(
3139 // enabled_features
3140 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3141 features::kPartitionConnectionsByNetworkIsolationKey},
3142 // disabled_features
3143 {});
3144 // Since HttpServerProperties caches the feature value, have to create a new
3145 // one.
3146 http_server_properties_ = std::make_unique<HttpServerProperties>();
3147
Peter Kastinge5a38ed2021-10-02 03:06:353148 context_.params()->idle_connection_timeout = base::Seconds(5);
Matt Menkeb32ba5122019-09-10 19:17:053149
3150 // The request will initially go out over QUIC.
3151 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:563152 uint64_t packet_number = 1;
Zhongyi Shi1c022d22020-03-20 19:00:163153 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:023154 quic_data.AddWrite(SYNCHRONOUS,
3155 ConstructInitialSettingsPacket(packet_number++));
Renjie Tang874398a2019-09-13 18:32:563156 quic_data.AddWrite(
3157 SYNCHRONOUS,
3158 ConstructClientRequestHeadersPacket(
3159 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033160 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163161 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:053162 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3163
3164 // Peer sending data from an non-existing stream causes this end to raise
3165 // error and close connection.
Tsuyoshi Horoea15e7a2023-05-23 00:12:033166 quic_data.AddRead(ASYNC,
3167 ConstructServerRstPacket(
3168 1, GetNthClientInitiatedBidirectionalStreamId(47),
3169 quic::QUIC_STREAM_LAST_ERROR));
Matt Menkeb32ba5122019-09-10 19:17:053170 std::string quic_error_details = "Data for nonexistent stream";
Nick Harper1ccb0ce2020-10-07 00:28:583171 quic::QuicErrorCode quic_error_code = quic::QUIC_INVALID_STREAM_ID;
Patrick Meenan885a00652023-02-15 20:07:023172 quic_error_code = quic::QUIC_HTTP_STREAM_WRONG_DIRECTION;
3173 quic_data.AddWrite(SYNCHRONOUS,
3174 ConstructClientAckAndConnectionClosePacket(
3175 packet_number++, 1, 1, quic_error_code,
3176 quic_error_details, quic::IETF_STOP_SENDING));
Matt Menkeb32ba5122019-09-10 19:17:053177 quic_data.AddSocketDataToFactory(&socket_factory_);
3178
3179 // After that fails, it will be resent via TCP.
3180 MockWrite http_writes[] = {
3181 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3182 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3183 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3184
Ryan Hamiltona2dcbae2022-02-09 19:02:453185 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3186 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:193187 MockRead(SYNCHRONOUS, 5, kHttpRespData),
Ryan Hamiltona2dcbae2022-02-09 19:02:453188 MockRead(SYNCHRONOUS, OK, 6)};
Matt Menkeb32ba5122019-09-10 19:17:053189 SequencedSocketData http_data(http_reads, http_writes);
3190 socket_factory_.AddSocketDataProvider(&http_data);
3191 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3192
3193 // In order for a new QUIC session to be established via alternate-protocol
3194 // without racing an HTTP connection, we need the host resolution to happen
3195 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3196 // connection to the the server, in this test we require confirmation
3197 // before encrypting so the HTTP job will still start.
3198 host_resolver_.set_synchronous_mode(true);
3199 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3200 "");
3201
3202 CreateSession();
3203
3204 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
Brianna Goldstein02cb74f2022-09-29 05:41:013205 kNetworkAnonymizationKey1);
Matt Menkeb32ba5122019-09-10 19:17:053206 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
Brianna Goldstein02cb74f2022-09-29 05:41:013207 kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:053208
3209 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3210 TestCompletionCallback callback;
3211 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:523212 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Reichhoff0049a0b72021-10-20 20:44:263213 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeb32ba5122019-09-10 19:17:053214 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3215
3216 // Pump the message loop to get the request started.
3217 base::RunLoop().RunUntilIdle();
3218 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283219 crypto_client_stream_factory_.last_stream()
3220 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:053221 quic_data.Resume();
3222
3223 // Run the QUIC session to completion.
3224 base::RunLoop().RunUntilIdle();
3225 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3226
3227 // Let the transaction proceed which will result in QUIC being marked
3228 // as broken and the request falling back to TCP.
3229 EXPECT_THAT(callback.WaitForResult(), IsOk());
3230 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3231 ASSERT_FALSE(http_data.AllReadDataConsumed());
3232
3233 // Read the response body over TCP.
Andrew Williams826d8742024-01-31 19:39:193234 CheckResponseData(&trans, kHttpRespData);
Matt Menkeb32ba5122019-09-10 19:17:053235 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3236 ASSERT_TRUE(http_data.AllReadDataConsumed());
3237
3238 // The alternative service shouldhave been marked as broken under
3239 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
Brianna Goldstein02cb74f2022-09-29 05:41:013240 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
3241 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:053242
3243 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3244 AddHttpDataAndRunRequest();
3245 // Requests using other NetworkIsolationKeys can still use QUIC.
3246 request_.network_isolation_key = kNetworkIsolationKey2;
Brianna Goldstein314ddf722022-09-24 02:00:523247 request_.network_anonymization_key = kNetworkAnonymizationKey2;
3248
Matt Menkeb32ba5122019-09-10 19:17:053249 AddQuicDataAndRunRequest();
3250
3251 // The last two requests should not have changed the alternative service
3252 // mappings.
Brianna Goldstein02cb74f2022-09-29 05:41:013253 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
3254 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:053255}
3256
Tsuyoshi Horo0f740832022-11-28 22:36:213257TEST_P(QuicNetworkTransactionTest,
3258 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithUseDnsHttpsSvcbAlpn) {
Tsuyoshi Horo94cc9fa2023-01-19 00:04:573259 session_params_.use_dns_https_svcb_alpn = true;
Tsuyoshi Horo0f740832022-11-28 22:36:213260 context_.params()->idle_connection_timeout = base::Seconds(5);
3261
3262 // The request will initially go out over QUIC.
3263 MockQuicData quic_data(version_);
3264 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
3265 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023266 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Tsuyoshi Horo0f740832022-11-28 22:36:213267 quic_data.AddWrite(
3268 SYNCHRONOUS,
3269 ConstructClientRequestHeadersPacket(
3270 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033271 GetRequestHeaders("GET", "https", "/")));
Tsuyoshi Horo0f740832022-11-28 22:36:213272 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
3273 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3274
3275 // Peer sending data from an non-existing stream causes this end to raise
3276 // error and close connection.
Tsuyoshi Horoea15e7a2023-05-23 00:12:033277 quic_data.AddRead(ASYNC,
3278 ConstructServerRstPacket(
3279 1, GetNthClientInitiatedBidirectionalStreamId(47),
3280 quic::QUIC_STREAM_LAST_ERROR));
Tsuyoshi Horo0f740832022-11-28 22:36:213281 std::string quic_error_details = "Data for nonexistent stream";
3282 quic_data.AddWrite(
3283 SYNCHRONOUS,
3284 ConstructClientAckAndConnectionClosePacket(
Patrick Meenan885a00652023-02-15 20:07:023285 packet_num++, 1, 1, quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
3286 quic_error_details, quic::IETF_STOP_SENDING));
Tsuyoshi Horo0f740832022-11-28 22:36:213287 quic_data.AddSocketDataToFactory(&socket_factory_);
3288
3289 // After that fails, it will be resent via TCP.
3290 MockWrite http_writes[] = {
3291 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3292 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3293 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3294
3295 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3296 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:193297 MockRead(SYNCHRONOUS, 5, kHttpRespData),
Tsuyoshi Horo0f740832022-11-28 22:36:213298 MockRead(SYNCHRONOUS, OK, 6)};
3299 SequencedSocketData http_data(http_reads, http_writes);
3300 socket_factory_.AddSocketDataProvider(&http_data);
3301 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3302
3303 HostResolverEndpointResult endpoint_result1;
3304 endpoint_result1.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
3305 endpoint_result1.metadata.supported_protocol_alpns = {
3306 quic::QuicVersionLabelToString(quic::CreateQuicVersionLabel(version_))};
3307 HostResolverEndpointResult endpoint_result2;
3308 endpoint_result2.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
3309 std::vector<HostResolverEndpointResult> endpoints;
3310 endpoints.push_back(endpoint_result1);
3311 endpoints.push_back(endpoint_result2);
3312 host_resolver_.rules()->AddRule(
3313 "mail.example.org",
3314 MockHostResolverBase::RuleResolver::RuleResult(
3315 std::move(endpoints),
3316 /*aliases=*/std::set<std::string>{"mail.example.org"}));
3317
3318 CreateSession();
3319
3320 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
3321
3322 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3323 TestCompletionCallback callback;
3324 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
3325 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3326
3327 // Pump the message loop to get the request started.
3328 base::RunLoop().RunUntilIdle();
3329 // Explicitly confirm the handshake.
3330 crypto_client_stream_factory_.last_stream()
3331 ->NotifySessionOneRttKeyAvailable();
3332 quic_data.Resume();
3333
3334 // Run the QUIC session to completion.
3335 base::RunLoop().RunUntilIdle();
3336 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3337
3338 ExpectQuicAlternateProtocolMapping();
3339
3340 // Let the transaction proceed which will result in QUIC being marked
3341 // as broken and the request falling back to TCP.
3342 EXPECT_THAT(callback.WaitForResult(), IsOk());
3343
3344 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3345 ASSERT_FALSE(http_data.AllReadDataConsumed());
3346
3347 // Read the response body over TCP.
Andrew Williams826d8742024-01-31 19:39:193348 CheckResponseData(&trans, kHttpRespData);
Tsuyoshi Horo0f740832022-11-28 22:36:213349 ExpectBrokenAlternateProtocolMapping();
3350 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3351 ASSERT_TRUE(http_data.AllReadDataConsumed());
3352}
3353
rch30943ee2017-06-12 21:28:443354// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3355// request is reset from, then QUIC will be marked as broken and the request
3356// retried over TCP.
3357TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:353358 if (version_.AlpnDeferToRFCv1()) {
3359 // These versions currently do not support Alt-Svc.
3360 return;
3361 }
rch30943ee2017-06-12 21:28:443362 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593363 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133364 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443365 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3366
Zhongyi Shi1c022d22020-03-20 19:00:163367 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493368 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023369 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton0d65a8c2019-06-07 00:46:023370 quic_data.AddWrite(
3371 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163372 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493373 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033374 priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453375
Zhongyi Shi1c022d22020-03-20 19:00:163376 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553377 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443378
Tsuyoshi Horoea15e7a2023-05-23 00:12:033379 quic_data.AddRead(ASYNC, ConstructServerRstPacket(
3380 1, GetNthClientInitiatedBidirectionalStreamId(0),
3381 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443382
Patrick Meenan885a00652023-02-15 20:07:023383 quic_data.AddWrite(
3384 SYNCHRONOUS,
3385 client_maker_->MakeAckRstAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033386 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Patrick Meenan885a00652023-02-15 20:07:023387 quic::QUIC_HEADERS_TOO_LARGE, 1, 1, GetQpackDecoderStreamId(), false,
3388 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:073389
rch30943ee2017-06-12 21:28:443390 quic_data.AddRead(ASYNC, OK);
3391 quic_data.AddSocketDataToFactory(&socket_factory_);
3392
3393 // After that fails, it will be resent via TCP.
3394 MockWrite http_writes[] = {
3395 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3396 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3397 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3398
Ryan Hamiltona2dcbae2022-02-09 19:02:453399 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3400 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:193401 MockRead(SYNCHRONOUS, 5, kHttpRespData),
Ryan Hamiltona2dcbae2022-02-09 19:02:453402 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013403 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443404 socket_factory_.AddSocketDataProvider(&http_data);
3405 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3406
3407 // In order for a new QUIC session to be established via alternate-protocol
3408 // without racing an HTTP connection, we need the host resolution to happen
3409 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3410 // connection to the the server, in this test we require confirmation
3411 // before encrypting so the HTTP job will still start.
3412 host_resolver_.set_synchronous_mode(true);
3413 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3414 "");
rch30943ee2017-06-12 21:28:443415
3416 CreateSession();
3417
Ryan Hamilton9835e662018-08-02 05:36:273418 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443419
3420 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3421 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:263422 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
rch30943ee2017-06-12 21:28:443423 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3424
3425 // Pump the message loop to get the request started.
3426 base::RunLoop().RunUntilIdle();
3427 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283428 crypto_client_stream_factory_.last_stream()
3429 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553430 quic_data.Resume();
rch30943ee2017-06-12 21:28:443431
3432 // Run the QUIC session to completion.
3433 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3434
3435 ExpectQuicAlternateProtocolMapping();
3436
3437 // Let the transaction proceed which will result in QUIC being marked
3438 // as broken and the request falling back to TCP.
3439 EXPECT_THAT(callback.WaitForResult(), IsOk());
3440
3441 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3442 ASSERT_FALSE(http_data.AllReadDataConsumed());
3443
3444 // Read the response body over TCP.
Andrew Williams826d8742024-01-31 19:39:193445 CheckResponseData(&trans, kHttpRespData);
rch30943ee2017-06-12 21:28:443446 ExpectBrokenAlternateProtocolMapping();
3447 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3448 ASSERT_TRUE(http_data.AllReadDataConsumed());
3449}
3450
Ryan Hamilton6c2a2a82017-12-15 02:06:283451// Verify that when an origin has two alt-svc advertisements, one local and one
3452// remote, that when the local is broken the request will go over QUIC via
3453// the remote Alt-Svc.
3454// This is a regression test for crbug/825646.
3455TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:383456 context_.params()->allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:283457
3458 GURL origin1 = request_.url; // mail.example.org
3459 GURL origin2("https://www.example.org/");
3460 ASSERT_NE(origin1.host(), origin2.host());
3461
3462 scoped_refptr<X509Certificate> cert(
3463 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243464 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3465 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283466
3467 ProofVerifyDetailsChromium verify_details;
3468 verify_details.cert_verify_result.verified_cert = cert;
3469 verify_details.cert_verify_result.is_issued_by_known_root = true;
3470 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3471
Ryan Hamiltonabad59e2019-06-06 04:02:593472 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233473 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023474 mock_quic_data.AddWrite(SYNCHRONOUS,
3475 ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton6c2a2a82017-12-15 02:06:283476 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233477 SYNCHRONOUS,
3478 ConstructClientRequestHeadersPacket(
3479 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033480 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433481 mock_quic_data.AddRead(
3482 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033483 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283484 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433485 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333486 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033487 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:193488 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:233489 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343490 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283491 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213492 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Ryan Hamilton6c2a2a82017-12-15 02:06:283493
3494 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:593495 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:283496 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3497 AddHangingNonAlternateProtocolSocketData();
3498
3499 CreateSession();
3500
3501 // Set up alternative service for |origin1|.
3502 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3503 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
Peter Kastinge5a38ed2021-10-02 03:06:353504 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamilton6c2a2a82017-12-15 02:06:283505 AlternativeServiceInfoVector alternative_services;
3506 alternative_services.push_back(
3507 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3508 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383509 context_.params()->supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:283510 alternative_services.push_back(
3511 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3512 remote_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383513 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:493514 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
Brianna Goldstein02cb74f2022-09-29 05:41:013515 NetworkAnonymizationKey(),
Matt Menke3233d8f22019-08-20 21:01:493516 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:283517
Brianna Goldstein02cb74f2022-09-29 05:41:013518 http_server_properties_->MarkAlternativeServiceBroken(
3519 local_alternative, NetworkAnonymizationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:283520
Andrew Williams826d8742024-01-31 19:39:193521 SendRequestAndExpectQuicResponse(kQuicRespData);
Ryan Hamilton6c2a2a82017-12-15 02:06:283522}
3523
Ryan Hamilton899c2e082019-11-14 01:22:023524// Verify that when multiple alternatives are broken,
3525// ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
3526// This is a regression test for crbug/1024613.
3527TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
Ryan Hamiltona51800a2022-02-12 19:34:353528 if (version_.AlpnDeferToRFCv1()) {
3529 // These versions currently do not support Alt-Svc.
3530 return;
3531 }
Ryan Hamilton899c2e082019-11-14 01:22:023532 base::HistogramTester histogram_tester;
3533
3534 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453535 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:193536 MockRead(kHttpRespData),
Ryan Hamilton899c2e082019-11-14 01:22:023537 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3538 MockRead(ASYNC, OK)};
3539
3540 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
3541 socket_factory_.AddSocketDataProvider(&http_data);
3542 AddCertificate(&ssl_data_);
3543 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3544
3545 GURL origin1 = request_.url; // mail.example.org
3546
3547 scoped_refptr<X509Certificate> cert(
3548 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
3549 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
3550
3551 ProofVerifyDetailsChromium verify_details;
3552 verify_details.cert_verify_result.verified_cert = cert;
3553 verify_details.cert_verify_result.is_issued_by_known_root = true;
3554 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3555
3556 CreateSession();
3557
3558 // Set up alternative service for |origin1|.
3559 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
Peter Kastinge5a38ed2021-10-02 03:06:353560 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamilton899c2e082019-11-14 01:22:023561 AlternativeServiceInfoVector alternative_services;
3562 alternative_services.push_back(
3563 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3564 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383565 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:023566 alternative_services.push_back(
3567 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3568 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383569 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:023570 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
Brianna Goldstein02cb74f2022-09-29 05:41:013571 NetworkAnonymizationKey(),
Ryan Hamilton899c2e082019-11-14 01:22:023572 alternative_services);
3573
Brianna Goldstein02cb74f2022-09-29 05:41:013574 http_server_properties_->MarkAlternativeServiceBroken(
3575 local_alternative, NetworkAnonymizationKey());
Ryan Hamilton899c2e082019-11-14 01:22:023576
Andrew Williams826d8742024-01-31 19:39:193577 SendRequestAndExpectHttpResponse(kHttpRespData);
Ryan Hamilton899c2e082019-11-14 01:22:023578
3579 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
3580 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
3581}
3582
rch30943ee2017-06-12 21:28:443583// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3584// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:053585// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:443586// connection instead of going back to the broken QUIC connection.
3587// This is a regression tests for crbug/731303.
3588TEST_P(QuicNetworkTransactionTest,
3589 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltona51800a2022-02-12 19:34:353590 if (version_.AlpnDeferToRFCv1()) {
3591 // These versions currently do not support Alt-Svc.
3592 return;
3593 }
Victor Vasilieva1e66d72019-12-05 17:55:383594 context_.params()->allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:443595
3596 GURL origin1 = request_.url;
3597 GURL origin2("https://www.example.org/");
3598 ASSERT_NE(origin1.host(), origin2.host());
3599
Ryan Hamiltonabad59e2019-06-06 04:02:593600 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:443601
3602 scoped_refptr<X509Certificate> cert(
3603 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243604 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3605 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:443606
3607 ProofVerifyDetailsChromium verify_details;
3608 verify_details.cert_verify_result.verified_cert = cert;
3609 verify_details.cert_verify_result.is_issued_by_known_root = true;
3610 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3611
Renjie Tangaadb84b2019-08-31 01:00:233612 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023613 mock_quic_data.AddWrite(SYNCHRONOUS,
3614 ConstructInitialSettingsPacket(packet_num++));
rch30943ee2017-06-12 21:28:443615 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433616 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233617 SYNCHRONOUS,
3618 ConstructClientRequestHeadersPacket(
3619 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033620 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433621 mock_quic_data.AddRead(
3622 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033623 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283624 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433625 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333626 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033627 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:193628 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:233629 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343630 ConstructClientAckPacket(packet_num++, 2, 1));
rch30943ee2017-06-12 21:28:443631
3632 // Second request will go over the pooled QUIC connection, but will be
3633 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:053634 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:223635 version_,
3636 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Bence Béky957bab12023-01-31 16:40:103637 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT, true);
David Schinazic8281052019-01-24 06:14:173638 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:223639 version_,
3640 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
3641 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:433642 mock_quic_data.AddWrite(
3643 SYNCHRONOUS,
3644 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033645 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
3646 GetRequestHeaders("GET", "https", "/", &client_maker2)));
Fan Yang32c5a112018-12-10 20:06:333647 mock_quic_data.AddRead(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033648 ASYNC,
3649 ConstructServerRstPacket(3, GetNthClientInitiatedBidirectionalStreamId(1),
3650 quic::QUIC_HEADERS_TOO_LARGE));
Bence Béky6e243aa2019-12-13 19:01:073651
Patrick Meenan885a00652023-02-15 20:07:023652 mock_quic_data.AddWrite(
3653 SYNCHRONOUS,
3654 client_maker_->MakeAckRstAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033655 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
Patrick Meenan885a00652023-02-15 20:07:023656 quic::QUIC_HEADERS_TOO_LARGE, 3, 2, GetQpackDecoderStreamId(),
3657 /*fin=*/false, StreamCancellationQpackDecoderInstruction(1)));
Bence Béky6e243aa2019-12-13 19:01:073658
rch30943ee2017-06-12 21:28:443659 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213660 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rch30943ee2017-06-12 21:28:443661
3662 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3663
3664 // After that fails, it will be resent via TCP.
3665 MockWrite http_writes[] = {
3666 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3667 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
3668 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3669
Ryan Hamiltona2dcbae2022-02-09 19:02:453670 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3671 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:193672 MockRead(SYNCHRONOUS, 5, kHttpRespData),
Ryan Hamiltona2dcbae2022-02-09 19:02:453673 MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013674 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443675 socket_factory_.AddSocketDataProvider(&http_data);
3676 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3677
Ryan Hamilton6c2a2a82017-12-15 02:06:283678 // Then the next request to the second origin will be sent over TCP.
3679 socket_factory_.AddSocketDataProvider(&http_data);
3680 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:443681
3682 CreateSession();
Dustin J. Mitchell795c7362024-01-18 16:50:523683 QuicSessionPoolPeer::SetAlarmFactory(
3684 session_->quic_session_pool(),
Fan Yangc9e00dc2018-10-09 14:17:563685 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223686 context_.clock()));
rch30943ee2017-06-12 21:28:443687
3688 // Set up alternative service for |origin1|.
Peter Kastinge5a38ed2021-10-02 03:06:353689 base::Time expiration = base::Time::Now() + base::Days(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:243690 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:493691 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013692 url::SchemeHostPort(origin1), NetworkAnonymizationKey(), alternative1,
Matt Menke9aa86262019-08-21 15:52:073693 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:443694
3695 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:243696 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:493697 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013698 url::SchemeHostPort(origin2), NetworkAnonymizationKey(), alternative2,
Matt Menke9aa86262019-08-21 15:52:073699 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:343700
Andrew Williams826d8742024-01-31 19:39:193701 // First request opens connection to `kDestination1`
Ryan Hamilton8d9ee76e2018-05-29 23:52:523702 // with quic::QuicServerId.host() == origin1.host().
Andrew Williams826d8742024-01-31 19:39:193703 SendRequestAndExpectQuicResponse(kQuicRespData);
rch30943ee2017-06-12 21:28:443704
3705 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:523706 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:053707 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:443708 request_.url = origin2;
Andrew Williams826d8742024-01-31 19:39:193709 SendRequestAndExpectHttpResponse(kHttpRespData);
Matt Menkeb32ba5122019-09-10 19:17:053710 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:013711 alternative1, NetworkAnonymizationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:243712 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:053713 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:013714 alternative2, NetworkAnonymizationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:243715 << alternative2.ToString();
rch30943ee2017-06-12 21:28:443716
Matt Menkeb32ba5122019-09-10 19:17:053717 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:443718 // QUIC connection.
Andrew Williams826d8742024-01-31 19:39:193719 SendRequestAndExpectHttpResponse(kHttpRespData);
rch30943ee2017-06-12 21:28:443720}
3721
bnc8be55ebb2015-10-30 14:12:073722TEST_P(QuicNetworkTransactionTest,
3723 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Ryan Hamiltona51800a2022-02-12 19:34:353724 if (version_.AlpnDeferToRFCv1()) {
3725 // These versions currently do not support Alt-Svc.
3726 return;
3727 }
Nick Harper23290b82019-05-02 00:02:563728 std::string altsvc_header =
3729 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
3730 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:073731 MockRead http_reads[] = {
3732 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
Andrew Williams826d8742024-01-31 19:39:193733 MockRead(kHttpRespData),
bnc8be55ebb2015-10-30 14:12:073734 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3735 MockRead(ASYNC, OK)};
3736
Ryan Sleevib8d7ea02018-05-07 20:01:013737 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:073738 socket_factory_.AddSocketDataProvider(&http_data);
3739 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3740 socket_factory_.AddSocketDataProvider(&http_data);
3741 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3742
rch3f4b8452016-02-23 16:59:323743 CreateSession();
bnc8be55ebb2015-10-30 14:12:073744
Andrew Williams826d8742024-01-31 19:39:193745 SendRequestAndExpectHttpResponse(kHttpRespData);
3746 SendRequestAndExpectHttpResponse(kHttpRespData);
bnc8be55ebb2015-10-30 14:12:073747}
3748
Xida Chen9bfe0b62018-04-24 19:52:213749// When multiple alternative services are advertised, HttpStreamFactory should
3750// select the alternative service which uses existing QUIC session if available.
3751// If no existing QUIC session can be used, use the first alternative service
3752// from the list.
zhongyi32569c62016-01-08 02:54:303753TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltona51800a2022-02-12 19:34:353754 if (version_.AlpnDeferToRFCv1()) {
3755 // These versions currently do not support Alt-Svc.
3756 return;
3757 }
Victor Vasilieva1e66d72019-12-05 17:55:383758 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltona2dcbae2022-02-09 19:02:453759 std::string alt_svc_header = base::StrCat(
3760 {"Alt-Svc: ",
3761 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.org", 443), ",",
3762 GenerateQuicAltSvcHeaderValue({version_}, 444), "\r\n\r\n"});
bncc958faa2015-07-31 18:14:523763 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:453764 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
Andrew Williams826d8742024-01-31 19:39:193765 MockRead(kHttpRespData),
bncc958faa2015-07-31 18:14:523766 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3767 MockRead(ASYNC, OK)};
3768
Ryan Sleevib8d7ea02018-05-07 20:01:013769 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:523770 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:083771 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:563772 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:523773
zhongyi32569c62016-01-08 02:54:303774 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:293775 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:303776 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:593777 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233778 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023779 mock_quic_data.AddWrite(SYNCHRONOUS,
3780 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:363781 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233782 SYNCHRONOUS,
3783 ConstructClientRequestHeadersPacket(
3784 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033785 GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:303786
Ryan Hamiltona2dcbae2022-02-09 19:02:453787 std::string alt_svc_list = base::StrCat(
3788 {GenerateQuicAltSvcHeaderValue({version_}, "mail.example.org", 444), ",",
3789 GenerateQuicAltSvcHeaderValue({version_}, "foo.example.org", 443), ",",
3790 GenerateQuicAltSvcHeaderValue({version_}, "bar.example.org", 445)});
Zhongyi Shi32f2fd02018-04-16 18:23:433791 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:023792 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033793 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283794 GetResponseHeaders("200", alt_svc_list)));
Zhongyi Shi32f2fd02018-04-16 18:23:433795 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333796 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033797 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:193798 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:233799 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343800 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:303801
3802 // Second QUIC request data.
3803 // Connection pooling, using existing session, no need to include version
3804 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:583805 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233806 SYNCHRONOUS,
3807 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033808 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
3809 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433810 mock_quic_data.AddRead(
3811 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033812 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283813 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433814 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333815 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033816 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
Andrew Williams826d8742024-01-31 19:39:193817 ConstructDataFrame(kQuicRespData)));
Renjie Tangb7afea82020-07-15 23:35:473818 mock_quic_data.AddWrite(SYNCHRONOUS,
3819 ConstructClientAckPacket(packet_num++, 4, 3));
bncc958faa2015-07-31 18:14:523820 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213821 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:523822
3823 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3824
rtennetib8e80fb2016-05-16 00:12:093825 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:323826 CreateSession();
Dustin J. Mitchell795c7362024-01-18 16:50:523827 QuicSessionPoolPeer::SetAlarmFactory(
3828 session_->quic_session_pool(),
Fan Yangc9e00dc2018-10-09 14:17:563829 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223830 context_.clock()));
bncc958faa2015-07-31 18:14:523831
Andrew Williams826d8742024-01-31 19:39:193832 SendRequestAndExpectHttpResponse(kHttpRespData);
zhongyi32569c62016-01-08 02:54:303833
Andrew Williams826d8742024-01-31 19:39:193834 SendRequestAndExpectQuicResponse(kQuicRespData);
3835 SendRequestAndExpectQuicResponse(kQuicRespData);
zhongyi32569c62016-01-08 02:54:303836}
3837
Ryan Hamilton8d9ee76e2018-05-29 23:52:523838// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:453839// even if alternative service destination is different.
3840TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Victor Vasilieva1e66d72019-12-05 17:55:383841 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:593842 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:453843
Renjie Tangaadb84b2019-08-31 01:00:233844 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023845 mock_quic_data.AddWrite(SYNCHRONOUS,
3846 ConstructInitialSettingsPacket(packet_num++));
bnc359ed2a2016-04-29 20:43:453847 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433848 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233849 SYNCHRONOUS,
3850 ConstructClientRequestHeadersPacket(
3851 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033852 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433853 mock_quic_data.AddRead(
3854 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033855 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283856 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433857 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333858 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033859 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:193860 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:233861 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343862 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:303863
bnc359ed2a2016-04-29 20:43:453864 // Second request.
alyssar2adf3ac2016-05-03 17:12:583865 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233866 SYNCHRONOUS,
3867 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033868 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
3869 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433870 mock_quic_data.AddRead(
3871 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033872 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283873 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433874 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333875 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033876 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
Andrew Williams826d8742024-01-31 19:39:193877 ConstructDataFrame(kQuicRespData)));
Renjie Tangb7afea82020-07-15 23:35:473878 mock_quic_data.AddWrite(SYNCHRONOUS,
3879 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:303880 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213881 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi32569c62016-01-08 02:54:303882
3883 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:453884
3885 AddHangingNonAlternateProtocolSocketData();
3886 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:303887
rch3f4b8452016-02-23 16:59:323888 CreateSession();
Dustin J. Mitchell795c7362024-01-18 16:50:523889 QuicSessionPoolPeer::SetAlarmFactory(
3890 session_->quic_session_pool(),
Fan Yangc9e00dc2018-10-09 14:17:563891 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223892 context_.clock()));
zhongyi32569c62016-01-08 02:54:303893
Andrew Williams826d8742024-01-31 19:39:193894 const char kDestination1[] = "first.example.com";
3895 const char kDestination2[] = "second.example.com";
bnc359ed2a2016-04-29 20:43:453896
Andrew Williams826d8742024-01-31 19:39:193897 // Set up alternative service entry to `kDestination1`.
bnc359ed2a2016-04-29 20:43:453898 url::SchemeHostPort server(request_.url);
Andrew Williams826d8742024-01-31 19:39:193899 AlternativeService alternative_service(kProtoQUIC, kDestination1, 443);
Peter Kastinge5a38ed2021-10-02 03:06:353900 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:493901 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013902 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:073903 supported_versions_);
Andrew Williams826d8742024-01-31 19:39:193904 // First request opens connection to `kDestination1`
Ryan Hamilton8d9ee76e2018-05-29 23:52:523905 // with quic::QuicServerId.host() == kDefaultServerHostName.
Andrew Williams826d8742024-01-31 19:39:193906 SendRequestAndExpectQuicResponse(kQuicRespData);
bnc359ed2a2016-04-29 20:43:453907
3908 // Set up alternative service entry to a different destination.
Andrew Williams826d8742024-01-31 19:39:193909 alternative_service = AlternativeService(kProtoQUIC, kDestination2, 443);
Matt Menke3233d8f22019-08-20 21:01:493910 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013911 server, NetworkAnonymizationKey(), alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:073912 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523913 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:453914 // even though alternative service destination is different.
Andrew Williams826d8742024-01-31 19:39:193915 SendRequestAndExpectQuicResponse(kQuicRespData);
bnc359ed2a2016-04-29 20:43:453916}
3917
3918// Pool to existing session with matching destination and matching certificate
3919// even if origin is different, and even if the alternative service with
3920// matching destination is not the first one on the list.
3921TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Victor Vasilieva1e66d72019-12-05 17:55:383922 context_.params()->allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:453923 GURL origin1 = request_.url;
3924 GURL origin2("https://www.example.org/");
3925 ASSERT_NE(origin1.host(), origin2.host());
3926
Ryan Hamiltonabad59e2019-06-06 04:02:593927 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:453928
Renjie Tangaadb84b2019-08-31 01:00:233929 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:023930 mock_quic_data.AddWrite(SYNCHRONOUS,
3931 ConstructInitialSettingsPacket(packet_num++));
bnc359ed2a2016-04-29 20:43:453932 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433933 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233934 SYNCHRONOUS,
3935 ConstructClientRequestHeadersPacket(
3936 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:033937 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433938 mock_quic_data.AddRead(
3939 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033940 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283941 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433942 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333943 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033944 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:193945 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:233946 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343947 ConstructClientAckPacket(packet_num++, 2, 1));
bnc359ed2a2016-04-29 20:43:453948
3949 // Second request.
Yixin Wang079ad542018-01-11 04:06:053950 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:223951 version_,
3952 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Bence Béky957bab12023-01-31 16:40:103953 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT, true);
David Schinazic8281052019-01-24 06:14:173954 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:223955 version_,
3956 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
3957 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:583958 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433959 SYNCHRONOUS,
3960 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033961 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
3962 GetRequestHeaders("GET", "https", "/", &client_maker2)));
Zhongyi Shi32f2fd02018-04-16 18:23:433963 mock_quic_data.AddRead(
3964 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033965 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:283966 GetResponseHeaders("200")));
Zhongyi Shi32f2fd02018-04-16 18:23:433967 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333968 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:033969 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
Andrew Williams826d8742024-01-31 19:39:193970 ConstructDataFrame(kQuicRespData)));
Renjie Tangb7afea82020-07-15 23:35:473971 mock_quic_data.AddWrite(SYNCHRONOUS,
3972 ConstructClientAckPacket(packet_num++, 4, 3));
bnc359ed2a2016-04-29 20:43:453973 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:213974 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:453975
3976 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3977
3978 AddHangingNonAlternateProtocolSocketData();
3979 AddHangingNonAlternateProtocolSocketData();
3980
3981 CreateSession();
Dustin J. Mitchell795c7362024-01-18 16:50:523982 QuicSessionPoolPeer::SetAlarmFactory(
3983 session_->quic_session_pool(),
Fan Yangc9e00dc2018-10-09 14:17:563984 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223985 context_.clock()));
bnc359ed2a2016-04-29 20:43:453986
Andrew Williams826d8742024-01-31 19:39:193987 const char kDestination1[] = "first.example.com";
3988 const char kDestination2[] = "second.example.com";
bnc359ed2a2016-04-29 20:43:453989
3990 // Set up alternative service for |origin1|.
Andrew Williams826d8742024-01-31 19:39:193991 AlternativeService alternative_service1(kProtoQUIC, kDestination1, 443);
Peter Kastinge5a38ed2021-10-02 03:06:353992 base::Time expiration = base::Time::Now() + base::Days(1);
Matt Menke3233d8f22019-08-20 21:01:493993 http_server_properties_->SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:013994 url::SchemeHostPort(origin1), NetworkAnonymizationKey(),
3995 alternative_service1, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:453996
3997 // Set up multiple alternative service entries for |origin2|,
3998 // the first one with a different destination as for |origin1|,
3999 // the second one with the same. The second one should be used,
4000 // because the request can be pooled to that one.
Andrew Williams826d8742024-01-31 19:39:194001 AlternativeService alternative_service2(kProtoQUIC, kDestination2, 443);
bnc359ed2a2016-04-29 20:43:454002 AlternativeServiceInfoVector alternative_services;
4003 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214004 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4005 alternative_service2, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384006 context_.params()->supported_versions));
bnc359ed2a2016-04-29 20:43:454007 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214008 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4009 alternative_service1, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384010 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494011 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
Brianna Goldstein02cb74f2022-09-29 05:41:014012 NetworkAnonymizationKey(),
Matt Menke3233d8f22019-08-20 21:01:494013 alternative_services);
Andrew Williams826d8742024-01-31 19:39:194014 // First request opens connection to `kDestination1`
Ryan Hamilton8d9ee76e2018-05-29 23:52:524015 // with quic::QuicServerId.host() == origin1.host().
Andrew Williams826d8742024-01-31 19:39:194016 SendRequestAndExpectQuicResponse(kQuicRespData);
bnc359ed2a2016-04-29 20:43:454017
4018 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524019 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454020 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584021
Andrew Williams826d8742024-01-31 19:39:194022 SendRequestAndExpectQuicResponse(kQuicRespData);
zhongyi32569c62016-01-08 02:54:304023}
4024
4025// Multiple origins have listed the same alternative services. When there's a
4026// existing QUIC session opened by a request to other origin,
4027// if the cert is valid, should select this QUIC session to make the request
4028// if this is also the first existing QUIC session.
4029TEST_P(QuicNetworkTransactionTest,
4030 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltona51800a2022-02-12 19:34:354031 if (version_.AlpnDeferToRFCv1()) {
4032 // These versions currently do not support Alt-Svc.
4033 return;
4034 }
Victor Vasilieva1e66d72019-12-05 17:55:384035 context_.params()->allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294036 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304037
rch9ae5b3b2016-02-11 00:36:294038 // HTTP data for request to www.example.org.
Andrew Williams826d8742024-01-31 19:39:194039 const char kWwwHttpRespData[] = "hello world from www.example.org";
zhongyi32569c62016-01-08 02:54:304040 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454041 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:194042 MockRead(kWwwHttpRespData),
zhongyi32569c62016-01-08 02:54:304043 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4044 MockRead(ASYNC, OK)};
4045
Ryan Sleevib8d7ea02018-05-07 20:01:014046 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304047 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084048 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304049 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4050
4051 // HTTP data for request to mail.example.org.
Ryan Hamiltona2dcbae2022-02-09 19:02:454052 std::string alt_svc_header2 = base::StrCat(
4053 {"Alt-Svc: ", GenerateQuicAltSvcHeaderValue({version_}, 444), ",",
4054 GenerateQuicAltSvcHeaderValue({version_}, "www.example.org", 443),
4055 "\r\n\r\n"});
Andrew Williams826d8742024-01-31 19:39:194056 const char kMailHttpRespData[] = "hello world from mail.example.org";
zhongyi32569c62016-01-08 02:54:304057 MockRead http_reads2[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454058 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header2.data()),
Andrew Williams826d8742024-01-31 19:39:194059 MockRead(kMailHttpRespData),
zhongyi32569c62016-01-08 02:54:304060 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4061 MockRead(ASYNC, OK)};
4062
Ryan Sleevib8d7ea02018-05-07 20:01:014063 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304064 socket_factory_.AddSocketDataProvider(&http_data2);
4065 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4066
Yixin Wang079ad542018-01-11 04:06:054067 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:224068 version_,
4069 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Bence Béky957bab12023-01-31 16:40:104070 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT, true);
alyssar2adf3ac2016-05-03 17:12:584071 server_maker_.set_hostname("www.example.org");
Zhongyi Shi1c022d22020-03-20 19:00:164072 client_maker_->set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594073 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234074 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:024075 mock_quic_data.AddWrite(SYNCHRONOUS,
4076 ConstructInitialSettingsPacket(packet_num++));
zhongyi32569c62016-01-08 02:54:304077 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584078 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234079 SYNCHRONOUS,
4080 ConstructClientRequestHeadersPacket(
4081 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034082 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434083
4084 mock_quic_data.AddRead(
4085 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034086 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284087 GetResponseHeaders("200")));
Andrew Williams826d8742024-01-31 19:39:194088 const char kMailQuicRespData[] = "hello from mail QUIC!";
Fan Yang32c5a112018-12-10 20:06:334089 mock_quic_data.AddRead(
4090 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034091 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:194092 ConstructDataFrame(kMailQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:234093 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344094 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434095 // Second QUIC request data.
4096 mock_quic_data.AddWrite(
4097 SYNCHRONOUS,
4098 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034099 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
4100 GetRequestHeaders("GET", "https", "/", &client_maker)));
Zhongyi Shi32f2fd02018-04-16 18:23:434101 mock_quic_data.AddRead(
4102 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034103 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284104 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334105 mock_quic_data.AddRead(
4106 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034107 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
Andrew Williams826d8742024-01-31 19:39:194108 ConstructDataFrame(kMailQuicRespData)));
Renjie Tangb7afea82020-07-15 23:35:474109 mock_quic_data.AddWrite(SYNCHRONOUS,
4110 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:304111 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214112 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
zhongyi32569c62016-01-08 02:54:304113
4114 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304115
rtennetib8e80fb2016-05-16 00:12:094116 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324117 CreateSession();
Dustin J. Mitchell795c7362024-01-18 16:50:524118 QuicSessionPoolPeer::SetAlarmFactory(
4119 session_->quic_session_pool(),
Fan Yangc9e00dc2018-10-09 14:17:564120 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224121 context_.clock()));
zhongyi32569c62016-01-08 02:54:304122
4123 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294124 request_.url = GURL("https://www.example.org/");
Andrew Williams826d8742024-01-31 19:39:194125 SendRequestAndExpectHttpResponse(kWwwHttpRespData);
zhongyi32569c62016-01-08 02:54:304126 request_.url = GURL("https://mail.example.org/");
Andrew Williams826d8742024-01-31 19:39:194127 SendRequestAndExpectHttpResponse(kMailHttpRespData);
zhongyi32569c62016-01-08 02:54:304128
rch9ae5b3b2016-02-11 00:36:294129 // Open a QUIC session to mail.example.org:443 when making request
4130 // to mail.example.org.
4131 request_.url = GURL("https://www.example.org/");
Andrew Williams826d8742024-01-31 19:39:194132 SendRequestAndExpectQuicResponse(kMailQuicRespData);
zhongyi32569c62016-01-08 02:54:304133
rch9ae5b3b2016-02-11 00:36:294134 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304135 request_.url = GURL("https://mail.example.org/");
Andrew Williams826d8742024-01-31 19:39:194136 SendRequestAndExpectQuicResponse(kMailQuicRespData);
bncc958faa2015-07-31 18:14:524137}
4138
4139TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
Ryan Hamiltona51800a2022-02-12 19:34:354140 if (version_.AlpnDeferToRFCv1()) {
4141 // These versions currently do not support Alt-Svc.
4142 return;
4143 }
Ryan Hamiltona2dcbae2022-02-09 19:02:454144 std::string alt_svc_header =
4145 base::StrCat({"Alt-Svc: ", GenerateQuicAltSvcHeaderValue({version_}, 137),
4146 "\r\n\r\n"});
bncc958faa2015-07-31 18:14:524147 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454148 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
Andrew Williams826d8742024-01-31 19:39:194149 MockRead(kHttpRespData),
bncc958faa2015-07-31 18:14:524150 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4151 MockRead(ASYNC, OK)};
4152
Ryan Sleevib8d7ea02018-05-07 20:01:014153 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524154 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084155 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564156 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524157
rtennetib8e80fb2016-05-16 00:12:094158 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324159 CreateSession();
bncc958faa2015-07-31 18:14:524160
Andrew Williams826d8742024-01-31 19:39:194161 SendRequestAndExpectHttpResponse(kHttpRespData);
bnc359ed2a2016-04-29 20:43:454162
4163 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344164 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494165 http_server_properties_->GetAlternativeServiceInfos(
Brianna Goldstein02cb74f2022-09-29 05:41:014166 http_server, NetworkAnonymizationKey());
zhongyic4de03032017-05-19 04:07:344167 ASSERT_EQ(1u, alternative_service_info_vector.size());
4168 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544169 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344170 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4171 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4172 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524173}
4174
4175TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
Ryan Hamiltona51800a2022-02-12 19:34:354176 if (version_.AlpnDeferToRFCv1()) {
4177 // These versions currently do not support Alt-Svc.
4178 return;
4179 }
bncc958faa2015-07-31 18:14:524180 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454181 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:194182 MockRead(kHttpRespData),
bncc958faa2015-07-31 18:14:524183 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4184 MockRead(ASYNC, OK)};
4185
Ryan Sleevib8d7ea02018-05-07 20:01:014186 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524187 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084188 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564189 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524190
Ryan Hamiltonabad59e2019-06-06 04:02:594191 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234192 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:024193 mock_quic_data.AddWrite(SYNCHRONOUS,
4194 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:364195 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234196 SYNCHRONOUS,
4197 ConstructClientRequestHeadersPacket(
4198 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034199 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434200 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334201 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034202 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284203 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334204 mock_quic_data.AddRead(
4205 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034206 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:194207 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:234208 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344209 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:524210 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214211 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bncc958faa2015-07-31 18:14:524212
4213 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4214
rtennetib8e80fb2016-05-16 00:12:094215 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324216 CreateSession();
bncc958faa2015-07-31 18:14:524217
bnc3472afd2016-11-17 15:27:214218 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524219 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494220 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014221 alternative_service, NetworkAnonymizationKey());
Matt Menke3233d8f22019-08-20 21:01:494222 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014223 alternative_service, NetworkAnonymizationKey()));
bncc958faa2015-07-31 18:14:524224
Andrew Williams826d8742024-01-31 19:39:194225 SendRequestAndExpectHttpResponse(kHttpRespData);
4226 SendRequestAndExpectQuicResponse(kQuicRespData);
bncc958faa2015-07-31 18:14:524227
mmenkee24011922015-12-17 22:12:594228 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524229
Matt Menke3233d8f22019-08-20 21:01:494230 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014231 alternative_service, NetworkAnonymizationKey()));
Matt Menke19475f72019-08-21 18:57:444232 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4233 url::SchemeHostPort("https", request_.url.host(), 443),
Brianna Goldstein02cb74f2022-09-29 05:41:014234 NetworkAnonymizationKey()));
bncc958faa2015-07-31 18:14:524235}
4236
Matt Menkeb32ba5122019-09-10 19:17:054237TEST_P(QuicNetworkTransactionTest,
4238 ConfirmAlternativeServiceWithNetworkIsolationKey) {
Ryan Hamiltona51800a2022-02-12 19:34:354239 if (version_.AlpnDeferToRFCv1()) {
4240 // These versions currently do not support Alt-Svc.
4241 return;
4242 }
Matt Menke4807a9a2020-11-21 00:14:414243 const SchemefulSite kSite1(GURL("https://foo.test/"));
4244 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Dustin J. Mitchell1d774ea2023-03-03 00:54:464245 const auto kNetworkAnonymizationKey1 =
4246 NetworkAnonymizationKey::CreateSameSite(kSite1);
Matt Menke4807a9a2020-11-21 00:14:414247 const SchemefulSite kSite2(GURL("https://bar.test/"));
4248 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Dustin J. Mitchell1d774ea2023-03-03 00:54:464249 const auto kNetworkAnonymizationKey2 =
4250 NetworkAnonymizationKey::CreateSameSite(kSite2);
Matt Menkeb32ba5122019-09-10 19:17:054251
4252 base::test::ScopedFeatureList feature_list;
4253 feature_list.InitWithFeatures(
4254 // enabled_features
4255 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4256 features::kPartitionConnectionsByNetworkIsolationKey},
4257 // disabled_features
4258 {});
4259 // Since HttpServerProperties caches the feature value, have to create a new
4260 // one.
4261 http_server_properties_ = std::make_unique<HttpServerProperties>();
4262
4263 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454264 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:194265 MockRead(kHttpRespData),
Matt Menkeb32ba5122019-09-10 19:17:054266 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4267 MockRead(ASYNC, OK)};
4268
4269 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4270 socket_factory_.AddSocketDataProvider(&http_data);
4271 AddCertificate(&ssl_data_);
4272 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4273
4274 MockQuicData mock_quic_data(version_);
4275 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:024276 mock_quic_data.AddWrite(SYNCHRONOUS,
4277 ConstructInitialSettingsPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:054278 mock_quic_data.AddWrite(
4279 SYNCHRONOUS,
4280 ConstructClientRequestHeadersPacket(
4281 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034282 GetRequestHeaders("GET", "https", "/")));
Matt Menkeb32ba5122019-09-10 19:17:054283 mock_quic_data.AddRead(
4284 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034285 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284286 GetResponseHeaders("200")));
Matt Menkeb32ba5122019-09-10 19:17:054287 mock_quic_data.AddRead(
4288 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034289 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:194290 ConstructDataFrame(kQuicRespData)));
Matt Menkeb32ba5122019-09-10 19:17:054291 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344292 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menkeb32ba5122019-09-10 19:17:054293 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214294 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Matt Menkeb32ba5122019-09-10 19:17:054295
4296 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4297
4298 CreateSession();
4299
4300 AlternativeService alternative_service(kProtoQUIC,
4301 HostPortPair::FromURL(request_.url));
4302 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014303 alternative_service, kNetworkAnonymizationKey1);
Matt Menkeb32ba5122019-09-10 19:17:054304 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014305 alternative_service, kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:054306 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014307 alternative_service, kNetworkAnonymizationKey1));
Matt Menkeb32ba5122019-09-10 19:17:054308 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014309 alternative_service, kNetworkAnonymizationKey2));
Matt Menkeb32ba5122019-09-10 19:17:054310
4311 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:524312 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Andrew Williams826d8742024-01-31 19:39:194313 SendRequestAndExpectHttpResponse(kHttpRespData);
4314 SendRequestAndExpectQuicResponse(kQuicRespData);
Matt Menkeb32ba5122019-09-10 19:17:054315
4316 mock_quic_data.Resume();
4317
4318 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014319 alternative_service, kNetworkAnonymizationKey1));
Matt Menkeb32ba5122019-09-10 19:17:054320 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4321 url::SchemeHostPort("https", request_.url.host(), 443),
Brianna Goldstein02cb74f2022-09-29 05:41:014322 kNetworkAnonymizationKey1));
Matt Menkeb32ba5122019-09-10 19:17:054323 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Brianna Goldstein02cb74f2022-09-29 05:41:014324 alternative_service, kNetworkAnonymizationKey2));
Matt Menkeb32ba5122019-09-10 19:17:054325 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4326 url::SchemeHostPort("https", request_.url.host(), 443),
Brianna Goldstein02cb74f2022-09-29 05:41:014327 kNetworkAnonymizationKey2));
Matt Menkeb32ba5122019-09-10 19:17:054328}
4329
bncc958faa2015-07-31 18:14:524330TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
Ryan Hamiltona51800a2022-02-12 19:34:354331 if (version_.AlpnDeferToRFCv1()) {
4332 // These versions currently do not support Alt-Svc.
4333 return;
4334 }
bncc958faa2015-07-31 18:14:524335 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:454336 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:194337 MockRead(kHttpRespData),
bncc958faa2015-07-31 18:14:524338 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4339 MockRead(ASYNC, OK)};
4340
Ryan Sleevib8d7ea02018-05-07 20:01:014341 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524342 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564343 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524344
Ryan Hamiltonabad59e2019-06-06 04:02:594345 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234346 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:024347 mock_quic_data.AddWrite(SYNCHRONOUS,
4348 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:364349 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234350 SYNCHRONOUS,
4351 ConstructClientRequestHeadersPacket(
4352 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034353 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434354 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334355 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034356 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284357 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334358 mock_quic_data.AddRead(
4359 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034360 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Bence Béky319388a882020-09-23 18:42:524361 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234362 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344363 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:524364 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4365
4366 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4367
4368 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324369 CreateSession();
bncc958faa2015-07-31 18:14:524370
4371 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
Andrew Williams826d8742024-01-31 19:39:194372 SendRequestAndExpectHttpResponse(kHttpRespData);
bncc958faa2015-07-31 18:14:524373}
4374
bnc1c196c6e2016-05-28 13:51:484375TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
Ryan Hamiltona51800a2022-02-12 19:34:354376 if (version_.AlpnDeferToRFCv1()) {
4377 // These versions currently do not support Alt-Svc.
4378 return;
4379 }
[email protected]dda75ab2013-06-22 22:43:304380 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274381 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304382
4383 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564384 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294385 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564386 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304387
Ryan Hamiltona2dcbae2022-02-09 19:02:454388 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4389 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:194390 MockRead(SYNCHRONOUS, 5, kHttpRespData),
Ryan Hamiltona2dcbae2022-02-09 19:02:454391 MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304392
Ryan Sleevib8d7ea02018-05-07 20:01:014393 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504394 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084395 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504396 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304397
4398 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454399 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304400 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454401 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304402 };
Ryan Sleevib8d7ea02018-05-07 20:01:014403 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504404 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304405
4406 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014407 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504408 socket_factory_.AddSocketDataProvider(&http_data2);
4409 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304410
bnc912a04b2016-04-20 14:19:504411 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304412
4413 // Run the first request.
Andrew Williams826d8742024-01-31 19:39:194414 SendRequestAndExpectHttpResponse(kHttpRespData);
rch37de576c2015-05-17 20:28:174415 ASSERT_TRUE(http_data.AllReadDataConsumed());
4416 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304417
4418 // Now run the second request in which the QUIC socket hangs,
4419 // and verify the the transaction continues over HTTP.
Andrew Williams826d8742024-01-31 19:39:194420 SendRequestAndExpectHttpResponse(kHttpRespData);
mmenke651bae7f2015-12-18 21:26:454421 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304422
rch37de576c2015-05-17 20:28:174423 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4424 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454425 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304426}
4427
[email protected]1e960032013-12-20 19:00:204428TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594429 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164430 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494431 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:024432 mock_quic_data.AddWrite(SYNCHRONOUS,
4433 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi32f2fd02018-04-16 18:23:434434 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494435 SYNCHRONOUS,
4436 ConstructClientRequestHeadersPacket(
4437 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034438 GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:164439 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4440 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Zhongyi Shi32f2fd02018-04-16 18:23:434441 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334442 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034443 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284444 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334445 mock_quic_data.AddRead(
4446 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034447 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:194448 ConstructDataFrame(kQuicRespData)));
Nick Harper057264a82019-09-12 23:33:494449 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344450 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:504451 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214452 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
[email protected]8ba81212013-05-03 13:11:484453
rcha5399e02015-04-21 19:32:044454 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484455
rtennetib8e80fb2016-05-16 00:12:094456 // The non-alternate protocol job needs to hang in order to guarantee that
4457 // the alternate-protocol job will "win".
4458 AddHangingNonAlternateProtocolSocketData();
4459
rch3f4b8452016-02-23 16:59:324460 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274461 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yang1ef6dfef2021-07-24 16:20:164462 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4463 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264464 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Fan Yang1ef6dfef2021-07-24 16:20:164465 IsError(ERR_IO_PENDING));
4466 // Complete host resolution in next message loop so that QUIC job could
4467 // proceed.
4468 base::RunLoop().RunUntilIdle();
4469 // Explicitly confirm the handshake.
4470 crypto_client_stream_factory_.last_stream()
4471 ->NotifySessionOneRttKeyAvailable();
4472
4473 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
4474 mock_quic_data.Resume();
4475
4476 // Run the QUIC session to completion.
4477 base::RunLoop().RunUntilIdle();
4478
4479 EXPECT_THAT(callback.WaitForResult(), IsOk());
4480
4481 CheckWasQuicResponse(&trans);
Andrew Williams826d8742024-01-31 19:39:194482 CheckResponseData(&trans, kQuicRespData);
rchac7f35e2017-03-15 20:42:304483
Matt Menke19475f72019-08-21 18:57:444484 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4485 url::SchemeHostPort("https", request_.url.host(), 443),
Brianna Goldstein02cb74f2022-09-29 05:41:014486 NetworkAnonymizationKey()));
[email protected]8ba81212013-05-03 13:11:484487}
4488
[email protected]1e960032013-12-20 19:00:204489TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594490 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164491 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494492 int packet_number = 1;
Patrick Meenan885a00652023-02-15 20:07:024493 mock_quic_data.AddWrite(
4494 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Fan Yang32c5a112018-12-10 20:06:334495 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494496 SYNCHRONOUS,
4497 ConstructClientRequestHeadersPacket(
4498 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034499 GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:164500 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4501 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Zhongyi Shi32f2fd02018-04-16 18:23:434502 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334503 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034504 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284505 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334506 mock_quic_data.AddRead(
4507 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034508 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:194509 ConstructDataFrame(kQuicRespData)));
Nick Harper057264a82019-09-12 23:33:494510 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344511 ConstructClientAckPacket(packet_number++, 2, 1));
rchb27683c2015-07-29 23:53:504512 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214513 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
rcha5399e02015-04-21 19:32:044514 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274515
4516 // In order for a new QUIC session to be established via alternate-protocol
4517 // without racing an HTTP connection, we need the host resolution to happen
4518 // synchronously.
4519 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294520 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564521 "");
[email protected]3a120a6b2013-06-25 01:08:274522
rtennetib8e80fb2016-05-16 00:12:094523 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324524 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274525 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yang1ef6dfef2021-07-24 16:20:164526 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4527 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264528 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Fan Yang1ef6dfef2021-07-24 16:20:164529 IsError(ERR_IO_PENDING));
4530 // Complete host resolution in next message loop so that QUIC job could
4531 // proceed.
4532 base::RunLoop().RunUntilIdle();
4533 // Explicitly confirm the handshake.
4534 crypto_client_stream_factory_.last_stream()
4535 ->NotifySessionOneRttKeyAvailable();
4536
4537 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
4538 mock_quic_data.Resume();
4539
4540 // Run the QUIC session to completion.
4541 base::RunLoop().RunUntilIdle();
4542
4543 EXPECT_THAT(callback.WaitForResult(), IsOk());
4544
4545 CheckWasQuicResponse(&trans);
Andrew Williams826d8742024-01-31 19:39:194546 CheckResponseData(&trans, kQuicRespData);
[email protected]3a120a6b2013-06-25 01:08:274547}
4548
[email protected]0fc924b2014-03-31 04:34:154549TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ryan Hamiltona51800a2022-02-12 19:34:354550 if (version_.AlpnDeferToRFCv1()) {
4551 // These versions currently do not support Alt-Svc.
4552 return;
4553 }
Nicolas Arciniegad2013f92020-02-07 23:00:564554 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:004555 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
4556 {ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTP,
4557 "myproxy", 70)},
4558 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154559
4560 // Since we are using a proxy, the QUIC job will not succeed.
4561 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294562 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4563 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564564 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154565
Ryan Hamiltona2dcbae2022-02-09 19:02:454566 MockRead http_reads[] = {MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4567 MockRead(SYNCHRONOUS, 4, alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:194568 MockRead(SYNCHRONOUS, 5, kHttpRespData),
Ryan Hamiltona2dcbae2022-02-09 19:02:454569 MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154570
Ryan Sleevib8d7ea02018-05-07 20:01:014571 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154572 socket_factory_.AddSocketDataProvider(&http_data);
4573
4574 // In order for a new QUIC session to be established via alternate-protocol
4575 // without racing an HTTP connection, we need the host resolution to happen
4576 // synchronously.
4577 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294578 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564579 "");
[email protected]0fc924b2014-03-31 04:34:154580
rch9ae5b3b2016-02-11 00:36:294581 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324582 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274583 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Andrew Williams826d8742024-01-31 19:39:194584 SendRequestAndExpectHttpResponse(kHttpRespData);
[email protected]0fc924b2014-03-31 04:34:154585}
4586
[email protected]1e960032013-12-20 19:00:204587TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:594588 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234589 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164590 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024591 mock_quic_data.AddWrite(SYNCHRONOUS,
4592 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164593 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364594 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234595 SYNCHRONOUS,
4596 ConstructClientRequestHeadersPacket(
4597 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034598 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434599 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334600 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034601 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284602 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334603 mock_quic_data.AddRead(
4604 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034605 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:194606 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:234607 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344608 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:594609 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044610 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124611
rtennetib8e80fb2016-05-16 00:12:094612 // The non-alternate protocol job needs to hang in order to guarantee that
4613 // the alternate-protocol job will "win".
4614 AddHangingNonAlternateProtocolSocketData();
4615
[email protected]11c05872013-08-20 02:04:124616 // In order for a new QUIC session to be established via alternate-protocol
4617 // without racing an HTTP connection, we need the host resolution to happen
4618 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4619 // connection to the the server, in this test we require confirmation
4620 // before encrypting so the HTTP job will still start.
4621 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294622 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564623 "");
[email protected]11c05872013-08-20 02:04:124624
rch3f4b8452016-02-23 16:59:324625 CreateSession();
Dustin J. Mitchell795c7362024-01-18 16:50:524626 session_->quic_session_pool()->set_is_quic_known_to_work_on_current_network(
Matt Menkeb566c392019-09-11 23:22:434627 false);
Ryan Hamilton9835e662018-08-02 05:36:274628 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:124629
bnc691fda62016-08-12 00:43:164630 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:124631 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264632 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014633 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Liza Burakova80b8ebd2023-02-15 16:29:584634 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284635 crypto_client_stream_factory_.last_stream()
4636 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:014637 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:504638
bnc691fda62016-08-12 00:43:164639 CheckWasQuicResponse(&trans);
Andrew Williams826d8742024-01-31 19:39:194640 CheckResponseData(&trans, kQuicRespData);
[email protected]11c05872013-08-20 02:04:124641}
4642
Steven Valdez58097ec32018-07-16 18:29:044643TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:014644 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594645 MockQuicData mock_quic_data(version_);
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(
4648 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Steven Valdez58097ec32018-07-16 18:29:044649 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014650 SYNCHRONOUS,
4651 ConstructClientRequestHeadersPacket(
4652 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034653 GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334654 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024655 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034656 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284657 GetResponseHeaders("425")));
Patrick Meenan885a00652023-02-15 20:07:024658 mock_quic_data.AddWrite(
4659 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034660 packet_number++, GetQpackDecoderStreamId(), 1, 1, false,
4661 StreamCancellationQpackDecoderInstruction(0)));
Patrick Meenan885a00652023-02-15 20:07:024662 mock_quic_data.AddWrite(
4663 SYNCHRONOUS,
4664 client_maker_->MakeRstPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034665 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Patrick Meenan885a00652023-02-15 20:07:024666 quic::QUIC_STREAM_CANCELLED));
Steven Valdez58097ec32018-07-16 18:29:044667
Zhongyi Shi1c022d22020-03-20 19:00:164668 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:044669
Steven Valdez58097ec32018-07-16 18:29:044670 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014671 SYNCHRONOUS,
4672 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034673 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), true,
4674 GetRequestHeaders("GET", "https", "/")));
Steven Valdez58097ec32018-07-16 18:29:044675 mock_quic_data.AddRead(
4676 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034677 2, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284678 GetResponseHeaders("200")));
Steven Valdez58097ec32018-07-16 18:29:044679 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334680 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034681 3, GetNthClientInitiatedBidirectionalStreamId(1), true,
Andrew Williams826d8742024-01-31 19:39:194682 ConstructDataFrame(kQuicRespData)));
Renjie Tangb7afea82020-07-15 23:35:474683 mock_quic_data.AddWrite(SYNCHRONOUS,
4684 ConstructClientAckPacket(packet_number++, 3, 1));
Steven Valdez58097ec32018-07-16 18:29:044685 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214686 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Steven Valdez58097ec32018-07-16 18:29:044687
4688 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4689
4690 // In order for a new QUIC session to be established via alternate-protocol
4691 // without racing an HTTP connection, we need the host resolution to happen
4692 // synchronously.
4693 host_resolver_.set_synchronous_mode(true);
4694 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4695 "");
Steven Valdez58097ec32018-07-16 18:29:044696
4697 AddHangingNonAlternateProtocolSocketData();
4698 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274699 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Dustin J. Mitchell795c7362024-01-18 16:50:524700 QuicSessionPoolPeer::SetAlarmFactory(
4701 session_->quic_session_pool(),
Fan Yangc9e00dc2018-10-09 14:17:564702 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224703 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:044704
4705 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4706 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264707 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Steven Valdez58097ec32018-07-16 18:29:044708 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4709
4710 // Confirm the handshake after the 425 Too Early.
4711 base::RunLoop().RunUntilIdle();
4712
4713 // The handshake hasn't been confirmed yet, so the retry should not have
4714 // succeeded.
4715 EXPECT_FALSE(callback.have_result());
4716
Fan Yang3673cc72020-02-07 14:49:284717 crypto_client_stream_factory_.last_stream()
4718 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:044719
4720 EXPECT_THAT(callback.WaitForResult(), IsOk());
4721 CheckWasQuicResponse(&trans);
Andrew Williams826d8742024-01-31 19:39:194722 CheckResponseData(&trans, kQuicRespData);
Steven Valdez58097ec32018-07-16 18:29:044723}
4724
4725TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:014726 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594727 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164728 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024729 mock_quic_data.AddWrite(
4730 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Steven Valdez58097ec32018-07-16 18:29:044731 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014732 SYNCHRONOUS,
4733 ConstructClientRequestHeadersPacket(
4734 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034735 GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334736 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024737 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034738 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284739 GetResponseHeaders("425")));
Patrick Meenan885a00652023-02-15 20:07:024740 mock_quic_data.AddWrite(
4741 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034742 packet_number++, GetQpackDecoderStreamId(), 1, 1, false,
4743 StreamCancellationQpackDecoderInstruction(0)));
Patrick Meenan885a00652023-02-15 20:07:024744 mock_quic_data.AddWrite(
4745 SYNCHRONOUS,
4746 client_maker_->MakeRstPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034747 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Patrick Meenan885a00652023-02-15 20:07:024748 quic::QUIC_STREAM_CANCELLED));
Steven Valdez58097ec32018-07-16 18:29:044749
Zhongyi Shi1c022d22020-03-20 19:00:164750 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:044751
Steven Valdez58097ec32018-07-16 18:29:044752 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014753 SYNCHRONOUS,
4754 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034755 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), true,
4756 GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334757 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024758 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034759 2, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284760 GetResponseHeaders("425")));
Patrick Meenan885a00652023-02-15 20:07:024761 mock_quic_data.AddWrite(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034762 SYNCHRONOUS, ConstructClientAckAndDataPacket(
4763 packet_number++, GetQpackDecoderStreamId(), 2, 1, false,
4764 StreamCancellationQpackDecoderInstruction(1, false)));
Patrick Meenan885a00652023-02-15 20:07:024765 mock_quic_data.AddWrite(
4766 SYNCHRONOUS,
4767 client_maker_->MakeRstPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034768 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
Patrick Meenan885a00652023-02-15 20:07:024769 quic::QUIC_STREAM_CANCELLED));
Steven Valdez58097ec32018-07-16 18:29:044770 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:214771 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Steven Valdez58097ec32018-07-16 18:29:044772
4773 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4774
4775 // In order for a new QUIC session to be established via alternate-protocol
4776 // without racing an HTTP connection, we need the host resolution to happen
4777 // synchronously.
4778 host_resolver_.set_synchronous_mode(true);
4779 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4780 "");
Steven Valdez58097ec32018-07-16 18:29:044781
4782 AddHangingNonAlternateProtocolSocketData();
4783 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274784 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Dustin J. Mitchell795c7362024-01-18 16:50:524785 QuicSessionPoolPeer::SetAlarmFactory(
4786 session_->quic_session_pool(),
Fan Yangc9e00dc2018-10-09 14:17:564787 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224788 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:044789
4790 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4791 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264792 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Steven Valdez58097ec32018-07-16 18:29:044793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4794
4795 // Confirm the handshake after the 425 Too Early.
4796 base::RunLoop().RunUntilIdle();
4797
4798 // The handshake hasn't been confirmed yet, so the retry should not have
4799 // succeeded.
4800 EXPECT_FALSE(callback.have_result());
4801
Fan Yang3673cc72020-02-07 14:49:284802 crypto_client_stream_factory_.last_stream()
4803 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:044804
4805 EXPECT_THAT(callback.WaitForResult(), IsOk());
4806 const HttpResponseInfo* response = trans.GetResponseInfo();
4807 ASSERT_TRUE(response != nullptr);
4808 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:284809 EXPECT_EQ("HTTP/1.1 425", response->headers->GetStatusLine());
Steven Valdez58097ec32018-07-16 18:29:044810 EXPECT_TRUE(response->was_fetched_via_spdy);
4811 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:084812 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
4813 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:044814}
4815
zhongyica364fbb2015-12-12 03:39:124816TEST_P(QuicNetworkTransactionTest,
4817 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Victor Vasilieva1e66d72019-12-05 17:55:384818 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:594819 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234820 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164821 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024822 mock_quic_data.AddWrite(SYNCHRONOUS,
4823 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164824 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364825 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234826 SYNCHRONOUS,
4827 ConstructClientRequestHeadersPacket(
4828 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034829 GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:124830 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:524831 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:434832 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:124833 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4834
4835 // The non-alternate protocol job needs to hang in order to guarantee that
4836 // the alternate-protocol job will "win".
4837 AddHangingNonAlternateProtocolSocketData();
4838
4839 // In order for a new QUIC session to be established via alternate-protocol
4840 // without racing an HTTP connection, we need the host resolution to happen
4841 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4842 // connection to the the server, in this test we require confirmation
4843 // before encrypting so the HTTP job will still start.
4844 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294845 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:124846 "");
zhongyica364fbb2015-12-12 03:39:124847
rch3f4b8452016-02-23 16:59:324848 CreateSession();
Dustin J. Mitchell795c7362024-01-18 16:50:524849 session_->quic_session_pool()->set_is_quic_known_to_work_on_current_network(
Matt Menkeb566c392019-09-11 23:22:434850 false);
Ryan Hamilton9835e662018-08-02 05:36:274851 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:124852
bnc691fda62016-08-12 00:43:164853 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:124854 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264855 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014856 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Liza Burakova80b8ebd2023-02-15 16:29:584857 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284858 crypto_client_stream_factory_.last_stream()
4859 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:014860 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:124861
4862 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524863 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124864
bnc691fda62016-08-12 00:43:164865 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:124866 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:524867 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
4868 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124869}
4870
4871TEST_P(QuicNetworkTransactionTest,
4872 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Victor Vasilieva1e66d72019-12-05 17:55:384873 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:594874 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234875 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164876 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024877 mock_quic_data.AddWrite(SYNCHRONOUS,
4878 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164879 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364880 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234881 SYNCHRONOUS,
4882 ConstructClientRequestHeadersPacket(
4883 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034884 GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:214885 // Peer sending data from an non-existing stream causes this end to raise
4886 // error and close connection.
Tsuyoshi Horoea15e7a2023-05-23 00:12:034887 mock_quic_data.AddRead(ASYNC,
4888 ConstructServerRstPacket(
4889 1, GetNthClientInitiatedBidirectionalStreamId(47),
4890 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:214891 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:374892 mock_quic_data.AddWrite(
Renjie Tang248e36ea2020-06-26 00:12:344893 SYNCHRONOUS,
4894 ConstructClientAckAndConnectionClosePacket(
Patrick Meenan885a00652023-02-15 20:07:024895 packet_num++, 1, 1, quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
4896 quic_error_details, quic::IETF_STOP_SENDING));
zhongyica364fbb2015-12-12 03:39:124897 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4898
4899 // The non-alternate protocol job needs to hang in order to guarantee that
4900 // the alternate-protocol job will "win".
4901 AddHangingNonAlternateProtocolSocketData();
4902
4903 // In order for a new QUIC session to be established via alternate-protocol
4904 // without racing an HTTP connection, we need the host resolution to happen
4905 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4906 // connection to the the server, in this test we require confirmation
4907 // before encrypting so the HTTP job will still start.
4908 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294909 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:124910 "");
zhongyica364fbb2015-12-12 03:39:124911
rch3f4b8452016-02-23 16:59:324912 CreateSession();
Dustin J. Mitchell795c7362024-01-18 16:50:524913 session_->quic_session_pool()->set_is_quic_known_to_work_on_current_network(
Matt Menkeb566c392019-09-11 23:22:434914 false);
Ryan Hamilton9835e662018-08-02 05:36:274915 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:124916
bnc691fda62016-08-12 00:43:164917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:124918 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264919 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Liza Burakova80b8ebd2023-02-15 16:29:584921 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284922 crypto_client_stream_factory_.last_stream()
4923 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:014924 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:124925 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524926 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124927
bnc691fda62016-08-12 00:43:164928 trans.PopulateNetErrorDetails(&details);
Patrick Meenan885a00652023-02-15 20:07:024929 EXPECT_EQ(quic::QUIC_HTTP_STREAM_WRONG_DIRECTION,
Renjie Tang248e36ea2020-06-26 00:12:344930 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124931}
4932
Nick Harper057264a82019-09-12 23:33:494933TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:594934 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234935 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164936 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:024937 mock_quic_data.AddWrite(SYNCHRONOUS,
4938 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:164939 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364940 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234941 SYNCHRONOUS,
4942 ConstructClientRequestHeadersPacket(
4943 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:034944 GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:484945 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:334946 mock_quic_data.AddRead(
4947 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034948 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:284949 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:334950 mock_quic_data.AddRead(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034951 ASYNC,
4952 ConstructServerRstPacket(2, GetNthClientInitiatedBidirectionalStreamId(0),
4953 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:074954
Patrick Meenan885a00652023-02-15 20:07:024955 mock_quic_data.AddWrite(
4956 SYNCHRONOUS,
4957 client_maker_->MakeAckRstAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:034958 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Patrick Meenan885a00652023-02-15 20:07:024959 quic::QUIC_STREAM_CANCELLED, 2, 1, GetQpackDecoderStreamId(), false,
4960 StreamCancellationQpackDecoderInstruction(0)));
rchcd5f1c62016-06-23 02:43:484961 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
4962 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4963
4964 // The non-alternate protocol job needs to hang in order to guarantee that
4965 // the alternate-protocol job will "win".
4966 AddHangingNonAlternateProtocolSocketData();
4967
4968 // In order for a new QUIC session to be established via alternate-protocol
4969 // without racing an HTTP connection, we need the host resolution to happen
4970 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4971 // connection to the the server, in this test we require confirmation
4972 // before encrypting so the HTTP job will still start.
4973 host_resolver_.set_synchronous_mode(true);
4974 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4975 "");
rchcd5f1c62016-06-23 02:43:484976
4977 CreateSession();
Dustin J. Mitchell795c7362024-01-18 16:50:524978 session_->quic_session_pool()->set_is_quic_known_to_work_on_current_network(
Matt Menkeb566c392019-09-11 23:22:434979 false);
Ryan Hamilton9835e662018-08-02 05:36:274980 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:484981
bnc691fda62016-08-12 00:43:164982 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:484983 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:264984 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:014985 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:484986
Liza Burakova80b8ebd2023-02-15 16:29:584987 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:284988 crypto_client_stream_factory_.last_stream()
4989 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:484990 // Read the headers.
robpercival214763f2016-07-01 23:27:014991 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:484992
bnc691fda62016-08-12 00:43:164993 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:484994 ASSERT_TRUE(response != nullptr);
4995 ASSERT_TRUE(response->headers.get() != nullptr);
Andrew Williams826d8742024-01-31 19:39:194996 EXPECT_EQ(kQuic200RespStatusLine, response->headers->GetStatusLine());
rchcd5f1c62016-06-23 02:43:484997 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:524998 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:084999 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5000 response->connection_info);
rchcd5f1c62016-06-23 02:43:485001
5002 std::string response_data;
bnc691fda62016-08-12 00:43:165003 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485004}
5005
Nick Harper057264a82019-09-12 23:33:495006TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:385007 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595008 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235009 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165010 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:025011 mock_quic_data.AddWrite(SYNCHRONOUS,
5012 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:165013 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365014 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235015 SYNCHRONOUS,
5016 ConstructClientRequestHeadersPacket(
5017 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035018 GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335019 mock_quic_data.AddRead(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035020 ASYNC,
5021 ConstructServerRstPacket(1, GetNthClientInitiatedBidirectionalStreamId(0),
5022 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075023
Patrick Meenan885a00652023-02-15 20:07:025024 mock_quic_data.AddWrite(
5025 SYNCHRONOUS,
5026 client_maker_->MakeAckRstAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035027 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Patrick Meenan885a00652023-02-15 20:07:025028 quic::QUIC_STREAM_CANCELLED, 1, 1, GetQpackDecoderStreamId(), false,
5029 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:075030
rchcd5f1c62016-06-23 02:43:485031 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5032 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5033
5034 // The non-alternate protocol job needs to hang in order to guarantee that
5035 // the alternate-protocol job will "win".
5036 AddHangingNonAlternateProtocolSocketData();
5037
5038 // In order for a new QUIC session to be established via alternate-protocol
5039 // without racing an HTTP connection, we need the host resolution to happen
5040 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5041 // connection to the the server, in this test we require confirmation
5042 // before encrypting so the HTTP job will still start.
5043 host_resolver_.set_synchronous_mode(true);
5044 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5045 "");
rchcd5f1c62016-06-23 02:43:485046
5047 CreateSession();
Dustin J. Mitchell795c7362024-01-18 16:50:525048 session_->quic_session_pool()->set_is_quic_known_to_work_on_current_network(
Matt Menkeb566c392019-09-11 23:22:435049 false);
Ryan Hamilton9835e662018-08-02 05:36:275050 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485051
bnc691fda62016-08-12 00:43:165052 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485053 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265054 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485056
Liza Burakova80b8ebd2023-02-15 16:29:585057 base::RunLoop().RunUntilIdle();
Fan Yang3673cc72020-02-07 14:49:285058 crypto_client_stream_factory_.last_stream()
5059 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:485060 // Read the headers.
robpercival214763f2016-07-01 23:27:015061 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485062}
5063
[email protected]1e960032013-12-20 19:00:205064TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305065 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525066 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585067 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305068 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505069 MockRead(ASYNC, close->data(), close->length()),
5070 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5071 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305072 };
Ryan Sleevib8d7ea02018-05-07 20:01:015073 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305074 socket_factory_.AddSocketDataProvider(&quic_data);
5075
5076 // Main job which will succeed even though the alternate job fails.
5077 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025078 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5079 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5080 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305081
Ryan Sleevib8d7ea02018-05-07 20:01:015082 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305083 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565084 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305085
rch3f4b8452016-02-23 16:59:325086 CreateSession();
David Schinazic8281052019-01-24 06:14:175087 AddQuicAlternateProtocolMapping(
5088 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195089 SendRequestAndExpectHttpResponse("hello from http");
5090 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305091}
5092
Matt Menkeb32ba5122019-09-10 19:17:055093TEST_P(QuicNetworkTransactionTest,
5094 BrokenAlternateProtocolWithNetworkIsolationKey) {
Matt Menke4807a9a2020-11-21 00:14:415095 const SchemefulSite kSite1(GURL("https://foo.test/"));
5096 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Dustin J. Mitchell1d774ea2023-03-03 00:54:465097 const auto kNetworkAnonymizationKey1 =
5098 NetworkAnonymizationKey::CreateSameSite(kSite1);
Matt Menke4807a9a2020-11-21 00:14:415099 const SchemefulSite kSite2(GURL("https://bar.test/"));
5100 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Dustin J. Mitchell1d774ea2023-03-03 00:54:465101 const auto kNetworkAnonymizationKey2 =
5102 NetworkAnonymizationKey::CreateSameSite(kSite2);
Matt Menkeb32ba5122019-09-10 19:17:055103
5104 base::test::ScopedFeatureList feature_list;
5105 feature_list.InitWithFeatures(
5106 // enabled_features
5107 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5108 features::kPartitionConnectionsByNetworkIsolationKey},
5109 // disabled_features
5110 {});
5111 // Since HttpServerProperties caches the feature value, have to create a new
5112 // one.
5113 http_server_properties_ = std::make_unique<HttpServerProperties>();
5114
5115 // Alternate-protocol job
5116 std::unique_ptr<quic::QuicEncryptedPacket> close(
5117 ConstructServerConnectionClosePacket(1));
5118 MockRead quic_reads[] = {
5119 MockRead(ASYNC, close->data(), close->length()),
5120 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5121 MockRead(ASYNC, OK), // EOF
5122 };
5123 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5124 socket_factory_.AddSocketDataProvider(&quic_data);
5125
5126 // Main job which will succeed even though the alternate job fails.
5127 MockRead http_reads[] = {
5128 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5129 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5130 MockRead(ASYNC, OK)};
5131
5132 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5133 socket_factory_.AddSocketDataProvider(&http_data);
5134 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5135
5136 CreateSession();
5137 AddQuicAlternateProtocolMapping(
Brianna Goldstein02cb74f2022-09-29 05:41:015138 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT,
5139 kNetworkAnonymizationKey1);
Matt Menkeb32ba5122019-09-10 19:17:055140 AddQuicAlternateProtocolMapping(
Brianna Goldstein02cb74f2022-09-29 05:41:015141 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT,
5142 kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:055143 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:525144 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Menkeb32ba5122019-09-10 19:17:055145 SendRequestAndExpectHttpResponse("hello from http");
5146
Brianna Goldstein02cb74f2022-09-29 05:41:015147 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
5148 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:055149}
5150
[email protected]1e960032013-12-20 19:00:205151TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595152 // Alternate-protocol job
5153 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025154 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595155 };
Ryan Sleevib8d7ea02018-05-07 20:01:015156 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595157 socket_factory_.AddSocketDataProvider(&quic_data);
5158
5159 // Main job which will succeed even though the alternate job fails.
5160 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025161 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5162 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5163 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595164
Ryan Sleevib8d7ea02018-05-07 20:01:015165 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595166 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565167 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595168
rch3f4b8452016-02-23 16:59:325169 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595170
Ryan Hamilton9835e662018-08-02 05:36:275171 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195172 SendRequestAndExpectHttpResponse("hello from http");
5173 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595174}
5175
[email protected]00c159f2014-05-21 22:38:165176TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535177 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165178 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025179 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165180 };
Ryan Sleevib8d7ea02018-05-07 20:01:015181 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165182 socket_factory_.AddSocketDataProvider(&quic_data);
5183
[email protected]eb71ab62014-05-23 07:57:535184 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165185 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025186 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165187 };
5188
Ryan Sleevib8d7ea02018-05-07 20:01:015189 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165190 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5191 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565192 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165193
rtennetib8e80fb2016-05-16 00:12:095194 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325195 CreateSession();
[email protected]00c159f2014-05-21 22:38:165196
Ryan Hamilton9835e662018-08-02 05:36:275197 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165198 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165199 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265200 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015201 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5202 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165203 ExpectQuicAlternateProtocolMapping();
5204}
5205
Zhongyi Shia0cef1082017-08-25 01:49:505206TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5207 // Tests that TCP job is delayed and QUIC job does not require confirmation
5208 // if QUIC was recently supported on the same IP on start.
5209
5210 // Set QUIC support on the last IP address, which is same with the local IP
5211 // address. Require confirmation mode will be turned off immediately when
5212 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435213 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5214 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:505215
Ryan Hamiltonabad59e2019-06-06 04:02:595216 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165217 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495218 int packet_number = 1;
Patrick Meenan885a00652023-02-15 20:07:025219 mock_quic_data.AddWrite(SYNCHRONOUS,
5220 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:435221 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495222 SYNCHRONOUS,
5223 ConstructClientRequestHeadersPacket(
5224 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035225 GetRequestHeaders("GET", "https", "/")));
Fan Yang1ef6dfef2021-07-24 16:20:165226 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5227 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
Zhongyi Shi32f2fd02018-04-16 18:23:435228 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335229 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035230 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285231 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335232 mock_quic_data.AddRead(
5233 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035234 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:195235 ConstructDataFrame(kQuicRespData)));
Nick Harper057264a82019-09-12 23:33:495236 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345237 ConstructClientAckPacket(packet_number++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505238 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215239 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Zhongyi Shia0cef1082017-08-25 01:49:505240
5241 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5242 // No HTTP data is mocked as TCP job never starts in this case.
5243
5244 CreateSession();
Dustin J. Mitchell795c7362024-01-18 16:50:525245 // QuicSessionPool by default requires confirmation on construction.
5246 session_->quic_session_pool()->set_is_quic_known_to_work_on_current_network(
Matt Menkeb566c392019-09-11 23:22:435247 false);
Zhongyi Shia0cef1082017-08-25 01:49:505248
Ryan Hamilton9835e662018-08-02 05:36:275249 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505250
5251 // Stall host resolution so that QUIC job will not succeed synchronously.
5252 // Socket will not be configured immediately and QUIC support is not sorted
5253 // out, TCP job will still be delayed as server properties indicates QUIC
5254 // support on last IP address.
5255 host_resolver_.set_synchronous_mode(false);
5256
5257 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5258 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265259 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Zhongyi Shia0cef1082017-08-25 01:49:505260 IsError(ERR_IO_PENDING));
5261 // Complete host resolution in next message loop so that QUIC job could
5262 // proceed.
5263 base::RunLoop().RunUntilIdle();
Fan Yang1ef6dfef2021-07-24 16:20:165264 // Explicitly confirm the handshake.
5265 crypto_client_stream_factory_.last_stream()
5266 ->NotifySessionOneRttKeyAvailable();
5267
5268 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
5269 mock_quic_data.Resume();
5270
5271 // Run the QUIC session to completion.
5272 base::RunLoop().RunUntilIdle();
Zhongyi Shia0cef1082017-08-25 01:49:505273 EXPECT_THAT(callback.WaitForResult(), IsOk());
5274
5275 CheckWasQuicResponse(&trans);
Andrew Williams826d8742024-01-31 19:39:195276 CheckResponseData(&trans, kQuicRespData);
Zhongyi Shia0cef1082017-08-25 01:49:505277}
5278
5279TEST_P(QuicNetworkTransactionTest,
5280 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5281 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5282 // was recently supported on a different IP address on start.
5283
5284 // Set QUIC support on the last IP address, which is different with the local
5285 // IP address. Require confirmation mode will remain when local IP address is
5286 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435287 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5288 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:505289
Ryan Hamiltonabad59e2019-06-06 04:02:595290 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235291 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165292 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Patrick Meenan885a00652023-02-15 20:07:025293 mock_quic_data.AddWrite(SYNCHRONOUS,
5294 ConstructInitialSettingsPacket(packet_num++));
Zhongyi Shi1c022d22020-03-20 19:00:165295 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:505296 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235297 SYNCHRONOUS,
5298 ConstructClientRequestHeadersPacket(
5299 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035300 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435301 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335302 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035303 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285304 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335305 mock_quic_data.AddRead(
5306 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035307 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:195308 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:235309 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345310 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505311 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5312 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5313 // No HTTP data is mocked as TCP job will be delayed and never starts.
5314
5315 CreateSession();
Dustin J. Mitchell795c7362024-01-18 16:50:525316 session_->quic_session_pool()->set_is_quic_known_to_work_on_current_network(
Matt Menkeb566c392019-09-11 23:22:435317 false);
Ryan Hamilton9835e662018-08-02 05:36:275318 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505319
5320 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5321 // Socket will not be configured immediately and QUIC support is not sorted
5322 // out, TCP job will still be delayed as server properties indicates QUIC
5323 // support on last IP address.
5324 host_resolver_.set_synchronous_mode(false);
5325
5326 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5327 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265328 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_with_source_),
Zhongyi Shia0cef1082017-08-25 01:49:505329 IsError(ERR_IO_PENDING));
5330
5331 // Complete host resolution in next message loop so that QUIC job could
5332 // proceed.
5333 base::RunLoop().RunUntilIdle();
5334 // Explicitly confirm the handshake so that QUIC job could succeed.
Fan Yang3673cc72020-02-07 14:49:285335 crypto_client_stream_factory_.last_stream()
5336 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia0cef1082017-08-25 01:49:505337 EXPECT_THAT(callback.WaitForResult(), IsOk());
5338
5339 CheckWasQuicResponse(&trans);
Andrew Williams826d8742024-01-31 19:39:195340 CheckResponseData(&trans, kQuicRespData);
Zhongyi Shia0cef1082017-08-25 01:49:505341}
5342
Ryan Hamilton75f197262017-08-17 14:00:075343TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5344 // Test that NetErrorDetails is correctly populated, even if the
5345 // handshake has not yet been confirmed and no stream has been created.
5346
5347 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595348 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075349 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5350 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5351 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5352
5353 // Main job will also fail.
5354 MockRead http_reads[] = {
5355 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5356 };
5357
Ryan Sleevib8d7ea02018-05-07 20:01:015358 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075359 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5360 socket_factory_.AddSocketDataProvider(&http_data);
5361 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5362
5363 AddHangingNonAlternateProtocolSocketData();
5364 CreateSession();
5365 // Require handshake confirmation to ensure that no QUIC streams are
5366 // created, and to ensure that the TCP job does not wait for the QUIC
5367 // job to fail before it starts.
Dustin J. Mitchell795c7362024-01-18 16:50:525368 session_->quic_session_pool()->set_is_quic_known_to_work_on_current_network(
Matt Menkeb566c392019-09-11 23:22:435369 false);
Ryan Hamilton75f197262017-08-17 14:00:075370
Ryan Hamilton9835e662018-08-02 05:36:275371 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075372 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5373 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265374 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton75f197262017-08-17 14:00:075375 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5376 // Allow the TCP job to fail.
5377 base::RunLoop().RunUntilIdle();
5378 // Now let the QUIC job fail.
5379 mock_quic_data.Resume();
5380 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5381 ExpectQuicAlternateProtocolMapping();
5382 NetErrorDetails details;
5383 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525384 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075385}
5386
[email protected]1e960032013-12-20 19:00:205387TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455388 // Alternate-protocol job
5389 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025390 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455391 };
Ryan Sleevib8d7ea02018-05-07 20:01:015392 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455393 socket_factory_.AddSocketDataProvider(&quic_data);
5394
[email protected]c92c1b52014-05-31 04:16:065395 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015396 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065397 socket_factory_.AddSocketDataProvider(&quic_data2);
5398
[email protected]4d283b32013-10-17 12:57:275399 // Final job that will proceed when the QUIC job fails.
5400 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025401 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5402 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5403 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275404
Ryan Sleevib8d7ea02018-05-07 20:01:015405 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275406 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565407 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275408
rch3f4b8452016-02-23 16:59:325409 CreateSession();
[email protected]77c6c162013-08-17 02:57:455410
Ryan Hamilton9835e662018-08-02 05:36:275411 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455412
[email protected]4d283b32013-10-17 12:57:275413 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455414
5415 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275416
rch37de576c2015-05-17 20:28:175417 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5418 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455419}
5420
Matt Menkeb32ba5122019-09-10 19:17:055421TEST_P(QuicNetworkTransactionTest,
5422 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
5423 base::test::ScopedFeatureList feature_list;
5424 feature_list.InitWithFeatures(
5425 // enabled_features
5426 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5427 features::kPartitionConnectionsByNetworkIsolationKey},
5428 // disabled_features
5429 {});
5430 // Since HttpServerProperties caches the feature value, have to create a new
5431 // one.
5432 http_server_properties_ = std::make_unique<HttpServerProperties>();
5433
Matt Menke4807a9a2020-11-21 00:14:415434 const SchemefulSite kSite1(GURL("https://foo.test/"));
5435 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
Dustin J. Mitchell1d774ea2023-03-03 00:54:465436 const auto kNetworkAnonymizationKey1 =
5437 NetworkAnonymizationKey::CreateSameSite(kSite1);
Matt Menke4807a9a2020-11-21 00:14:415438 const SchemefulSite kSite2(GURL("https://bar.test/"));
5439 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Dustin J. Mitchell1d774ea2023-03-03 00:54:465440 const auto kNetworkAnonymizationKey2 =
5441 NetworkAnonymizationKey::CreateSameSite(kSite2);
Matt Menkeb32ba5122019-09-10 19:17:055442
5443 // Alternate-protocol job
5444 MockRead quic_reads[] = {
5445 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5446 };
5447 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5448 socket_factory_.AddSocketDataProvider(&quic_data);
5449
5450 // Second Alternate-protocol job which will race with the TCP job.
5451 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
5452 socket_factory_.AddSocketDataProvider(&quic_data2);
5453
5454 // Final job that will proceed when the QUIC job fails.
5455 MockRead http_reads[] = {
5456 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5457 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5458 MockRead(ASYNC, OK)};
5459
5460 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5461 socket_factory_.AddSocketDataProvider(&http_data);
5462 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5463
5464 CreateSession();
5465
5466 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
Brianna Goldstein02cb74f2022-09-29 05:41:015467 kNetworkAnonymizationKey1);
Matt Menkeb32ba5122019-09-10 19:17:055468 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
Brianna Goldstein02cb74f2022-09-29 05:41:015469 kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:055470
5471 request_.network_isolation_key = kNetworkIsolationKey1;
Brianna Goldstein314ddf722022-09-24 02:00:525472 request_.network_anonymization_key = kNetworkAnonymizationKey1;
Matt Menkeb32ba5122019-09-10 19:17:055473 SendRequestAndExpectHttpResponse("hello from http");
5474 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5475 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
5476
Brianna Goldstein02cb74f2022-09-29 05:41:015477 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
5478 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:055479
5480 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
5481 AddHttpDataAndRunRequest();
5482 // Requests using other NetworkIsolationKeys can still use QUIC.
5483 request_.network_isolation_key = kNetworkIsolationKey2;
Brianna Goldstein314ddf722022-09-24 02:00:525484 request_.network_anonymization_key = kNetworkAnonymizationKey2;
5485
Matt Menkeb32ba5122019-09-10 19:17:055486 AddQuicDataAndRunRequest();
5487
5488 // The last two requests should not have changed the alternative service
5489 // mappings.
Brianna Goldstein02cb74f2022-09-29 05:41:015490 ExpectBrokenAlternateProtocolMapping(kNetworkAnonymizationKey1);
5491 ExpectQuicAlternateProtocolMapping(kNetworkAnonymizationKey2);
Matt Menkeb32ba5122019-09-10 19:17:055492}
5493
[email protected]eb71ab62014-05-23 07:57:535494TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335495 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015496 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495497 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335498 socket_factory_.AddSocketDataProvider(&quic_data);
5499
5500 // Main job which will succeed even though the alternate job fails.
5501 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025502 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5503 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5504 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335505
Ryan Sleevib8d7ea02018-05-07 20:01:015506 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335507 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565508 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335509
rch3f4b8452016-02-23 16:59:325510 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275511 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335512 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535513
5514 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335515}
5516
Kenichi Ishibashi6fc20b82023-08-01 21:43:595517TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
5518 FLAGS_quic_enable_chaos_protection = false;
Ryan Hamiltona51800a2022-02-12 19:34:355519 if (version_.AlpnDeferToRFCv1()) {
5520 // These versions currently do not support Alt-Svc.
5521 return;
5522 }
Ryan Hamiltonabad59e2019-06-06 04:02:595523 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165524 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:175525 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045526 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155527
5528 // When the QUIC connection fails, we will try the request again over HTTP.
5529 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:455530 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:195531 MockRead(kHttpRespData),
rchf114d982015-10-21 01:34:565532 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5533 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155534
Ryan Sleevib8d7ea02018-05-07 20:01:015535 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155536 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565537 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155538
5539 // In order for a new QUIC session to be established via alternate-protocol
5540 // without racing an HTTP connection, we need the host resolution to happen
5541 // synchronously.
5542 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295543 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565544 "");
[email protected]4fee9672014-01-08 14:47:155545
rch3f4b8452016-02-23 16:59:325546 CreateSession();
David Schinazic8281052019-01-24 06:14:175547 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5548 AddQuicAlternateProtocolMapping(
5549 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Andrew Williams826d8742024-01-31 19:39:195550 SendRequestAndExpectHttpResponse(kHttpRespData);
[email protected]4fee9672014-01-08 14:47:155551}
5552
tbansalc3308d72016-08-27 10:25:045553TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltona51800a2022-02-12 19:34:355554 if (version_.AlpnDeferToRFCv1()) {
5555 // These versions currently do not support Alt-Svc.
5556 return;
5557 }
Ryan Hamiltonabad59e2019-06-06 04:02:595558 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165559 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:175560 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335561 mock_quic_data.AddWrite(
5562 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5563 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035564 GetRequestHeaders("GET", "https", "/")));
Renjie Tangcd594f32020-07-11 20:18:345565 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1));
tbansalc3308d72016-08-27 10:25:045566 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5567
5568 // When the QUIC connection fails, we will try the request again over HTTP.
5569 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:455570 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:195571 MockRead(kHttpRespData),
tbansalc3308d72016-08-27 10:25:045572 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5573 MockRead(ASYNC, OK)};
5574
Ryan Sleevib8d7ea02018-05-07 20:01:015575 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045576 socket_factory_.AddSocketDataProvider(&http_data);
5577 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5578
Andrew Williams826d8742024-01-31 19:39:195579 const char kProxyHost[] = "myproxy.org";
5580 const auto kQuicProxyChain =
Ciara McMullin20d24572024-01-31 13:15:535581 ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
Andrew Williams826d8742024-01-31 19:39:195582 ProxyServer::SCHEME_QUIC, kProxyHost, 443)});
5583 const auto kHttpsProxyChain = ProxyChain::FromSchemeHostAndPort(
5584 ProxyServer::SCHEME_HTTPS, kProxyHost, 443);
Nicolas Arciniegad2013f92020-02-07 23:00:565585 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:005586 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Andrew Williams826d8742024-01-31 19:39:195587 {kQuicProxyChain, kHttpsProxyChain}, TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045588 request_.url = GURL("http://mail.example.org/");
5589
5590 // In order for a new QUIC session to be established via alternate-protocol
5591 // without racing an HTTP connection, we need the host resolution to happen
5592 // synchronously.
5593 host_resolver_.set_synchronous_mode(true);
Andrew Williams826d8742024-01-31 19:39:195594 host_resolver_.rules()->AddIPLiteralRule(kProxyHost, "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045595
5596 CreateSession();
David Schinazic8281052019-01-24 06:14:175597 crypto_client_stream_factory_.set_handshake_mode(
5598 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Andrew Williams826d8742024-01-31 19:39:195599 SendRequestAndExpectHttpResponseFromProxy(
Dustin J. Mitchell5bf18582024-02-16 16:20:135600 kHttpRespData, kHttpsProxyChain.First().GetPort(), kHttpsProxyChain);
Lily Houghton8c2f97d2018-01-22 05:06:595601 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Andrew Williams826d8742024-01-31 19:39:195602 ElementsAre(Key(kQuicProxyChain)));
tbansalc3308d72016-08-27 10:25:045603}
5604
bnc508835902015-05-12 20:10:295605TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
Zhongyi Shi1c022d22020-03-20 19:00:165606 client_maker_->set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385607 EXPECT_FALSE(
5608 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:595609 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235610 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025611 mock_quic_data.AddWrite(SYNCHRONOUS,
5612 ConstructInitialSettingsPacket(packet_num++));
rch5cb522462017-04-25 20:18:365613 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235614 SYNCHRONOUS,
5615 ConstructClientRequestHeadersPacket(
5616 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035617 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435618 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335619 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035620 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285621 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335622 mock_quic_data.AddRead(
5623 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035624 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:195625 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:235626 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345627 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:505628 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295629 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5630
bncb07c05532015-05-14 19:07:205631 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095632 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325633 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275634 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Andrew Williams826d8742024-01-31 19:39:195635 SendRequestAndExpectQuicResponse(kQuicRespData);
tbansal0f56a39a2016-04-07 22:03:385636 EXPECT_TRUE(
5637 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295638}
5639
rtenneti56977812016-01-15 19:26:565640TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Victor Vasilieva1e66d72019-12-05 17:55:385641 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575642 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565643
Renjie Tangaadb84b2019-08-31 01:00:235644 MockQuicData mock_quic_data(version_);
Patrick Meenan885a00652023-02-15 20:07:025645 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:235646 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5647 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5648
rtennetib8e80fb2016-05-16 00:12:095649 // The non-alternate protocol job needs to hang in order to guarantee that
5650 // the alternate-protocol job will "win".
5651 AddHangingNonAlternateProtocolSocketData();
5652
rtenneti56977812016-01-15 19:26:565653 CreateSession();
5654 request_.method = "POST";
5655 ChunkedUploadDataStream upload_data(0);
5656 upload_data.AppendData("1", 1, true);
5657
5658 request_.upload_data_stream = &upload_data;
5659
bnc691fda62016-08-12 00:43:165660 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:565661 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265662 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:015663 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:565664 EXPECT_NE(OK, callback.WaitForResult());
5665}
5666
rche11300ef2016-09-02 01:44:285667TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Victor Vasilieva1e66d72019-12-05 17:55:385668 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:285669 ScopedMockNetworkChangeNotifier network_change_notifier;
5670 MockNetworkChangeNotifier* mock_ncn =
5671 network_change_notifier.mock_network_change_notifier();
5672 mock_ncn->ForceNetworkHandlesSupported();
5673 mock_ncn->SetConnectedNetworksList(
5674 {kDefaultNetworkForTests, kNewNetworkForTests});
5675
Victor Vasilieva1e66d72019-12-05 17:55:385676 context_.params()->origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:285677 HostPortPair::FromString("mail.example.org:443"));
Victor Vasilieva1e66d72019-12-05 17:55:385678 context_.params()->migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:285679
Ryan Hamiltonabad59e2019-06-06 04:02:595680 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:285681 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:235682 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025683 socket_data.AddWrite(SYNCHRONOUS,
5684 ConstructInitialSettingsPacket(packet_num++));
Fan Yang32c5a112018-12-10 20:06:335685 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235686 SYNCHRONOUS,
5687 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035688 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
5689 GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:285690 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5691 socket_data.AddSocketDataToFactory(&socket_factory_);
5692
Ryan Hamiltonabad59e2019-06-06 04:02:595693 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:285694 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
5695 socket_data2.AddSocketDataToFactory(&socket_factory_);
5696
5697 // The non-alternate protocol job needs to hang in order to guarantee that
5698 // the alternate-protocol job will "win".
5699 AddHangingNonAlternateProtocolSocketData();
5700
5701 CreateSession();
5702 request_.method = "POST";
5703 ChunkedUploadDataStream upload_data(0);
5704
5705 request_.upload_data_stream = &upload_data;
5706
Tsuyoshi Horof8861cb2022-07-05 23:50:205707 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5708 session_.get());
rche11300ef2016-09-02 01:44:285709 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265710 int rv = trans->Start(&request_, callback.callback(), net_log_with_source_);
rche11300ef2016-09-02 01:44:285711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5712
5713 base::RunLoop().RunUntilIdle();
5714 upload_data.AppendData("1", 1, true);
5715 base::RunLoop().RunUntilIdle();
5716
5717 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:505718 trans.reset();
rche11300ef2016-09-02 01:44:285719 session_.reset();
5720}
5721
Ryan Hamilton4b3574532017-10-30 20:17:255722TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:385723 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255724 HostPortPair::FromString("mail.example.org:443"));
5725
Ryan Hamiltonabad59e2019-06-06 04:02:595726 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235727 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025728 socket_data.AddWrite(SYNCHRONOUS,
5729 ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton4b3574532017-10-30 20:17:255730 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:335731 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235732 SYNCHRONOUS,
5733 ConstructClientRequestHeadersPacket(
5734 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035735 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435736 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335737 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035738 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285739 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335740 socket_data.AddRead(
5741 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035742 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:195743 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:235744 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345745 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:255746 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Tsuyoshi Horoea15e7a2023-05-23 00:12:035747 socket_data.AddWrite(
5748 SYNCHRONOUS,
5749 client_maker_->MakeAckAndConnectionClosePacket(
5750 packet_num++, 2, 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:255751
5752 socket_data.AddSocketDataToFactory(&socket_factory_);
5753
5754 CreateSession();
5755
Andrew Williams826d8742024-01-31 19:39:195756 SendRequestAndExpectQuicResponse(kQuicRespData);
Ryan Hamilton4b3574532017-10-30 20:17:255757 session_.reset();
5758}
5759
5760TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:385761 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255762 HostPortPair::FromString("mail.example.org:443"));
5763
Ryan Hamiltonabad59e2019-06-06 04:02:595764 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235765 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025766 socket_data.AddWrite(SYNCHRONOUS,
5767 ConstructInitialSettingsPacket(packet_num++));
Ryan Hamilton4b3574532017-10-30 20:17:255768 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:335769 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235770 SYNCHRONOUS,
5771 ConstructClientRequestHeadersPacket(
5772 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035773 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435774 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335775 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035776 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285777 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335778 socket_data.AddRead(
5779 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035780 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:195781 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:235782 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345783 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:255784 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Tsuyoshi Horoea15e7a2023-05-23 00:12:035785 socket_data.AddWrite(
5786 SYNCHRONOUS,
5787 client_maker_->MakeAckAndConnectionClosePacket(
5788 packet_num++, 2, 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:255789
5790 socket_data.AddSocketDataToFactory(&socket_factory_);
5791
5792 CreateSession();
5793
Andrew Williams826d8742024-01-31 19:39:195794 SendRequestAndExpectQuicResponse(kQuicRespData);
Ryan Hamilton4b3574532017-10-30 20:17:255795 session_.reset();
5796}
5797
Ryan Hamilton9edcf1a2017-11-22 05:55:175798TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:385799 context_.params()->retry_without_alt_svc_on_quic_errors = false;
5800 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255801 HostPortPair::FromString("mail.example.org:443"));
5802
Ryan Hamiltonabad59e2019-06-06 04:02:595803 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:255804 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Patrick Meenan885a00652023-02-15 20:07:025805 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:175806 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:255807 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
5808 }
5809 socket_data.AddSocketDataToFactory(&socket_factory_);
5810
5811 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:175812 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Dustin J. Mitchell795c7362024-01-18 16:50:525813 QuicSessionPoolPeer::SetTaskRunner(session_->quic_session_pool(),
5814 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:255815
Victor Vasiliev7752898d2019-11-14 21:30:225816 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:255817 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5818 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265819 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton4b3574532017-10-30 20:17:255820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:175821 while (!callback.have_result()) {
5822 base::RunLoop().RunUntilIdle();
5823 quic_task_runner_->RunUntilIdle();
5824 }
5825 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:255826 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:175827 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5828 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5829 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:225830 EXPECT_TRUE(context_.clock()->Now() - start >
5831 quic::QuicTime::Delta::FromSeconds(4));
5832 EXPECT_TRUE(context_.clock()->Now() - start <
5833 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:255834}
5835
Ryan Hamilton9edcf1a2017-11-22 05:55:175836TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:385837 context_.params()->retry_without_alt_svc_on_quic_errors = false;
5838 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255839 HostPortPair::FromString("mail.example.org:443"));
5840
Ryan Hamiltonabad59e2019-06-06 04:02:595841 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:255842 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Patrick Meenan885a00652023-02-15 20:07:025843 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:175844 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:255845 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
5846 }
5847 socket_data.AddSocketDataToFactory(&socket_factory_);
5848
5849 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:175850 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Dustin J. Mitchell795c7362024-01-18 16:50:525851 QuicSessionPoolPeer::SetTaskRunner(session_->quic_session_pool(),
5852 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:255853
Victor Vasiliev7752898d2019-11-14 21:30:225854 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:255855 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5856 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265857 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Ryan Hamilton4b3574532017-10-30 20:17:255858 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:175859 while (!callback.have_result()) {
5860 base::RunLoop().RunUntilIdle();
5861 quic_task_runner_->RunUntilIdle();
5862 }
5863 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:255864 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:175865 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5866 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5867 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:225868 EXPECT_TRUE(context_.clock()->Now() - start >
5869 quic::QuicTime::Delta::FromSeconds(4));
5870 EXPECT_TRUE(context_.clock()->Now() - start <
5871 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:255872}
5873
Cherie Shi7596de632018-02-22 07:28:185874TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Victor Vasilieva1e66d72019-12-05 17:55:385875 context_.params()->retry_without_alt_svc_on_quic_errors = false;
5876 context_.params()->origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:185877 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev62c09dc2020-11-06 18:18:295878 const std::string error_details = base::StrCat(
5879 {"Write failed with error: ", base::NumberToString(ERR_MSG_TOO_BIG), " (",
5880 strerror(ERR_MSG_TOO_BIG), ")"});
Cherie Shi7596de632018-02-22 07:28:185881
Ryan Hamiltonabad59e2019-06-06 04:02:595882 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:185883 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:235884 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025885 socket_data.AddWrite(SYNCHRONOUS,
5886 ConstructInitialSettingsPacket(packet_num++));
Cherie Shi7596de632018-02-22 07:28:185887 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
5888 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525889 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235890 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165891 client_maker_->MakeConnectionClosePacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035892 packet_num + 1, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:185893 socket_data.AddSocketDataToFactory(&socket_factory_);
5894
5895 CreateSession();
5896
5897 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5898 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:265899 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Cherie Shi7596de632018-02-22 07:28:185900 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5901 base::RunLoop().RunUntilIdle();
5902 ASSERT_TRUE(callback.have_result());
5903 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5904 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5905 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5906}
5907
ckrasicda193a82016-07-09 00:39:365908TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Victor Vasilieva1e66d72019-12-05 17:55:385909 context_.params()->origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:365910 HostPortPair::FromString("mail.example.org:443"));
5911
Ryan Hamiltonabad59e2019-06-06 04:02:595912 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:365913
Renjief49758b2019-01-11 23:32:415914 int write_packet_index = 1;
Patrick Meenan885a00652023-02-15 20:07:025915 mock_quic_data.AddWrite(SYNCHRONOUS,
5916 ConstructInitialSettingsPacket(write_packet_index++));
ckrasicda193a82016-07-09 00:39:365917
Bence Béky319388a882020-09-23 18:42:525918 mock_quic_data.AddWrite(
5919 SYNCHRONOUS,
5920 ConstructClientRequestHeadersAndDataFramesPacket(
5921 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:035922 true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
Bence Béky957bab12023-01-31 16:40:105923 nullptr, {ConstructDataFrame("1")}));
ckrasicda193a82016-07-09 00:39:365924
Zhongyi Shi32f2fd02018-04-16 18:23:435925 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335926 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035927 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285928 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335929
5930 mock_quic_data.AddRead(
5931 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035932 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:195933 ConstructDataFrame(kQuicRespData)));
ckrasicda193a82016-07-09 00:39:365934
Renjie Tangcd594f32020-07-11 20:18:345935 mock_quic_data.AddWrite(SYNCHRONOUS,
5936 ConstructClientAckPacket(write_packet_index++, 2, 1));
ckrasicda193a82016-07-09 00:39:365937
5938 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215939 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
ckrasicda193a82016-07-09 00:39:365940 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5941
5942 // The non-alternate protocol job needs to hang in order to guarantee that
5943 // the alternate-protocol job will "win".
5944 AddHangingNonAlternateProtocolSocketData();
5945
5946 CreateSession();
5947 request_.method = "POST";
5948 ChunkedUploadDataStream upload_data(0);
5949 upload_data.AppendData("1", 1, true);
5950
5951 request_.upload_data_stream = &upload_data;
5952
Andrew Williams826d8742024-01-31 19:39:195953 SendRequestAndExpectQuicResponse(kQuicRespData);
ckrasicda193a82016-07-09 00:39:365954}
5955
Ryan Sleevia9d6aa62019-07-26 13:32:185956TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
Ryan Hamiltona51800a2022-02-12 19:34:355957 if (version_.AlpnDeferToRFCv1()) {
5958 // These versions currently do not support Alt-Svc.
5959 return;
5960 }
Ryan Sleevia9d6aa62019-07-26 13:32:185961 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:205962
5963 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:455964 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:195965 MockRead(kHttpRespData),
Yixin Wang10f477ed2017-11-21 04:20:205966 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5967 MockRead(ASYNC, OK)};
5968
Ryan Sleevib8d7ea02018-05-07 20:01:015969 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:205970 socket_factory_.AddSocketDataProvider(&http_data);
5971 AddCertificate(&ssl_data_);
5972 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5973
Ryan Hamiltonabad59e2019-06-06 04:02:595974 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235975 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:025976 mock_quic_data.AddWrite(SYNCHRONOUS,
5977 ConstructInitialSettingsPacket(packet_num++));
Yixin Wang10f477ed2017-11-21 04:20:205978 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235979 SYNCHRONOUS,
5980 ConstructClientRequestHeadersPacket(
5981 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:035982 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435983 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335984 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035985 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:285986 GetResponseHeaders("200")));
Fan Yang32c5a112018-12-10 20:06:335987 mock_quic_data.AddRead(
5988 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:035989 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:195990 ConstructDataFrame(kQuicRespData)));
Renjie Tangaadb84b2019-08-31 01:00:235991 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345992 ConstructClientAckPacket(packet_num++, 2, 1));
Yixin Wang10f477ed2017-11-21 04:20:205993 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:215994 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yixin Wang10f477ed2017-11-21 04:20:205995
5996 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5997
5998 AddHangingNonAlternateProtocolSocketData();
5999 CreateSession();
6000
Andrew Williams826d8742024-01-31 19:39:196001 SendRequestAndExpectHttpResponse(kHttpRespData);
6002 SendRequestAndExpectQuicResponse(kQuicRespData);
Yixin Wang10f477ed2017-11-21 04:20:206003}
6004
Ryan Sleevia9d6aa62019-07-26 13:32:186005TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
Ryan Hamiltona51800a2022-02-12 19:34:356006 if (version_.AlpnDeferToRFCv1()) {
6007 // These versions currently do not support Alt-Svc.
6008 return;
6009 }
Ryan Sleevia9d6aa62019-07-26 13:32:186010 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:206011
6012 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:456013 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:196014 MockRead(kHttpRespData),
Yixin Wang10f477ed2017-11-21 04:20:206015 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6016 MockRead(ASYNC, OK)};
6017
Ryan Sleevib8d7ea02018-05-07 20:01:016018 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206019 socket_factory_.AddSocketDataProvider(&http_data);
6020 AddCertificate(&ssl_data_);
6021 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6022 socket_factory_.AddSocketDataProvider(&http_data);
6023 AddCertificate(&ssl_data_);
6024 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6025
6026 AddHangingNonAlternateProtocolSocketData();
6027 CreateSession();
6028
Andrew Williams826d8742024-01-31 19:39:196029 SendRequestAndExpectHttpResponse(kHttpRespData);
6030 SendRequestAndExpectHttpResponse(kHttpRespData);
Yixin Wang10f477ed2017-11-21 04:20:206031}
6032
bnc359ed2a2016-04-29 20:43:456033class QuicNetworkTransactionWithDestinationTest
6034 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016035 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:056036 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456037 protected:
6038 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556039 : version_(GetParam().version),
Nick Harper23290b82019-05-02 00:02:566040 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:456041 destination_type_(GetParam().destination_type),
Tsuyoshi Horof8861cb2022-07-05 23:50:206042 ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()),
Nicolas Arciniegad2013f92020-02-07 23:00:566043 proxy_resolution_service_(
6044 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:116045 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Ryan Hamiltonf9a421f2020-01-31 21:09:526046 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:196047 FLAGS_quic_enable_http3_grease_randomness = false;
Ryan Hamiltonf9a421f2020-01-31 21:09:526048 }
bnc359ed2a2016-04-29 20:43:456049
6050 void SetUp() override {
6051 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556052 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456053
Matt Menke30a878c2021-07-20 22:25:096054 HttpNetworkSessionParams session_params;
mmenke6ddfbea2017-05-31 21:48:416055 session_params.enable_quic = true;
Tsuyoshi Horo76b96592023-08-28 09:09:496056 // To simplefy tests, we disable UseDnsHttpsSvcbAlpn feature. If this is
6057 // enabled, we need to prepare mock sockets for `dns_alpn_h3_job_`. Also
6058 // AsyncQuicSession feature makes it more complecated because it changes the
6059 // socket call order.
6060 session_params.use_dns_https_svcb_alpn = false;
6061
Victor Vasilieva1e66d72019-12-05 17:55:386062 context_.params()->allow_remote_alt_svc = true;
6063 context_.params()->supported_versions = supported_versions_;
mmenke6ddfbea2017-05-31 21:48:416064
Matt Menke30a878c2021-07-20 22:25:096065 HttpNetworkSessionContext session_context;
bnc359ed2a2016-04-29 20:43:456066
Victor Vasiliev7752898d2019-11-14 21:30:226067 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
bnc359ed2a2016-04-29 20:43:456068
6069 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276070 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416071 session_context.quic_crypto_client_stream_factory =
6072 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456073
Victor Vasiliev7752898d2019-11-14 21:30:226074 session_context.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:416075 session_context.client_socket_factory = &socket_factory_;
6076 session_context.host_resolver = &host_resolver_;
6077 session_context.cert_verifier = &cert_verifier_;
6078 session_context.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:416079 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456080 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416081 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596082 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416083 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6084 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456085
Renjie Tang6ff9a9b2021-02-03 22:11:096086 session_ =
6087 std::make_unique<HttpNetworkSession>(session_params, session_context);
Dustin J. Mitchell795c7362024-01-18 16:50:526088 session_->quic_session_pool()->set_is_quic_known_to_work_on_current_network(
6089 false);
bnc359ed2a2016-04-29 20:43:456090 }
6091
6092 void TearDown() override {
6093 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6094 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556095 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456096 PlatformTest::TearDown();
6097 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556098 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406099 session_.reset();
bnc359ed2a2016-04-29 20:43:456100 }
6101
zhongyie537a002017-06-27 16:48:216102 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456103 HostPortPair destination;
6104 switch (destination_type_) {
6105 case SAME_AS_FIRST:
6106 destination = HostPortPair(origin1_, 443);
6107 break;
6108 case SAME_AS_SECOND:
6109 destination = HostPortPair(origin2_, 443);
6110 break;
6111 case DIFFERENT:
6112 destination = HostPortPair(kDifferentHostname, 443);
6113 break;
6114 }
bnc3472afd2016-11-17 15:27:216115 AlternativeService alternative_service(kProtoQUIC, destination);
Peter Kastinge5a38ed2021-10-02 03:06:356116 base::Time expiration = base::Time::Now() + base::Days(1);
zhongyie537a002017-06-27 16:48:216117 http_server_properties_.SetQuicAlternativeService(
Brianna Goldstein02cb74f2022-09-29 05:41:016118 url::SchemeHostPort("https", origin, 443), NetworkAnonymizationKey(),
Matt Menke9aa86262019-08-21 15:52:076119 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456120 }
6121
Ryan Hamilton8d9ee76e2018-05-29 23:52:526122 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236123 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526124 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526125 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136126 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456127 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Bence Béky4c325e52020-10-22 20:48:016128 spdy::Http2HeaderBlock headers(
Ryan Hamilton0239aac2018-05-19 00:03:136129 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:026130 return maker->MakeRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036131 packet_number, stream_id, true, priority, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:456132 }
6133
Ryan Hamilton8d9ee76e2018-05-29 23:52:526134 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236135 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526136 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526137 QuicTestPacketMaker* maker) {
Kenichi Ishibashif8634ab2021-03-16 23:41:286138 spdy::Http2HeaderBlock headers(maker->GetResponseHeaders("200"));
Ryan Hamilton0d65a8c2019-06-07 00:46:026139 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:036140 std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:456141 }
6142
Ryan Hamilton8d9ee76e2018-05-29 23:52:526143 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:236144 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526145 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456146 QuicTestPacketMaker* maker) {
Bence Béky319388a882020-09-23 18:42:526147 return maker->MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036148 packet_number, stream_id, true,
Bence Béky319388a882020-09-23 18:42:526149 ConstructDataFrameForVersion("hello", version_));
bnc359ed2a2016-04-29 20:43:456150 }
6151
Ryan Hamilton8d9ee76e2018-05-29 23:52:526152 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:236153 uint64_t packet_number,
6154 uint64_t largest_received,
6155 uint64_t smallest_received,
bnc359ed2a2016-04-29 20:43:456156 QuicTestPacketMaker* maker) {
6157 return maker->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:346158 smallest_received);
bnc359ed2a2016-04-29 20:43:456159 }
6160
Ryan Hamilton8d9ee76e2018-05-29 23:52:526161 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:236162 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:376163 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026164 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:376165 }
6166
bnc359ed2a2016-04-29 20:43:456167 void AddRefusedSocketData() {
Tsuyoshi Horof8861cb2022-07-05 23:50:206168 auto refused_data = std::make_unique<StaticSocketDataProvider>();
bnc359ed2a2016-04-29 20:43:456169 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6170 refused_data->set_connect_data(refused_connect);
6171 socket_factory_.AddSocketDataProvider(refused_data.get());
6172 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6173 }
6174
6175 void AddHangingSocketData() {
Tsuyoshi Horof8861cb2022-07-05 23:50:206176 auto hanging_data = std::make_unique<StaticSocketDataProvider>();
bnc359ed2a2016-04-29 20:43:456177 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6178 hanging_data->set_connect_data(hanging_connect);
6179 socket_factory_.AddSocketDataProvider(hanging_data.get());
6180 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6181 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6182 }
6183
6184 bool AllDataConsumed() {
6185 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6186 if (!socket_data_ptr->AllReadDataConsumed() ||
6187 !socket_data_ptr->AllWriteDataConsumed()) {
6188 return false;
6189 }
6190 }
6191 return true;
6192 }
6193
6194 void SendRequestAndExpectQuicResponse(const std::string& host) {
6195 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6196 HttpRequestInfo request;
6197 std::string url("https://");
6198 url.append(host);
6199 request.url = GURL(url);
6200 request.load_flags = 0;
6201 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106202 request.traffic_annotation =
6203 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456204 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266205 int rv = trans.Start(&request, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:016206 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456207
6208 std::string response_data;
robpercival214763f2016-07-01 23:27:016209 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456210 EXPECT_EQ("hello", response_data);
6211
6212 const HttpResponseInfo* response = trans.GetResponseInfo();
6213 ASSERT_TRUE(response != nullptr);
6214 ASSERT_TRUE(response->headers.get() != nullptr);
Andrew Williams826d8742024-01-31 19:39:196215 EXPECT_EQ(kQuic200RespStatusLine, response->headers->GetStatusLine());
bnc359ed2a2016-04-29 20:43:456216 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526217 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:086218 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:456219 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:376220 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:456221 }
6222
Fan Yang32c5a112018-12-10 20:06:336223 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:566224 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
6225 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:366226 }
6227
Patrick Meenan0041f332022-05-19 23:48:356228 quic::test::QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Nick Harper23290b82019-05-02 00:02:566229 const quic::ParsedQuicVersion version_;
Nick Harper23290b82019-05-02 00:02:566230 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:456231 DestinationType destination_type_;
6232 std::string origin1_;
6233 std::string origin2_;
Victor Vasiliev7752898d2019-11-14 21:30:226234 MockQuicContext context_;
bnc359ed2a2016-04-29 20:43:456235 std::unique_ptr<HttpNetworkSession> session_;
6236 MockClientSocketFactory socket_factory_;
Eric Orthbe86fee2021-10-28 22:31:116237 MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
6238 RuleResolver::GetLocalhostResult()};
bnc359ed2a2016-04-29 20:43:456239 MockCertVerifier cert_verifier_;
6240 TransportSecurityState transport_security_state_;
bnc359ed2a2016-04-29 20:43:456241 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:076242 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:266243 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:456244 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:266245 HttpServerProperties http_server_properties_;
Matt Reichhoff0049a0b72021-10-20 20:44:266246 NetLogWithSource net_log_with_source_{
6247 NetLogWithSource::Make(NetLogSourceType::NONE)};
bnc359ed2a2016-04-29 20:43:456248 MockCryptoClientStreamFactory crypto_client_stream_factory_;
6249 std::vector<std::unique_ptr<StaticSocketDataProvider>>
6250 static_socket_data_provider_vector_;
6251 SSLSocketDataProvider ssl_data_;
6252};
6253
Victor Costane635086f2019-01-27 05:20:306254INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
6255 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:576256 ::testing::ValuesIn(GetPoolingTestParams()),
6257 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:456258
6259// A single QUIC request fails because the certificate does not match the origin
6260// hostname, regardless of whether it matches the alternative service hostname.
6261TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
Dustin J. Mitchell496de812024-01-16 19:14:546262 if (destination_type_ == DIFFERENT) {
bnc359ed2a2016-04-29 20:43:456263 return;
Dustin J. Mitchell496de812024-01-16 19:14:546264 }
bnc359ed2a2016-04-29 20:43:456265
6266 GURL url("https://mail.example.com/");
6267 origin1_ = url.host();
6268
6269 // Not used for requests, but this provides a test case where the certificate
6270 // is valid for the hostname of the alternative service.
6271 origin2_ = "mail.example.org";
6272
zhongyie537a002017-06-27 16:48:216273 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:456274
6275 scoped_refptr<X509Certificate> cert(
6276 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246277 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
6278 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:456279
6280 ProofVerifyDetailsChromium verify_details;
6281 verify_details.cert_verify_result.verified_cert = cert;
6282 verify_details.cert_verify_result.is_issued_by_known_root = true;
6283 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6284
Ryan Hamiltonabad59e2019-06-06 04:02:596285 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:456286 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
David Schinazi395918c2021-02-05 18:56:216287 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:456288
6289 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6290
6291 AddRefusedSocketData();
6292
6293 HttpRequestInfo request;
6294 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:106295 request.traffic_annotation =
6296 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456297
6298 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6299 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:266300 int rv = trans.Start(&request, callback.callback(), net_log_with_source_);
robpercival214763f2016-07-01 23:27:016301 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:456302
6303 EXPECT_TRUE(AllDataConsumed());
6304}
6305
6306// First request opens QUIC session to alternative service. Second request
6307// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:526308// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:456309TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
6310 origin1_ = "mail.example.org";
6311 origin2_ = "news.example.org";
6312
zhongyie537a002017-06-27 16:48:216313 SetQuicAlternativeService(origin1_);
6314 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:456315
6316 scoped_refptr<X509Certificate> cert(
6317 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246318 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
6319 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
6320 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456321
6322 ProofVerifyDetailsChromium verify_details;
6323 verify_details.cert_verify_result.verified_cert = cert;
6324 verify_details.cert_verify_result.is_issued_by_known_root = true;
6325 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6326
Yixin Wang079ad542018-01-11 04:06:056327 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:226328 version_,
6329 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Patrick Meenan0b1b18cf2023-09-21 20:19:476330 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
6331 /*client_priority_uses_incremental=*/true, /*use_priority_header=*/true);
David Schinazic8281052019-01-24 06:14:176332 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:226333 version_,
6334 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Patrick Meenan0b1b18cf2023-09-21 20:19:476335 context_.clock(), origin1_, quic::Perspective::IS_SERVER,
6336 /*client_priority_uses_incremental=*/false,
6337 /*use_priority_header=*/false);
bnc359ed2a2016-04-29 20:43:456338
Ryan Hamiltonabad59e2019-06-06 04:02:596339 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236340 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026341 mock_quic_data.AddWrite(
6342 SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++, &client_maker));
Fan Yang32c5a112018-12-10 20:06:336343 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236344 SYNCHRONOUS,
6345 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036346 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangaadb84b2019-08-31 01:00:236347 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:026348 mock_quic_data.AddRead(
6349 ASYNC,
6350 ConstructServerResponseHeadersPacket(
6351 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:436352 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336353 ASYNC,
6354 ConstructServerDataPacket(
6355 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:236356 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346357 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:456358
Yixin Wang079ad542018-01-11 04:06:056359 client_maker.set_hostname(origin2_);
6360 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:456361
Zhongyi Shi32f2fd02018-04-16 18:23:436362 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026363 SYNCHRONOUS,
6364 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036365 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
Bence Béky957bab12023-01-31 16:40:106366 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:026367 mock_quic_data.AddRead(
6368 ASYNC,
6369 ConstructServerResponseHeadersPacket(
6370 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:436371 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336372 ASYNC,
6373 ConstructServerDataPacket(
6374 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:236375 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346376 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3, &client_maker));
bnc359ed2a2016-04-29 20:43:456377 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:216378 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
bnc359ed2a2016-04-29 20:43:456379
6380 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6381
6382 AddHangingSocketData();
6383 AddHangingSocketData();
6384
Tsuyoshi Horo2c0a5042022-07-06 05:53:076385 auto quic_task_runner =
6386 base::MakeRefCounted<TestTaskRunner>(context_.mock_clock());
Dustin J. Mitchell795c7362024-01-18 16:50:526387 QuicSessionPoolPeer::SetAlarmFactory(
6388 session_->quic_session_pool(),
Nick Harpereb483e12019-05-14 00:18:096389 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Victor Vasiliev7752898d2019-11-14 21:30:226390 context_.clock()));
Fan Yangc9e00dc2018-10-09 14:17:566391
bnc359ed2a2016-04-29 20:43:456392 SendRequestAndExpectQuicResponse(origin1_);
6393 SendRequestAndExpectQuicResponse(origin2_);
6394
6395 EXPECT_TRUE(AllDataConsumed());
6396}
6397
6398// First request opens QUIC session to alternative service. Second request does
6399// not pool to it, even though destination matches, because certificate is not
6400// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:526401// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:456402TEST_P(QuicNetworkTransactionWithDestinationTest,
6403 DoNotPoolIfCertificateInvalid) {
6404 origin1_ = "news.example.org";
6405 origin2_ = "mail.example.com";
6406
zhongyie537a002017-06-27 16:48:216407 SetQuicAlternativeService(origin1_);
6408 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:456409
6410 scoped_refptr<X509Certificate> cert1(
6411 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246412 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
6413 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
6414 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456415
6416 scoped_refptr<X509Certificate> cert2(
6417 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246418 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
6419 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456420
6421 ProofVerifyDetailsChromium verify_details1;
6422 verify_details1.cert_verify_result.verified_cert = cert1;
6423 verify_details1.cert_verify_result.is_issued_by_known_root = true;
6424 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
6425
6426 ProofVerifyDetailsChromium verify_details2;
6427 verify_details2.cert_verify_result.verified_cert = cert2;
6428 verify_details2.cert_verify_result.is_issued_by_known_root = true;
6429 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
6430
Yixin Wang079ad542018-01-11 04:06:056431 QuicTestPacketMaker client_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:226432 version_,
6433 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Patrick Meenan0b1b18cf2023-09-21 20:19:476434 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
6435 /*client_priority_uses_incremental=*/true, /*use_priority_header=*/true);
David Schinazic8281052019-01-24 06:14:176436 QuicTestPacketMaker server_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:226437 version_,
6438 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Patrick Meenan0b1b18cf2023-09-21 20:19:476439 context_.clock(), origin1_, quic::Perspective::IS_SERVER,
6440 /*client_priority_uses_incremental=*/false,
6441 /*use_priority_header=*/false);
bnc359ed2a2016-04-29 20:43:456442
Ryan Hamiltonabad59e2019-06-06 04:02:596443 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:236444 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026445 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6446 packet_num++, &client_maker1));
Fan Yang32c5a112018-12-10 20:06:336447 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236448 SYNCHRONOUS,
6449 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036450 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangaadb84b2019-08-31 01:00:236451 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:436452 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336453 ASYNC,
6454 ConstructServerResponseHeadersPacket(
6455 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:436456 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336457 ASYNC,
6458 ConstructServerDataPacket(
6459 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:436460 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236461 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346462 ConstructClientAckPacket(packet_num++, 2, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:456463 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6464 mock_quic_data1.AddRead(ASYNC, 0); // EOF
6465
6466 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
6467
Yixin Wang079ad542018-01-11 04:06:056468 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:226469 version_,
6470 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Patrick Meenan0b1b18cf2023-09-21 20:19:476471 context_.clock(), origin2_, quic::Perspective::IS_CLIENT,
6472 /*client_priority_uses_incremental=*/true, /*use_priority_header=*/true);
David Schinazic8281052019-01-24 06:14:176473 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:226474 version_,
6475 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
Patrick Meenan0b1b18cf2023-09-21 20:19:476476 context_.clock(), origin2_, quic::Perspective::IS_SERVER,
6477 /*client_priority_uses_incremental=*/false,
6478 /*use_priority_header=*/false);
bnc359ed2a2016-04-29 20:43:456479
Ryan Hamiltonabad59e2019-06-06 04:02:596480 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:236481 int packet_num2 = 1;
Patrick Meenan885a00652023-02-15 20:07:026482 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6483 packet_num2++, &client_maker2));
Fan Yang32c5a112018-12-10 20:06:336484 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236485 SYNCHRONOUS,
6486 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036487 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangaadb84b2019-08-31 01:00:236488 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:436489 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:336490 ASYNC,
6491 ConstructServerResponseHeadersPacket(
6492 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:436493 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:336494 ASYNC,
6495 ConstructServerDataPacket(
6496 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:436497 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236498 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346499 ConstructClientAckPacket(packet_num2++, 2, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:456500 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6501 mock_quic_data2.AddRead(ASYNC, 0); // EOF
6502
6503 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
6504
bnc359ed2a2016-04-29 20:43:456505 SendRequestAndExpectQuicResponse(origin1_);
6506 SendRequestAndExpectQuicResponse(origin2_);
6507
6508 EXPECT_TRUE(AllDataConsumed());
6509}
6510
Yixin Wang46a273ec302018-01-23 17:59:566511// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:146512TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Patrick Meenan0b1b18cf2023-09-21 20:19:476513 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:566514 session_params_.enable_quic = true;
Andrew Williams826d8742024-01-31 19:39:196515
6516 const auto kQuicProxyChain =
6517 ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
6518 ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)});
Nicolas Arciniegad2013f92020-02-07 23:00:566519 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:006520 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Andrew Williams826d8742024-01-31 19:39:196521 {kQuicProxyChain}, TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566522
Ryan Hamiltonabad59e2019-06-06 04:02:596523 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236524 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026525 mock_quic_data.AddWrite(SYNCHRONOUS,
6526 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:436527
Patrick Meenan8f8c8352023-07-06 17:20:196528 mock_quic_data.AddWrite(
6529 SYNCHRONOUS,
6530 ConstructClientPriorityPacket(
6531 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6532 DEFAULT_PRIORITY));
Fan Yang32c5a112018-12-10 20:06:336533 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236534 SYNCHRONOUS,
6535 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036536 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
6537 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
6538 false));
Fan Yang32c5a112018-12-10 20:06:336539 mock_quic_data.AddRead(
6540 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036541 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286542 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566543
Andrew Williams826d8742024-01-31 19:39:196544 const char kGetRequest[] =
Yixin Wang46a273ec302018-01-23 17:59:566545 "GET / HTTP/1.1\r\n"
6546 "Host: mail.example.org\r\n"
6547 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526548 mock_quic_data.AddWrite(
6549 SYNCHRONOUS,
6550 ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036551 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
Andrew Williams826d8742024-01-31 19:39:196552 false, ConstructDataFrame(kGetRequest)));
Renjief49758b2019-01-11 23:32:416553
Andrew Williams826d8742024-01-31 19:39:196554 const char kGetResponse[] =
Yixin Wang46a273ec302018-01-23 17:59:566555 "HTTP/1.1 200 OK\r\n"
6556 "Content-Length: 10\r\n\r\n";
Andrew Williams826d8742024-01-31 19:39:196557 const char kRespData[] = "0123456789";
6558
Zhongyi Shi32f2fd02018-04-16 18:23:436559 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336560 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036561 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Andrew Williams826d8742024-01-31 19:39:196562 ConstructDataFrame(kGetResponse)));
6563
Fan Yang32c5a112018-12-10 20:06:336564 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:416565 SYNCHRONOUS, ConstructServerDataPacket(
6566 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Andrew Williams826d8742024-01-31 19:39:196567 ConstructDataFrame(kRespData)));
Renjie Tangaadb84b2019-08-31 01:00:236568 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346569 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:566570 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6571
Patrick Meenan885a00652023-02-15 20:07:026572 mock_quic_data.AddWrite(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036573 SYNCHRONOUS,
6574 ConstructClientDataPacket(packet_num++, GetQpackDecoderStreamId(), false,
6575 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:076576
Yixin Wang46a273ec302018-01-23 17:59:566577 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:416578 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236579 ConstructClientRstPacket(packet_num++,
6580 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416581 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566582
6583 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6584
6585 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6586
6587 CreateSession();
6588
6589 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:096590 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Andrew Williams826d8742024-01-31 19:39:196591 SendRequestAndExpectHttpResponseFromProxy(
Dustin J. Mitchell5bf18582024-02-16 16:20:136592 kRespData, kQuicProxyChain.First().GetPort(), kQuicProxyChain);
Cammie Smith Barnesbf91e2a2020-12-23 20:49:046593
Yixin Wang46a273ec302018-01-23 17:59:566594 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
6595 // proxy socket to disconnect.
6596 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6597
6598 base::RunLoop().RunUntilIdle();
6599 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6600 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6601}
6602
6603// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:146604TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Patrick Meenan0b1b18cf2023-09-21 20:19:476605 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:566606 session_params_.enable_quic = true;
Andrew Williams826d8742024-01-31 19:39:196607
6608 const auto kQuicProxyChain =
6609 ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
6610 ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)});
Nicolas Arciniegad2013f92020-02-07 23:00:566611 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:006612 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Andrew Williams826d8742024-01-31 19:39:196613 {kQuicProxyChain}, TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566614
Ryan Hamiltonabad59e2019-06-06 04:02:596615 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236616 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026617 mock_quic_data.AddWrite(SYNCHRONOUS,
6618 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:436619
Patrick Meenan8f8c8352023-07-06 17:20:196620 mock_quic_data.AddWrite(
6621 SYNCHRONOUS,
6622 ConstructClientPriorityPacket(
6623 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6624 DEFAULT_PRIORITY));
Fan Yang32c5a112018-12-10 20:06:336625 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236626 SYNCHRONOUS,
6627 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036628 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
6629 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
6630 false));
Fan Yang32c5a112018-12-10 20:06:336631 mock_quic_data.AddRead(
6632 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036633 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286634 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566635
Patrick Meenan0b1b18cf2023-09-21 20:19:476636 SpdyTestUtil spdy_util(/*use_priority_header=*/true);
Yixin Wang46a273ec302018-01-23 17:59:566637
Ryan Hamilton0239aac2018-05-19 00:03:136638 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:566639 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:526640 mock_quic_data.AddWrite(
6641 SYNCHRONOUS,
6642 ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036643 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
6644 false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Ryan Hamilton0239aac2018-05-19 00:03:136645 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:566646 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:436647 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:176648 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036649 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:526650 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:566651
Andrew Williams826d8742024-01-31 19:39:196652 const char kRespData[] = "0123456789";
Ryan Hamilton0239aac2018-05-19 00:03:136653 spdy::SpdySerializedFrame data_frame =
Andrew Williams826d8742024-01-31 19:39:196654 spdy_util.ConstructSpdyDataFrame(1, kRespData, true);
Zhongyi Shi32f2fd02018-04-16 18:23:436655 mock_quic_data.AddRead(
6656 SYNCHRONOUS,
6657 ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036658 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:526659 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Renjie Tangaadb84b2019-08-31 01:00:236660 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346661 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:566662 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6663
Patrick Meenan885a00652023-02-15 20:07:026664 mock_quic_data.AddWrite(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036665 SYNCHRONOUS,
6666 ConstructClientDataPacket(packet_num++, GetQpackDecoderStreamId(), false,
6667 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:076668
Yixin Wang46a273ec302018-01-23 17:59:566669 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436670 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236671 ConstructClientRstPacket(packet_num++,
6672 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416673 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566674
6675 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6676
6677 SSLSocketDataProvider ssl_data(ASYNC, OK);
6678 ssl_data.next_proto = kProtoHTTP2;
6679 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
6680
6681 CreateSession();
6682
6683 request_.url = GURL("https://mail.example.org/");
Andrew Williams826d8742024-01-31 19:39:196684 SendRequestAndExpectSpdyResponseFromProxy(
Dustin J. Mitchell5bf18582024-02-16 16:20:136685 kRespData, kQuicProxyChain.First().GetPort(), kQuicProxyChain);
Yixin Wang46a273ec302018-01-23 17:59:566686
Andrew Williams826d8742024-01-31 19:39:196687 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
6688 // proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:566689 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6690
6691 base::RunLoop().RunUntilIdle();
6692 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6693 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6694}
6695
6696// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
6697// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:146698TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Patrick Meenan0b1b18cf2023-09-21 20:19:476699 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:566700 session_params_.enable_quic = true;
Andrew Williams826d8742024-01-31 19:39:196701
6702 const auto kQuicProxyChain =
6703 ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
6704 ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)});
Nicolas Arciniegad2013f92020-02-07 23:00:566705 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:006706 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Andrew Williams826d8742024-01-31 19:39:196707 {kQuicProxyChain}, TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566708
Ryan Hamiltonabad59e2019-06-06 04:02:596709 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:416710 int write_packet_index = 1;
Patrick Meenan885a00652023-02-15 20:07:026711 mock_quic_data.AddWrite(SYNCHRONOUS,
6712 ConstructInitialSettingsPacket(write_packet_index++));
Patrick Meenanf741c6082023-01-03 18:06:436713
Patrick Meenan8f8c8352023-07-06 17:20:196714 mock_quic_data.AddWrite(
6715 SYNCHRONOUS,
6716 ConstructClientPriorityPacket(
6717 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6718 DEFAULT_PRIORITY));
Fan Yang32c5a112018-12-10 20:06:336719 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:416720 SYNCHRONOUS,
6721 ConstructClientRequestHeadersPacket(
6722 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:036723 false, DEFAULT_PRIORITY,
Bence Béky957bab12023-01-31 16:40:106724 ConnectRequestHeaders("mail.example.org:443"), false));
Fan Yang32c5a112018-12-10 20:06:336725 mock_quic_data.AddRead(
6726 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036727 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286728 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566729
Andrew Williams826d8742024-01-31 19:39:196730 const char kGetRequest1[] =
Yixin Wang46a273ec302018-01-23 17:59:566731 "GET / HTTP/1.1\r\n"
6732 "Host: mail.example.org\r\n"
6733 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526734 mock_quic_data.AddWrite(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036735 SYNCHRONOUS,
6736 ConstructClientAckAndDataPacket(
6737 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Andrew Williams826d8742024-01-31 19:39:196738 1, 1, false, ConstructDataFrame(kGetRequest1)));
Renjief49758b2019-01-11 23:32:416739
Andrew Williams826d8742024-01-31 19:39:196740 const char kGetResponse1[] =
Yixin Wang46a273ec302018-01-23 17:59:566741 "HTTP/1.1 200 OK\r\n"
6742 "Content-Length: 10\r\n\r\n";
Andrew Williams826d8742024-01-31 19:39:196743 const char kRespData1[] = "0123456789";
6744
Zhongyi Shi32f2fd02018-04-16 18:23:436745 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:436746 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036747 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Andrew Williams826d8742024-01-31 19:39:196748 ConstructDataFrame(kGetResponse1)));
Yixin Wang46a273ec302018-01-23 17:59:566749
Fan Yang32c5a112018-12-10 20:06:336750 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:176751 SYNCHRONOUS, ConstructServerDataPacket(
6752 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Andrew Williams826d8742024-01-31 19:39:196753 ConstructDataFrame(kRespData1)));
Yixin Wang46a273ec302018-01-23 17:59:566754
Renjie Tangcd594f32020-07-11 20:18:346755 mock_quic_data.AddWrite(SYNCHRONOUS,
6756 ConstructClientAckPacket(write_packet_index++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:566757
Andrew Williams826d8742024-01-31 19:39:196758 const char kGetRequest2[] =
Yixin Wang46a273ec302018-01-23 17:59:566759 "GET /2 HTTP/1.1\r\n"
6760 "Host: mail.example.org\r\n"
6761 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526762 mock_quic_data.AddWrite(
6763 SYNCHRONOUS,
Tsuyoshi Horoea15e7a2023-05-23 00:12:036764 ConstructClientDataPacket(write_packet_index++,
6765 GetNthClientInitiatedBidirectionalStreamId(0),
Andrew Williams826d8742024-01-31 19:39:196766 false, ConstructDataFrame(kGetRequest2)));
Yixin Wang46a273ec302018-01-23 17:59:566767
Andrew Williams826d8742024-01-31 19:39:196768 const char kGetResponse2[] =
Yixin Wang46a273ec302018-01-23 17:59:566769 "HTTP/1.1 200 OK\r\n"
6770 "Content-Length: 7\r\n\r\n";
Andrew Williams826d8742024-01-31 19:39:196771 const char kRespData2[] = "0123456";
6772
Zhongyi Shi32f2fd02018-04-16 18:23:436773 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:436774 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036775 4, GetNthClientInitiatedBidirectionalStreamId(0), false,
Andrew Williams826d8742024-01-31 19:39:196776 ConstructDataFrame(kGetResponse2)));
Yixin Wang46a273ec302018-01-23 17:59:566777
Ryan Hamilton8d9ee76e2018-05-29 23:52:526778 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:176779 SYNCHRONOUS, ConstructServerDataPacket(
6780 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
Andrew Williams826d8742024-01-31 19:39:196781 ConstructDataFrame(kRespData2)));
Yixin Wang46a273ec302018-01-23 17:59:566782
Renjie Tangcd594f32020-07-11 20:18:346783 mock_quic_data.AddWrite(SYNCHRONOUS,
6784 ConstructClientAckPacket(write_packet_index++, 5, 4));
Yixin Wang46a273ec302018-01-23 17:59:566785 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6786
Patrick Meenan885a00652023-02-15 20:07:026787 mock_quic_data.AddWrite(
6788 SYNCHRONOUS, ConstructClientDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036789 write_packet_index++, GetQpackDecoderStreamId(), false,
6790 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:076791
Renjief49758b2019-01-11 23:32:416792 mock_quic_data.AddWrite(
6793 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416794 ConstructClientRstPacket(write_packet_index++,
6795 GetNthClientInitiatedBidirectionalStreamId(0),
6796 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566797
6798 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6799
6800 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6801
6802 CreateSession();
6803
6804 request_.url = GURL("https://mail.example.org/");
Andrew Williams826d8742024-01-31 19:39:196805 SendRequestAndExpectHttpResponseFromProxy(
Dustin J. Mitchell5bf18582024-02-16 16:20:136806 kRespData1, kQuicProxyChain.First().GetPort(), kQuicProxyChain);
Yixin Wang46a273ec302018-01-23 17:59:566807
6808 request_.url = GURL("https://mail.example.org/2");
Andrew Williams826d8742024-01-31 19:39:196809 SendRequestAndExpectHttpResponseFromProxy(
Dustin J. Mitchell5bf18582024-02-16 16:20:136810 kRespData2, kQuicProxyChain.First().GetPort(), kQuicProxyChain);
Yixin Wang46a273ec302018-01-23 17:59:566811
6812 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
6813 // proxy socket to disconnect.
6814 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6815
6816 base::RunLoop().RunUntilIdle();
6817 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6818 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6819}
6820
6821// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
6822// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
6823// server is reused for the second request.
Bence Békyf6bb6b22020-04-17 20:22:116824TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Patrick Meenan0b1b18cf2023-09-21 20:19:476825 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:566826 session_params_.enable_quic = true;
Andrew Williams826d8742024-01-31 19:39:196827
6828 const auto kQuicProxyChain =
6829 ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
6830 ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)});
Nicolas Arciniegad2013f92020-02-07 23:00:566831 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:006832 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Andrew Williams826d8742024-01-31 19:39:196833 {kQuicProxyChain}, TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566834
Ryan Hamiltonabad59e2019-06-06 04:02:596835 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236836 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:026837 mock_quic_data.AddWrite(SYNCHRONOUS,
6838 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:436839
Patrick Meenan8f8c8352023-07-06 17:20:196840 mock_quic_data.AddWrite(
6841 SYNCHRONOUS,
6842 ConstructClientPriorityPacket(
6843 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
6844 DEFAULT_PRIORITY));
Yixin Wang46a273ec302018-01-23 17:59:566845
6846 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:336847 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236848 SYNCHRONOUS,
6849 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036850 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
6851 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
6852 false));
Zhongyi Shi32f2fd02018-04-16 18:23:436853 mock_quic_data.AddRead(
6854 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036855 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286856 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566857
6858 // GET request, response, and data over QUIC tunnel for first request
Andrew Williams826d8742024-01-31 19:39:196859 const char kGetRequest[] =
Yixin Wang46a273ec302018-01-23 17:59:566860 "GET / HTTP/1.1\r\n"
6861 "Host: mail.example.org\r\n"
6862 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:526863 mock_quic_data.AddWrite(
6864 SYNCHRONOUS,
6865 ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036866 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
Andrew Williams826d8742024-01-31 19:39:196867 false, ConstructDataFrame(kGetRequest)));
Renjief49758b2019-01-11 23:32:416868
Andrew Williams826d8742024-01-31 19:39:196869 const char kGetResponse[] =
Yixin Wang46a273ec302018-01-23 17:59:566870 "HTTP/1.1 200 OK\r\n"
6871 "Content-Length: 10\r\n\r\n";
Andrew Williams826d8742024-01-31 19:39:196872 const char kRespData1[] = "0123456789";
6873
Yixin Wang46a273ec302018-01-23 17:59:566874 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336875 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036876 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Andrew Williams826d8742024-01-31 19:39:196877 ConstructDataFrame(kGetResponse)));
Fan Yang32c5a112018-12-10 20:06:336878 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:416879 SYNCHRONOUS, ConstructServerDataPacket(
6880 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Andrew Williams826d8742024-01-31 19:39:196881 ConstructDataFrame(kRespData1)));
Renjie Tangaadb84b2019-08-31 01:00:236882 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346883 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:566884
6885 // CONNECT request and response for second request
Patrick Meenan8f8c8352023-07-06 17:20:196886 mock_quic_data.AddWrite(
6887 SYNCHRONOUS,
6888 ConstructClientPriorityPacket(
6889 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
6890 DEFAULT_PRIORITY));
Zhongyi Shi32f2fd02018-04-16 18:23:436891 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236892 SYNCHRONOUS,
6893 ConstructClientRequestHeadersPacket(
6894 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:036895 DEFAULT_PRIORITY, ConnectRequestHeaders("different.example.org:443"),
6896 false));
Zhongyi Shi32f2fd02018-04-16 18:23:436897 mock_quic_data.AddRead(
6898 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036899 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:286900 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:566901
6902 // GET request, response, and data over QUIC tunnel for second request
Patrick Meenan0b1b18cf2023-09-21 20:19:476903 SpdyTestUtil spdy_util(/*use_priority_header=*/true);
Ryan Hamilton0239aac2018-05-19 00:03:136904 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:566905 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:526906 mock_quic_data.AddWrite(
6907 SYNCHRONOUS,
6908 ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036909 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4,
6910 false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:566911
Ryan Hamilton0239aac2018-05-19 00:03:136912 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:566913 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:436914 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:176915 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036916 5, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:526917 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:566918
Andrew Williams826d8742024-01-31 19:39:196919 const char kRespData2[] = "0123456";
Ryan Hamilton0239aac2018-05-19 00:03:136920 spdy::SpdySerializedFrame data_frame =
Andrew Williams826d8742024-01-31 19:39:196921 spdy_util.ConstructSpdyDataFrame(1, kRespData2, true);
Zhongyi Shi32f2fd02018-04-16 18:23:436922 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:436923 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036924 6, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:526925 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:566926
Renjie Tangaadb84b2019-08-31 01:00:236927 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346928 ConstructClientAckPacket(packet_num++, 6, 5));
Yixin Wang46a273ec302018-01-23 17:59:566929 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Patrick Meenan885a00652023-02-15 20:07:026930 mock_quic_data.AddWrite(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036931 SYNCHRONOUS,
6932 ConstructClientDataPacket(packet_num++, GetQpackDecoderStreamId(), false,
6933 StreamCancellationQpackDecoderInstruction(0)));
Yixin Wang46a273ec302018-01-23 17:59:566934 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:416935 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236936 ConstructClientRstPacket(packet_num++,
6937 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416938 quic::QUIC_STREAM_CANCELLED));
Patrick Meenan885a00652023-02-15 20:07:026939 mock_quic_data.AddWrite(
6940 SYNCHRONOUS, ConstructClientDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:036941 packet_num++, GetQpackDecoderStreamId(), false,
Patrick Meenan885a00652023-02-15 20:07:026942 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:076943
Yixin Wang46a273ec302018-01-23 17:59:566944 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436945 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:236946 ConstructClientRstPacket(packet_num++,
6947 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:416948 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:566949
6950 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6951
6952 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6953
6954 SSLSocketDataProvider ssl_data(ASYNC, OK);
6955 ssl_data.next_proto = kProtoHTTP2;
6956 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
6957
6958 CreateSession();
6959
6960 request_.url = GURL("https://mail.example.org/");
Andrew Williams826d8742024-01-31 19:39:196961 SendRequestAndExpectHttpResponseFromProxy(
Dustin J. Mitchell5bf18582024-02-16 16:20:136962 kRespData1, kQuicProxyChain.First().GetPort(), kQuicProxyChain);
Yixin Wang46a273ec302018-01-23 17:59:566963
6964 request_.url = GURL("https://different.example.org/");
Andrew Williams826d8742024-01-31 19:39:196965 SendRequestAndExpectSpdyResponseFromProxy(
Dustin J. Mitchell5bf18582024-02-16 16:20:136966 kRespData2, kQuicProxyChain.First().GetPort(), kQuicProxyChain);
Yixin Wang46a273ec302018-01-23 17:59:566967
6968 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
6969 // proxy socket to disconnect.
6970 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6971
6972 base::RunLoop().RunUntilIdle();
6973 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6974 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6975}
6976
Andrew Williams5fcff8e2024-01-23 21:22:416977// Make two HTTP/1.1 requests, one to a host through a QUIC proxy and another
6978// directly to the proxy. The proxy socket should not be reused for the second
6979// request.
6980TEST_P(QuicNetworkTransactionTest, QuicProxyConnectNoReuseDifferentChains) {
6981 DisablePriorityHeader();
6982 session_params_.enable_quic = true;
Andrew Williams5fcff8e2024-01-23 21:22:416983
6984 const ProxyServer kQuicProxyServer{ProxyServer::SCHEME_QUIC,
6985 HostPortPair("proxy.example.org", 443)};
Ciara McMullin20d24572024-01-31 13:15:536986 const ProxyChain kQuicProxyChain =
6987 ProxyChain::ForIpProtection({kQuicProxyServer});
Andrew Williams5fcff8e2024-01-23 21:22:416988
6989 proxy_delegate_ = std::make_unique<TestProxyDelegate>();
6990 proxy_delegate_->set_proxy_chain(kQuicProxyChain);
6991
6992 proxy_resolution_service_ =
6993 ConfiguredProxyResolutionService::CreateFixedForTest(
6994 "https://not-used:70", TRAFFIC_ANNOTATION_FOR_TESTS);
6995 proxy_resolution_service_->SetProxyDelegate(proxy_delegate_.get());
6996
6997 MockQuicData mock_quic_data_1(version_);
6998 size_t write_packet_index = 1;
6999
7000 mock_quic_data_1.AddWrite(
7001 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7002
7003 mock_quic_data_1.AddWrite(
7004 SYNCHRONOUS,
7005 ConstructClientPriorityPacket(
7006 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7007 DEFAULT_PRIORITY));
7008 mock_quic_data_1.AddWrite(
7009 SYNCHRONOUS,
7010 ConstructClientRequestHeadersPacket(
7011 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7012 false, DEFAULT_PRIORITY,
7013 ConnectRequestHeaders("mail.example.org:443"), false));
7014 mock_quic_data_1.AddRead(
7015 ASYNC, ConstructServerResponseHeadersPacket(
7016 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
7017 GetResponseHeaders("200")));
7018
Andrew Williams826d8742024-01-31 19:39:197019 const char kGetRequest1[] =
Andrew Williams5fcff8e2024-01-23 21:22:417020 "GET / HTTP/1.1\r\n"
7021 "Host: mail.example.org\r\n"
7022 "Connection: keep-alive\r\n\r\n";
7023 mock_quic_data_1.AddWrite(
7024 SYNCHRONOUS,
7025 ConstructClientAckAndDataPacket(
7026 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Andrew Williams826d8742024-01-31 19:39:197027 1, 1, false, ConstructDataFrame(kGetRequest1)));
Andrew Williams5fcff8e2024-01-23 21:22:417028
Andrew Williams826d8742024-01-31 19:39:197029 const char kGetResponse1[] =
Andrew Williams5fcff8e2024-01-23 21:22:417030 "HTTP/1.1 200 OK\r\n"
7031 "Content-Length: 10\r\n\r\n";
Andrew Williams826d8742024-01-31 19:39:197032 const char kTrans1RespData[] = "0123456789";
7033
Andrew Williams5fcff8e2024-01-23 21:22:417034 mock_quic_data_1.AddRead(
7035 ASYNC, ConstructServerDataPacket(
7036 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Andrew Williams826d8742024-01-31 19:39:197037 ConstructDataFrame(kGetResponse1)));
Andrew Williams5fcff8e2024-01-23 21:22:417038
Andrew Williams5fcff8e2024-01-23 21:22:417039 mock_quic_data_1.AddRead(
7040 SYNCHRONOUS, ConstructServerDataPacket(
7041 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7042 ConstructDataFrame(kTrans1RespData)));
7043
7044 mock_quic_data_1.AddWrite(
7045 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2));
7046 mock_quic_data_1.AddRead(SYNCHRONOUS,
7047 ERR_IO_PENDING); // No more data to read
7048
7049 mock_quic_data_1.AddWrite(
7050 SYNCHRONOUS, ConstructClientDataPacket(
7051 write_packet_index++, GetQpackDecoderStreamId(), false,
7052 StreamCancellationQpackDecoderInstruction(0)));
7053
7054 mock_quic_data_1.AddWrite(
7055 SYNCHRONOUS,
7056 ConstructClientRstPacket(write_packet_index++,
7057 GetNthClientInitiatedBidirectionalStreamId(0),
7058 quic::QUIC_STREAM_CANCELLED));
7059
7060 mock_quic_data_1.AddSocketDataToFactory(&socket_factory_);
7061
7062 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7063
7064 CreateSession();
7065
7066 request_.url = GURL("https://mail.example.org/");
Andrew Williams826d8742024-01-31 19:39:197067 SendRequestAndExpectHttpResponseFromProxy(kTrans1RespData, 443,
7068 kQuicProxyChain);
Andrew Williams5fcff8e2024-01-23 21:22:417069
7070 proxy_delegate_->set_proxy_chain(ProxyChain::Direct());
7071
7072 context_.params()->origins_to_force_quic_on.insert(
7073 kQuicProxyServer.host_port_pair());
7074
7075 QuicTestPacketMaker client_maker2(
7076 version_,
7077 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7078 context_.clock(), kQuicProxyServer.GetHost(),
7079 quic::Perspective::IS_CLIENT,
7080 /*client_priority_uses_incremental=*/true,
7081 /*use_priority_header=*/GetParam().priority_header_enabled);
7082
7083 QuicTestPacketMaker server_maker2(
7084 version_,
7085 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7086 context_.clock(), kQuicProxyServer.GetHost(),
7087 quic::Perspective::IS_SERVER,
7088 /*client_priority_uses_incremental=*/false,
7089 /*use_priority_header=*/false);
7090
7091 MockQuicData mock_quic_data_2(version_);
7092 write_packet_index = 1;
7093
7094 mock_quic_data_2.AddWrite(
7095 SYNCHRONOUS,
7096 client_maker2.MakeInitialSettingsPacket(write_packet_index++));
7097
7098 mock_quic_data_2.AddWrite(
7099 SYNCHRONOUS,
7100 client_maker2.MakeRequestHeadersPacket(
7101 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7102 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
7103 GetRequestHeaders("GET", "https", "/", &client_maker2), nullptr));
7104 mock_quic_data_2.AddRead(
7105 ASYNC, server_maker2.MakeResponseHeadersPacket(
7106 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
7107 GetResponseHeaders("200"), nullptr));
7108 const char kTrans2RespData[] = "0123456";
7109 mock_quic_data_2.AddRead(
7110 ASYNC, server_maker2.MakeDataPacket(
7111 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7112 ConstructDataFrame(kTrans2RespData)));
7113 mock_quic_data_2.AddWrite(
7114 SYNCHRONOUS, client_maker2.MakeAckPacket(write_packet_index++, 2, 1));
7115 mock_quic_data_2.AddRead(SYNCHRONOUS,
7116 ERR_IO_PENDING); // No more data to read
7117
7118 mock_quic_data_2.AddSocketDataToFactory(&socket_factory_);
7119
7120 SSLSocketDataProvider ssl_2(ASYNC, OK);
7121 socket_factory_.AddSSLSocketDataProvider(&ssl_2);
7122
7123 request_.url =
7124 GURL(base::StrCat({"https://", kQuicProxyServer.GetHost(), "/"}));
Andrew Williams826d8742024-01-31 19:39:197125 SendRequestAndExpectQuicResponse(kTrans2RespData);
Andrew Williams5fcff8e2024-01-23 21:22:417126
7127 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7128 // proxy socket to disconnect.
7129 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7130
7131 base::RunLoop().RunUntilIdle();
7132 EXPECT_TRUE(mock_quic_data_1.AllReadDataConsumed());
7133 EXPECT_TRUE(mock_quic_data_1.AllWriteDataConsumed());
7134 EXPECT_TRUE(mock_quic_data_2.AllReadDataConsumed());
7135 EXPECT_TRUE(mock_quic_data_2.AllWriteDataConsumed());
7136}
7137
Yixin Wang46a273ec302018-01-23 17:59:567138// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:147139TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Patrick Meenan0b1b18cf2023-09-21 20:19:477140 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:567141 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567142 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:007143 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Ciara McMullin20d24572024-01-31 13:15:537144 {ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
7145 ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)})},
Ciara McMullin021c66e2024-01-19 16:47:007146 TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567147
Ryan Hamiltonabad59e2019-06-06 04:02:597148 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237149 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:027150 mock_quic_data.AddWrite(SYNCHRONOUS,
7151 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:437152
Patrick Meenan8f8c8352023-07-06 17:20:197153 mock_quic_data.AddWrite(
7154 SYNCHRONOUS,
7155 ConstructClientPriorityPacket(
7156 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
7157 DEFAULT_PRIORITY));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527158 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237159 SYNCHRONOUS,
7160 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037161 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
7162 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
7163 false));
Fan Yang32c5a112018-12-10 20:06:337164 mock_quic_data.AddRead(
7165 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037166 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
Fan Yang32c5a112018-12-10 20:06:337167 GetResponseHeaders("500")));
7168 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:237169 mock_quic_data.AddWrite(
7170 SYNCHRONOUS,
7171 ConstructClientAckAndRstPacket(
7172 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:347173 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567174
7175 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7176
7177 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7178
7179 CreateSession();
7180
7181 request_.url = GURL("https://mail.example.org/");
7182 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567183 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267184 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:567185 EXPECT_EQ(ERR_IO_PENDING, rv);
7186 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
Yixin Wang46a273ec302018-01-23 17:59:567187
7188 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7189 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7190}
7191
7192// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:147193TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Patrick Meenan0b1b18cf2023-09-21 20:19:477194 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:567195 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567196 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:007197 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Ciara McMullin20d24572024-01-31 13:15:537198 {ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
7199 ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)})},
Ciara McMullin021c66e2024-01-19 16:47:007200 TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567201
Ryan Hamiltonabad59e2019-06-06 04:02:597202 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237203 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:027204 mock_quic_data.AddWrite(SYNCHRONOUS,
7205 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenan8f8c8352023-07-06 17:20:197206 mock_quic_data.AddWrite(
7207 SYNCHRONOUS,
7208 ConstructClientPriorityPacket(
7209 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
7210 DEFAULT_PRIORITY));
Fan Yang32c5a112018-12-10 20:06:337211 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237212 SYNCHRONOUS,
7213 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037214 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
7215 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
7216 false));
Yixin Wang46a273ec302018-01-23 17:59:567217 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7218
7219 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7220
7221 CreateSession();
7222
7223 request_.url = GURL("https://mail.example.org/");
7224 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567225 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267226 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:567227 EXPECT_EQ(ERR_IO_PENDING, rv);
7228 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7229
7230 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7231 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7232}
7233
7234// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
7235// host. Retries request and succeeds.
Bence Békyf6bb6b22020-04-17 20:22:117236TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Patrick Meenan0b1b18cf2023-09-21 20:19:477237 DisablePriorityHeader();
Yixin Wang46a273ec302018-01-23 17:59:567238 session_params_.enable_quic = true;
Andrew Williams826d8742024-01-31 19:39:197239
7240 const auto kQuicProxyChain =
7241 ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
7242 ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)});
Nicolas Arciniegad2013f92020-02-07 23:00:567243 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:007244 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Andrew Williams826d8742024-01-31 19:39:197245 {kQuicProxyChain}, TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567246
Ryan Hamiltonabad59e2019-06-06 04:02:597247 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237248 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:027249 mock_quic_data.AddWrite(SYNCHRONOUS,
7250 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:437251
Patrick Meenan8f8c8352023-07-06 17:20:197252 mock_quic_data.AddWrite(
7253 SYNCHRONOUS,
7254 ConstructClientPriorityPacket(
7255 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
7256 DEFAULT_PRIORITY));
Fan Yang32c5a112018-12-10 20:06:337257 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237258 SYNCHRONOUS,
7259 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037260 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
7261 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
7262 false));
Zhongyi Shi32f2fd02018-04-16 18:23:437263 mock_quic_data.AddRead(
7264 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037265 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287266 GetResponseHeaders("200")));
Patrick Meenan885a00652023-02-15 20:07:027267 mock_quic_data.AddWrite(
7268 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037269 packet_num++, GetQpackDecoderStreamId(), 1, 1, false,
7270 StreamCancellationQpackDecoderInstruction(0)));
Patrick Meenan885a00652023-02-15 20:07:027271 mock_quic_data.AddWrite(
7272 SYNCHRONOUS,
7273 ConstructClientRstPacket(packet_num++,
7274 GetNthClientInitiatedBidirectionalStreamId(0),
7275 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567276
Patrick Meenan8f8c8352023-07-06 17:20:197277 mock_quic_data.AddWrite(
7278 SYNCHRONOUS,
7279 ConstructClientPriorityPacket(
7280 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
7281 DEFAULT_PRIORITY));
Zhongyi Shi32f2fd02018-04-16 18:23:437282 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237283 SYNCHRONOUS,
7284 ConstructClientRequestHeadersPacket(
7285 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037286 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
7287 false));
Zhongyi Shi32f2fd02018-04-16 18:23:437288 mock_quic_data.AddRead(
7289 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037290 2, GetNthClientInitiatedBidirectionalStreamId(1), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:287291 GetResponseHeaders("200")));
Yixin Wang46a273ec302018-01-23 17:59:567292
Andrew Williams826d8742024-01-31 19:39:197293 const char kGetRequest[] =
Yixin Wang46a273ec302018-01-23 17:59:567294 "GET / HTTP/1.1\r\n"
7295 "Host: mail.example.org\r\n"
7296 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:527297 mock_quic_data.AddWrite(
7298 SYNCHRONOUS,
7299 ConstructClientAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037300 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2,
Andrew Williams826d8742024-01-31 19:39:197301 false, ConstructDataFrame(kGetRequest)));
7302
7303 const char kGetResponse[] =
Yixin Wang46a273ec302018-01-23 17:59:567304 "HTTP/1.1 200 OK\r\n"
7305 "Content-Length: 10\r\n\r\n";
Andrew Williams826d8742024-01-31 19:39:197306 const char kRespData[] = "0123456789";
7307
Zhongyi Shi32f2fd02018-04-16 18:23:437308 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337309 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037310 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Andrew Williams826d8742024-01-31 19:39:197311 ConstructDataFrame(kGetResponse)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527312
Fan Yang32c5a112018-12-10 20:06:337313 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417314 SYNCHRONOUS, ConstructServerDataPacket(
7315 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Andrew Williams826d8742024-01-31 19:39:197316 ConstructDataFrame(kRespData)));
Renjie Tangaadb84b2019-08-31 01:00:237317 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347318 ConstructClientAckPacket(packet_num++, 4, 3));
Yixin Wang46a273ec302018-01-23 17:59:567319 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7320
Patrick Meenan885a00652023-02-15 20:07:027321 mock_quic_data.AddWrite(
7322 SYNCHRONOUS, ConstructClientDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037323 packet_num++, GetQpackDecoderStreamId(), false,
Patrick Meenan885a00652023-02-15 20:07:027324 StreamCancellationQpackDecoderInstruction(1, false)));
Yixin Wang46a273ec302018-01-23 17:59:567325 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417326 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237327 ConstructClientRstPacket(packet_num++,
7328 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417329 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567330
7331 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7332
7333 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7334 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
7335
7336 SSLSocketDataProvider ssl_data(ASYNC, OK);
7337 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7338
7339 CreateSession();
7340
7341 request_.url = GURL("https://mail.example.org/");
7342 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567343 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267344 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:567345 EXPECT_EQ(ERR_IO_PENDING, rv);
7346 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
7347
7348 rv = trans.RestartIgnoringLastError(callback.callback());
7349 EXPECT_EQ(ERR_IO_PENDING, rv);
7350 EXPECT_EQ(OK, callback.WaitForResult());
7351
7352 CheckWasHttpResponse(&trans);
Dustin J. Mitchell5bf18582024-02-16 16:20:137353 CheckResponsePort(&trans, kQuicProxyChain.First().GetPort());
Andrew Williams826d8742024-01-31 19:39:197354 CheckResponseData(&trans, kRespData);
7355 EXPECT_EQ(trans.GetResponseInfo()->proxy_chain, kQuicProxyChain);
Yixin Wang46a273ec302018-01-23 17:59:567356
7357 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7358 // proxy socket to disconnect.
7359 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7360
7361 base::RunLoop().RunUntilIdle();
7362 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7363 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7364}
7365
7366// Checks if a request's specified "user-agent" header shows up correctly in the
7367// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:147368TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Patrick Meenan0b1b18cf2023-09-21 20:19:477369 DisablePriorityHeader();
Matt Menked732ea42019-03-08 12:05:007370 const char kConfiguredUserAgent[] = "Configured User-Agent";
7371 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:567372 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567373 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:007374 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Ciara McMullin20d24572024-01-31 13:15:537375 {ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
7376 ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)})},
Ciara McMullin021c66e2024-01-19 16:47:007377 TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567378
Ryan Hamiltonabad59e2019-06-06 04:02:597379 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237380 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:027381 mock_quic_data.AddWrite(SYNCHRONOUS,
7382 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenan8f8c8352023-07-06 17:20:197383 mock_quic_data.AddWrite(
7384 SYNCHRONOUS,
7385 ConstructClientPriorityPacket(
7386 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
7387 DEFAULT_PRIORITY));
Yixin Wang46a273ec302018-01-23 17:59:567388
Bence Béky4c325e52020-10-22 20:48:017389 spdy::Http2HeaderBlock headers =
7390 ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:007391 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:337392 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027393 SYNCHRONOUS,
7394 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037395 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
7396 DEFAULT_PRIORITY, std::move(headers), false));
Yixin Wang46a273ec302018-01-23 17:59:567397 // Return an error, so the transaction stops here (this test isn't interested
7398 // in the rest).
7399 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7400
7401 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7402
Matt Menked732ea42019-03-08 12:05:007403 StaticHttpUserAgentSettings http_user_agent_settings(
7404 std::string() /* accept_language */, kConfiguredUserAgent);
7405 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:567406 CreateSession();
7407
7408 request_.url = GURL("https://mail.example.org/");
7409 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:007410 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:567411 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567412 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267413 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang46a273ec302018-01-23 17:59:567414 EXPECT_EQ(ERR_IO_PENDING, rv);
7415 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7416
7417 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7418 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7419}
7420
Yixin Wang00fc44c2018-01-23 21:12:207421// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
7422// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:147423TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Patrick Meenan0b1b18cf2023-09-21 20:19:477424 DisablePriorityHeader();
Yixin Wang00fc44c2018-01-23 21:12:207425 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567426 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:007427 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Ciara McMullin20d24572024-01-31 13:15:537428 {ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
7429 ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)})},
Ciara McMullin021c66e2024-01-19 16:47:007430 TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:207431
7432 const RequestPriority request_priority = MEDIUM;
7433
Ryan Hamiltonabad59e2019-06-06 04:02:597434 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237435 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:027436 mock_quic_data.AddWrite(SYNCHRONOUS,
7437 ConstructInitialSettingsPacket(packet_num++));
Patrick Meenan8f8c8352023-07-06 17:20:197438 mock_quic_data.AddWrite(
7439 SYNCHRONOUS,
7440 ConstructClientPriorityPacket(
7441 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
7442 DEFAULT_PRIORITY));
Zhongyi Shi32f2fd02018-04-16 18:23:437443 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237444 SYNCHRONOUS,
7445 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037446 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
7447 DEFAULT_PRIORITY, ConnectRequestHeaders("mail.example.org:443"),
7448 false));
Yixin Wang00fc44c2018-01-23 21:12:207449 // Return an error, so the transaction stops here (this test isn't interested
7450 // in the rest).
7451 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7452
7453 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7454
7455 CreateSession();
7456
7457 request_.url = GURL("https://mail.example.org/");
7458 HttpNetworkTransaction trans(request_priority, session_.get());
7459 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267460 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yixin Wang00fc44c2018-01-23 21:12:207461 EXPECT_EQ(ERR_IO_PENDING, rv);
7462 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7463
7464 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7465 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7466}
7467
Matt Menkeedaf3b82019-03-14 21:39:447468// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
7469// HTTP/2 stream dependency and weights given the request priority.
7470TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
7471 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567472 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:007473 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Ciara McMullin20d24572024-01-31 13:15:537474 {ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
7475 ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)})},
Ciara McMullin021c66e2024-01-19 16:47:007476 TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeedaf3b82019-03-14 21:39:447477
7478 const RequestPriority kRequestPriority = MEDIUM;
7479 const RequestPriority kRequestPriority2 = LOWEST;
7480
Ryan Hamiltonabad59e2019-06-06 04:02:597481 MockQuicData mock_quic_data(version_);
Patrick Meenan885a00652023-02-15 20:07:027482 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
7483 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
Matt Menkeedaf3b82019-03-14 21:39:447484 // This should never be reached.
7485 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7486 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7487
7488 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:597489 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:447490 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
7491 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7492
7493 int original_max_sockets_per_group =
7494 ClientSocketPoolManager::max_sockets_per_group(
7495 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
7496 ClientSocketPoolManager::set_max_sockets_per_group(
7497 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
7498 int original_max_sockets_per_pool =
7499 ClientSocketPoolManager::max_sockets_per_pool(
7500 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
7501 ClientSocketPoolManager::set_max_sockets_per_pool(
7502 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
7503 CreateSession();
7504
7505 request_.url = GURL("https://mail.example.org/");
7506 HttpNetworkTransaction trans(kRequestPriority, session_.get());
7507 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:267508 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Matt Menkeedaf3b82019-03-14 21:39:447509 EXPECT_EQ(ERR_IO_PENDING, rv);
7510
7511 HttpRequestInfo request2;
7512 request2.url = GURL("https://mail.example.org/some/other/path/");
7513 request2.traffic_annotation =
7514 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7515
7516 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
7517 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:267518 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
Matt Menkeedaf3b82019-03-14 21:39:447519 EXPECT_EQ(ERR_IO_PENDING, rv2);
7520
7521 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7522 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7523
7524 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
7525
7526 ClientSocketPoolManager::set_max_sockets_per_pool(
7527 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
7528 original_max_sockets_per_pool);
7529 ClientSocketPoolManager::set_max_sockets_per_group(
7530 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
7531 original_max_sockets_per_group);
7532}
7533
Yixin Wang46a273ec302018-01-23 17:59:567534// Test the request-challenge-retry sequence for basic auth, over a QUIC
7535// connection when setting up a QUIC proxy tunnel.
Bence Békyf6bb6b22020-04-17 20:22:117536TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Jan Wilken Dörriec92a6d7242021-03-23 17:43:487537 const std::u16string kBaz(u"baz");
7538 const std::u16string kFoo(u"foo");
Yixin Wang46a273ec302018-01-23 17:59:567539
Matt Menked0e29e302024-03-26 12:47:267540 session_params_.enable_quic = true;
7541 proxy_resolution_service_ =
7542 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
7543 {ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
7544 ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)})},
7545 TRAFFIC_ANNOTATION_FOR_TESTS);
7546
Yixin Wang46a273ec302018-01-23 17:59:567547 // On the second pass, the body read of the auth challenge is synchronous, so
7548 // IsConnectedAndIdle returns false. The socket should still be drained and
7549 // reused. See http://crbug.com/544255.
7550 for (int i = 0; i < 2; ++i) {
Bence Béky6e243aa2019-12-13 19:01:077551 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227552 version_,
7553 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7554 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky957bab12023-01-31 16:40:107555 true);
Bence Béky6e243aa2019-12-13 19:01:077556 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227557 version_,
7558 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7559 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Bence Béky6e243aa2019-12-13 19:01:077560 false);
Yixin Wang46a273ec302018-01-23 17:59:567561
Ryan Hamiltonabad59e2019-06-06 04:02:597562 MockQuicData mock_quic_data(version_);
Yixin Wang46a273ec302018-01-23 17:59:567563
Renjie Tangaadb84b2019-08-31 01:00:237564 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:027565 mock_quic_data.AddWrite(
7566 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:437567
Patrick Meenan8f8c8352023-07-06 17:20:197568 mock_quic_data.AddWrite(
7569 SYNCHRONOUS,
7570 client_maker.MakePriorityPacket(
7571 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
7572 quic::HttpStreamPriority::kDefaultUrgency));
Yixin Wang46a273ec302018-01-23 17:59:567573
7574 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437575 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:077576 client_maker.MakeRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037577 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
7578 quic::HttpStreamPriority::kDefaultUrgency,
Bence Béky957bab12023-01-31 16:40:107579 client_maker.ConnectRequestHeaders("mail.example.org:443"), nullptr,
7580 false));
Yixin Wang46a273ec302018-01-23 17:59:567581
Kenichi Ishibashif8634ab2021-03-16 23:41:287582 spdy::Http2HeaderBlock headers = server_maker.GetResponseHeaders("407");
Yixin Wang46a273ec302018-01-23 17:59:567583 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
7584 headers["content-length"] = "10";
7585 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:077586 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337587 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037588 std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:567589
7590 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:437591 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:077592 ASYNC, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:337593 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037594 "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:567595 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:437596 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:077597 SYNCHRONOUS, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:337598 2, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:037599 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:567600 }
Yixin Wang46a273ec302018-01-23 17:59:567601
Bence Béky7a45d4d2020-05-08 01:59:237602 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347603 client_maker.MakeAckPacket(packet_num++, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:077604
Patrick Meenan885a00652023-02-15 20:07:027605 mock_quic_data.AddWrite(
7606 SYNCHRONOUS,
7607 client_maker.MakeDataPacket(
7608 packet_num++, GetQpackDecoderStreamId(),
Patrick Meenan885a00652023-02-15 20:07:027609 /* fin = */ false, StreamCancellationQpackDecoderInstruction(0)));
Yixin Wang46a273ec302018-01-23 17:59:567610
7611 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337612 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:077613 client_maker.MakeRstPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037614 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417615 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:187616 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:567617
Patrick Meenan8f8c8352023-07-06 17:20:197618 mock_quic_data.AddWrite(
7619 SYNCHRONOUS,
7620 client_maker.MakePriorityPacket(
7621 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
7622 quic::HttpStreamPriority::kDefaultUrgency));
Patrick Meenanf741c6082023-01-03 18:06:437623
Bence Béky6e243aa2019-12-13 19:01:077624 headers = client_maker.ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:567625 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
7626 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:047627 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:077628 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237629 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037630 quic::HttpStreamPriority::kDefaultUrgency, std::move(headers),
7631 nullptr, false));
Yixin Wang46a273ec302018-01-23 17:59:567632
7633 // Response to wrong password
Kenichi Ishibashif8634ab2021-03-16 23:41:287634 headers = server_maker.GetResponseHeaders("407");
Yixin Wang46a273ec302018-01-23 17:59:567635 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
7636 headers["content-length"] = "10";
7637 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:077638 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337639 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:037640 std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:567641 mock_quic_data.AddRead(SYNCHRONOUS,
7642 ERR_IO_PENDING); // No more data to read
7643
Patrick Meenan885a00652023-02-15 20:07:027644 mock_quic_data.AddWrite(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037645 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
7646 packet_num++, GetQpackDecoderStreamId(), 3, 3, false,
7647 StreamCancellationQpackDecoderInstruction(1, false)));
Patrick Meenan885a00652023-02-15 20:07:027648 mock_quic_data.AddWrite(
7649 SYNCHRONOUS,
7650 client_maker.MakeRstPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:037651 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
Patrick Meenan885a00652023-02-15 20:07:027652 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567653
7654 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7655 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
7656
7657 CreateSession();
7658
7659 request_.url = GURL("https://mail.example.org/");
7660 // Ensure that proxy authentication is attempted even
Matt Menke25eaa432020-08-25 00:10:007661 // when privacy mode is enabled.
7662 request_.privacy_mode = PRIVACY_MODE_ENABLED;
Yixin Wang46a273ec302018-01-23 17:59:567663 {
7664 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567665 RunTransaction(&trans);
7666
7667 const HttpResponseInfo* response = trans.GetResponseInfo();
7668 ASSERT_TRUE(response != nullptr);
7669 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:287670 EXPECT_EQ("HTTP/1.1 407", response->headers->GetStatusLine());
Yixin Wang46a273ec302018-01-23 17:59:567671 EXPECT_TRUE(response->headers->IsKeepAlive());
7672 EXPECT_EQ(407, response->headers->response_code());
7673 EXPECT_EQ(10, response->headers->GetContentLength());
7674 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Arthur Sonzogni4787fce2024-02-08 13:42:487675 std::optional<AuthChallengeInfo> auth_challenge =
Emily Starkf2c9bbd2019-04-09 17:08:587676 response->auth_challenge;
7677 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:567678 EXPECT_TRUE(auth_challenge->is_proxy);
7679 EXPECT_EQ("https://proxy.example.org:70",
7680 auth_challenge->challenger.Serialize());
7681 EXPECT_EQ("MyRealm1", auth_challenge->realm);
7682 EXPECT_EQ("basic", auth_challenge->scheme);
7683
7684 TestCompletionCallback callback;
7685 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
7686 callback.callback());
7687 EXPECT_EQ(ERR_IO_PENDING, rv);
7688 EXPECT_EQ(OK, callback.WaitForResult());
7689
7690 response = trans.GetResponseInfo();
7691 ASSERT_TRUE(response != nullptr);
7692 ASSERT_TRUE(response->headers.get() != nullptr);
Kenichi Ishibashif8634ab2021-03-16 23:41:287693 EXPECT_EQ("HTTP/1.1 407", response->headers->GetStatusLine());
Yixin Wang46a273ec302018-01-23 17:59:567694 EXPECT_TRUE(response->headers->IsKeepAlive());
7695 EXPECT_EQ(407, response->headers->response_code());
7696 EXPECT_EQ(10, response->headers->GetContentLength());
7697 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:587698 auth_challenge = response->auth_challenge;
7699 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:567700 EXPECT_TRUE(auth_challenge->is_proxy);
7701 EXPECT_EQ("https://proxy.example.org:70",
7702 auth_challenge->challenger.Serialize());
7703 EXPECT_EQ("MyRealm1", auth_challenge->realm);
7704 EXPECT_EQ("basic", auth_challenge->scheme);
7705 }
7706 // HttpNetworkTransaction is torn down now that it's out of scope, causing
7707 // the QUIC stream to be cleaned up (since the proxy socket cannot be
7708 // reused because it's not connected).
7709 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7710 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7711 }
7712}
7713
Brianna Goldsteind22b0642022-10-11 16:30:507714// Test that NetworkAnonymizationKey is respected by QUIC connections, when
Matt Menke26e41542019-06-05 01:09:517715// kPartitionConnectionsByNetworkIsolationKey is enabled.
7716TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Matt Menke4807a9a2020-11-21 00:14:417717 const SchemefulSite kSite1(GURL("http://origin1/"));
7718 const SchemefulSite kSite2(GURL("http://origin2/"));
7719 NetworkIsolationKey network_isolation_key1(kSite1, kSite1);
7720 NetworkIsolationKey network_isolation_key2(kSite2, kSite2);
Dustin J. Mitchell1d774ea2023-03-03 00:54:467721 const auto network_anonymization_key1 =
7722 NetworkAnonymizationKey::CreateSameSite(kSite1);
7723 const auto network_anonymization_key2 =
7724 NetworkAnonymizationKey::CreateSameSite(kSite2);
Matt Menke26e41542019-06-05 01:09:517725
Victor Vasilieva1e66d72019-12-05 17:55:387726 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:517727 HostPortPair::FromString("mail.example.org:443"));
7728
Dustin J. Mitchelldfd537d2024-03-13 13:09:317729 GURL url1 = GURL("https://mail.example.org/1");
7730 GURL url2 = GURL("https://mail.example.org/2");
7731 GURL url3 = GURL("https://mail.example.org/3");
Matt Menke26e41542019-06-05 01:09:517732
Dustin J. Mitchelldfd537d2024-03-13 13:09:317733 for (bool partition_connections : {false, true}) {
7734 SCOPED_TRACE(partition_connections);
7735
7736 base::test::ScopedFeatureList feature_list;
7737 if (partition_connections) {
7738 feature_list.InitAndEnableFeature(
7739 features::kPartitionConnectionsByNetworkIsolationKey);
Matt Menke26e41542019-06-05 01:09:517740 } else {
Dustin J. Mitchelldfd537d2024-03-13 13:09:317741 feature_list.InitAndDisableFeature(
7742 features::kPartitionConnectionsByNetworkIsolationKey);
Matt Menke26e41542019-06-05 01:09:517743 }
7744
Dustin J. Mitchelldfd537d2024-03-13 13:09:317745 // Reads and writes for the unpartitioned case, where only one socket is
7746 // used.
7747
7748 context_.params()->origins_to_force_quic_on.insert(
7749 HostPortPair::FromString("mail.example.org:443"));
7750
7751 MockQuicData unpartitioned_mock_quic_data(version_);
7752 QuicTestPacketMaker client_maker1(
7753 version_,
7754 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7755 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
7756 /*client_priority_uses_incremental=*/true,
7757 /*use_priority_header=*/true);
7758 QuicTestPacketMaker server_maker1(
7759 version_,
7760 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7761 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
7762 /*client_priority_uses_incremental=*/false,
7763 /*use_priority_header=*/false);
7764
7765 int packet_num = 1;
7766 unpartitioned_mock_quic_data.AddWrite(
7767 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
7768
7769 unpartitioned_mock_quic_data.AddWrite(
7770 SYNCHRONOUS,
7771 client_maker1.MakeRequestHeadersPacket(
7772 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7773 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
7774 GetRequestHeaders("GET", url1.scheme(), "/1"), nullptr));
7775 unpartitioned_mock_quic_data.AddRead(
7776 ASYNC, server_maker1.MakeResponseHeadersPacket(
7777 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
7778 GetResponseHeaders("200"), nullptr));
7779 const char kRespData1[] = "1";
7780 unpartitioned_mock_quic_data.AddRead(
7781 ASYNC, server_maker1.MakeDataPacket(
7782 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7783 ConstructDataFrame(kRespData1)));
7784 unpartitioned_mock_quic_data.AddWrite(
7785 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1));
7786
7787 unpartitioned_mock_quic_data.AddWrite(
7788 SYNCHRONOUS,
7789 client_maker1.MakeRequestHeadersPacket(
7790 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), true,
7791 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
7792 GetRequestHeaders("GET", url2.scheme(), "/2"), nullptr));
7793 unpartitioned_mock_quic_data.AddRead(
7794 ASYNC, server_maker1.MakeResponseHeadersPacket(
7795 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
7796 GetResponseHeaders("200"), nullptr));
7797 const char kRespData2[] = "2";
7798 unpartitioned_mock_quic_data.AddRead(
7799 ASYNC, server_maker1.MakeDataPacket(
7800 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
7801 ConstructDataFrame(kRespData2)));
7802 unpartitioned_mock_quic_data.AddWrite(
7803 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3));
7804
7805 unpartitioned_mock_quic_data.AddWrite(
7806 SYNCHRONOUS,
7807 client_maker1.MakeRequestHeadersPacket(
7808 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2), true,
7809 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
7810 GetRequestHeaders("GET", url3.scheme(), "/3"), nullptr));
7811 unpartitioned_mock_quic_data.AddRead(
7812 ASYNC, server_maker1.MakeResponseHeadersPacket(
7813 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
7814 GetResponseHeaders("200"), nullptr));
7815 const char kRespData3[] = "3";
7816 unpartitioned_mock_quic_data.AddRead(
7817 ASYNC, server_maker1.MakeDataPacket(
7818 6, GetNthClientInitiatedBidirectionalStreamId(2), true,
7819 ConstructDataFrame(kRespData3)));
7820 unpartitioned_mock_quic_data.AddWrite(
7821 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 6, 5));
7822
7823 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
7824
7825 // Reads and writes for the partitioned case, where two sockets are used.
7826
7827 MockQuicData partitioned_mock_quic_data1(version_);
7828 QuicTestPacketMaker client_maker2(
7829 version_,
7830 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7831 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
7832 /*client_priority_uses_incremental=*/true,
7833 /*use_priority_header=*/true);
7834 QuicTestPacketMaker server_maker2(
7835 version_,
7836 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7837 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
7838 /*client_priority_uses_incremental=*/false,
7839 /*use_priority_header=*/false);
7840
7841 int packet_num2 = 1;
7842 partitioned_mock_quic_data1.AddWrite(
7843 SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(packet_num2++));
7844
7845 partitioned_mock_quic_data1.AddWrite(
7846 SYNCHRONOUS,
7847 client_maker2.MakeRequestHeadersPacket(
7848 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7849 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
7850 GetRequestHeaders("GET", url1.scheme(), "/1"), nullptr));
7851 partitioned_mock_quic_data1.AddRead(
7852 ASYNC, server_maker2.MakeResponseHeadersPacket(
7853 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
7854 GetResponseHeaders("200"), nullptr));
7855 partitioned_mock_quic_data1.AddRead(
7856 ASYNC, server_maker2.MakeDataPacket(
7857 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7858 ConstructDataFrame(kRespData1)));
7859 partitioned_mock_quic_data1.AddWrite(
7860 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 2, 1));
7861
7862 partitioned_mock_quic_data1.AddWrite(
7863 SYNCHRONOUS,
7864 client_maker2.MakeRequestHeadersPacket(
7865 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1), true,
7866 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
7867 GetRequestHeaders("GET", url3.scheme(), "/3"), nullptr));
7868 partitioned_mock_quic_data1.AddRead(
7869 ASYNC, server_maker2.MakeResponseHeadersPacket(
7870 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
7871 GetResponseHeaders("200"), nullptr));
7872 partitioned_mock_quic_data1.AddRead(
7873 ASYNC, server_maker2.MakeDataPacket(
7874 4, GetNthClientInitiatedBidirectionalStreamId(1), true,
7875 ConstructDataFrame(kRespData3)));
7876 partitioned_mock_quic_data1.AddWrite(
7877 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 4, 3));
7878
7879 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
7880
7881 MockQuicData partitioned_mock_quic_data2(version_);
7882 QuicTestPacketMaker client_maker3(
7883 version_,
7884 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7885 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
7886 /*client_priority_uses_incremental=*/true,
7887 /*use_priority_header=*/true);
7888 QuicTestPacketMaker server_maker3(
7889 version_,
7890 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7891 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
7892 /*client_priority_uses_incremental=*/false,
7893 /*use_priority_header=*/false);
7894
7895 int packet_num3 = 1;
7896 partitioned_mock_quic_data2.AddWrite(
7897 SYNCHRONOUS, client_maker3.MakeInitialSettingsPacket(packet_num3++));
7898
7899 partitioned_mock_quic_data2.AddWrite(
7900 SYNCHRONOUS,
7901 client_maker3.MakeRequestHeadersPacket(
7902 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7903 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
7904 GetRequestHeaders("GET", url2.scheme(), "/2"), nullptr));
7905 partitioned_mock_quic_data2.AddRead(
7906 ASYNC, server_maker3.MakeResponseHeadersPacket(
7907 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
7908 GetResponseHeaders("200"), nullptr));
7909 partitioned_mock_quic_data2.AddRead(
7910 ASYNC, server_maker3.MakeDataPacket(
7911 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7912 ConstructDataFrame(kRespData2)));
7913 partitioned_mock_quic_data2.AddWrite(
7914 SYNCHRONOUS, client_maker3.MakeAckPacket(packet_num3++, 2, 1));
7915
7916 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
7917
7918 if (partition_connections) {
7919 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7920 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:517921 } else {
Dustin J. Mitchelldfd537d2024-03-13 13:09:317922 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:517923 }
7924
Dustin J. Mitchelldfd537d2024-03-13 13:09:317925 CreateSession();
Matt Menke26e41542019-06-05 01:09:517926
Dustin J. Mitchelldfd537d2024-03-13 13:09:317927 TestCompletionCallback callback;
7928 HttpRequestInfo request1;
7929 request1.method = "GET";
7930 request1.url = GURL(url1);
7931 request1.traffic_annotation =
7932 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7933 request1.network_isolation_key = network_isolation_key1;
7934 request1.network_anonymization_key = network_anonymization_key1;
7935 HttpNetworkTransaction trans1(LOWEST, session_.get());
7936 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
7937 EXPECT_THAT(callback.GetResult(rv), IsOk());
7938 std::string response_data1;
7939 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
7940 EXPECT_EQ(kRespData1, response_data1);
Matt Menke26e41542019-06-05 01:09:517941
Dustin J. Mitchelldfd537d2024-03-13 13:09:317942 HttpRequestInfo request2;
7943 request2.method = "GET";
7944 request2.url = GURL(url2);
7945 request2.traffic_annotation =
7946 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7947 request2.network_isolation_key = network_isolation_key2;
7948 request2.network_anonymization_key = network_anonymization_key2;
7949 HttpNetworkTransaction trans2(LOWEST, session_.get());
7950 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
7951 EXPECT_THAT(callback.GetResult(rv), IsOk());
7952 std::string response_data2;
7953 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
7954 EXPECT_EQ(kRespData2, response_data2);
Matt Menke26e41542019-06-05 01:09:517955
Dustin J. Mitchelldfd537d2024-03-13 13:09:317956 HttpRequestInfo request3;
7957 request3.method = "GET";
7958 request3.url = GURL(url3);
7959 request3.traffic_annotation =
7960 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7961 request3.network_isolation_key = network_isolation_key1;
7962 request3.network_anonymization_key = network_anonymization_key1;
Matt Menke26e41542019-06-05 01:09:517963
Dustin J. Mitchelldfd537d2024-03-13 13:09:317964 HttpNetworkTransaction trans3(LOWEST, session_.get());
7965 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
7966 EXPECT_THAT(callback.GetResult(rv), IsOk());
7967 std::string response_data3;
7968 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
7969 EXPECT_EQ(kRespData3, response_data3);
Matt Menke26e41542019-06-05 01:09:517970
Dustin J. Mitchelldfd537d2024-03-13 13:09:317971 if (partition_connections) {
7972 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
7973 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
7974 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
7975 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
7976 } else {
7977 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
7978 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:517979 }
7980 }
7981}
7982
7983// Test that two requests to the same origin over QUIC tunnels use different
7984// QUIC sessions if their NetworkIsolationKeys don't match, and
7985// kPartitionConnectionsByNetworkIsolationKey is enabled.
7986TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
7987 base::test::ScopedFeatureList feature_list;
7988 feature_list.InitAndEnableFeature(
7989 features::kPartitionConnectionsByNetworkIsolationKey);
7990
7991 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567992 proxy_resolution_service_ =
Ciara McMullin021c66e2024-01-19 16:47:007993 ConfiguredProxyResolutionService::CreateFixedFromProxyChainsForTest(
Ciara McMullin20d24572024-01-31 13:15:537994 {ProxyChain::ForIpProtection({ProxyServer::FromSchemeHostAndPort(
7995 ProxyServer::SCHEME_QUIC, "proxy.example.org", 70)})},
Ciara McMullin021c66e2024-01-19 16:47:007996 TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menke26e41542019-06-05 01:09:517997
7998 const char kGetRequest[] =
7999 "GET / HTTP/1.1\r\n"
8000 "Host: mail.example.org\r\n"
8001 "Connection: keep-alive\r\n\r\n";
8002 const char kGetResponse[] =
8003 "HTTP/1.1 200 OK\r\n"
8004 "Content-Length: 10\r\n\r\n";
Andrew Williams826d8742024-01-31 19:39:198005 const char kRespData[] = "0123456789";
Matt Menke26e41542019-06-05 01:09:518006
Ryan Hamiltonabad59e2019-06-06 04:02:598007 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
8008 std::make_unique<MockQuicData>(version_),
8009 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:518010
8011 for (int index : {0, 1}) {
8012 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:228013 version_,
8014 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8015 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky957bab12023-01-31 16:40:108016 true);
Matt Menke26e41542019-06-05 01:09:518017 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:228018 version_,
8019 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8020 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
8021 false);
Matt Menke26e41542019-06-05 01:09:518022
Renjie Tangaadb84b2019-08-31 01:00:238023 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:028024 mock_quic_data[index]->AddWrite(
8025 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Patrick Meenanf741c6082023-01-03 18:06:438026
Patrick Meenan8f8c8352023-07-06 17:20:198027 mock_quic_data[index]->AddWrite(
8028 SYNCHRONOUS,
8029 client_maker.MakePriorityPacket(
8030 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8031 quic::HttpStreamPriority::kDefaultUrgency));
Matt Menke26e41542019-06-05 01:09:518032
Ryan Hamiltonabad59e2019-06-06 04:02:598033 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:518034 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028035 client_maker.MakeRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038036 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), false,
8037 quic::HttpStreamPriority::kDefaultUrgency,
Bence Béky957bab12023-01-31 16:40:108038 ConnectRequestHeaders("mail.example.org:443"), nullptr, false));
Ryan Hamiltonabad59e2019-06-06 04:02:598039 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028040 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:518041 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:038042 GetResponseHeaders("200"), nullptr));
Matt Menke26e41542019-06-05 01:09:518043
Bence Béky319388a882020-09-23 18:42:528044 mock_quic_data[index]->AddWrite(
8045 SYNCHRONOUS,
8046 client_maker.MakeAckAndDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038047 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
8048 false, ConstructDataFrame(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:518049
Ryan Hamiltonabad59e2019-06-06 04:02:598050 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:518051 ASYNC, server_maker.MakeDataPacket(
8052 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:038053 ConstructDataFrame(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:598054 mock_quic_data[index]->AddRead(
Bence Béky319388a882020-09-23 18:42:528055 SYNCHRONOUS, server_maker.MakeDataPacket(
8056 3, GetNthClientInitiatedBidirectionalStreamId(0),
Andrew Williams826d8742024-01-31 19:39:198057 false, ConstructDataFrame(kRespData)));
Ryan Hamiltonabad59e2019-06-06 04:02:598058 mock_quic_data[index]->AddWrite(
Renjie Tangcd594f32020-07-11 20:18:348059 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2));
Ryan Hamiltonabad59e2019-06-06 04:02:598060 mock_quic_data[index]->AddRead(SYNCHRONOUS,
8061 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:518062
Ryan Hamiltonabad59e2019-06-06 04:02:598063 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:518064 }
8065
8066 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8067 SSLSocketDataProvider ssl_data2(ASYNC, OK);
8068 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
8069
8070 CreateSession();
8071
8072 request_.url = GURL("https://mail.example.org/");
8073 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
8074 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8075 RunTransaction(&trans);
Andrew Williams826d8742024-01-31 19:39:198076 CheckResponseData(&trans, kRespData);
Matt Menke26e41542019-06-05 01:09:518077
Matt Menke4807a9a2020-11-21 00:14:418078 const SchemefulSite kSite1(GURL("http://origin1/"));
8079 request_.network_isolation_key = NetworkIsolationKey(kSite1, kSite1);
Dustin J. Mitchell1d774ea2023-03-03 00:54:468080 request_.network_anonymization_key =
8081 NetworkAnonymizationKey::CreateSameSite(kSite1);
Matt Menke26e41542019-06-05 01:09:518082 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8083 RunTransaction(&trans2);
Andrew Williams826d8742024-01-31 19:39:198084 CheckResponseData(&trans2, kRespData);
Matt Menke26e41542019-06-05 01:09:518085
Ryan Hamiltonabad59e2019-06-06 04:02:598086 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
8087 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
8088 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
8089 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:518090}
8091
Yoichi Osato4c75c0c2020-06-24 08:03:578092TEST_P(QuicNetworkTransactionTest, AllowHTTP1FalseProhibitsH1) {
8093 MockRead http_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING),
8094 MockRead(ASYNC, OK)};
8095 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
8096 socket_factory_.AddSocketDataProvider(&http_data);
8097 AddCertificate(&ssl_data_);
8098 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8099
8100 CreateSession();
8101
8102 request_.method = "POST";
8103 UploadDataStreamNotAllowHTTP1 upload_data("");
8104 request_.upload_data_stream = &upload_data;
8105
8106 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8107 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268108 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:578109 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8110 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_H2_OR_QUIC_REQUIRED));
8111}
8112
8113// Confirm mock class UploadDataStreamNotAllowHTTP1 can upload content over
8114// QUIC.
8115TEST_P(QuicNetworkTransactionTest, AllowHTTP1MockTest) {
8116 context_.params()->origins_to_force_quic_on.insert(
8117 HostPortPair::FromString("mail.example.org:443"));
8118
8119 MockQuicData mock_quic_data(version_);
8120 int write_packet_index = 1;
Patrick Meenan885a00652023-02-15 20:07:028121 mock_quic_data.AddWrite(SYNCHRONOUS,
8122 ConstructInitialSettingsPacket(write_packet_index++));
Andrew Williams826d8742024-01-31 19:39:198123 const std::string kUploadContent = "foo";
Bence Béky319388a882020-09-23 18:42:528124 mock_quic_data.AddWrite(
8125 SYNCHRONOUS,
8126 ConstructClientRequestHeadersAndDataFramesPacket(
8127 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:038128 true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
Andrew Williams826d8742024-01-31 19:39:198129 nullptr, {ConstructDataFrame(kUploadContent)}));
Yoichi Osato4c75c0c2020-06-24 08:03:578130 mock_quic_data.AddRead(
8131 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038132 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Kenichi Ishibashif8634ab2021-03-16 23:41:288133 GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:578134
Yoichi Osato4c75c0c2020-06-24 08:03:578135 mock_quic_data.AddRead(
8136 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038137 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:198138 ConstructDataFrame(kQuicRespData)));
Yoichi Osato4c75c0c2020-06-24 08:03:578139
Renjie Tangcd594f32020-07-11 20:18:348140 mock_quic_data.AddWrite(SYNCHRONOUS,
8141 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:578142
8143 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:218144 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:578145 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8146
8147 // The non-alternate protocol job needs to hang in order to guarantee that
8148 // the alternate-protocol job will "win".
8149 AddHangingNonAlternateProtocolSocketData();
8150
8151 CreateSession();
8152 request_.method = "POST";
Andrew Williams826d8742024-01-31 19:39:198153 UploadDataStreamNotAllowHTTP1 upload_data(kUploadContent);
Yoichi Osato4c75c0c2020-06-24 08:03:578154 request_.upload_data_stream = &upload_data;
8155
Andrew Williams826d8742024-01-31 19:39:198156 SendRequestAndExpectQuicResponse(kQuicRespData);
Yoichi Osato4c75c0c2020-06-24 08:03:578157}
8158
Kenichi Ishibashi6fc20b82023-08-01 21:43:598159TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadPauseAndResume) {
8160 FLAGS_quic_enable_chaos_protection = false;
Yoichi Osato4c75c0c2020-06-24 08:03:578161 context_.params()->origins_to_force_quic_on.insert(
8162 HostPortPair::FromString("mail.example.org:443"));
8163
8164 MockQuicData mock_quic_data(version_);
8165 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
8166 int write_packet_index = 1;
8167 mock_quic_data.AddWrite(
8168 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
8169 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Patrick Meenan885a00652023-02-15 20:07:028170 mock_quic_data.AddWrite(SYNCHRONOUS,
8171 ConstructInitialSettingsPacket(write_packet_index++));
Andrew Williams826d8742024-01-31 19:39:198172 const std::string kUploadContent = "foo";
Bence Béky319388a882020-09-23 18:42:528173 mock_quic_data.AddWrite(
8174 SYNCHRONOUS,
8175 ConstructClientRequestHeadersAndDataFramesPacket(
8176 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:038177 true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
Andrew Williams826d8742024-01-31 19:39:198178 nullptr, {ConstructDataFrame(kUploadContent)}));
Yoichi Osato4c75c0c2020-06-24 08:03:578179 mock_quic_data.AddRead(
8180 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
8181 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:038182 GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:578183 mock_quic_data.AddRead(
8184 SYNCHRONOUS, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038185 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:198186 ConstructDataFrame(kQuicRespData)));
Yoichi Osato4c75c0c2020-06-24 08:03:578187
Renjie Tangcd594f32020-07-11 20:18:348188 mock_quic_data.AddWrite(SYNCHRONOUS,
8189 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:578190 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:218191 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:578192 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8193 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
8194
8195 CreateSession();
8196
8197 AddQuicAlternateProtocolMapping(
8198 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
8199
8200 // Set up request.
8201 request_.method = "POST";
Andrew Williams826d8742024-01-31 19:39:198202 UploadDataStreamNotAllowHTTP1 upload_data(kUploadContent);
Yoichi Osato4c75c0c2020-06-24 08:03:578203 request_.upload_data_stream = &upload_data;
8204
8205 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8206 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268207 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:578208 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8209 base::RunLoop().RunUntilIdle();
8210 // Resume QUIC job
8211 crypto_client_stream_factory_.last_stream()
8212 ->NotifySessionOneRttKeyAvailable();
8213 socket_data->Resume();
8214
8215 base::RunLoop().RunUntilIdle();
Andrew Williams826d8742024-01-31 19:39:198216 CheckResponseData(&trans, kQuicRespData);
Yoichi Osato4c75c0c2020-06-24 08:03:578217}
8218
Kenichi Ishibashi6fc20b82023-08-01 21:43:598219TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadFailH1AndResumeQuic) {
8220 FLAGS_quic_enable_chaos_protection = false;
Ryan Hamiltona51800a2022-02-12 19:34:358221 if (version_.AlpnDeferToRFCv1()) {
8222 // These versions currently do not support Alt-Svc.
8223 return;
8224 }
Yoichi Osato4c75c0c2020-06-24 08:03:578225 // This test confirms failed main job should not bother quic job.
8226 MockRead http_reads[] = {
Ryan Hamiltona2dcbae2022-02-09 19:02:458227 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Yoichi Osato4c75c0c2020-06-24 08:03:578228 MockRead("1.1 Body"),
8229 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8230 MockRead(ASYNC, OK)};
8231 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
8232 socket_factory_.AddSocketDataProvider(&http_data);
8233 AddCertificate(&ssl_data_);
8234 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8235
8236 MockQuicData mock_quic_data(version_);
8237 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
8238 int write_packet_index = 1;
8239 mock_quic_data.AddWrite(
8240 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
8241 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Patrick Meenan885a00652023-02-15 20:07:028242 mock_quic_data.AddWrite(SYNCHRONOUS,
8243 ConstructInitialSettingsPacket(write_packet_index++));
Andrew Williams826d8742024-01-31 19:39:198244 const std::string kUploadContent = "foo";
Bence Béky319388a882020-09-23 18:42:528245 mock_quic_data.AddWrite(
8246 SYNCHRONOUS,
8247 ConstructClientRequestHeadersAndDataFramesPacket(
8248 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:038249 true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
Andrew Williams826d8742024-01-31 19:39:198250 nullptr, {ConstructDataFrame(kUploadContent)}));
Yoichi Osato4c75c0c2020-06-24 08:03:578251 mock_quic_data.AddRead(
8252 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
8253 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:038254 GetResponseHeaders("200")));
Yoichi Osato4c75c0c2020-06-24 08:03:578255 mock_quic_data.AddRead(
8256 SYNCHRONOUS, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038257 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:198258 ConstructDataFrame(kQuicRespData)));
Renjie Tangcd594f32020-07-11 20:18:348259 mock_quic_data.AddWrite(SYNCHRONOUS,
8260 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:578261 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
David Schinazi395918c2021-02-05 18:56:218262 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Yoichi Osato4c75c0c2020-06-24 08:03:578263 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8264 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
8265
8266 // This packet won't be read because AllowHTTP1:false doesn't allow H/1
8267 // connection.
8268 MockRead http_reads2[] = {MockRead("HTTP/1.1 200 OK\r\n")};
8269 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
8270 socket_factory_.AddSocketDataProvider(&http_data2);
8271 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8272
8273 CreateSession();
8274
8275 // Send the first request via TCP and set up alternative service (QUIC) for
8276 // the origin.
8277 SendRequestAndExpectHttpResponse("1.1 Body");
8278
8279 // Settings to resume main H/1 job quickly while pausing quic job.
8280 AddQuicAlternateProtocolMapping(
8281 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
8282 ServerNetworkStats stats1;
Peter Kastinge5a38ed2021-10-02 03:06:358283 stats1.srtt = base::Microseconds(10);
Yoichi Osato4c75c0c2020-06-24 08:03:578284 http_server_properties_->SetServerNetworkStats(
Brianna Goldstein02cb74f2022-09-29 05:41:018285 url::SchemeHostPort(request_.url), NetworkAnonymizationKey(), stats1);
Yoichi Osato4c75c0c2020-06-24 08:03:578286
8287 // Set up request.
8288 request_.method = "POST";
Andrew Williams826d8742024-01-31 19:39:198289 UploadDataStreamNotAllowHTTP1 upload_data(kUploadContent);
Yoichi Osato4c75c0c2020-06-24 08:03:578290 request_.upload_data_stream = &upload_data;
8291
8292 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8293 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268294 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Yoichi Osato4c75c0c2020-06-24 08:03:578295 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8296 // Confirm TCP job was resumed.
8297 // We can not check its failure because HttpStreamFactory::JobController.
8298 // main_job_net_error is not exposed.
Dustin J. Mitchell496de812024-01-16 19:14:548299 while (socket_factory_.mock_data().next_index() < 3u) {
Yoichi Osato4c75c0c2020-06-24 08:03:578300 base::RunLoop().RunUntilIdle();
Dustin J. Mitchell496de812024-01-16 19:14:548301 }
Yoichi Osato4c75c0c2020-06-24 08:03:578302 // Resume QUIC job.
8303 crypto_client_stream_factory_.last_stream()
8304 ->NotifySessionOneRttKeyAvailable();
8305 socket_data->Resume();
8306 base::RunLoop().RunUntilIdle();
Andrew Williams826d8742024-01-31 19:39:198307 CheckResponseData(&trans, kQuicRespData);
Yoichi Osato4c75c0c2020-06-24 08:03:578308}
8309
Bence Békyc164e0d22020-09-22 20:08:598310TEST_P(QuicNetworkTransactionTest, IncorrectHttp3GoAway) {
Bence Békyc164e0d22020-09-22 20:08:598311 context_.params()->retry_without_alt_svc_on_quic_errors = false;
8312
8313 MockQuicData mock_quic_data(version_);
8314 int write_packet_number = 1;
8315 mock_quic_data.AddWrite(
8316 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number++));
8317 mock_quic_data.AddWrite(
8318 SYNCHRONOUS,
8319 ConstructClientRequestHeadersPacket(
8320 write_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Tsuyoshi Horoea15e7a2023-05-23 00:12:038321 true, GetRequestHeaders("GET", "https", "/")));
Bence Békyc164e0d22020-09-22 20:08:598322
8323 int read_packet_number = 1;
8324 mock_quic_data.AddRead(
8325 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number++));
8326 // The GOAWAY frame sent by the server MUST have a stream ID corresponding to
8327 // a client-initiated bidirectional stream. Any other kind of stream ID
8328 // should cause the client to close the connection.
8329 quic::GoAwayFrame goaway{3};
Nidhi Jaju391105a2022-07-28 02:09:518330 auto goaway_buffer = quic::HttpEncoder::SerializeGoAwayFrame(goaway);
Bence Békyc164e0d22020-09-22 20:08:598331 const quic::QuicStreamId control_stream_id =
8332 quic::QuicUtils::GetFirstUnidirectionalStreamId(
8333 version_.transport_version, quic::Perspective::IS_SERVER);
8334 mock_quic_data.AddRead(
Nidhi Jaju391105a2022-07-28 02:09:518335 ASYNC, ConstructServerDataPacket(read_packet_number++, control_stream_id,
Tsuyoshi Horoea15e7a2023-05-23 00:12:038336 false, goaway_buffer));
Bence Békyc164e0d22020-09-22 20:08:598337 mock_quic_data.AddWrite(
8338 SYNCHRONOUS,
8339 ConstructClientAckAndConnectionClosePacket(
8340 write_packet_number++, 2, 4, quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
8341 "GOAWAY with invalid stream ID", 0));
8342 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8343
8344 // In order for a new QUIC session to be established via alternate-protocol
8345 // without racing an HTTP connection, we need the host resolution to happen
8346 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
8347 // connection to the the server, in this test we require confirmation
8348 // before encrypting so the HTTP job will still start.
8349 host_resolver_.set_synchronous_mode(true);
8350 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
8351 "");
8352
8353 CreateSession();
Liza Burakova80b8ebd2023-02-15 16:29:588354 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ASYNC_ZERO_RTT);
Bence Békyc164e0d22020-09-22 20:08:598355
8356 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8357 TestCompletionCallback callback;
Matt Reichhoff0049a0b72021-10-20 20:44:268358 int rv = trans.Start(&request_, callback.callback(), net_log_with_source_);
Bence Békyc164e0d22020-09-22 20:08:598359 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Liza Burakova80b8ebd2023-02-15 16:29:588360 base::RunLoop().RunUntilIdle();
Bence Békyc164e0d22020-09-22 20:08:598361 crypto_client_stream_factory_.last_stream()
8362 ->NotifySessionOneRttKeyAvailable();
8363 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
8364
8365 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8366 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8367
8368 NetErrorDetails details;
8369 trans.PopulateNetErrorDetails(&details);
8370 EXPECT_THAT(details.quic_connection_error,
8371 quic::test::IsError(quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID));
8372}
8373
Bence Béky2ee18922020-09-25 12:11:328374TEST_P(QuicNetworkTransactionTest, RetryOnHttp3GoAway) {
Bence Béky2ee18922020-09-25 12:11:328375 MockQuicData mock_quic_data1(version_);
8376 int write_packet_number1 = 1;
8377 mock_quic_data1.AddWrite(
8378 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number1++));
8379 const quic::QuicStreamId stream_id1 =
8380 GetNthClientInitiatedBidirectionalStreamId(0);
8381 mock_quic_data1.AddWrite(SYNCHRONOUS,
8382 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038383 write_packet_number1++, stream_id1, true,
Bence Béky2ee18922020-09-25 12:11:328384 GetRequestHeaders("GET", "https", "/")));
8385 const quic::QuicStreamId stream_id2 =
8386 GetNthClientInitiatedBidirectionalStreamId(1);
8387 mock_quic_data1.AddWrite(SYNCHRONOUS,
8388 ConstructClientRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038389 write_packet_number1++, stream_id2, true,
Bence Béky2ee18922020-09-25 12:11:328390 GetRequestHeaders("GET", "https", "/foo")));
8391
8392 int read_packet_number1 = 1;
8393 mock_quic_data1.AddRead(
8394 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number1++));
8395
8396 // GOAWAY with stream_id2 informs the client that stream_id2 (and streams with
8397 // larger IDs) have not been processed and can safely be retried.
8398 quic::GoAwayFrame goaway{stream_id2};
Nidhi Jaju391105a2022-07-28 02:09:518399 auto goaway_buffer = quic::HttpEncoder::SerializeGoAwayFrame(goaway);
Bence Béky2ee18922020-09-25 12:11:328400 const quic::QuicStreamId control_stream_id =
8401 quic::QuicUtils::GetFirstUnidirectionalStreamId(
8402 version_.transport_version, quic::Perspective::IS_SERVER);
8403 mock_quic_data1.AddRead(
Nidhi Jaju391105a2022-07-28 02:09:518404 ASYNC, ConstructServerDataPacket(read_packet_number1++, control_stream_id,
Tsuyoshi Horoea15e7a2023-05-23 00:12:038405 false, goaway_buffer));
Bence Béky2ee18922020-09-25 12:11:328406 mock_quic_data1.AddWrite(
8407 ASYNC, ConstructClientAckPacket(write_packet_number1++, 2, 1));
8408
8409 // Response to first request is accepted after GOAWAY.
8410 mock_quic_data1.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8411 read_packet_number1++, stream_id1, false,
Tsuyoshi Horoea15e7a2023-05-23 00:12:038412 GetResponseHeaders("200")));
Andrew Williams826d8742024-01-31 19:39:198413 const char kRespData1[] = "response on the first connection";
Bence Béky2ee18922020-09-25 12:11:328414 mock_quic_data1.AddRead(
Andrew Williams826d8742024-01-31 19:39:198415 ASYNC, ConstructServerDataPacket(read_packet_number1++, stream_id1, true,
8416 ConstructDataFrame(kRespData1)));
Bence Béky2ee18922020-09-25 12:11:328417 mock_quic_data1.AddWrite(
8418 ASYNC, ConstructClientAckPacket(write_packet_number1++, 4, 1));
Bence Békye7426ec2021-02-02 18:18:198419 // Make socket hang to make sure connection stays in connection pool.
8420 // This should not prevent the retry from opening a new connection.
8421 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING);
David Schinazi395918c2021-02-05 18:56:218422 mock_quic_data1.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
Bence Béky2ee18922020-09-25 12:11:328423 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
8424
8425 // Second request is retried on a new connection.
8426 MockQuicData mock_quic_data2(version_);
8427 QuicTestPacketMaker client_maker2(
8428 version_,
8429 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8430 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Patrick Meenan0b1b18cf2023-09-21 20:19:478431 /*client_priority_uses_incremental=*/true, /*use_priority_header=*/true);
Bence Béky2ee18922020-09-25 12:11:328432 int write_packet_number2 = 1;
8433 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(
8434 write_packet_number2++));
8435 spdy::SpdyPriority priority =
8436 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8437 mock_quic_data2.AddWrite(
8438 SYNCHRONOUS, client_maker2.MakeRequestHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038439 write_packet_number2++, stream_id1, true, priority,
Bence Béky957bab12023-01-31 16:40:108440 GetRequestHeaders("GET", "https", "/foo"), nullptr));
Bence Béky2ee18922020-09-25 12:11:328441
8442 QuicTestPacketMaker server_maker2(
8443 version_,
8444 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8445 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Patrick Meenan0b1b18cf2023-09-21 20:19:478446 /*client_priority_uses_incremental=*/false,
8447 /*use_priority_header=*/false);
Bence Béky2ee18922020-09-25 12:11:328448 int read_packet_number2 = 1;
Tsuyoshi Horoea15e7a2023-05-23 00:12:038449 mock_quic_data2.AddRead(ASYNC, server_maker2.MakeResponseHeadersPacket(
8450 read_packet_number2++, stream_id1, false,
8451 GetResponseHeaders("200"), nullptr));
Andrew Williams826d8742024-01-31 19:39:198452 const char kRespData2[] = "response on the second connection";
8453 mock_quic_data2.AddRead(ASYNC, server_maker2.MakeDataPacket(
8454 read_packet_number2++, stream_id1, true,
8455 ConstructDataFrame(kRespData2)));
Bence Béky2ee18922020-09-25 12:11:328456 mock_quic_data2.AddWrite(
8457 ASYNC, client_maker2.MakeAckPacket(write_packet_number2++, 2, 1));
8458 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8459 mock_quic_data2.AddRead(ASYNC, 0); // EOF
8460 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8461
8462 AddHangingNonAlternateProtocolSocketData();
8463 CreateSession();
8464 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
8465
8466 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
8467 TestCompletionCallback callback1;
Matt Reichhoff0049a0b72021-10-20 20:44:268468 int rv = trans1.Start(&request_, callback1.callback(), net_log_with_source_);
Bence Béky2ee18922020-09-25 12:11:328469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8470 base::RunLoop().RunUntilIdle();
8471
8472 HttpRequestInfo request2;
8473 request2.method = "GET";
8474 std::string url("https://");
8475 url.append(kDefaultServerHostName);
8476 url.append("/foo");
8477 request2.url = GURL(url);
8478 request2.load_flags = 0;
8479 request2.traffic_annotation =
8480 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8481 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8482 TestCompletionCallback callback2;
Matt Reichhoff0049a0b72021-10-20 20:44:268483 rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
Bence Béky2ee18922020-09-25 12:11:328484 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8485
8486 EXPECT_THAT(callback1.WaitForResult(), IsOk());
Andrew Williams826d8742024-01-31 19:39:198487 CheckResponseData(&trans1, kRespData1);
Bence Béky2ee18922020-09-25 12:11:328488
8489 EXPECT_THAT(callback2.WaitForResult(), IsOk());
Andrew Williams826d8742024-01-31 19:39:198490 CheckResponseData(&trans2, kRespData2);
Bence Béky2ee18922020-09-25 12:11:328491
Bence Békye7426ec2021-02-02 18:18:198492 mock_quic_data1.Resume();
Bence Béky2ee18922020-09-25 12:11:328493 mock_quic_data2.Resume();
8494 EXPECT_TRUE(mock_quic_data1.AllWriteDataConsumed());
8495 EXPECT_TRUE(mock_quic_data1.AllReadDataConsumed());
8496 EXPECT_TRUE(mock_quic_data2.AllWriteDataConsumed());
8497 EXPECT_TRUE(mock_quic_data2.AllReadDataConsumed());
8498}
8499
Yoichi Osato4c75c0c2020-06-24 08:03:578500// TODO(yoichio): Add the TCP job reuse case. See crrev.com/c/2174099.
8501
Momoka Yamamotoff688972022-11-02 03:37:468502#if BUILDFLAG(ENABLE_WEBSOCKETS)
8503
8504// This test verifies that when there is an HTTP/3 connection open to a server,
8505// a WebSocket request does not use it, but instead opens a new connection with
8506// HTTP/1.
8507TEST_P(QuicNetworkTransactionTest, WebsocketOpensNewConnectionWithHttp1) {
8508 context_.params()->origins_to_force_quic_on.insert(
8509 HostPortPair::FromString("mail.example.org:443"));
8510 context_.params()->retry_without_alt_svc_on_quic_errors = false;
8511
8512 MockQuicData mock_quic_data(version_);
8513
8514 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
8515
8516 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:028517 mock_quic_data.AddWrite(SYNCHRONOUS,
8518 ConstructInitialSettingsPacket(packet_num++));
Momoka Yamamotoff688972022-11-02 03:37:468519
8520 spdy::SpdyPriority priority =
8521 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8522
8523 // The request will initially go out over HTTP/3.
8524 mock_quic_data.AddWrite(
8525 SYNCHRONOUS,
8526 client_maker_->MakeRequestHeadersPacket(
8527 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:038528 priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Momoka Yamamotoff688972022-11-02 03:37:468529 mock_quic_data.AddRead(
8530 ASYNC, server_maker_.MakeResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038531 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Momoka Yamamotoff688972022-11-02 03:37:468532 server_maker_.GetResponseHeaders("200"), nullptr));
8533 mock_quic_data.AddRead(
8534 ASYNC, server_maker_.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038535 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:198536 ConstructDataFrame(kQuicRespData)));
Momoka Yamamotoff688972022-11-02 03:37:468537 mock_quic_data.AddWrite(SYNCHRONOUS,
8538 ConstructClientAckPacket(packet_num++, 2, 1));
8539 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read.
8540 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
8541
8542 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8543 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8544
8545 MockWrite http_writes[] = {
8546 MockWrite(SYNCHRONOUS, 0,
8547 "GET / HTTP/1.1\r\n"
8548 "Host: mail.example.org\r\n"
8549 "Connection: Upgrade\r\n"
8550 "Upgrade: websocket\r\n"
8551 "Origin: http://mail.example.org\r\n"
8552 "Sec-WebSocket-Version: 13\r\n"
8553 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
8554 "Sec-WebSocket-Extensions: permessage-deflate; "
8555 "client_max_window_bits\r\n\r\n")};
8556
8557 MockRead http_reads[] = {
8558 MockRead(SYNCHRONOUS, 1,
8559 "HTTP/1.1 101 Switching Protocols\r\n"
8560 "Upgrade: websocket\r\n"
8561 "Connection: Upgrade\r\n"
8562 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
8563
8564 SequencedSocketData http_data(http_reads, http_writes);
8565 socket_factory_.AddSocketDataProvider(&http_data);
8566
8567 CreateSession();
8568
8569 TestCompletionCallback callback1;
8570 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
8571 int rv = trans1.Start(&request_, callback1.callback(), net_log_with_source_);
8572 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8573 rv = callback1.WaitForResult();
8574 ASSERT_THAT(rv, IsOk());
8575
8576 const HttpResponseInfo* response = trans1.GetResponseInfo();
8577 ASSERT_TRUE(response->headers);
8578 EXPECT_TRUE(response->was_fetched_via_spdy);
Andrew Williams826d8742024-01-31 19:39:198579 EXPECT_EQ(kQuic200RespStatusLine, response->headers->GetStatusLine());
Momoka Yamamotoff688972022-11-02 03:37:468580
8581 std::string response_data;
8582 rv = ReadTransaction(&trans1, &response_data);
8583 EXPECT_THAT(rv, IsOk());
Andrew Williams826d8742024-01-31 19:39:198584 EXPECT_EQ(kQuicRespData, response_data);
Momoka Yamamotoff688972022-11-02 03:37:468585
8586 HttpRequestInfo request2;
8587 request2.method = "GET";
8588 request2.url = GURL("wss://mail.example.org/");
8589 request2.traffic_annotation =
8590 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8591 EXPECT_TRUE(HostPortPair::FromURL(request_.url)
8592 .Equals(HostPortPair::FromURL(request2.url)));
8593 request2.extra_headers.SetHeader("Connection", "Upgrade");
8594 request2.extra_headers.SetHeader("Upgrade", "websocket");
8595 request2.extra_headers.SetHeader("Origin", "http://mail.example.org");
8596 request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
8597
8598 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
8599
8600 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8601 trans2.SetWebSocketHandshakeStreamCreateHelper(
8602 &websocket_stream_create_helper);
8603
8604 TestCompletionCallback callback2;
8605 rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
8606 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8607 rv = callback2.WaitForResult();
8608 ASSERT_THAT(rv, IsOk());
8609
8610 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
8611 mock_quic_data.Resume();
8612 // Run the QUIC session to completion.
8613 base::RunLoop().RunUntilIdle();
8614
8615 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8616 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8617}
Momoka Yamamoto751ecf72022-11-11 14:38:348618
8619// Much like above, but for Alt-Svc QUIC.
8620TEST_P(QuicNetworkTransactionTest,
8621 WebsocketOpensNewConnectionWithHttp1AfterAltSvcQuic) {
8622 if (version_.AlpnDeferToRFCv1()) {
8623 // These versions currently do not support Alt-Svc.
8624 return;
8625 }
8626 MockRead http_reads[] = {
8627 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header_.data()),
Andrew Williams826d8742024-01-31 19:39:198628 MockRead(kHttpRespData),
Momoka Yamamoto751ecf72022-11-11 14:38:348629 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
8630 MockRead(ASYNC, OK)};
8631
8632 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
8633 socket_factory_.AddSocketDataProvider(&http_data);
8634 AddCertificate(&ssl_data_);
8635 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8636
8637 MockQuicData mock_quic_data(version_);
8638 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:028639 mock_quic_data.AddWrite(SYNCHRONOUS,
8640 ConstructInitialSettingsPacket(packet_num++));
Momoka Yamamoto751ecf72022-11-11 14:38:348641 mock_quic_data.AddWrite(
8642 SYNCHRONOUS,
8643 ConstructClientRequestHeadersPacket(
8644 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:038645 GetRequestHeaders("GET", "https", "/")));
Momoka Yamamoto751ecf72022-11-11 14:38:348646 mock_quic_data.AddRead(
8647 ASYNC, ConstructServerResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038648 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Momoka Yamamoto751ecf72022-11-11 14:38:348649 GetResponseHeaders("200")));
8650 mock_quic_data.AddRead(
8651 ASYNC, ConstructServerDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038652 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:198653 ConstructDataFrame(kQuicRespData)));
Momoka Yamamoto751ecf72022-11-11 14:38:348654 mock_quic_data.AddWrite(SYNCHRONOUS,
8655 ConstructClientAckPacket(packet_num++, 2, 1));
8656 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8657 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
8658
8659 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8660 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8661
8662 MockWrite http_writes2[] = {
8663 MockWrite(SYNCHRONOUS, 0,
8664 "GET / HTTP/1.1\r\n"
8665 "Host: mail.example.org\r\n"
8666 "Connection: Upgrade\r\n"
8667 "Upgrade: websocket\r\n"
8668 "Origin: http://mail.example.org\r\n"
8669 "Sec-WebSocket-Version: 13\r\n"
8670 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
8671 "Sec-WebSocket-Extensions: permessage-deflate; "
8672 "client_max_window_bits\r\n\r\n")};
8673
8674 MockRead http_reads2[] = {
8675 MockRead(SYNCHRONOUS, 1,
8676 "HTTP/1.1 101 Switching Protocols\r\n"
8677 "Upgrade: websocket\r\n"
8678 "Connection: Upgrade\r\n"
8679 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
8680
8681 SequencedSocketData http_data2(http_reads2, http_writes2);
8682 socket_factory_.AddSocketDataProvider(&http_data2);
8683 AddCertificate(&ssl_data_);
8684 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8685
8686 CreateSession();
8687
Andrew Williams826d8742024-01-31 19:39:198688 SendRequestAndExpectHttpResponse(kHttpRespData);
8689 SendRequestAndExpectQuicResponse(kQuicRespData);
Momoka Yamamoto751ecf72022-11-11 14:38:348690
8691 HttpRequestInfo request2;
8692 request2.method = "GET";
8693 request2.url = GURL("wss://mail.example.org/");
8694 request2.traffic_annotation =
8695 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8696 EXPECT_TRUE(HostPortPair::FromURL(request_.url)
8697 .Equals(HostPortPair::FromURL(request2.url)));
8698 request2.extra_headers.SetHeader("Connection", "Upgrade");
8699 request2.extra_headers.SetHeader("Upgrade", "websocket");
8700 request2.extra_headers.SetHeader("Origin", "http://mail.example.org");
8701 request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
8702
8703 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
8704
8705 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8706 trans2.SetWebSocketHandshakeStreamCreateHelper(
8707 &websocket_stream_create_helper);
8708
8709 TestCompletionCallback callback2;
8710 int rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
8711 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8712 rv = callback2.WaitForResult();
8713 ASSERT_THAT(rv, IsOk());
8714 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
8715 mock_quic_data.Resume();
8716 // Run the QUIC session to completion.
8717 base::RunLoop().RunUntilIdle();
8718
8719 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8720 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8721}
Momoka Yamamotoff688972022-11-02 03:37:468722
Momoka Yamamoto8d36ce22023-01-19 02:56:498723// Much like above, but for DnsHttpsSvcbAlpn QUIC.
8724TEST_P(QuicNetworkTransactionTest,
8725 WebsocketOpensNewConnectionWithHttp1AfterDnsHttpsSvcbAlpn) {
8726 session_params_.use_dns_https_svcb_alpn = true;
8727
8728 MockQuicData mock_quic_data(version_);
8729
8730 int packet_num = 1;
Patrick Meenan885a00652023-02-15 20:07:028731 mock_quic_data.AddWrite(SYNCHRONOUS,
8732 ConstructInitialSettingsPacket(packet_num++));
Momoka Yamamoto8d36ce22023-01-19 02:56:498733
8734 spdy::SpdyPriority priority =
8735 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8736
8737 // The request will initially go out over HTTP/3.
8738 mock_quic_data.AddWrite(
8739 SYNCHRONOUS,
8740 client_maker_->MakeRequestHeadersPacket(
8741 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Tsuyoshi Horoea15e7a2023-05-23 00:12:038742 priority, GetRequestHeaders("GET", "https", "/"), nullptr));
Momoka Yamamoto8d36ce22023-01-19 02:56:498743 mock_quic_data.AddRead(
8744 ASYNC, server_maker_.MakeResponseHeadersPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038745 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Momoka Yamamoto8d36ce22023-01-19 02:56:498746 server_maker_.GetResponseHeaders("200"), nullptr));
8747 mock_quic_data.AddRead(
8748 ASYNC, server_maker_.MakeDataPacket(
Tsuyoshi Horoea15e7a2023-05-23 00:12:038749 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Andrew Williams826d8742024-01-31 19:39:198750 ConstructDataFrame(kQuicRespData)));
Momoka Yamamoto8d36ce22023-01-19 02:56:498751 mock_quic_data.AddWrite(SYNCHRONOUS,
8752 ConstructClientAckPacket(packet_num++, 2, 1));
8753 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read.
8754 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
8755
8756 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8757
8758 MockWrite http_writes[] = {
8759 MockWrite(SYNCHRONOUS, 0,
8760 "GET / HTTP/1.1\r\n"
8761 "Host: mail.example.org\r\n"
8762 "Connection: Upgrade\r\n"
8763 "Upgrade: websocket\r\n"
8764 "Origin: http://mail.example.org\r\n"
8765 "Sec-WebSocket-Version: 13\r\n"
8766 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
8767 "Sec-WebSocket-Extensions: permessage-deflate; "
8768 "client_max_window_bits\r\n\r\n")};
8769
8770 MockRead http_reads[] = {
8771 MockRead(SYNCHRONOUS, 1,
8772 "HTTP/1.1 101 Switching Protocols\r\n"
8773 "Upgrade: websocket\r\n"
8774 "Connection: Upgrade\r\n"
8775 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
8776
8777 SequencedSocketData http_data(http_reads, http_writes);
8778 socket_factory_.AddSocketDataProvider(&http_data);
8779 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8780
8781 HostResolverEndpointResult endpoint_result1;
8782 endpoint_result1.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
8783 endpoint_result1.metadata.supported_protocol_alpns = {
8784 quic::QuicVersionLabelToString(quic::CreateQuicVersionLabel(version_))};
8785 HostResolverEndpointResult endpoint_result2;
8786 endpoint_result2.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
8787 std::vector<HostResolverEndpointResult> endpoints;
8788 endpoints.push_back(endpoint_result1);
8789 endpoints.push_back(endpoint_result2);
8790 host_resolver_.rules()->AddRule(
8791 "mail.example.org",
8792 MockHostResolverBase::RuleResolver::RuleResult(
8793 std::move(endpoints),
8794 /*aliases=*/std::set<std::string>{"mail.example.org"}));
8795
8796 CreateSession();
8797 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
8798 TestCompletionCallback callback1;
8799 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
8800 int rv = trans1.Start(&request_, callback1.callback(), net_log_with_source_);
8801 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8802 rv = callback1.WaitForResult();
8803 ASSERT_THAT(rv, IsOk());
8804
8805 const HttpResponseInfo* response = trans1.GetResponseInfo();
8806 ASSERT_TRUE(response->headers);
8807 EXPECT_TRUE(response->was_fetched_via_spdy);
Andrew Williams826d8742024-01-31 19:39:198808 EXPECT_EQ(kQuic200RespStatusLine, response->headers->GetStatusLine());
Momoka Yamamoto8d36ce22023-01-19 02:56:498809
8810 std::string response_data;
8811 rv = ReadTransaction(&trans1, &response_data);
8812 EXPECT_THAT(rv, IsOk());
Andrew Williams826d8742024-01-31 19:39:198813 EXPECT_EQ(kQuicRespData, response_data);
Momoka Yamamoto8d36ce22023-01-19 02:56:498814
8815 HttpRequestInfo request2;
8816 request2.method = "GET";
8817 request2.url = GURL("wss://mail.example.org/");
8818 request2.traffic_annotation =
8819 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8820 EXPECT_TRUE(HostPortPair::FromURL(request_.url)
8821 .Equals(HostPortPair::FromURL(request2.url)));
8822 request2.extra_headers.SetHeader("Connection", "Upgrade");
8823 request2.extra_headers.SetHeader("Upgrade", "websocket");
8824 request2.extra_headers.SetHeader("Origin", "http://mail.example.org");
8825 request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13");
8826
8827 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
8828
8829 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8830 trans2.SetWebSocketHandshakeStreamCreateHelper(
8831 &websocket_stream_create_helper);
8832
8833 TestCompletionCallback callback2;
8834 rv = trans2.Start(&request2, callback2.callback(), net_log_with_source_);
8835 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
8836 rv = callback2.WaitForResult();
8837 ASSERT_THAT(rv, IsOk());
8838
8839 ASSERT_FALSE(mock_quic_data.AllReadDataConsumed());
8840 mock_quic_data.Resume();
8841 // Run the QUIC session to completion.
8842 base::RunLoop().RunUntilIdle();
8843
8844 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8845 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8846}
8847
Momoka Yamamotoff688972022-11-02 03:37:468848#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
8849
Tsuyoshi Horo4f516be2022-06-14 11:53:138850} // namespace net::test