blob: 228c91661ac2093ef8191c81300ffdf08bde9820 [file] [log] [blame]
[email protected]61a527782013-02-21 03:58:001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
rchbd089ab2017-05-26 23:05:045#include <algorithm>
bnc359ed2a2016-04-29 20:43:456#include <ostream>
bnc912a04b2016-04-20 14:19:507#include <string>
8#include <utility>
[email protected]1e960032013-12-20 19:00:209#include <vector>
10
Sebastien Marchand6d0558fd2019-01-25 16:49:3711#include "base/bind.h"
[email protected]61a527782013-02-21 03:58:0012#include "base/compiler_specific.h"
Avi Drissman13fc8932015-12-20 04:40:4613#include "base/macros.h"
mmenke651bae7f2015-12-18 21:26:4514#include "base/run_loop.h"
[email protected]98b20ce2013-05-10 05:55:2615#include "base/stl_util.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"
Bence Békyd74f4382018-02-20 18:26:1918#include "base/strings/string_piece.h"
bnc8be55ebb2015-10-30 14:12:0719#include "base/strings/stringprintf.h"
Devlin Cronine4bcb40e2018-06-05 18:02:4720#include "base/test/metrics/histogram_tester.h"
Matt Menke26e41542019-06-05 01:09:5121#include "base/test/scoped_feature_list.h"
rtenneti56977812016-01-15 19:26:5622#include "net/base/chunked_upload_data_stream.h"
Bence Békyd8a21fc32018-06-27 18:29:5823#include "net/base/completion_once_callback.h"
Matt Menke26e41542019-06-05 01:09:5124#include "net/base/features.h"
Tsuyoshi Horo01faed62019-02-20 22:11:3725#include "net/base/ip_endpoint.h"
mgershaf9a9232017-04-13 20:19:0326#include "net/base/mock_network_change_notifier.h"
Matt Menke9aa86262019-08-21 15:52:0727#include "net/base/network_isolation_key.h"
Matt Menke4807a9a2020-11-21 00:14:4128#include "net/base/schemeful_site.h"
[email protected]61a527782013-02-21 03:58:0029#include "net/base/test_completion_callback.h"
tbansalc3308d72016-08-27 10:25:0430#include "net/base/test_proxy_delegate.h"
rsleevid6de8302016-06-21 01:33:2031#include "net/cert/ct_policy_enforcer.h"
[email protected]6e7845ae2013-03-29 21:48:1132#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5333#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0034#include "net/http/http_auth_handler_factory.h"
35#include "net/http/http_network_session.h"
36#include "net/http/http_network_transaction.h"
Matt Menke6e879bd2019-03-18 17:26:0437#include "net/http/http_proxy_connect_job.h"
Matt Menke609160742019-08-02 18:47:2638#include "net/http/http_server_properties.h"
[email protected]61a527782013-02-21 03:58:0039#include "net/http/http_stream.h"
40#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1941#include "net/http/http_transaction_test_util.h"
Yoichi Osato4c75c0c2020-06-24 08:03:5742#include "net/http/test_upload_data_stream_not_allow_http1.h"
[email protected]b1c988b2013-06-13 06:48:1143#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0044#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5145#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4646#include "net/log/test_net_log_util.h"
Nicolas Arciniegad2013f92020-02-07 23:00:5647#include "net/proxy_resolution/configured_proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4048#include "net/proxy_resolution/proxy_config_service_fixed.h"
49#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0850#include "net/quic/crypto/proof_verifier_chromium.h"
51#include "net/quic/mock_crypto_client_stream_factory.h"
Victor Vasiliev7752898d2019-11-14 21:30:2252#include "net/quic/mock_quic_context.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0853#include "net/quic/mock_quic_data.h"
54#include "net/quic/quic_chromium_alarm_factory.h"
55#include "net/quic/quic_http_stream.h"
56#include "net/quic/quic_http_utils.h"
57#include "net/quic/quic_stream_factory_peer.h"
58#include "net/quic/quic_test_packet_maker.h"
59#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0060#include "net/socket/client_socket_factory.h"
61#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2162#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2863#include "net/socket/socket_performance_watcher.h"
64#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0065#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5866#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5767#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2968#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0169#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4370#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4071#include "net/test/test_with_task_environment.h"
Zhongyi Shid1c00fc42019-12-14 06:05:0972#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
73#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5174#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
75#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
76#include "net/third_party/quiche/src/quic/core/quic_framer.h"
77#include "net/third_party/quiche/src/quic/core/quic_utils.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5178#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
79#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
80#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
81#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
82#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
83#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1484#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
85#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2986#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0087#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4888#include "net/url_request/url_request.h"
Matt Menkea9606a0eb2020-09-11 20:36:3889#include "net/url_request/url_request_job_factory.h"
allada71b2efb2016-09-09 04:57:4890#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0191#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0092#include "testing/gtest/include/gtest/gtest.h"
93#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4694#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0095
Reilly Grant89a7e512018-01-20 01:57:1696using ::testing::ElementsAre;
97using ::testing::Key;
98
bnc508835902015-05-12 20:10:2999namespace net {
100namespace test {
[email protected]61a527782013-02-21 03:58:00101
102namespace {
103
bnc359ed2a2016-04-29 20:43:45104enum DestinationType {
105 // In pooling tests with two requests for different origins to the same
106 // destination, the destination should be
107 SAME_AS_FIRST, // the same as the first origin,
108 SAME_AS_SECOND, // the same as the second origin, or
109 DIFFERENT, // different from both.
110};
111
rchf114d982015-10-21 01:34:56112static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52113 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12114static const char kQuicAlternativeServiceWithProbabilityHeader[] =
115 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56116static const char kQuicAlternativeServiceDifferentPortHeader[] =
117 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20118
rch9ae5b3b2016-02-11 00:36:29119const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45120const char kDifferentHostname[] = "different.example.com";
121
David Schinazi09e9a6012019-10-03 17:37:57122struct TestParams {
123 quic::ParsedQuicVersion version;
124 bool client_headers_include_h2_stream_dependency;
125};
126
127// Used by ::testing::PrintToStringParamName().
128std::string PrintToString(const TestParams& p) {
Victor Vasiliev62c09dc2020-11-06 18:18:29129 return base::StrCat(
130 {ParsedQuicVersionToString(p.version), "_",
131 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
132 "Dependency"});
David Schinazi09e9a6012019-10-03 17:37:57133}
134
bnc359ed2a2016-04-29 20:43:45135// Run QuicNetworkTransactionWithDestinationTest instances with all value
136// combinations of version and destination_type.
137struct PoolingTestParams {
Nick Harper23290b82019-05-02 00:02:56138 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45139 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05140 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45141};
142
David Schinazi09e9a6012019-10-03 17:37:57143// Used by ::testing::PrintToStringParamName().
144std::string PrintToString(const PoolingTestParams& p) {
145 const char* destination_string = "";
146 switch (p.destination_type) {
147 case SAME_AS_FIRST:
148 destination_string = "SAME_AS_FIRST";
149 break;
150 case SAME_AS_SECOND:
151 destination_string = "SAME_AS_SECOND";
152 break;
153 case DIFFERENT:
154 destination_string = "DIFFERENT";
155 break;
156 }
Victor Vasiliev62c09dc2020-11-06 18:18:29157 return base::StrCat(
158 {ParsedQuicVersionToString(p.version), "_", destination_string, "_",
159 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
160 "Dependency"});
David Schinazi09e9a6012019-10-03 17:37:57161}
162
David Schinazifbd4c432020-04-07 19:23:55163std::string GenerateQuicAltSvcHeader(
164 const quic::ParsedQuicVersionVector& versions) {
Bence Békyb89104962020-01-24 00:05:17165 std::string altsvc_header = "Alt-Svc: ";
166 std::string version_string;
David Schinazifbd4c432020-04-07 19:23:55167 bool first_version = true;
168 for (const auto& version : versions) {
169 if (first_version) {
170 first_version = false;
Bence Békyb89104962020-01-24 00:05:17171 } else {
David Schinazifbd4c432020-04-07 19:23:55172 altsvc_header.append(", ");
173 }
174 altsvc_header.append(quic::AlpnForVersion(version));
175 altsvc_header.append("=\":443\"");
176 if (version.SupportsGoogleAltSvcFormat()) {
Bence Békyb89104962020-01-24 00:05:17177 if (!version_string.empty()) {
178 version_string.append(",");
179 }
180 version_string.append(base::NumberToString(version.transport_version));
181 }
zhongyie537a002017-06-27 16:48:21182 }
David Schinazifbd4c432020-04-07 19:23:55183 if (!version_string.empty()) {
184 altsvc_header.append(", quic=\":443\"; v=\"" + version_string + "\"");
185 }
186 altsvc_header.append("\r\n");
Bence Békyb89104962020-01-24 00:05:17187
188 return altsvc_header;
zhongyie537a002017-06-27 16:48:21189}
190
David Schinazi09e9a6012019-10-03 17:37:57191std::vector<TestParams> GetTestParams() {
192 std::vector<TestParams> params;
193 quic::ParsedQuicVersionVector all_supported_versions =
194 quic::AllSupportedVersions();
Nico Weber6dcde5b2020-02-22 20:49:20195 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
Renjie Tang3d8a6ddd2019-11-20 00:18:43196 params.push_back(TestParams{version, false});
197 params.push_back(TestParams{version, true});
David Schinazi09e9a6012019-10-03 17:37:57198 }
199 return params;
200}
201
bnc359ed2a2016-04-29 20:43:45202std::vector<PoolingTestParams> GetPoolingTestParams() {
203 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56204 quic::ParsedQuicVersionVector all_supported_versions =
Ryan Hamilton93424eb82019-08-23 04:28:40205 quic::AllSupportedVersions();
Nico Weber6dcde5b2020-02-22 20:49:20206 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
Renjie Tang3d8a6ddd2019-11-20 00:18:43207 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
208 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
209 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
210 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
211 params.push_back(PoolingTestParams{version, DIFFERENT, false});
212 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45213 }
214 return params;
215}
bncb07c05532015-05-14 19:07:20216
Bence Béky319388a882020-09-23 18:42:52217std::string ConstructDataFrameForVersion(base::StringPiece body,
218 quic::ParsedQuicVersion version) {
219 if (!version.HasIetfQuicFrames()) {
220 return body.as_string();
221 }
222 std::unique_ptr<char[]> buffer;
223 auto header_length =
224 quic::HttpEncoder::SerializeDataFrameHeader(body.size(), &buffer);
225 return base::StrCat({base::StringPiece(buffer.get(), header_length), body});
226}
227
[email protected]61a527782013-02-21 03:58:00228} // namespace
229
tbansal0f56a39a2016-04-07 22:03:38230class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40231 public:
tbansal180587c2017-02-16 15:13:23232 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
233 bool* rtt_notification_received)
234 : should_notify_updated_rtt_(should_notify_updated_rtt),
235 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38236 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40237
tbansal180587c2017-02-16 15:13:23238 bool ShouldNotifyUpdatedRTT() const override {
239 return *should_notify_updated_rtt_;
240 }
tbansalfdf5665b2015-09-21 22:46:40241
tbansal0f56a39a2016-04-07 22:03:38242 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
243 *rtt_notification_received_ = true;
244 }
245
246 void OnConnectionChanged() override {}
247
248 private:
tbansal180587c2017-02-16 15:13:23249 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38250 bool* rtt_notification_received_;
251
252 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
253};
254
255class TestSocketPerformanceWatcherFactory
256 : public SocketPerformanceWatcherFactory {
257 public:
258 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23259 : watcher_count_(0u),
260 should_notify_updated_rtt_(true),
261 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38262 ~TestSocketPerformanceWatcherFactory() override {}
263
264 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42265 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41266 const Protocol protocol,
267 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51268 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38269 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51270 }
271 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42272 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23273 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
274 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40275 }
276
tbansalc8a94ea2015-11-02 23:58:51277 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40278
tbansalc8a94ea2015-11-02 23:58:51279 bool rtt_notification_received() const { return rtt_notification_received_; }
280
tbansal180587c2017-02-16 15:13:23281 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
282 should_notify_updated_rtt_ = should_notify_updated_rtt;
283 }
284
tbansalc8a94ea2015-11-02 23:58:51285 private:
tbansal0f56a39a2016-04-07 22:03:38286 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23287 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51288 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38289
290 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51291};
292
Ryan Hamilton8d9ee76e2018-05-29 23:52:52293class QuicNetworkTransactionTest
294 : public PlatformTest,
David Schinazi09e9a6012019-10-03 17:37:57295 public ::testing::WithParamInterface<TestParams>,
Gabriel Charette694c3c332019-08-19 14:53:05296 public WithTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00297 protected:
[email protected]1c04f9522013-02-21 20:32:43298 QuicNetworkTransactionTest()
David Schinazi09e9a6012019-10-03 17:37:57299 : version_(GetParam().version),
300 client_headers_include_h2_stream_dependency_(
301 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:56302 supported_versions_(quic::test::SupportedVersions(version_)),
Zhongyi Shi1c022d22020-03-20 19:00:16303 client_maker_(new QuicTestPacketMaker(
304 version_,
305 quic::QuicUtils::CreateRandomConnectionId(
306 context_.random_generator()),
307 context_.clock(),
308 kDefaultServerHostName,
309 quic::Perspective::IS_CLIENT,
310 client_headers_include_h2_stream_dependency_)),
Victor Vasiliev7752898d2019-11-14 21:30:22311 server_maker_(version_,
312 quic::QuicUtils::CreateRandomConnectionId(
313 context_.random_generator()),
314 context_.clock(),
315 kDefaultServerHostName,
316 quic::Perspective::IS_SERVER,
317 false),
318 quic_task_runner_(new TestTaskRunner(context_.mock_clock())),
[email protected]1c04f9522013-02-21 20:32:43319 ssl_config_service_(new SSLConfigServiceDefaults),
Nicolas Arciniegad2013f92020-02-07 23:00:56320 proxy_resolution_service_(
321 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11322 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke3233d8f22019-08-20 21:01:49323 http_server_properties_(std::make_unique<HttpServerProperties>()),
rchf114d982015-10-21 01:34:56324 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:19325 FLAGS_quic_enable_http3_grease_randomness = false;
[email protected]aa9b14d2013-05-10 23:45:19326 request_.method = "GET";
rchf114d982015-10-21 01:34:56327 std::string url("https://");
bncb07c05532015-05-14 19:07:20328 url.append(kDefaultServerHostName);
329 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19330 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10331 request_.traffic_annotation =
332 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Victor Vasiliev7752898d2019-11-14 21:30:22333 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56334
335 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29336 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56337 verify_details_.cert_verify_result.verified_cert = cert;
338 verify_details_.cert_verify_result.is_issued_by_known_root = true;
339 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43340 }
[email protected]61a527782013-02-21 03:58:00341
dcheng67be2b1f2014-10-27 21:47:29342 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00343 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55344 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00345 }
346
dcheng67be2b1f2014-10-27 21:47:29347 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00348 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
349 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55350 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00351 PlatformTest::TearDown();
352 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55353 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40354 session_.reset();
[email protected]61a527782013-02-21 03:58:00355 }
356
Ryan Hamilton8d9ee76e2018-05-29 23:52:52357 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23358 ConstructClientConnectionClosePacket(uint64_t num) {
Zhongyi Shi1c022d22020-03-20 19:00:16359 return client_maker_->MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52360 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30361 }
362
Ryan Hamilton8d9ee76e2018-05-29 23:52:52363 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23364 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03365 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52366 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58367 }
368
Ryan Hamilton8d9ee76e2018-05-29 23:52:52369 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23370 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52371 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20372 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58373 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20374 }
375
Ryan Hamilton8d9ee76e2018-05-29 23:52:52376 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23377 uint64_t packet_number,
378 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34379 uint64_t smallest_received) {
Zhongyi Shi1c022d22020-03-20 19:00:16380 return client_maker_->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34381 smallest_received);
fayang3bcb8b502016-12-07 21:44:37382 }
383
Ryan Hamilton8d9ee76e2018-05-29 23:52:52384 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23385 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52386 quic::QuicStreamId stream_id,
387 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23388 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34389 uint64_t smallest_received) {
390 return client_maker_->MakeAckAndRstPacket(
391 num, false, stream_id, error_code, largest_received, smallest_received);
zhongyi6b5a3892016-03-12 04:46:20392 }
393
Ryan Hamilton8d9ee76e2018-05-29 23:52:52394 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23395 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52396 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41397 quic::QuicRstStreamErrorCode error_code) {
Zhongyi Shi1c022d22020-03-20 19:00:16398 return client_maker_->MakeRstPacket(num, false, stream_id, error_code,
399 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56400 }
401
Ryan Hamilton8d9ee76e2018-05-29 23:52:52402 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58403 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23404 uint64_t num,
Fan Yangac867502019-01-28 21:10:23405 uint64_t largest_received,
406 uint64_t smallest_received,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52407 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29408 const std::string& quic_error_details,
409 uint64_t frame_type) {
Zhongyi Shi1c022d22020-03-20 19:00:16410 return client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:34411 num, false, largest_received, smallest_received, quic_error,
412 quic_error_details, frame_type);
zhongyica364fbb2015-12-12 03:39:12413 }
414
Ryan Hamilton8d9ee76e2018-05-29 23:52:52415 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23416 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12417 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52418 quic::QuicStreamId stream_id,
419 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58420 return server_maker_.MakeRstPacket(num, include_version, stream_id,
421 error_code);
zhongyica364fbb2015-12-12 03:39:12422 }
423
Ryan Hamilton8d9ee76e2018-05-29 23:52:52424 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02425 uint64_t packet_number) {
Zhongyi Shi1c022d22020-03-20 19:00:16426 return client_maker_->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37427 }
428
Ryan Hamilton8d9ee76e2018-05-29 23:52:52429 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23430 uint64_t packet_number,
431 uint64_t largest_received,
Renjie Tangcd594f32020-07-11 20:18:34432 uint64_t smallest_received) {
fayang3bcb8b502016-12-07 21:44:37433 return server_maker_.MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34434 smallest_received);
fayang3bcb8b502016-12-07 21:44:37435 }
436
Ryan Hamilton8d9ee76e2018-05-29 23:52:52437 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23438 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57439 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52440 quic::QuicStreamId id,
441 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02442 RequestPriority request_priority) {
Zhongyi Shi1c022d22020-03-20 19:00:16443 return client_maker_->MakePriorityPacket(
Yixin Wangb470bc882018-02-15 18:43:57444 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02445 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wang385652a2018-02-16 02:37:23446 }
447
Ryan Hamilton8d9ee76e2018-05-29 23:52:52448 std::unique_ptr<quic::QuicEncryptedPacket>
Haoyue Wang9d70d65c2020-05-29 22:45:34449 ConstructClientPriorityFramesPacket(
450 uint64_t packet_number,
451 bool should_include_version,
452 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
453 priority_frames) {
454 return client_maker_->MakeMultiplePriorityFramesPacket(
455 packet_number, should_include_version, priority_frames);
456 }
457
458 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25459 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23460 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23461 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23462 uint64_t largest_received,
463 uint64_t smallest_received,
Yixin Wange7ecc472018-03-06 19:00:25464 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
Ryan Hamilton0d65a8c2019-06-07 00:46:02465 priority_frames) {
Zhongyi Shi1c022d22020-03-20 19:00:16466 return client_maker_->MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23467 packet_number, should_include_version, largest_received,
Renjie Tangcd594f32020-07-11 20:18:34468 smallest_received, priority_frames);
Yixin Wangb470bc882018-02-15 18:43:57469 }
470
Haoyue Wang9d70d65c2020-05-29 22:45:34471 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckAndPriorityPacket(
472 uint64_t packet_number,
473 bool should_include_version,
474 uint64_t largest_received,
475 uint64_t smallest_received,
476 quic::QuicStreamId id,
477 quic::QuicStreamId parent_stream_id,
478 RequestPriority request_priority) {
479 return client_maker_->MakeAckAndPriorityPacket(
480 packet_number, should_include_version, largest_received,
481 smallest_received, id, parent_stream_id,
482 ConvertRequestPriorityToQuicPriority(request_priority));
483 }
484
zhongyi32569c62016-01-08 02:54:30485 // Uses default QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01486 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
487 const std::string& scheme,
488 const std::string& path) {
Zhongyi Shi1c022d22020-03-20 19:00:16489 return GetRequestHeaders(method, scheme, path, client_maker_.get());
zhongyi32569c62016-01-08 02:54:30490 }
491
492 // Uses customized QuicTestPacketMaker.
Bence Béky4c325e52020-10-22 20:48:01493 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method,
494 const std::string& scheme,
495 const std::string& path,
496 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50497 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00498 }
499
Bence Béky4c325e52020-10-22 20:48:01500 spdy::Http2HeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Zhongyi Shi1c022d22020-03-20 19:00:16501 return client_maker_->ConnectRequestHeaders(host_port);
Yixin Wang46a273ec302018-01-23 17:59:56502 }
503
Bence Béky4c325e52020-10-22 20:48:01504 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58505 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00506 }
507
zhongyi32569c62016-01-08 02:54:30508 // Appends alt_svc headers in the response headers.
Bence Béky4c325e52020-10-22 20:48:01509 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status,
510 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58511 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30512 }
513
Ryan Hamilton8d9ee76e2018-05-29 23:52:52514 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23515 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52516 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05517 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00518 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10519 absl::string_view data) {
Ryan Hamilton7505eb92019-06-08 00:22:17520 return server_maker_.MakeDataPacket(packet_number, stream_id,
521 should_include_version, fin, data);
[email protected]61a527782013-02-21 03:58:00522 }
523
Ryan Hamilton8d9ee76e2018-05-29 23:52:52524 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23525 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52526 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36527 bool should_include_version,
528 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10529 absl::string_view data) {
Zhongyi Shi1c022d22020-03-20 19:00:16530 return client_maker_->MakeDataPacket(packet_number, stream_id,
531 should_include_version, fin, data);
ckrasicda193a82016-07-09 00:39:36532 }
533
Ryan Hamilton8d9ee76e2018-05-29 23:52:52534 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23535 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56536 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52537 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23538 uint64_t largest_received,
539 uint64_t smallest_received,
Yixin Wang46a273ec302018-01-23 17:59:56540 bool fin,
Victor Vasiliev47ecb6a2020-10-14 17:22:10541 absl::string_view data) {
Renjie Tangcd594f32020-07-11 20:18:34542 return client_maker_->MakeAckAndDataPacket(packet_number, include_version,
543 stream_id, largest_received,
544 smallest_received, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56545 }
546
Ryan Hamilton8d9ee76e2018-05-29 23:52:52547 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23548 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52549 quic::QuicStreamId stream_id,
550 bool should_include_version,
551 bool fin,
Bence Béky4c325e52020-10-22 20:48:01552 spdy::Http2HeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56553 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
554 should_include_version, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02555 std::move(headers), 0);
Yixin Wang46a273ec302018-01-23 17:59:56556 }
557
Ryan Hamilton8d9ee76e2018-05-29 23:52:52558 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23559 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52560 quic::QuicStreamId stream_id,
561 bool should_include_version,
562 bool fin,
Bence Béky4c325e52020-10-22 20:48:01563 spdy::Http2HeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02564 quic::QuicStreamId parent_stream_id) {
Yixin Wang46a273ec302018-01-23 17:59:56565 return ConstructClientRequestHeadersPacket(
566 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:02567 std::move(headers), parent_stream_id);
zhongyi32569c62016-01-08 02:54:30568 }
569
Ryan Hamilton8d9ee76e2018-05-29 23:52:52570 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23571 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52572 quic::QuicStreamId stream_id,
573 bool should_include_version,
574 bool fin,
575 RequestPriority request_priority,
Bence Béky4c325e52020-10-22 20:48:01576 spdy::Http2HeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02577 quic::QuicStreamId parent_stream_id) {
Ryan Hamilton0239aac2018-05-19 00:03:13578 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56579 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16580 return client_maker_->MakeRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56581 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02582 std::move(headers), parent_stream_id, nullptr);
[email protected]61a527782013-02-21 03:58:00583 }
584
Ryan Hamilton8d9ee76e2018-05-29 23:52:52585 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25586 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23587 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52588 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25589 bool should_include_version,
590 bool fin,
591 RequestPriority request_priority,
Bence Béky4c325e52020-10-22 20:48:01592 spdy::Http2HeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52593 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25594 size_t* spdy_headers_frame_length,
595 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13596 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25597 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16598 return client_maker_->MakeRequestHeadersAndMultipleDataFramesPacket(
Yixin Wange7ecc472018-03-06 19:00:25599 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02600 std::move(headers), parent_stream_id, spdy_headers_frame_length,
Yixin Wange7ecc472018-03-06 19:00:25601 data_writes);
602 }
603
Ryan Hamilton8d9ee76e2018-05-29 23:52:52604 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23605 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52606 quic::QuicStreamId stream_id,
607 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13608 bool should_include_version,
Bence Béky4c325e52020-10-22 20:48:01609 spdy::Http2HeaderBlock headers) {
Renjie Tangb7afea82020-07-15 23:35:47610 return server_maker_.MakePushPromisePacket(
ckrasic769733c2016-06-30 00:42:13611 packet_number, stream_id, promised_stream_id, should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02612 false, std::move(headers), nullptr);
ckrasic769733c2016-06-30 00:42:13613 }
614
Ryan Hamilton8d9ee76e2018-05-29 23:52:52615 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23616 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52617 quic::QuicStreamId stream_id,
618 bool should_include_version,
619 bool fin,
Bence Béky4c325e52020-10-22 20:48:01620 spdy::Http2HeaderBlock headers) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02621 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
622 should_include_version, fin,
623 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30624 }
625
Bence Béky319388a882020-09-23 18:42:52626 std::string ConstructDataFrame(base::StringPiece body) {
627 return ConstructDataFrameForVersion(body, version_);
Renjief49758b2019-01-11 23:32:41628 }
629
Nick Harper23290b82019-05-02 00:02:56630 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41631 session_params_.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:38632 context_.params()->supported_versions = supported_versions;
Victor Vasilieva1e66d72019-12-05 17:55:38633 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:05634 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00635
Victor Vasiliev7752898d2019-11-14 21:30:22636 session_context_.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:41637 session_context_.client_socket_factory = &socket_factory_;
638 session_context_.quic_crypto_client_stream_factory =
639 &crypto_client_stream_factory_;
640 session_context_.host_resolver = &host_resolver_;
641 session_context_.cert_verifier = &cert_verifier_;
642 session_context_.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:41643 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
644 session_context_.socket_performance_watcher_factory =
645 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59646 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41647 session_context_.ssl_config_service = ssl_config_service_.get();
648 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49649 session_context_.http_server_properties = http_server_properties_.get();
mmenke6ddfbea2017-05-31 21:48:41650 session_context_.net_log = net_log_.bound().net_log();
651
652 session_.reset(new HttpNetworkSession(session_params_, session_context_));
Matt Menkeb566c392019-09-11 23:22:43653 session_->quic_stream_factory()
654 ->set_is_quic_known_to_work_on_current_network(true);
Yixin Wang46a273ec302018-01-23 17:59:56655 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
656 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00657 }
658
zhongyi86838d52017-06-30 01:19:44659 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21660
David Schinazif832cb82019-11-08 22:25:27661 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
Zhongyi Shi1c022d22020-03-20 19:00:16662 const std::string& status_line,
663 const quic::ParsedQuicVersion& version) {
[email protected]aa9b14d2013-05-10 23:45:19664 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42665 ASSERT_TRUE(response != nullptr);
666 ASSERT_TRUE(response->headers.get() != nullptr);
David Schinazif832cb82019-11-08 22:25:27667 EXPECT_EQ(status_line, response->headers->GetStatusLine());
[email protected]aa9b14d2013-05-10 23:45:19668 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52669 EXPECT_TRUE(response->was_alpn_negotiated);
Zhongyi Shi1c022d22020-03-20 19:00:16670 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version),
[email protected]aa9b14d2013-05-10 23:45:19671 response->connection_info);
672 }
673
Zhongyi Shi1c022d22020-03-20 19:00:16674 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
675 const std::string& status_line) {
676 CheckWasQuicResponse(trans, status_line, version_);
677 }
678
David Schinazif832cb82019-11-08 22:25:27679 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
Zhongyi Shi1c022d22020-03-20 19:00:16680 CheckWasQuicResponse(trans, "HTTP/1.1 200 OK", version_);
David Schinazif832cb82019-11-08 22:25:27681 }
682
bnc691fda62016-08-12 00:43:16683 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41684 const HttpResponseInfo* response = trans->GetResponseInfo();
685 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37686 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41687 }
688
bnc691fda62016-08-12 00:43:16689 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19690 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42691 ASSERT_TRUE(response != nullptr);
692 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19693 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
694 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52695 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52696 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19697 response->connection_info);
698 }
699
Yixin Wang46a273ec302018-01-23 17:59:56700 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
701 const HttpResponseInfo* response = trans->GetResponseInfo();
702 ASSERT_TRUE(response != nullptr);
703 ASSERT_TRUE(response->headers.get() != nullptr);
704 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
705 EXPECT_TRUE(response->was_fetched_via_spdy);
706 EXPECT_TRUE(response->was_alpn_negotiated);
707 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
708 response->connection_info);
709 }
710
bnc691fda62016-08-12 00:43:16711 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19712 const std::string& expected) {
713 std::string response_data;
bnc691fda62016-08-12 00:43:16714 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19715 EXPECT_EQ(expected, response_data);
716 }
717
bnc691fda62016-08-12 00:43:16718 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19719 TestCompletionCallback callback;
720 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01721 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
722 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19723 }
724
725 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16726 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
727 RunTransaction(&trans);
728 CheckWasHttpResponse(&trans);
729 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19730 }
731
tbansalc3308d72016-08-27 10:25:04732 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
733 bool used_proxy,
734 uint16_t port) {
735 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalc3308d72016-08-27 10:25:04736 RunTransaction(&trans);
737 CheckWasHttpResponse(&trans);
738 CheckResponsePort(&trans, port);
739 CheckResponseData(&trans, expected);
tbansal2ecbbc72016-10-06 17:15:47740 if (used_proxy) {
741 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
742 } else {
743 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
744 }
tbansalc3308d72016-08-27 10:25:04745 }
David Schinazif832cb82019-11-08 22:25:27746 void SendRequestAndExpectQuicResponse(const std::string& expected,
747 const std::string& status_line) {
748 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443,
749 status_line);
750 }
tbansalc3308d72016-08-27 10:25:04751
[email protected]aa9b14d2013-05-10 23:45:19752 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56753 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12754 }
755
bnc62a44f022015-04-02 15:59:41756 void SendRequestAndExpectQuicResponseFromProxyOnPort(
757 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46758 uint16_t port) {
bnc62a44f022015-04-02 15:59:41759 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19760 }
761
762 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05763 MockCryptoClientStream::HandshakeMode handshake_mode,
764 const NetworkIsolationKey& network_isolation_key =
765 NetworkIsolationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19766 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46767 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21768 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12769 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49770 http_server_properties_->SetQuicAlternativeService(
Matt Menkeb32ba5122019-09-10 19:17:05771 server, network_isolation_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07772 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19773 }
774
rchbe69cb902016-02-11 01:10:48775 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27776 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48777 const HostPortPair& alternative) {
778 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46779 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21780 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48781 alternative.port());
782 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49783 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07784 server, NetworkIsolationKey(), alternative_service, expiration,
785 supported_versions_);
rchbe69cb902016-02-11 01:10:48786 }
787
Matt Menkeb32ba5122019-09-10 19:17:05788 void ExpectBrokenAlternateProtocolMapping(
789 const NetworkIsolationKey& network_isolation_key =
790 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46791 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34792 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49793 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05794 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34795 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49796 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05797 alternative_service_info_vector[0].alternative_service(),
798 network_isolation_key));
[email protected]aa9b14d2013-05-10 23:45:19799 }
800
Matt Menkeb32ba5122019-09-10 19:17:05801 void ExpectQuicAlternateProtocolMapping(
802 const NetworkIsolationKey& network_isolation_key =
803 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46804 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34805 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49806 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05807 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34808 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54809 EXPECT_EQ(
810 kProtoQUIC,
811 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49812 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05813 alternative_service_info_vector[0].alternative_service(),
814 network_isolation_key));
[email protected]4d590c9c2014-05-02 05:14:33815 }
816
[email protected]aa9b14d2013-05-10 23:45:19817 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42818 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30819 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30820 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30821 hanging_data->set_connect_data(hanging_connect);
822 hanging_data_.push_back(std::move(hanging_data));
823 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
[email protected]aa9b14d2013-05-10 23:45:19824 }
825
Zhongyi Shia6b68d112018-09-24 07:49:03826 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Victor Vasilieva1e66d72019-12-05 17:55:38827 context_.params()->migrate_sessions_on_network_change_v2 = true;
828 context_.params()->migrate_sessions_early_v2 = true;
829 context_.params()->retry_on_alternate_network_before_handshake = true;
Zhongyi Shia6b68d112018-09-24 07:49:03830 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
831 MockNetworkChangeNotifier* mock_ncn =
832 scoped_mock_change_notifier_->mock_network_change_notifier();
833 mock_ncn->ForceNetworkHandlesSupported();
834 mock_ncn->SetConnectedNetworksList(
835 {kDefaultNetworkForTests, kNewNetworkForTests});
836 }
837
Matt Menkeb32ba5122019-09-10 19:17:05838 // Adds a new socket data provider for an HTTP request, and runs a request,
839 // expecting it to be used.
840 void AddHttpDataAndRunRequest() {
841 MockWrite http_writes[] = {
842 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
843 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
844 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
845
846 MockRead http_reads[] = {
847 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
848 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
849 MockRead(SYNCHRONOUS, 5, "http used"),
850 // Connection closed.
851 MockRead(SYNCHRONOUS, OK, 6)};
852 SequencedSocketData http_data(http_reads, http_writes);
853 socket_factory_.AddSocketDataProvider(&http_data);
854 SSLSocketDataProvider ssl_data(ASYNC, OK);
855 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
856 SendRequestAndExpectHttpResponse("http used");
857 EXPECT_TRUE(http_data.AllWriteDataConsumed());
858 EXPECT_TRUE(http_data.AllReadDataConsumed());
859 }
860
861 // Adds a new socket data provider for a QUIC request, and runs a request,
862 // expecting it to be used. The new QUIC session is not closed.
863 void AddQuicDataAndRunRequest() {
864 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22865 version_,
866 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
867 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menkeb32ba5122019-09-10 19:17:05868 client_headers_include_h2_stream_dependency_);
869 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22870 version_,
871 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
872 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
873 false);
Matt Menkeb32ba5122019-09-10 19:17:05874 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56875 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05876 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:25877 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:56878 quic_data.AddWrite(
879 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_number++));
880 }
Matt Menkeb32ba5122019-09-10 19:17:05881 quic_data.AddWrite(
882 SYNCHRONOUS,
883 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56884 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
885 true, true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Matt Menkeb32ba5122019-09-10 19:17:05886 GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
887 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
888 quic_data.AddRead(
889 ASYNC, server_maker.MakeResponseHeadersPacket(
890 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
891 false, server_maker.GetResponseHeaders("200 OK"), nullptr));
Matt Menkeb32ba5122019-09-10 19:17:05892 quic_data.AddRead(
893 ASYNC, server_maker.MakeDataPacket(
894 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:52895 true, ConstructDataFrame("quic used")));
Matt Menkeb32ba5122019-09-10 19:17:05896 // Don't care about the final ack.
897 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
898 // No more data to read.
899 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
900 quic_data.AddSocketDataToFactory(&socket_factory_);
901 SendRequestAndExpectQuicResponse("quic used");
902
903 EXPECT_TRUE(quic_data.AllReadDataConsumed());
904 }
905
Bence Béky6e243aa2019-12-13 19:01:07906 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56907 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
908 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36909 }
910
Bence Béky6e243aa2019-12-13 19:01:07911 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56912 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
913 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36914 }
915
Bence Béky6e243aa2019-12-13 19:01:07916 quic::QuicStreamId GetQpackDecoderStreamId() const {
917 return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
918 version_.transport_version, 1);
919 }
920
921 std::string StreamCancellationQpackDecoderInstruction(int n) const {
Ian Swettb70d9f8f2020-04-10 23:38:43922 return StreamCancellationQpackDecoderInstruction(n, true);
923 }
924
925 std::string StreamCancellationQpackDecoderInstruction(
926 int n,
927 bool create_stream) const {
Bence Béky6e243aa2019-12-13 19:01:07928 const quic::QuicStreamId cancelled_stream_id =
929 GetNthClientInitiatedBidirectionalStreamId(n);
930 EXPECT_LT(cancelled_stream_id, 63u);
931
932 const unsigned char opcode = 0x40;
Ian Swettb70d9f8f2020-04-10 23:38:43933 if (create_stream) {
934 return {0x03, opcode | static_cast<unsigned char>(cancelled_stream_id)};
935 } else {
936 return {opcode | static_cast<unsigned char>(cancelled_stream_id)};
937 }
Bence Béky6e243aa2019-12-13 19:01:07938 }
939
Bence Béky230ac612017-08-30 19:17:08940 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49941 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08942 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49943 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08944 }
945
Zhongyi Shi1c022d22020-03-20 19:00:16946 void SendRequestAndExpectQuicResponseMaybeFromProxy(
947 const std::string& expected,
948 bool used_proxy,
949 uint16_t port,
950 const std::string& status_line,
951 const quic::ParsedQuicVersion& version) {
952 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Zhongyi Shi1c022d22020-03-20 19:00:16953 RunTransaction(&trans);
954 CheckWasQuicResponse(&trans, status_line, version);
955 CheckResponsePort(&trans, port);
956 CheckResponseData(&trans, expected);
Zhongyi Shi1c022d22020-03-20 19:00:16957 if (used_proxy) {
958 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
Cammie Smith Barnesbf91e2a2020-12-23 20:49:04959
960 // DNS aliases should be empty when using a proxy.
961 EXPECT_TRUE(trans.GetResponseInfo()->dns_aliases.empty());
Zhongyi Shi1c022d22020-03-20 19:00:16962 } else {
963 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
964 }
965 }
966
Nick Harper23290b82019-05-02 00:02:56967 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05968 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:56969 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01970 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Victor Vasiliev7752898d2019-11-14 21:30:22971 MockQuicContext context_;
Zhongyi Shi1c022d22020-03-20 19:00:16972 std::unique_ptr<QuicTestPacketMaker> client_maker_;
alyssar2adf3ac2016-05-03 17:12:58973 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:09974 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:42975 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00976 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56977 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05978 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43979 MockHostResolver host_resolver_;
980 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11981 TransportSecurityState transport_security_state_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23982 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38983 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07984 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:26985 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42986 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:49987 std::unique_ptr<HttpServerProperties> http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41988 HttpNetworkSession::Params session_params_;
989 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19990 HttpRequestInfo request_;
Matt Muellerd9342e3a2019-11-26 01:41:14991 RecordingBoundTestNetLog net_log_;
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_;
tbansal7cec3812015-02-05 21:25:12995
996 private:
997 void SendRequestAndExpectQuicResponseMaybeFromProxy(
998 const std::string& expected,
bnc62a44f022015-04-02 15:59:41999 bool used_proxy,
David Schinazif832cb82019-11-08 22:25:271000 uint16_t port,
1001 const std::string& status_line) {
Zhongyi Shi1c022d22020-03-20 19:00:161002 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
1003 status_line, version_);
tbansal7cec3812015-02-05 21:25:121004 }
David Schinazif832cb82019-11-08 22:25:271005
1006 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1007 const std::string& expected,
1008 bool used_proxy,
1009 uint16_t port) {
1010 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
Zhongyi Shi1c022d22020-03-20 19:00:161011 "HTTP/1.1 200 OK", version_);
David Schinazif832cb82019-11-08 22:25:271012 }
[email protected]61a527782013-02-21 03:58:001013};
1014
David Schinazi09e9a6012019-10-03 17:37:571015INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1016 QuicNetworkTransactionTest,
1017 ::testing::ValuesIn(GetTestParams()),
1018 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201019
Ryan Hamiltona64a5bcf2017-11-30 07:35:281020TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:381021 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281022 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381023 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281024 HostPortPair::FromString("mail.example.org:443"));
1025 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271026 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281027
Ryan Hamiltonabad59e2019-06-06 04:02:591028 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251029 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231030 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281031 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1032 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1033 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1034
1035 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1036
1037 CreateSession();
1038
1039 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1040 TestCompletionCallback callback;
1041 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1043 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1044
1045 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1046 -ERR_INTERNET_DISCONNECTED, 1);
1047 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1048 -ERR_INTERNET_DISCONNECTED, 1);
1049}
1050
1051TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Victor Vasilieva1e66d72019-12-05 17:55:381052 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281053 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381054 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281055 HostPortPair::FromString("mail.example.org:443"));
1056 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271057 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281058
Ryan Hamiltonabad59e2019-06-06 04:02:591059 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251060 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231061 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281062 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1063 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1064 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1065
1066 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1067
1068 CreateSession();
1069
1070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1071 TestCompletionCallback callback;
1072 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1074 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1075
1076 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1077 -ERR_INTERNET_DISCONNECTED, 1);
1078 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1079 -ERR_INTERNET_DISCONNECTED, 1);
1080}
1081
tbansal180587c2017-02-16 15:13:231082TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381083 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231084 HostPortPair::FromString("mail.example.org:443"));
1085
Ryan Hamiltonabad59e2019-06-06 04:02:591086 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231087 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251088 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231089 mock_quic_data.AddWrite(SYNCHRONOUS,
1090 ConstructInitialSettingsPacket(packet_num++));
1091 }
rch5cb522462017-04-25 20:18:361092 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231093 SYNCHRONOUS,
1094 ConstructClientRequestHeadersPacket(
1095 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1096 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431097 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331098 ASYNC, ConstructServerResponseHeadersPacket(
1099 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1100 GetResponseHeaders("200 OK")));
1101 mock_quic_data.AddRead(
1102 ASYNC, ConstructServerDataPacket(
1103 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521104 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231105 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341106 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231107 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1108
1109 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1110
1111 CreateSession();
1112 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1113
1114 EXPECT_FALSE(
1115 test_socket_performance_watcher_factory_.rtt_notification_received());
1116 SendRequestAndExpectQuicResponse("hello!");
1117 EXPECT_TRUE(
1118 test_socket_performance_watcher_factory_.rtt_notification_received());
1119}
1120
1121TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381122 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231123 HostPortPair::FromString("mail.example.org:443"));
1124
Ryan Hamiltonabad59e2019-06-06 04:02:591125 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231126 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251127 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231128 mock_quic_data.AddWrite(SYNCHRONOUS,
1129 ConstructInitialSettingsPacket(packet_num++));
1130 }
rch5cb522462017-04-25 20:18:361131 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231132 SYNCHRONOUS,
1133 ConstructClientRequestHeadersPacket(
1134 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1135 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431136 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331137 ASYNC, ConstructServerResponseHeadersPacket(
1138 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1139 GetResponseHeaders("200 OK")));
1140 mock_quic_data.AddRead(
1141 ASYNC, ConstructServerDataPacket(
1142 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521143 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231144 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341145 ConstructClientAckPacket(packet_num++, 2, 1));
tbansal180587c2017-02-16 15:13:231146 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1147
1148 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1149
1150 CreateSession();
1151 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1152
1153 EXPECT_FALSE(
1154 test_socket_performance_watcher_factory_.rtt_notification_received());
1155 SendRequestAndExpectQuicResponse("hello!");
1156 EXPECT_FALSE(
1157 test_socket_performance_watcher_factory_.rtt_notification_received());
1158}
1159
[email protected]1e960032013-12-20 19:00:201160TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:381161 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571162 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471163
Ryan Hamiltonabad59e2019-06-06 04:02:591164 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231165 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251166 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231167 mock_quic_data.AddWrite(SYNCHRONOUS,
1168 ConstructInitialSettingsPacket(packet_num++));
1169 }
rch5cb522462017-04-25 20:18:361170 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231171 SYNCHRONOUS,
1172 ConstructClientRequestHeadersPacket(
1173 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1174 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431175 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331176 ASYNC, ConstructServerResponseHeadersPacket(
1177 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1178 GetResponseHeaders("200 OK")));
1179 mock_quic_data.AddRead(
1180 ASYNC, ConstructServerDataPacket(
1181 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521182 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231183 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341184 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:591185 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471186
rcha5399e02015-04-21 19:32:041187 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471188
[email protected]4dca587c2013-03-07 16:54:471189 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471190
[email protected]aa9b14d2013-05-10 23:45:191191 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471192
[email protected]98b20ce2013-05-10 05:55:261193 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:541194 auto entries = net_log_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261195 EXPECT_LT(0u, entries.size());
1196
1197 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291198 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001199 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1200 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261201 EXPECT_LT(0, pos);
1202
David Schinazi24bfaa02020-10-22 19:54:381203 // ... and also a TYPE_QUIC_SESSION_PACKET_SENT.
1204 pos = ExpectLogContainsSomewhere(entries, 0,
1205 NetLogEventType::QUIC_SESSION_PACKET_SENT,
1206 NetLogEventPhase::NONE);
1207 EXPECT_LT(0, pos);
1208
rchfd527212015-08-25 00:41:261209 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291210 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261211 entries, 0,
mikecirone8b85c432016-09-08 19:11:001212 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1213 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261214 EXPECT_LT(0, pos);
1215
Eric Roman79cc7552019-07-19 02:17:541216 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261217
rchfd527212015-08-25 00:41:261218 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1219 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001220 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1221 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261222 EXPECT_LT(0, pos);
1223
[email protected]98b20ce2013-05-10 05:55:261224 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291225 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001226 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1227 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261228 EXPECT_LT(0, pos);
1229
Eric Roman79cc7552019-07-19 02:17:541230 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Victor Vasiliev7da08172019-10-14 06:04:251231 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451232 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1233 static_cast<quic::QuicStreamId>(log_stream_id));
1234 } else {
1235 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1236 static_cast<quic::QuicStreamId>(log_stream_id));
1237 }
[email protected]4dca587c2013-03-07 16:54:471238}
1239
Bence Békyb6300042020-01-28 21:18:201240// Regression test for https://crbug.com/1043531.
1241TEST_P(QuicNetworkTransactionTest, ResetOnEmptyResponseHeaders) {
1242 if (!quic::VersionUsesHttp3(version_.transport_version)) {
1243 return;
1244 }
1245
1246 context_.params()->origins_to_force_quic_on.insert(
1247 HostPortPair::FromString("mail.example.org:443"));
1248
1249 MockQuicData mock_quic_data(version_);
1250 int write_packet_num = 1;
1251 mock_quic_data.AddWrite(SYNCHRONOUS,
1252 ConstructInitialSettingsPacket(write_packet_num++));
1253 mock_quic_data.AddWrite(
1254 SYNCHRONOUS,
1255 ConstructClientRequestHeadersPacket(
1256 write_packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1257 true, true, GetRequestHeaders("GET", "https", "/")));
1258
1259 const quic::QuicStreamId request_stream_id =
1260 GetNthClientInitiatedBidirectionalStreamId(0);
Bence Béky4c325e52020-10-22 20:48:011261 spdy::Http2HeaderBlock empty_response_headers;
Bence Békyb6300042020-01-28 21:18:201262 const std::string response_data = server_maker_.QpackEncodeHeaders(
1263 request_stream_id, std::move(empty_response_headers), nullptr);
1264 uint64_t read_packet_num = 1;
1265 mock_quic_data.AddRead(
1266 ASYNC, ConstructServerDataPacket(read_packet_num++, request_stream_id,
1267 false, false, response_data));
1268 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1269
1270 mock_quic_data.AddWrite(
1271 ASYNC,
1272 ConstructClientAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:341273 write_packet_num++, true, GetQpackDecoderStreamId(), 1, 1, false,
Bence Békyb6300042020-01-28 21:18:201274 StreamCancellationQpackDecoderInstruction(request_stream_id)));
1275
1276 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1277
1278 CreateSession();
1279
1280 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1281 TestCompletionCallback callback;
1282 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1283 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1284 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_INVALID_RESPONSE));
1285}
1286
rchbd089ab2017-05-26 23:05:041287TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381288 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041289 HostPortPair::FromString("mail.example.org:443"));
1290
Ryan Hamiltonabad59e2019-06-06 04:02:591291 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231292 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251293 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231294 mock_quic_data.AddWrite(SYNCHRONOUS,
1295 ConstructInitialSettingsPacket(packet_num++));
1296 }
rchbd089ab2017-05-26 23:05:041297 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231298 SYNCHRONOUS,
1299 ConstructClientRequestHeadersPacket(
1300 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1301 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky4c325e52020-10-22 20:48:011302 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041303 response_headers["key1"] = std::string(30000, 'A');
1304 response_headers["key2"] = std::string(30000, 'A');
1305 response_headers["key3"] = std::string(30000, 'A');
1306 response_headers["key4"] = std::string(30000, 'A');
1307 response_headers["key5"] = std::string(30000, 'A');
1308 response_headers["key6"] = std::string(30000, 'A');
1309 response_headers["key7"] = std::string(30000, 'A');
1310 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451311 quic::QuicStreamId stream_id;
1312 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251313 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451314 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281315 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451316 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451317 } else {
1318 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1319 spdy::SpdyHeadersIR headers_frame(
1320 GetNthClientInitiatedBidirectionalStreamId(0),
1321 std::move(response_headers));
1322 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1323 spdy::SpdySerializedFrame spdy_frame =
1324 response_framer.SerializeFrame(headers_frame);
1325 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1326 }
rchbd089ab2017-05-26 23:05:041327
Fan Yangac867502019-01-28 21:10:231328 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041329 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451330 for (size_t offset = 0; offset < response_data.length();
1331 offset += chunk_size) {
1332 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431333 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451334 ASYNC, ConstructServerDataPacket(
1335 packet_number++, stream_id, false, false,
Victor Vasiliev502ba582020-09-15 23:16:151336 absl::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041337 }
1338
1339 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331340 ASYNC, ConstructServerDataPacket(
1341 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Bence Béky319388a882020-09-23 18:42:521342 false, true, ConstructDataFrame("hello!")));
rchbd089ab2017-05-26 23:05:041343 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341344 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Renjie Tangaadb84b2019-08-31 01:00:231345 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:341346 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3));
rchbd089ab2017-05-26 23:05:041347
1348 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1349
1350 CreateSession();
1351
1352 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421353 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1354 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041355}
1356
1357TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381358 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1359 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041360 HostPortPair::FromString("mail.example.org:443"));
1361
Ryan Hamiltonabad59e2019-06-06 04:02:591362 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231363 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251364 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231365 mock_quic_data.AddWrite(SYNCHRONOUS,
1366 ConstructInitialSettingsPacket(packet_num++));
1367 }
rchbd089ab2017-05-26 23:05:041368 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231369 SYNCHRONOUS,
1370 ConstructClientRequestHeadersPacket(
1371 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1372 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451373
Bence Béky4c325e52020-10-22 20:48:011374 spdy::Http2HeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041375 response_headers["key1"] = std::string(30000, 'A');
1376 response_headers["key2"] = std::string(30000, 'A');
1377 response_headers["key3"] = std::string(30000, 'A');
1378 response_headers["key4"] = std::string(30000, 'A');
1379 response_headers["key5"] = std::string(30000, 'A');
1380 response_headers["key6"] = std::string(30000, 'A');
1381 response_headers["key7"] = std::string(30000, 'A');
1382 response_headers["key8"] = std::string(30000, 'A');
1383 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451384
1385 quic::QuicStreamId stream_id;
1386 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251387 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451388 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281389 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451390 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451391 } else {
1392 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1393 spdy::SpdyHeadersIR headers_frame(
1394 GetNthClientInitiatedBidirectionalStreamId(0),
1395 std::move(response_headers));
1396 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1397 spdy::SpdySerializedFrame spdy_frame =
1398 response_framer.SerializeFrame(headers_frame);
1399 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1400 }
rchbd089ab2017-05-26 23:05:041401
Fan Yangac867502019-01-28 21:10:231402 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041403 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451404 for (size_t offset = 0; offset < response_data.length();
1405 offset += chunk_size) {
1406 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431407 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451408 ASYNC, ConstructServerDataPacket(
1409 packet_number++, stream_id, false, false,
Victor Vasiliev502ba582020-09-15 23:16:151410 absl::string_view(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041411 }
1412
1413 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331414 ASYNC, ConstructServerDataPacket(
1415 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Bence Béky319388a882020-09-23 18:42:521416 false, true, ConstructDataFrame("hello!")));
rchbd089ab2017-05-26 23:05:041417 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangcd594f32020-07-11 20:18:341418 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431419 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331420 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231421 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:341422 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3));
rchbd089ab2017-05-26 23:05:041423
1424 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1425
1426 CreateSession();
1427
1428 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1429 TestCompletionCallback callback;
1430 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1431 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1432 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1433}
1434
rcha2bd44b2016-07-02 00:42:551435TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Victor Vasilieva1e66d72019-12-05 17:55:381436 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551437
Ryan Hamilton9835e662018-08-02 05:36:271438 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551439
Ryan Hamiltonabad59e2019-06-06 04:02:591440 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231441 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251442 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231443 mock_quic_data.AddWrite(SYNCHRONOUS,
1444 ConstructInitialSettingsPacket(packet_num++));
1445 }
rch5cb522462017-04-25 20:18:361446 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231447 SYNCHRONOUS,
1448 ConstructClientRequestHeadersPacket(
1449 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1450 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431451 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331452 ASYNC, ConstructServerResponseHeadersPacket(
1453 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1454 GetResponseHeaders("200 OK")));
1455 mock_quic_data.AddRead(
1456 ASYNC, ConstructServerDataPacket(
1457 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521458 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231459 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341460 ConstructClientAckPacket(packet_num++, 2, 1));
rcha2bd44b2016-07-02 00:42:551461 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1462
1463 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1464
1465 CreateSession();
1466
1467 SendRequestAndExpectQuicResponse("hello!");
1468 EXPECT_TRUE(
1469 test_socket_performance_watcher_factory_.rtt_notification_received());
1470}
1471
David Schinazif832cb82019-11-08 22:25:271472// Regression test for https://crbug.com/695225
1473TEST_P(QuicNetworkTransactionTest, 408Response) {
Victor Vasilieva1e66d72019-12-05 17:55:381474 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
David Schinazif832cb82019-11-08 22:25:271475
1476 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1477
1478 MockQuicData mock_quic_data(version_);
1479 int packet_num = 1;
1480 if (VersionUsesHttp3(version_.transport_version)) {
1481 mock_quic_data.AddWrite(SYNCHRONOUS,
1482 ConstructInitialSettingsPacket(packet_num++));
1483 }
1484 mock_quic_data.AddWrite(
1485 SYNCHRONOUS,
1486 ConstructClientRequestHeadersPacket(
1487 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1488 true, GetRequestHeaders("GET", "https", "/")));
1489 mock_quic_data.AddRead(
1490 ASYNC, ConstructServerResponseHeadersPacket(
1491 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1492 GetResponseHeaders("408 Request Timeout")));
David Schinazif832cb82019-11-08 22:25:271493 mock_quic_data.AddRead(
1494 ASYNC, ConstructServerDataPacket(
1495 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521496 ConstructDataFrame("hello!")));
David Schinazif832cb82019-11-08 22:25:271497 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341498 ConstructClientAckPacket(packet_num++, 2, 1));
David Schinazif832cb82019-11-08 22:25:271499 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1500
1501 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1502
1503 CreateSession();
1504
1505 SendRequestAndExpectQuicResponse("hello!", "HTTP/1.1 408 Request Timeout");
1506}
1507
[email protected]cf3e3cd62014-02-05 16:16:161508TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411509 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561510 proxy_resolution_service_ =
1511 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
1512 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161513
Ryan Hamiltonabad59e2019-06-06 04:02:591514 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231515 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251516 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231517 mock_quic_data.AddWrite(SYNCHRONOUS,
1518 ConstructInitialSettingsPacket(packet_num++));
1519 }
rch5cb522462017-04-25 20:18:361520 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231521 SYNCHRONOUS,
1522 ConstructClientRequestHeadersPacket(
1523 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1524 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431525 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331526 ASYNC, ConstructServerResponseHeadersPacket(
1527 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1528 GetResponseHeaders("200 OK")));
1529 mock_quic_data.AddRead(
1530 ASYNC, ConstructServerDataPacket(
1531 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521532 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231533 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341534 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:501535 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591536 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161537
rcha5399e02015-04-21 19:32:041538 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161539
tbansal0f56a39a2016-04-07 22:03:381540 EXPECT_FALSE(
1541 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161542 // There is no need to set up an alternate protocol job, because
1543 // no attempt will be made to speak to the proxy over TCP.
1544
rch9ae5b3b2016-02-11 00:36:291545 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161546 CreateSession();
1547
bnc62a44f022015-04-02 15:59:411548 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381549 EXPECT_TRUE(
1550 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161551}
1552
bnc313ba9c2015-06-11 15:42:311553// Regression test for https://crbug.com/492458. Test that for an HTTP
1554// connection through a QUIC proxy, the certificate exhibited by the proxy is
1555// checked against the proxy hostname, not the origin hostname.
1556TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291557 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311558 const std::string proxy_host = "www.example.org";
1559
mmenke6ddfbea2017-05-31 21:48:411560 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561561 proxy_resolution_service_ =
1562 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
1563 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311564
Zhongyi Shi1c022d22020-03-20 19:00:161565 client_maker_->set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591566 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231567 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251568 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231569 mock_quic_data.AddWrite(SYNCHRONOUS,
1570 ConstructInitialSettingsPacket(packet_num++));
1571 }
rch5cb522462017-04-25 20:18:361572 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231573 SYNCHRONOUS,
1574 ConstructClientRequestHeadersPacket(
1575 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1576 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431577 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331578 ASYNC, ConstructServerResponseHeadersPacket(
1579 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1580 GetResponseHeaders("200 OK")));
1581 mock_quic_data.AddRead(
1582 ASYNC, ConstructServerDataPacket(
1583 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521584 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231585 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341586 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:501587 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591588 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311589 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1590
1591 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291592 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311593 ASSERT_TRUE(cert.get());
1594 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241595 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1596 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311597 ProofVerifyDetailsChromium verify_details;
1598 verify_details.cert_verify_result.verified_cert = cert;
1599 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561600 ProofVerifyDetailsChromium verify_details2;
1601 verify_details2.cert_verify_result.verified_cert = cert;
1602 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311603
1604 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091605 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321606 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271607 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311608 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1609}
1610
rchbe69cb902016-02-11 01:10:481611TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Victor Vasilieva1e66d72019-12-05 17:55:381612 context_.params()->allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481613 HostPortPair origin("www.example.org", 443);
1614 HostPortPair alternative("mail.example.org", 443);
1615
1616 base::FilePath certs_dir = GetTestCertsDirectory();
1617 scoped_refptr<X509Certificate> cert(
1618 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1619 ASSERT_TRUE(cert.get());
1620 // TODO(rch): the connection should be "to" the origin, so if the cert is
1621 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241622 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1623 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481624 ProofVerifyDetailsChromium verify_details;
1625 verify_details.cert_verify_result.verified_cert = cert;
1626 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1627
Zhongyi Shi1c022d22020-03-20 19:00:161628 client_maker_->set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591629 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021630
Renjie Tangaadb84b2019-08-31 01:00:231631 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251632 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231633 mock_quic_data.AddWrite(SYNCHRONOUS,
1634 ConstructInitialSettingsPacket(packet_num++));
1635 }
rch5cb522462017-04-25 20:18:361636 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231637 SYNCHRONOUS,
1638 ConstructClientRequestHeadersPacket(
1639 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1640 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431641 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331642 ASYNC, ConstructServerResponseHeadersPacket(
1643 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1644 GetResponseHeaders("200 OK")));
1645 mock_quic_data.AddRead(
1646 ASYNC, ConstructServerDataPacket(
1647 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521648 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231649 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341650 ConstructClientAckPacket(packet_num++, 2, 1));
rchbe69cb902016-02-11 01:10:481651 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1652 mock_quic_data.AddRead(ASYNC, 0);
1653 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1654
1655 request_.url = GURL("https://" + origin.host());
1656 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271657 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091658 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321659 CreateSession();
rchbe69cb902016-02-11 01:10:481660
1661 SendRequestAndExpectQuicResponse("hello!");
1662}
1663
zhongyief3f4ce52017-07-05 23:53:281664TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
David Schinazi84c58bb2020-06-04 20:14:331665 quic::ParsedQuicVersion unsupported_version =
1666 quic::ParsedQuicVersion::Unsupported();
Bence Békyb89104962020-01-24 00:05:171667 // Add support for another QUIC version besides |version_|. Also find an
zhongyief3f4ce52017-07-05 23:53:281668 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561669 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281670 if (version == version_)
1671 continue;
1672 if (supported_versions_.size() != 2) {
1673 supported_versions_.push_back(version);
1674 continue;
1675 }
1676 unsupported_version = version;
1677 break;
1678 }
Bence Békyb89104962020-01-24 00:05:171679 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:331680 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), unsupported_version);
zhongyief3f4ce52017-07-05 23:53:281681
1682 // Set up alternative service to use QUIC with a version that is not
1683 // supported.
1684 url::SchemeHostPort server(request_.url);
1685 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1686 443);
1687 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491688 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071689 server, NetworkIsolationKey(), alternative_service, expiration,
1690 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281691
1692 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491693 http_server_properties_->GetAlternativeServiceInfos(
1694 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281695 EXPECT_EQ(1u, alt_svc_info_vector.size());
1696 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1697 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1698 EXPECT_EQ(unsupported_version,
1699 alt_svc_info_vector[0].advertised_versions()[0]);
1700
1701 // First request should still be sent via TCP as the QUIC version advertised
1702 // in the stored AlternativeService is not supported by the client. However,
1703 // the response from the server will advertise new Alt-Svc with supported
1704 // versions.
David Schinazifbd4c432020-04-07 19:23:551705 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyief3f4ce52017-07-05 23:53:281706 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:171707 MockRead("HTTP/1.1 200 OK\r\n"),
1708 MockRead(altsvc_header.c_str()),
1709 MockRead("\r\n"),
zhongyief3f4ce52017-07-05 23:53:281710 MockRead("hello world"),
1711 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1712 MockRead(ASYNC, OK)};
1713
Ryan Sleevib8d7ea02018-05-07 20:01:011714 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281715 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081716 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281717 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1718
1719 // Second request should be sent via QUIC as a new list of verions supported
1720 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591721 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231722 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251723 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231724 mock_quic_data.AddWrite(SYNCHRONOUS,
1725 ConstructInitialSettingsPacket(packet_num++));
1726 }
zhongyief3f4ce52017-07-05 23:53:281727 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231728 SYNCHRONOUS,
1729 ConstructClientRequestHeadersPacket(
1730 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1731 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431732 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331733 ASYNC, ConstructServerResponseHeadersPacket(
1734 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1735 GetResponseHeaders("200 OK")));
1736 mock_quic_data.AddRead(
1737 ASYNC, ConstructServerDataPacket(
1738 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521739 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231740 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341741 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyief3f4ce52017-07-05 23:53:281742 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1743 mock_quic_data.AddRead(ASYNC, 0); // EOF
1744
1745 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1746
1747 AddHangingNonAlternateProtocolSocketData();
1748
1749 CreateSession(supported_versions_);
1750
1751 SendRequestAndExpectHttpResponse("hello world");
1752 SendRequestAndExpectQuicResponse("hello!");
1753
1754 // Check alternative service list is updated with new versions.
1755 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491756 session_->http_server_properties()->GetAlternativeServiceInfos(
1757 server, NetworkIsolationKey());
David Schinazi84c58bb2020-06-04 20:14:331758 // Versions that support the legacy Google-specific Alt-Svc format are sent in
1759 // a single Alt-Svc entry, therefore they are accumulated in a single
1760 // AlternativeServiceInfo, whereas more recent versions all have their own
1761 // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
Bence Békyb89104962020-01-24 00:05:171762 quic::ParsedQuicVersionVector alt_svc_negotiated_versions;
1763 for (const auto& alt_svc_info : alt_svc_info_vector) {
1764 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
1765 for (const auto& version : alt_svc_info.advertised_versions()) {
David Schinazifbd4c432020-04-07 19:23:551766 if (std::find(alt_svc_negotiated_versions.begin(),
1767 alt_svc_negotiated_versions.end(),
1768 version) == alt_svc_negotiated_versions.end()) {
1769 alt_svc_negotiated_versions.push_back(version);
1770 }
Bence Békyb89104962020-01-24 00:05:171771 }
1772 }
1773
1774 ASSERT_EQ(supported_versions_.size(), alt_svc_negotiated_versions.size());
1775 auto version_compare = [](const quic::ParsedQuicVersion& a,
1776 const quic::ParsedQuicVersion& b) {
1777 return std::tie(a.transport_version, a.handshake_protocol) <
1778 std::tie(b.transport_version, b.handshake_protocol);
1779 };
1780 std::sort(supported_versions_.begin(), supported_versions_.end(),
1781 version_compare);
1782 std::sort(alt_svc_negotiated_versions.begin(),
1783 alt_svc_negotiated_versions.end(), version_compare);
1784 EXPECT_TRUE(std::equal(supported_versions_.begin(), supported_versions_.end(),
1785 alt_svc_negotiated_versions.begin()));
zhongyief3f4ce52017-07-05 23:53:281786}
1787
bncaccd4962017-04-06 21:00:261788// Regression test for https://crbug.com/546991.
1789// The server might not be able to serve a request on an alternative connection,
1790// and might send a 421 Misdirected Request response status to indicate this.
1791// HttpNetworkTransaction should reset the request and retry without using
1792// alternative services.
1793TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1794 // Set up alternative service to use QUIC.
1795 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1796 // that overrides |enable_alternative_services|.
1797 url::SchemeHostPort server(request_.url);
1798 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1799 443);
1800 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491801 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071802 server, NetworkIsolationKey(), alternative_service, expiration,
1803 supported_versions_);
bncaccd4962017-04-06 21:00:261804
davidbena4449722017-05-05 23:30:531805 // First try: The alternative job uses QUIC and reports an HTTP 421
1806 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1807 // paused at Connect(), so it will never exit the socket pool. This ensures
1808 // that the alternate job always wins the race and keeps whether the
1809 // |http_data| exits the socket pool before the main job is aborted
1810 // deterministic. The first main job gets aborted without the socket pool ever
1811 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591812 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231813 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251814 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231815 mock_quic_data.AddWrite(SYNCHRONOUS,
1816 ConstructInitialSettingsPacket(packet_num++));
1817 }
rch5cb522462017-04-25 20:18:361818 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231819 SYNCHRONOUS,
1820 ConstructClientRequestHeadersPacket(
1821 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1822 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331823 mock_quic_data.AddRead(
1824 ASYNC, ConstructServerResponseHeadersPacket(
1825 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021826 GetResponseHeaders("421")));
bncaccd4962017-04-06 21:00:261827 mock_quic_data.AddRead(ASYNC, OK);
1828 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1829
davidbena4449722017-05-05 23:30:531830 // Second try: The main job uses TCP, and there is no alternate job. Once the
1831 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1832 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261833 // Note that if there was an alternative QUIC Job created for the second try,
1834 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1835 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531836 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1837 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1838 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1839 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1840 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1841 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011842 reads, writes);
bncaccd4962017-04-06 21:00:261843 socket_factory_.AddSocketDataProvider(&http_data);
1844 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1845
bncaccd4962017-04-06 21:00:261846 CreateSession();
1847 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531848
1849 // Run until |mock_quic_data| has failed and |http_data| has paused.
1850 TestCompletionCallback callback;
1851 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1852 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1853 base::RunLoop().RunUntilIdle();
1854
1855 // |mock_quic_data| must have run to completion.
1856 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1857 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1858
1859 // Now that the QUIC data has been consumed, unblock |http_data|.
1860 http_data.socket()->OnConnectComplete(MockConnect());
1861
1862 // The retry logic must hide the 421 status. The transaction succeeds on
1863 // |http_data|.
1864 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261865 CheckWasHttpResponse(&trans);
1866 CheckResponsePort(&trans, 443);
1867 CheckResponseData(&trans, "hello!");
1868}
1869
[email protected]1e960032013-12-20 19:00:201870TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Victor Vasilieva1e66d72019-12-05 17:55:381871 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571872 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301873
Ryan Hamiltonabad59e2019-06-06 04:02:591874 MockQuicData mock_quic_data1(version_);
Victor Vasiliev7da08172019-10-14 06:04:251875 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231876 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401877 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Zhongyi Shi1c022d22020-03-20 19:00:161878 client_maker_->Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591879 MockQuicData mock_quic_data2(version_);
Victor Vasiliev7da08172019-10-14 06:04:251880 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231881 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301882 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401883 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431884 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401885
1886 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1887 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301888
1889 CreateSession();
1890
tbansal0f56a39a2016-04-07 22:03:381891 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401892 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161893 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401894 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161895 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1897 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381898 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531899
1900 NetErrorDetails details;
1901 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521902 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401903 }
[email protected]cebe3282013-05-22 23:49:301904}
1905
tbansalc8a94ea2015-11-02 23:58:511906TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1907 // Attempt to "force" quic on 443, which will not be honored.
Victor Vasilieva1e66d72019-12-05 17:55:381908 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571909 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511910
1911 MockRead http_reads[] = {
1912 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1913 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1914 MockRead(ASYNC, OK)};
1915
Ryan Sleevib8d7ea02018-05-07 20:01:011916 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511917 socket_factory_.AddSocketDataProvider(&data);
1918 SSLSocketDataProvider ssl(ASYNC, OK);
1919 socket_factory_.AddSSLSocketDataProvider(&ssl);
1920
1921 CreateSession();
1922
1923 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381924 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511925}
1926
bncc958faa2015-07-31 18:14:521927TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521928 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561929 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1930 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521931 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1932 MockRead(ASYNC, OK)};
1933
Ryan Sleevib8d7ea02018-05-07 20:01:011934 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521935 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081936 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561937 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521938
Ryan Hamiltonabad59e2019-06-06 04:02:591939 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231940 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251941 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231942 mock_quic_data.AddWrite(SYNCHRONOUS,
1943 ConstructInitialSettingsPacket(packet_num++));
1944 }
rch5cb522462017-04-25 20:18:361945 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231946 SYNCHRONOUS,
1947 ConstructClientRequestHeadersPacket(
1948 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1949 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431950 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331951 ASYNC, ConstructServerResponseHeadersPacket(
1952 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1953 GetResponseHeaders("200 OK")));
1954 mock_quic_data.AddRead(
1955 ASYNC, ConstructServerDataPacket(
1956 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:521957 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:231958 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:341959 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:521960 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591961 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521962
1963 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1964
rtennetib8e80fb2016-05-16 00:12:091965 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321966 CreateSession();
bncc958faa2015-07-31 18:14:521967
1968 SendRequestAndExpectHttpResponse("hello world");
1969 SendRequestAndExpectQuicResponse("hello!");
1970}
1971
Ryan Hamilton64f21d52019-08-31 07:10:511972TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
1973 std::string alt_svc_header =
1974 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
1975 MockRead http_reads[] = {
1976 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
1977 MockRead("hello world"),
1978 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1979 MockRead(ASYNC, OK)};
1980
1981 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
1982 socket_factory_.AddSocketDataProvider(&http_data);
1983 AddCertificate(&ssl_data_);
1984 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1985
1986 MockQuicData mock_quic_data(version_);
1987 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251988 if (VersionUsesHttp3(version_.transport_version)) {
Ryan Hamilton64f21d52019-08-31 07:10:511989 mock_quic_data.AddWrite(SYNCHRONOUS,
1990 ConstructInitialSettingsPacket(packet_num++));
1991 }
1992 mock_quic_data.AddWrite(
1993 SYNCHRONOUS,
1994 ConstructClientRequestHeadersPacket(
1995 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1996 true, GetRequestHeaders("GET", "https", "/")));
1997 mock_quic_data.AddRead(
1998 ASYNC, ConstructServerResponseHeadersPacket(
1999 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2000 GetResponseHeaders("200 OK")));
Ryan Hamilton64f21d52019-08-31 07:10:512001 mock_quic_data.AddRead(
2002 ASYNC, ConstructServerDataPacket(
2003 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522004 ConstructDataFrame("hello!")));
Ryan Hamilton64f21d52019-08-31 07:10:512005 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342006 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton64f21d52019-08-31 07:10:512007 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2008 mock_quic_data.AddRead(ASYNC, 0); // EOF
2009
2010 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2011
2012 AddHangingNonAlternateProtocolSocketData();
2013 CreateSession();
2014
2015 SendRequestAndExpectHttpResponse("hello world");
2016 SendRequestAndExpectQuicResponse("hello!");
2017}
2018
Matt Menke3233d8f22019-08-20 21:01:492019// Much like above, but makes sure NetworkIsolationKey is respected.
2020TEST_P(QuicNetworkTransactionTest,
2021 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
2022 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:052023 feature_list.InitWithFeatures(
2024 // enabled_features
2025 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2026 features::kPartitionConnectionsByNetworkIsolationKey},
2027 // disabled_features
2028 {});
Matt Menke3233d8f22019-08-20 21:01:492029 // Since HttpServerProperties caches the feature value, have to create a new
2030 // one.
2031 http_server_properties_ = std::make_unique<HttpServerProperties>();
2032
Matt Menke4807a9a2020-11-21 00:14:412033 const SchemefulSite kSite1(GURL("https://foo.test/"));
2034 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
2035 const SchemefulSite kSite2(GURL("https://bar.test/"));
2036 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menke3233d8f22019-08-20 21:01:492037
2038 MockRead http_reads[] = {
2039 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
2040 MockRead("hello world"),
2041 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2042 MockRead(ASYNC, OK)};
2043
2044 AddCertificate(&ssl_data_);
2045
2046 // Request with empty NetworkIsolationKey.
2047 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2048 socket_factory_.AddSocketDataProvider(&http_data1);
2049 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2050
2051 // First request with kNetworkIsolationKey1.
2052 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2053 socket_factory_.AddSocketDataProvider(&http_data2);
2054 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2055
2056 // Request with kNetworkIsolationKey2.
2057 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2058 socket_factory_.AddSocketDataProvider(&http_data3);
2059 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2060
2061 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2062 // alternative service infrmation has been received in this context before.
2063 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232064 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252065 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232066 mock_quic_data.AddWrite(SYNCHRONOUS,
2067 ConstructInitialSettingsPacket(packet_num++));
2068 }
Matt Menke3233d8f22019-08-20 21:01:492069 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232070 SYNCHRONOUS,
2071 ConstructClientRequestHeadersPacket(
2072 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2073 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492074 mock_quic_data.AddRead(
2075 ASYNC, ConstructServerResponseHeadersPacket(
2076 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2077 GetResponseHeaders("200 OK")));
Matt Menke3233d8f22019-08-20 21:01:492078 mock_quic_data.AddRead(
2079 ASYNC, ConstructServerDataPacket(
2080 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522081 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232082 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342083 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menke3233d8f22019-08-20 21:01:492084 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2085 mock_quic_data.AddRead(ASYNC, 0); // EOF
2086
2087 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2088
2089 AddHangingNonAlternateProtocolSocketData();
2090 CreateSession();
2091
2092 // This is first so that the test fails if alternative service info is
2093 // written with the right NetworkIsolationKey, but always queried with an
2094 // empty one.
2095 request_.network_isolation_key = NetworkIsolationKey();
2096 SendRequestAndExpectHttpResponse("hello world");
2097 request_.network_isolation_key = kNetworkIsolationKey1;
2098 SendRequestAndExpectHttpResponse("hello world");
2099 request_.network_isolation_key = kNetworkIsolationKey2;
2100 SendRequestAndExpectHttpResponse("hello world");
2101
2102 // Only use QUIC when using a NetworkIsolationKey which has been used when
2103 // alternative service information was received.
2104 request_.network_isolation_key = kNetworkIsolationKey1;
2105 SendRequestAndExpectQuicResponse("hello!");
2106}
2107
zhongyia00ca012017-07-06 23:36:392108TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
2109 // Both server advertises and client supports two QUIC versions.
2110 // Only |version_| is advertised and supported.
2111 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2112 // PacketMakers are using |version_|.
2113
2114 // Add support for another QUIC version besides |version_| on the client side.
2115 // Also find a different version advertised by the server.
David Schinazi84c58bb2020-06-04 20:14:332116 quic::ParsedQuicVersion advertised_version_2 =
2117 quic::ParsedQuicVersion::Unsupported();
Nick Harper23290b82019-05-02 00:02:562118 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392119 if (version == version_)
2120 continue;
2121 if (supported_versions_.size() != 2) {
2122 supported_versions_.push_back(version);
2123 continue;
2124 }
2125 advertised_version_2 = version;
2126 break;
2127 }
Bence Békyb89104962020-01-24 00:05:172128 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:332129 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), advertised_version_2);
zhongyia00ca012017-07-06 23:36:392130
Bence Békyb89104962020-01-24 00:05:172131 std::string QuicAltSvcWithVersionHeader =
2132 base::StringPrintf("Alt-Svc: %s=\":443\", %s=\":443\"\r\n\r\n",
2133 quic::AlpnForVersion(advertised_version_2).c_str(),
2134 quic::AlpnForVersion(version_).c_str());
zhongyia00ca012017-07-06 23:36:392135
2136 MockRead http_reads[] = {
2137 MockRead("HTTP/1.1 200 OK\r\n"),
2138 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2139 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2140 MockRead(ASYNC, OK)};
2141
Ryan Sleevib8d7ea02018-05-07 20:01:012142 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392143 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082144 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392145 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2146
Ryan Hamiltonabad59e2019-06-06 04:02:592147 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232148 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252149 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232150 mock_quic_data.AddWrite(SYNCHRONOUS,
2151 ConstructInitialSettingsPacket(packet_num++));
2152 }
zhongyia00ca012017-07-06 23:36:392153 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232154 SYNCHRONOUS,
2155 ConstructClientRequestHeadersPacket(
2156 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2157 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432158 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332159 ASYNC, ConstructServerResponseHeadersPacket(
2160 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2161 GetResponseHeaders("200 OK")));
2162 mock_quic_data.AddRead(
2163 ASYNC, ConstructServerDataPacket(
2164 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522165 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232166 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342167 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392168 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2169 mock_quic_data.AddRead(ASYNC, 0); // EOF
2170
2171 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2172
2173 AddHangingNonAlternateProtocolSocketData();
2174 CreateSession(supported_versions_);
2175
2176 SendRequestAndExpectHttpResponse("hello world");
2177 SendRequestAndExpectQuicResponse("hello!");
2178}
2179
Zhongyi Shi1c022d22020-03-20 19:00:162180TEST_P(QuicNetworkTransactionTest,
2181 PickQuicVersionWhenMultipleVersionsAreSupported) {
2182 // Client and server both support more than one QUIC_VERSION.
2183 // Client prefers |version_|, and then common_version_2.
2184 // Server prefers common_version_2, and then |version_|.
David Schinazifbd4c432020-04-07 19:23:552185 // We should honor the server's preference.
Zhongyi Shi1c022d22020-03-20 19:00:162186 // The picked version is verified via checking the version used by the
2187 // TestPacketMakers and the response.
Bence Békyb89104962020-01-24 00:05:172188
Zhongyi Shi1c022d22020-03-20 19:00:162189 // Find an alternative commonly supported version other than |version_|.
David Schinazi84c58bb2020-06-04 20:14:332190 quic::ParsedQuicVersion common_version_2 =
2191 quic::ParsedQuicVersion::Unsupported();
2192 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
2193 if (version != version_) {
Zhongyi Shi1c022d22020-03-20 19:00:162194 common_version_2 = version;
2195 break;
2196 }
zhongyia00ca012017-07-06 23:36:392197 }
David Schinazi84c58bb2020-06-04 20:14:332198 ASSERT_NE(common_version_2, quic::ParsedQuicVersion::Unsupported());
zhongyia00ca012017-07-06 23:36:392199
Zhongyi Shi1c022d22020-03-20 19:00:162200 // Setting up client's preference list: {|version_|, |common_version_2|}.
2201 supported_versions_.clear();
2202 supported_versions_.push_back(version_);
2203 supported_versions_.push_back(common_version_2);
zhongyia00ca012017-07-06 23:36:392204
Zhongyi Shi1c022d22020-03-20 19:00:162205 // Setting up server's Alt-Svc header in the following preference order:
2206 // |common_version_2|, |version_|.
2207 std::string QuicAltSvcWithVersionHeader;
David Schinazi84c58bb2020-06-04 20:14:332208 quic::ParsedQuicVersion picked_version =
2209 quic::ParsedQuicVersion::Unsupported();
2210 QuicAltSvcWithVersionHeader =
2211 "Alt-Svc: " + quic::AlpnForVersion(common_version_2) +
2212 "=\":443\"; ma=3600, " + quic::AlpnForVersion(version_) +
2213 "=\":443\"; ma=3600\r\n\r\n";
2214 picked_version = common_version_2; // Use server's preference.
zhongyia00ca012017-07-06 23:36:392215
2216 MockRead http_reads[] = {
2217 MockRead("HTTP/1.1 200 OK\r\n"),
2218 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2219 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2220 MockRead(ASYNC, OK)};
2221
Ryan Sleevib8d7ea02018-05-07 20:01:012222 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392223 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082224 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392225 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2226
Zhongyi Shi1c022d22020-03-20 19:00:162227 MockQuicData mock_quic_data(picked_version);
2228
2229 // Reset QuicTestPacket makers as the version picked may not be |version_|.
2230 client_maker_.reset(new QuicTestPacketMaker(
2231 picked_version,
2232 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2233 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
2234 client_headers_include_h2_stream_dependency_));
2235 QuicTestPacketMaker server_maker(
2236 picked_version,
2237 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2238 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
2239 false);
2240
Renjie Tangaadb84b2019-08-31 01:00:232241 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:162242 if (VersionUsesHttp3(picked_version.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232243 mock_quic_data.AddWrite(SYNCHRONOUS,
2244 ConstructInitialSettingsPacket(packet_num++));
2245 }
Zhongyi Shi1c022d22020-03-20 19:00:162246
2247 quic::QuicStreamId client_stream_0 =
2248 quic::test::GetNthClientInitiatedBidirectionalStreamId(
2249 picked_version.transport_version, 0);
2250 mock_quic_data.AddWrite(SYNCHRONOUS,
2251 ConstructClientRequestHeadersPacket(
2252 packet_num++, client_stream_0, true, true,
2253 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432254 mock_quic_data.AddRead(
Zhongyi Shi1c022d22020-03-20 19:00:162255 ASYNC, server_maker.MakeResponseHeadersPacket(
2256 1, client_stream_0, false, false,
2257 server_maker.GetResponseHeaders("200 OK"), nullptr));
Fan Yang32c5a112018-12-10 20:06:332258 mock_quic_data.AddRead(
Bence Béky319388a882020-09-23 18:42:522259 ASYNC, server_maker.MakeDataPacket(
2260 2, client_stream_0, false, true,
2261 ConstructDataFrameForVersion("hello!", picked_version)));
Renjie Tangaadb84b2019-08-31 01:00:232262 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342263 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyia00ca012017-07-06 23:36:392264 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2265 mock_quic_data.AddRead(ASYNC, 0); // EOF
2266
2267 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2268
2269 AddHangingNonAlternateProtocolSocketData();
2270 CreateSession(supported_versions_);
2271
2272 SendRequestAndExpectHttpResponse("hello world");
Zhongyi Shi1c022d22020-03-20 19:00:162273 SendRequestAndExpectQuicResponseMaybeFromProxy(
2274 "hello!", false, 443, "HTTP/1.1 200 OK", picked_version);
zhongyia00ca012017-07-06 23:36:392275}
2276
rchf47265dc2016-03-21 21:33:122277TEST_P(QuicNetworkTransactionTest,
2278 UseAlternativeServiceWithProbabilityForQuic) {
2279 MockRead http_reads[] = {
2280 MockRead("HTTP/1.1 200 OK\r\n"),
2281 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
2282 MockRead("hello world"),
2283 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2284 MockRead(ASYNC, OK)};
2285
Ryan Sleevib8d7ea02018-05-07 20:01:012286 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:122287 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082288 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:122289 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2290
Ryan Hamiltonabad59e2019-06-06 04:02:592291 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232292 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252293 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232294 mock_quic_data.AddWrite(SYNCHRONOUS,
2295 ConstructInitialSettingsPacket(packet_num++));
2296 }
rch5cb522462017-04-25 20:18:362297 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232298 SYNCHRONOUS,
2299 ConstructClientRequestHeadersPacket(
2300 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2301 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432302 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332303 ASYNC, ConstructServerResponseHeadersPacket(
2304 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2305 GetResponseHeaders("200 OK")));
2306 mock_quic_data.AddRead(
2307 ASYNC, ConstructServerDataPacket(
2308 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522309 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232310 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342311 ConstructClientAckPacket(packet_num++, 2, 1));
rchf47265dc2016-03-21 21:33:122312 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2313 mock_quic_data.AddRead(ASYNC, 0); // EOF
2314
2315 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2316
rtennetib8e80fb2016-05-16 00:12:092317 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:122318 CreateSession();
2319
2320 SendRequestAndExpectHttpResponse("hello world");
2321 SendRequestAndExpectQuicResponse("hello!");
2322}
2323
zhongyi3d4a55e72016-04-22 20:36:462324TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2325 MockRead http_reads[] = {
2326 MockRead("HTTP/1.1 200 OK\r\n"),
2327 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2328 MockRead("hello world"),
2329 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2330 MockRead(ASYNC, OK)};
2331
Ryan Sleevib8d7ea02018-05-07 20:01:012332 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462333 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082334 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462335 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2336
2337 CreateSession();
bncb26024382016-06-29 02:39:452338 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462339 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452340 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462341 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402342 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462343 session_->http_server_properties();
2344 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2345 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2346 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462347 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492348 2u, http_server_properties
2349 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2350 .size());
bncb26024382016-06-29 02:39:452351 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492352 http_server_properties
2353 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2354 .empty());
zhongyi3d4a55e72016-04-22 20:36:462355}
2356
2357TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2358 MockRead http_reads[] = {
2359 MockRead("HTTP/1.1 200 OK\r\n"),
2360 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2361 MockRead("hello world"),
2362 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2363 MockRead(ASYNC, OK)};
2364
Ryan Sleevib8d7ea02018-05-07 20:01:012365 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082366 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462367
2368 socket_factory_.AddSocketDataProvider(&http_data);
2369 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2370 socket_factory_.AddSocketDataProvider(&http_data);
2371 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2372
2373 CreateSession();
2374
2375 // Send https request and set alternative services if response header
2376 // advertises alternative service for mail.example.org.
2377 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402378 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462379 session_->http_server_properties();
2380
2381 const url::SchemeHostPort https_server(request_.url);
2382 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342383 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492384 2u, http_server_properties
2385 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2386 .size());
zhongyi3d4a55e72016-04-22 20:36:462387
2388 // Send http request to the same origin but with diffrent scheme, should not
2389 // use QUIC.
2390 request_.url = GURL("http://mail.example.org:443");
2391 SendRequestAndExpectHttpResponse("hello world");
2392}
2393
zhongyie537a002017-06-27 16:48:212394TEST_P(QuicNetworkTransactionTest,
2395 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442396 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562397 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Bence Békyb89104962020-01-24 00:05:172398 if (version != version_) {
2399 supported_versions_.push_back(version);
2400 break;
2401 }
zhongyi86838d52017-06-30 01:19:442402 }
2403
David Schinazifbd4c432020-04-07 19:23:552404 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyie537a002017-06-27 16:48:212405 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:172406 MockRead("HTTP/1.1 200 OK\r\n"),
2407 MockRead(altsvc_header.c_str()),
2408 MockRead("\r\n"),
zhongyie537a002017-06-27 16:48:212409 MockRead("hello world"),
2410 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2411 MockRead(ASYNC, OK)};
2412
Ryan Sleevib8d7ea02018-05-07 20:01:012413 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212414 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082415 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212416 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2417
Ryan Hamiltonabad59e2019-06-06 04:02:592418 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232419 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252420 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232421 mock_quic_data.AddWrite(SYNCHRONOUS,
2422 ConstructInitialSettingsPacket(packet_num++));
2423 }
zhongyie537a002017-06-27 16:48:212424 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232425 SYNCHRONOUS,
2426 ConstructClientRequestHeadersPacket(
2427 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2428 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432429 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332430 ASYNC, ConstructServerResponseHeadersPacket(
2431 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2432 GetResponseHeaders("200 OK")));
2433 mock_quic_data.AddRead(
2434 ASYNC, ConstructServerDataPacket(
2435 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522436 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232437 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342438 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyie537a002017-06-27 16:48:212439 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2440 mock_quic_data.AddRead(ASYNC, 0); // EOF
2441
2442 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2443
2444 AddHangingNonAlternateProtocolSocketData();
2445
zhongyi86838d52017-06-30 01:19:442446 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212447
2448 SendRequestAndExpectHttpResponse("hello world");
2449 SendRequestAndExpectQuicResponse("hello!");
2450
Bence Békyb89104962020-01-24 00:05:172451 // Alt-Svc header contains all possible versions, so alternative services
2452 // should contain all of |supported_versions_|.
zhongyie537a002017-06-27 16:48:212453 const url::SchemeHostPort https_server(request_.url);
2454 const AlternativeServiceInfoVector alt_svc_info_vector =
2455 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492456 https_server, NetworkIsolationKey());
David Schinazi84c58bb2020-06-04 20:14:332457 // Versions that support the legacy Google-specific Alt-Svc format are sent in
2458 // a single Alt-Svc entry, therefore they are accumulated in a single
2459 // AlternativeServiceInfo, whereas more recent versions all have their own
2460 // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
Bence Békyb89104962020-01-24 00:05:172461 quic::ParsedQuicVersionVector alt_svc_negotiated_versions;
2462 for (const auto& alt_svc_info : alt_svc_info_vector) {
2463 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
2464 for (const auto& version : alt_svc_info.advertised_versions()) {
David Schinazifbd4c432020-04-07 19:23:552465 if (std::find(alt_svc_negotiated_versions.begin(),
2466 alt_svc_negotiated_versions.end(),
2467 version) == alt_svc_negotiated_versions.end()) {
2468 alt_svc_negotiated_versions.push_back(version);
2469 }
Bence Békyb89104962020-01-24 00:05:172470 }
2471 }
2472
2473 ASSERT_EQ(supported_versions_.size(), alt_svc_negotiated_versions.size());
2474 auto version_compare = [](const quic::ParsedQuicVersion& a,
2475 const quic::ParsedQuicVersion& b) {
2476 return std::tie(a.transport_version, a.handshake_protocol) <
2477 std::tie(b.transport_version, b.handshake_protocol);
2478 };
2479 std::sort(supported_versions_.begin(), supported_versions_.end(),
2480 version_compare);
2481 std::sort(alt_svc_negotiated_versions.begin(),
2482 alt_svc_negotiated_versions.end(), version_compare);
2483 EXPECT_TRUE(std::equal(supported_versions_.begin(), supported_versions_.end(),
2484 alt_svc_negotiated_versions.begin()));
zhongyie537a002017-06-27 16:48:212485}
2486
danzh3134c2562016-08-12 14:07:522487TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562488 std::string altsvc_header = base::StringPrintf(
Bence Békyb89104962020-01-24 00:05:172489 "Alt-Svc: %s=\":443\"\r\n\r\n", quic::AlpnForVersion(version_).c_str());
bnc8be55ebb2015-10-30 14:12:072490 MockRead http_reads[] = {
2491 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2492 MockRead("hello world"),
2493 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2494 MockRead(ASYNC, OK)};
2495
Ryan Sleevib8d7ea02018-05-07 20:01:012496 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072497 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082498 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072499 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2500
Ryan Hamiltonabad59e2019-06-06 04:02:592501 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232502 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252503 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232504 mock_quic_data.AddWrite(SYNCHRONOUS,
2505 ConstructInitialSettingsPacket(packet_num++));
2506 }
rch5cb522462017-04-25 20:18:362507 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232508 SYNCHRONOUS,
2509 ConstructClientRequestHeadersPacket(
2510 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2511 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432512 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332513 ASYNC, ConstructServerResponseHeadersPacket(
2514 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2515 GetResponseHeaders("200 OK")));
2516 mock_quic_data.AddRead(
2517 ASYNC, ConstructServerDataPacket(
2518 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:522519 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232520 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342521 ConstructClientAckPacket(packet_num++, 2, 1));
bnc8be55ebb2015-10-30 14:12:072522 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592523 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072524
2525 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2526
rtennetib8e80fb2016-05-16 00:12:092527 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322528 CreateSession();
bnc8be55ebb2015-10-30 14:12:072529
2530 SendRequestAndExpectHttpResponse("hello world");
2531 SendRequestAndExpectQuicResponse("hello!");
2532}
2533
zhongyi6b5a3892016-03-12 04:46:202534TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harperc6cb7a612020-02-24 20:03:322535 if (version_.HasIetfQuicFrames()) {
Renjie Tangba21e032019-09-27 21:52:282536 // GoAway is not available under version 99
Frank Kastenholz6e4c5382018-06-21 23:00:092537 return;
2538 }
Ryan Hamiltonabad59e2019-06-06 04:02:592539 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232540 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252541 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232542 mock_quic_data.AddWrite(SYNCHRONOUS,
2543 ConstructInitialSettingsPacket(packet_num++));
2544 }
rch5cb522462017-04-25 20:18:362545 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232546 SYNCHRONOUS,
2547 ConstructClientRequestHeadersPacket(
2548 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2549 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332550 mock_quic_data.AddRead(
2551 ASYNC, ConstructServerResponseHeadersPacket(
2552 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2553 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202554 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522555 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432556 mock_quic_data.AddRead(SYNCHRONOUS,
2557 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522558 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432559 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232560 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:342561 ConstructClientAckPacket(packet_num++, 2, 1));
Fan Yang32c5a112018-12-10 20:06:332562 mock_quic_data.AddRead(
2563 SYNCHRONOUS, ConstructServerDataPacket(
2564 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:522565 true, ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:232566 mock_quic_data.AddWrite(
2567 SYNCHRONOUS,
2568 ConstructClientAckAndRstPacket(
2569 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:342570 quic::QUIC_STREAM_CANCELLED, 3, 3));
zhongyi6b5a3892016-03-12 04:46:202571 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2572 mock_quic_data.AddRead(ASYNC, 0); // EOF
2573
2574 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2575
2576 // The non-alternate protocol job needs to hang in order to guarantee that
2577 // the alternate-protocol job will "win".
2578 AddHangingNonAlternateProtocolSocketData();
2579
2580 // In order for a new QUIC session to be established via alternate-protocol
2581 // without racing an HTTP connection, we need the host resolution to happen
2582 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2583 // connection to the the server, in this test we require confirmation
2584 // before encrypting so the HTTP job will still start.
2585 host_resolver_.set_synchronous_mode(true);
2586 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2587 "");
zhongyi6b5a3892016-03-12 04:46:202588
2589 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432590 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2591 false);
Ryan Hamilton9835e662018-08-02 05:36:272592 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202593
bnc691fda62016-08-12 00:43:162594 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202595 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362596 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012597 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202598
Fan Yang3673cc72020-02-07 14:49:282599 crypto_client_stream_factory_.last_stream()
2600 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:012601 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202602
2603 // Check whether this transaction is correctly marked as received a go-away
2604 // because of migrating port.
2605 NetErrorDetails details;
2606 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162607 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202608 EXPECT_TRUE(details.quic_port_migration_detected);
2609}
2610
Zhongyi Shia6b68d112018-09-24 07:49:032611// This test verifies that a new QUIC connection will be attempted on the
2612// alternate network if the original QUIC connection fails with idle timeout
2613// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2614// alternate network as well, QUIC is marked as broken and the brokenness will
2615// not expire when default network changes.
Renjie Tangb6fc5e02020-06-30 00:48:342616// TODO(fayang): Add time driven idle network detection test.
2617TEST_P(QuicNetworkTransactionTest,
2618 DISABLED_QuicFailsOnBothNetworksWhileTCPSucceeds) {
2619 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432620 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2621 return;
2622 }
Zhongyi Shia6b68d112018-09-24 07:49:032623 SetUpTestForRetryConnectionOnAlternateNetwork();
2624
Zhongyi Shi1c022d22020-03-20 19:00:162625 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032626
2627 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592628 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032629 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2630 int packet_num = 1;
2631 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162632 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:592633 // Retransmit the handshake messages.
Zhongyi Shia6b68d112018-09-24 07:49:032634 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162635 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032636 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162637 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032638 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162639 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032640 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162641 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032642 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2643 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162644 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:032645 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522646 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:032647 quic_data.AddSocketDataToFactory(&socket_factory_);
2648
2649 // Add successful TCP data so that TCP job will succeed.
2650 MockWrite http_writes[] = {
2651 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2652 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2653 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2654
2655 MockRead http_reads[] = {
2656 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2657 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2658 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2659 SequencedSocketData http_data(http_reads, http_writes);
2660 socket_factory_.AddSocketDataProvider(&http_data);
2661 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2662
2663 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592664 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032665 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2666 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2667 quic_data2.AddSocketDataToFactory(&socket_factory_);
2668
2669 // Resolve the host resolution synchronously.
2670 host_resolver_.set_synchronous_mode(true);
2671 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2672 "");
Zhongyi Shia6b68d112018-09-24 07:49:032673
2674 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432675 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2676 false);
Zhongyi Shia6b68d112018-09-24 07:49:032677 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032678 QuicStreamFactoryPeer::SetAlarmFactory(
2679 session_->quic_stream_factory(),
2680 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222681 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032682 // Add alternate protocol mapping to race QUIC and TCP.
2683 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2684 // peer.
2685 AddQuicAlternateProtocolMapping(
2686 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2687
2688 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2689 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362690 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032691 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2692
2693 // Pump the message loop to get the request started.
2694 // Request will be served with TCP job.
2695 base::RunLoop().RunUntilIdle();
2696 EXPECT_THAT(callback.WaitForResult(), IsOk());
2697 CheckResponseData(&trans, "TCP succeeds");
2698
Zhongyi Shia6b68d112018-09-24 07:49:032699 // Fast forward to idle timeout the original connection. A new connection will
2700 // be kicked off on the alternate network.
2701 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2702 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2703 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2704
2705 // Run the message loop to execute posted tasks, which will report job status.
2706 base::RunLoop().RunUntilIdle();
2707
2708 // Verify that QUIC is marked as broken.
2709 ExpectBrokenAlternateProtocolMapping();
2710
2711 // Deliver a message to notify the new network becomes default, the brokenness
2712 // will not expire as QUIC is broken on both networks.
2713 scoped_mock_change_notifier_->mock_network_change_notifier()
2714 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2715 ExpectBrokenAlternateProtocolMapping();
2716
2717 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2718 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2719}
2720
2721// This test verifies that a new QUIC connection will be attempted on the
2722// alternate network if the original QUIC connection fails with idle timeout
2723// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2724// alternate network, QUIC is marked as broken. The brokenness will expire when
2725// the default network changes.
Renjie Tangb6fc5e02020-06-30 00:48:342726// TODO(fayang): Add time driven idle network detection test.
2727TEST_P(QuicNetworkTransactionTest,
2728 DISABLED_RetryOnAlternateNetworkWhileTCPSucceeds) {
2729 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432730 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2731 return;
2732 }
2733
Zhongyi Shia6b68d112018-09-24 07:49:032734 SetUpTestForRetryConnectionOnAlternateNetwork();
2735
Zhongyi Shi1c022d22020-03-20 19:00:162736 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032737
2738 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592739 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032740 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2741 int packet_num = 1;
2742 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162743 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:592744 // Retransmit the handshake messages.
Zhongyi Shia6b68d112018-09-24 07:49:032745 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162746 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032747 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162748 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032749 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162750 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032751 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162752 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032753 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2754 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162755 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:032756 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522757 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:032758 quic_data.AddSocketDataToFactory(&socket_factory_);
2759
2760 // Add successful TCP data so that TCP job will succeed.
2761 MockWrite http_writes[] = {
2762 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2763 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2764 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2765
2766 MockRead http_reads[] = {
2767 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2768 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2769 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2770 SequencedSocketData http_data(http_reads, http_writes);
2771 socket_factory_.AddSocketDataProvider(&http_data);
2772 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2773
2774 // Quic connection will be retried on the alternate network after the initial
2775 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592776 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032777 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2778 quic_data2.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162779 client_maker_->MakeDummyCHLOPacket(1)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:032780
Zhongyi Shi1c022d22020-03-20 19:00:162781 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252782 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232783 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032784 quic_data2.AddSocketDataToFactory(&socket_factory_);
2785
2786 // Resolve the host resolution synchronously.
2787 host_resolver_.set_synchronous_mode(true);
2788 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2789 "");
Zhongyi Shia6b68d112018-09-24 07:49:032790
2791 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432792 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2793 false);
Zhongyi Shia6b68d112018-09-24 07:49:032794 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032795 QuicStreamFactoryPeer::SetAlarmFactory(
2796 session_->quic_stream_factory(),
2797 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222798 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032799 // Add alternate protocol mapping to race QUIC and TCP.
2800 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2801 // peer.
2802 AddQuicAlternateProtocolMapping(
2803 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2804
2805 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2806 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362807 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032808 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2809
2810 // Pump the message loop to get the request started.
2811 // Request will be served with TCP job.
2812 base::RunLoop().RunUntilIdle();
2813 EXPECT_THAT(callback.WaitForResult(), IsOk());
2814 CheckResponseData(&trans, "TCP succeeds");
2815
Zhongyi Shia6b68d112018-09-24 07:49:032816 // Fast forward to idle timeout the original connection. A new connection will
2817 // be kicked off on the alternate network.
2818 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2819 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2820 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2821
2822 // The second connection hasn't finish handshake, verify that QUIC is not
2823 // marked as broken.
2824 ExpectQuicAlternateProtocolMapping();
2825 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:282826 crypto_client_stream_factory_.last_stream()
2827 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia6b68d112018-09-24 07:49:032828 // Run message loop to execute posted tasks, which will notify JoController
2829 // about the orphaned job status.
2830 base::RunLoop().RunUntilIdle();
2831
2832 // Verify that QUIC is marked as broken.
2833 ExpectBrokenAlternateProtocolMapping();
2834
2835 // Deliver a message to notify the new network becomes default, the previous
2836 // brokenness will be clear as the brokenness is bond with old default
2837 // network.
2838 scoped_mock_change_notifier_->mock_network_change_notifier()
2839 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2840 ExpectQuicAlternateProtocolMapping();
2841
2842 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2843 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2844}
2845
Matt Menkeb32ba5122019-09-10 19:17:052846// Much like above test, but verifies NetworkIsolationKeys are respected.
Renjie Tangb6fc5e02020-06-30 00:48:342847// TODO(fayang): Add time driven idle network detection test.
2848TEST_P(
2849 QuicNetworkTransactionTest,
2850 DISABLED_RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
2851 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432852 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2853 return;
2854 }
2855
Matt Menke4807a9a2020-11-21 00:14:412856 const SchemefulSite kSite1(GURL("https://foo.test/"));
2857 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
2858 const SchemefulSite kSite2(GURL("https://bar.test/"));
2859 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:052860
2861 base::test::ScopedFeatureList feature_list;
2862 feature_list.InitWithFeatures(
2863 // enabled_features
2864 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2865 // Need to partition connections by NetworkIsolationKey for
2866 // QuicSessionAliasKey to include NetworkIsolationKeys.
2867 features::kPartitionConnectionsByNetworkIsolationKey},
2868 // disabled_features
2869 {});
2870 // Since HttpServerProperties caches the feature value, have to create a new
2871 // one.
2872 http_server_properties_ = std::make_unique<HttpServerProperties>();
2873
2874 SetUpTestForRetryConnectionOnAlternateNetwork();
2875
Zhongyi Shi1c022d22020-03-20 19:00:162876 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Matt Menkeb32ba5122019-09-10 19:17:052877
2878 // The request will initially go out over QUIC.
2879 MockQuicData quic_data(version_);
2880 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2881 int packet_num = 1;
2882 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162883 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:592884 // Retransmit the handshake messages.
Matt Menkeb32ba5122019-09-10 19:17:052885 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162886 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052887 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162888 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052889 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162890 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052891 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162892 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052893 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2894 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162895 client_maker_->MakeConnectionClosePacket(
Matt Menkeb32ba5122019-09-10 19:17:052896 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522897 "No recent network activity after 4s. Timeout:4s"));
Matt Menkeb32ba5122019-09-10 19:17:052898 quic_data.AddSocketDataToFactory(&socket_factory_);
2899
2900 // Add successful TCP data so that TCP job will succeed.
2901 MockWrite http_writes[] = {
2902 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2903 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2904 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2905
2906 MockRead http_reads[] = {
2907 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2908 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2909 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2910 SequencedSocketData http_data(http_reads, http_writes);
2911 socket_factory_.AddSocketDataProvider(&http_data);
2912 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2913
2914 // Quic connection will be retried on the alternate network after the initial
2915 // one fails on the default network.
2916 MockQuicData quic_data2(version_);
2917 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2918 quic_data2.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162919 client_maker_->MakeDummyCHLOPacket(1)); // CHLO
Matt Menkeb32ba5122019-09-10 19:17:052920
Zhongyi Shi1c022d22020-03-20 19:00:162921 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252922 if (VersionUsesHttp3(version_.transport_version))
Matt Menkeb32ba5122019-09-10 19:17:052923 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
2924 quic_data2.AddSocketDataToFactory(&socket_factory_);
2925
2926 // Resolve the host resolution synchronously.
2927 host_resolver_.set_synchronous_mode(true);
2928 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2929 "");
2930
2931 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432932 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2933 false);
Matt Menkeb32ba5122019-09-10 19:17:052934 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2935 QuicStreamFactoryPeer::SetAlarmFactory(
2936 session_->quic_stream_factory(),
2937 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222938 context_.clock()));
Matt Menkeb32ba5122019-09-10 19:17:052939 // Add alternate protocol mapping to race QUIC and TCP.
2940 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2941 // peer.
2942 AddQuicAlternateProtocolMapping(
2943 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
2944 AddQuicAlternateProtocolMapping(
2945 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
2946
2947 request_.network_isolation_key = kNetworkIsolationKey1;
2948 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2949 TestCompletionCallback callback;
2950 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2951 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2952
2953 // Pump the message loop to get the request started.
2954 // Request will be served with TCP job.
2955 base::RunLoop().RunUntilIdle();
2956 EXPECT_THAT(callback.WaitForResult(), IsOk());
2957 CheckResponseData(&trans, "TCP succeeds");
2958
2959 // Fast forward to idle timeout the original connection. A new connection will
2960 // be kicked off on the alternate network.
2961 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2962 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2963 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2964
2965 // The second connection hasn't finish handshake, verify that QUIC is not
2966 // marked as broken.
2967 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2968 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2969 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:282970 crypto_client_stream_factory_.last_stream()
2971 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:052972 // Run message loop to execute posted tasks, which will notify JoController
2973 // about the orphaned job status.
2974 base::RunLoop().RunUntilIdle();
2975
2976 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
2977 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
2978 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2979
2980 // Deliver a message to notify the new network becomes default, the previous
2981 // brokenness will be clear as the brokenness is bond with old default
2982 // network.
2983 scoped_mock_change_notifier_->mock_network_change_notifier()
2984 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2985 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2986 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2987
2988 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2989 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2990}
2991
Zhongyi Shia6b68d112018-09-24 07:49:032992// This test verifies that a new QUIC connection will be attempted on the
2993// alternate network if the original QUIC connection fails with idle timeout
2994// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2995// alternative network succeeds, QUIC is not marked as broken.
Renjie Tangb6fc5e02020-06-30 00:48:342996// TODO(fayang): Add time driven idle network detection test.
2997TEST_P(QuicNetworkTransactionTest,
2998 DISABLED_RetryOnAlternateNetworkWhileTCPHanging) {
2999 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433000 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3001 return;
3002 }
3003
Zhongyi Shia6b68d112018-09-24 07:49:033004 SetUpTestForRetryConnectionOnAlternateNetwork();
3005
Zhongyi Shi1c022d22020-03-20 19:00:163006 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:033007
3008 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593009 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:033010 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
3011 int packet_num = 1;
3012 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163013 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Bence Békyc164e0d22020-09-22 20:08:593014 // Retransmit the handshake messages.
Zhongyi Shia6b68d112018-09-24 07:49:033015 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163016 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033017 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163018 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033019 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163020 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033021 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163022 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033023 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
3024 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163025 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:033026 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523027 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:033028 quic_data.AddSocketDataToFactory(&socket_factory_);
3029
3030 // Add hanging TCP data so that TCP job will never succeeded.
3031 AddHangingNonAlternateProtocolSocketData();
3032
3033 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:593034 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:233035 packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:163036 quic_data2.AddWrite(
3037 SYNCHRONOUS,
3038 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:033039
Victor Vasiliev076657c2019-03-12 02:46:433040 const std::string body = "hello!";
Renjief49758b2019-01-11 23:32:413041
Zhongyi Shi1c022d22020-03-20 19:00:163042 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253043 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233044 quic_data2.AddWrite(SYNCHRONOUS,
3045 ConstructInitialSettingsPacket(packet_num++));
3046 }
Zhongyi Shia6b68d112018-09-24 07:49:033047 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233048 SYNCHRONOUS,
3049 ConstructClientRequestHeadersPacket(
3050 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3051 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:033052 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333053 ASYNC, ConstructServerResponseHeadersPacket(
3054 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
3055 GetResponseHeaders("200 OK")));
3056 quic_data2.AddRead(
3057 ASYNC, ConstructServerDataPacket(
3058 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523059 ConstructDataFrame(body)));
Renjie Tangaadb84b2019-08-31 01:00:233060 quic_data2.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343061 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shia6b68d112018-09-24 07:49:033062 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
3063 quic_data2.AddSocketDataToFactory(&socket_factory_);
3064
3065 // Resolve the host resolution synchronously.
3066 host_resolver_.set_synchronous_mode(true);
3067 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3068 "");
Zhongyi Shia6b68d112018-09-24 07:49:033069
3070 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433071 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3072 false);
Zhongyi Shia6b68d112018-09-24 07:49:033073 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:033074 QuicStreamFactoryPeer::SetAlarmFactory(
3075 session_->quic_stream_factory(),
3076 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223077 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:033078 // Add alternate protocol mapping to race QUIC and TCP.
3079 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3080 // peer.
3081 AddQuicAlternateProtocolMapping(
3082 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3083
3084 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3085 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363086 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:033087 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3088
3089 // Pump the message loop to get the request started.
3090 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:033091
3092 // Fast forward to idle timeout the original connection. A new connection will
3093 // be kicked off on the alternate network.
3094 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3095 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3096 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3097
3098 // Verify that QUIC is not marked as broken.
3099 ExpectQuicAlternateProtocolMapping();
3100 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:283101 crypto_client_stream_factory_.last_stream()
3102 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia6b68d112018-09-24 07:49:033103
3104 // Read the response.
3105 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:413106 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:033107 // Verify that QUIC is not marked as broken.
3108 ExpectQuicAlternateProtocolMapping();
3109
3110 // Deliver a message to notify the new network becomes default.
3111 scoped_mock_change_notifier_->mock_network_change_notifier()
3112 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3113 ExpectQuicAlternateProtocolMapping();
3114 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3115 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3116}
3117
rch9ecde09b2017-04-08 00:18:233118// Verify that if a QUIC connection times out, the QuicHttpStream will
3119// return QUIC_PROTOCOL_ERROR.
3120TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:383121 context_.params()->retry_without_alt_svc_on_quic_errors = false;
3122 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:233123
3124 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593125 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133126 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233127 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3128
Zhongyi Shi1c022d22020-03-20 19:00:163129 client_maker_->set_save_packet_frames(true);
3130 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493131 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253132 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493133 quic_data.AddWrite(SYNCHRONOUS,
3134 ConstructInitialSettingsPacket(packet_num++));
3135 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023136 quic_data.AddWrite(
3137 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163138 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493139 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3140 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453141
Zhongyi Shi1c022d22020-03-20 19:00:163142 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233143
Victor Vasiliev7da08172019-10-14 06:04:253144 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper0b214c132020-10-26 20:10:233145 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3146 // sending PTO packets.
3147 packet_num++;
3148 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163149 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493150 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233151 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3152 // sending PTO packets.
3153 packet_num++;
3154 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163155 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493156 2, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233157 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3158 // sending PTO packets.
3159 packet_num++;
3160 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163161 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493162 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233163
3164 quic_data.AddWrite(SYNCHRONOUS,
3165 client_maker_->MakeConnectionClosePacket(
3166 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3167 "No recent network activity after 4s. Timeout:4s"));
3168 } else if (version_.UsesTls()) {
3169 // Settings were sent in the request packet so there is only 1 packet to
3170 // retransmit.
3171 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3172 // sending PTO packets.
3173 packet_num++;
3174 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163175 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493176 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233177 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3178 // sending PTO packets.
3179 packet_num++;
3180 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163181 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493182 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233183 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3184 // sending PTO packets.
3185 packet_num++;
3186 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163187 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper0b214c132020-10-26 20:10:233188 1, packet_num++, true));
Ryan Hamilton3cc2c152019-07-09 19:36:013189
Findit2403b85d2019-11-19 05:06:373190 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163191 client_maker_->MakeConnectionClosePacket(
Findit2403b85d2019-11-19 05:06:373192 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523193 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493194 } else {
3195 // Settings were sent in the request packet so there is only 1 packet to
3196 // retransmit.
3197 // TLP 1
Zhongyi Shi1c022d22020-03-20 19:00:163198 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493199 1, packet_num++, true));
3200 // TLP 2
Zhongyi Shi1c022d22020-03-20 19:00:163201 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493202 1, packet_num++, true));
3203 // RTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163204 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493205 1, packet_num++, true));
3206 // RTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163207 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493208 1, packet_num++, true));
3209 // RTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163210 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493211 1, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373212
Nick Harper057264a82019-09-12 23:33:493213 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163214 client_maker_->MakeConnectionClosePacket(
Nick Harper057264a82019-09-12 23:33:493215 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523216 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493217 }
Fan Yang928f1632017-12-14 18:55:223218
rch9ecde09b2017-04-08 00:18:233219 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3220 quic_data.AddRead(ASYNC, OK);
3221 quic_data.AddSocketDataToFactory(&socket_factory_);
3222
3223 // In order for a new QUIC session to be established via alternate-protocol
3224 // without racing an HTTP connection, we need the host resolution to happen
3225 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3226 // connection to the the server, in this test we require confirmation
3227 // before encrypting so the HTTP job will still start.
3228 host_resolver_.set_synchronous_mode(true);
3229 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3230 "");
rch9ecde09b2017-04-08 00:18:233231
3232 CreateSession();
3233 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233234 QuicStreamFactoryPeer::SetAlarmFactory(
3235 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193236 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223237 context_.clock()));
rch9ecde09b2017-04-08 00:18:233238
Ryan Hamilton9835e662018-08-02 05:36:273239 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233240
3241 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3242 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363243 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233244 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3245
3246 // Pump the message loop to get the request started.
3247 base::RunLoop().RunUntilIdle();
3248 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283249 crypto_client_stream_factory_.last_stream()
3250 ->NotifySessionOneRttKeyAvailable();
rch9ecde09b2017-04-08 00:18:233251
3252 // Run the QUIC session to completion.
3253 quic_task_runner_->RunUntilIdle();
3254
3255 ExpectQuicAlternateProtocolMapping();
3256 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3257 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3258}
3259
David Schinazi7e980ab2020-05-13 20:26:553260// TODO(fayang): Add time driven TOO_MANY_RTOS test.
rch9ecde09b2017-04-08 00:18:233261
rch2f2991c2017-04-13 19:28:173262// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3263// the request fails with QUIC_PROTOCOL_ERROR.
3264TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:383265 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173266 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593267 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:163268 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493269 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253270 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493271 quic_data.AddWrite(SYNCHRONOUS,
3272 ConstructInitialSettingsPacket(packet_num++));
3273 }
3274 quic_data.AddWrite(
3275 SYNCHRONOUS,
3276 ConstructClientRequestHeadersPacket(
3277 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3278 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163279 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553280 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173281 // Peer sending data from an non-existing stream causes this end to raise
3282 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333283 quic_data.AddRead(
3284 ASYNC, ConstructServerRstPacket(
3285 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3286 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173287 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:343288 quic_data.AddWrite(
3289 SYNCHRONOUS,
3290 ConstructClientAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:343291 packet_num++, 1, 1,
Renjie Tang248e36ea2020-06-26 00:12:343292 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
3293 : quic::QUIC_INVALID_STREAM_ID,
Renjie Tanga35322a2020-12-02 20:12:273294 quic_error_details,
3295 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
3296 : quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173297 quic_data.AddSocketDataToFactory(&socket_factory_);
3298
3299 // In order for a new QUIC session to be established via alternate-protocol
3300 // without racing an HTTP connection, we need the host resolution to happen
3301 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3302 // connection to the the server, in this test we require confirmation
3303 // before encrypting so the HTTP job will still start.
3304 host_resolver_.set_synchronous_mode(true);
3305 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3306 "");
rch2f2991c2017-04-13 19:28:173307
3308 CreateSession();
3309
Ryan Hamilton9835e662018-08-02 05:36:273310 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173311
3312 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3313 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363314 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173315 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3316
3317 // Pump the message loop to get the request started.
3318 base::RunLoop().RunUntilIdle();
3319 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283320 crypto_client_stream_factory_.last_stream()
3321 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:173322
3323 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553324 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173325
3326 // Run the QUIC session to completion.
3327 base::RunLoop().RunUntilIdle();
3328 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3329 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3330
3331 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3332 ExpectQuicAlternateProtocolMapping();
3333 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3334}
3335
rch2f2991c2017-04-13 19:28:173336// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3337// connection times out, then QUIC will be marked as broken and the request
3338// retried over TCP.
3339TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Victor Vasilieva1e66d72019-12-05 17:55:383340 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173341
3342 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593343 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133344 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173345 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3346
Zhongyi Shi1c022d22020-03-20 19:00:163347 client_maker_->set_save_packet_frames(true);
3348 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493349 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253350 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493351 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163352 client_maker_->MakeInitialSettingsPacket(packet_num++));
Nick Harper057264a82019-09-12 23:33:493353 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023354 quic_data.AddWrite(
3355 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163356 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493357 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3358 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453359
Zhongyi Shi1c022d22020-03-20 19:00:163360 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253361 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper0b214c132020-10-26 20:10:233362 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3363 // sending PTO packets.
3364 packet_num++;
3365 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163366 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493367 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233368
3369 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3370 // sending PTO packets.
3371 packet_num++;
3372 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163373 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493374 2, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233375
3376 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3377 // sending PTO packets.
3378 packet_num++;
3379 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163380 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493381 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233382
3383 quic_data.AddWrite(SYNCHRONOUS,
3384 client_maker_->MakeConnectionClosePacket(
3385 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3386 "No recent network activity after 4s. Timeout:4s"));
3387 } else if (version_.UsesTls()) {
3388 // Settings were sent in the request packet so there is only 1 packet to
3389 // retransmit.
3390 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3391 // sending PTO packets.
3392 packet_num++;
3393 // PTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163394 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493395 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233396 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3397 // sending PTO packets.
3398 packet_num++;
3399 // PTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163400 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493401 1, packet_num++, true));
Nick Harper0b214c132020-10-26 20:10:233402 // QuicConnection::OnRetransmissionTimeout skips a packet number when
3403 // sending PTO packets.
3404 packet_num++;
3405 // PTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163406 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper0b214c132020-10-26 20:10:233407 1, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373408
3409 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163410 client_maker_->MakeConnectionClosePacket(
Findit2403b85d2019-11-19 05:06:373411 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523412 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493413 } else {
3414 // TLP 1
Zhongyi Shi1c022d22020-03-20 19:00:163415 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493416 1, packet_num++, true));
3417 // TLP 2
Zhongyi Shi1c022d22020-03-20 19:00:163418 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493419 1, packet_num++, true));
3420 // RTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163421 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493422 1, packet_num++, true));
3423 // RTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163424 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493425 1, packet_num++, true));
3426 // RTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163427 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493428 1, packet_num++, true));
3429
3430 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163431 client_maker_->MakeConnectionClosePacket(
Nick Harper057264a82019-09-12 23:33:493432 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523433 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493434 }
Fan Yang928f1632017-12-14 18:55:223435
rch2f2991c2017-04-13 19:28:173436 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3437 quic_data.AddRead(ASYNC, OK);
3438 quic_data.AddSocketDataToFactory(&socket_factory_);
3439
3440 // After that fails, it will be resent via TCP.
3441 MockWrite http_writes[] = {
3442 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3443 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3444 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3445
3446 MockRead http_reads[] = {
3447 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3448 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3449 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013450 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173451 socket_factory_.AddSocketDataProvider(&http_data);
3452 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3453
3454 // In order for a new QUIC session to be established via alternate-protocol
3455 // without racing an HTTP connection, we need the host resolution to happen
3456 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3457 // connection to the the server, in this test we require confirmation
3458 // before encrypting so the HTTP job will still start.
3459 host_resolver_.set_synchronous_mode(true);
3460 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3461 "");
rch2f2991c2017-04-13 19:28:173462
3463 CreateSession();
3464 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173465 QuicStreamFactoryPeer::SetAlarmFactory(
3466 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193467 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223468 context_.clock()));
rch2f2991c2017-04-13 19:28:173469
Ryan Hamilton9835e662018-08-02 05:36:273470 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173471
3472 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3473 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363474 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3476
3477 // Pump the message loop to get the request started.
3478 base::RunLoop().RunUntilIdle();
3479 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283480 crypto_client_stream_factory_.last_stream()
3481 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:173482
3483 // Run the QUIC session to completion.
3484 quic_task_runner_->RunUntilIdle();
3485 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3486
3487 ExpectQuicAlternateProtocolMapping();
3488
3489 // Let the transaction proceed which will result in QUIC being marked
3490 // as broken and the request falling back to TCP.
3491 EXPECT_THAT(callback.WaitForResult(), IsOk());
3492
3493 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3494 ASSERT_FALSE(http_data.AllReadDataConsumed());
3495
3496 // Read the response body over TCP.
3497 CheckResponseData(&trans, "hello world");
3498 ExpectBrokenAlternateProtocolMapping();
3499 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3500 ASSERT_TRUE(http_data.AllReadDataConsumed());
3501}
3502
rch2f2991c2017-04-13 19:28:173503// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3504// protocol error occurs after the handshake is confirmed, the request
3505// retried over TCP and the QUIC will be marked as broken.
3506TEST_P(QuicNetworkTransactionTest,
3507 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:383508 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173509
3510 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593511 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:163512 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493513 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253514 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493515 quic_data.AddWrite(SYNCHRONOUS,
3516 ConstructInitialSettingsPacket(packet_num++));
3517 }
3518 quic_data.AddWrite(
3519 SYNCHRONOUS,
3520 ConstructClientRequestHeadersPacket(
3521 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3522 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163523 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553524 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3525
rch2f2991c2017-04-13 19:28:173526 // Peer sending data from an non-existing stream causes this end to raise
3527 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333528 quic_data.AddRead(
3529 ASYNC, ConstructServerRstPacket(
3530 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3531 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173532 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:343533 quic_data.AddWrite(
3534 SYNCHRONOUS,
3535 ConstructClientAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:343536 packet_num++, 1, 1,
Renjie Tang248e36ea2020-06-26 00:12:343537 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
3538 : quic::QUIC_INVALID_STREAM_ID,
Renjie Tanga35322a2020-12-02 20:12:273539 quic_error_details,
3540 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
3541 : quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173542 quic_data.AddSocketDataToFactory(&socket_factory_);
3543
3544 // After that fails, it will be resent via TCP.
3545 MockWrite http_writes[] = {
3546 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3547 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3548 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3549
3550 MockRead http_reads[] = {
3551 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3552 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3553 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013554 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173555 socket_factory_.AddSocketDataProvider(&http_data);
3556 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3557
3558 // In order for a new QUIC session to be established via alternate-protocol
3559 // without racing an HTTP connection, we need the host resolution to happen
3560 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3561 // connection to the the server, in this test we require confirmation
3562 // before encrypting so the HTTP job will still start.
3563 host_resolver_.set_synchronous_mode(true);
3564 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3565 "");
rch2f2991c2017-04-13 19:28:173566
3567 CreateSession();
3568
Ryan Hamilton9835e662018-08-02 05:36:273569 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173570
3571 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3572 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363573 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173574 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3575
3576 // Pump the message loop to get the request started.
3577 base::RunLoop().RunUntilIdle();
3578 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283579 crypto_client_stream_factory_.last_stream()
3580 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553581 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173582
3583 // Run the QUIC session to completion.
3584 base::RunLoop().RunUntilIdle();
3585 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3586
3587 ExpectQuicAlternateProtocolMapping();
3588
3589 // Let the transaction proceed which will result in QUIC being marked
3590 // as broken and the request falling back to TCP.
3591 EXPECT_THAT(callback.WaitForResult(), IsOk());
3592
3593 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3594 ASSERT_FALSE(http_data.AllReadDataConsumed());
3595
3596 // Read the response body over TCP.
3597 CheckResponseData(&trans, "hello world");
3598 ExpectBrokenAlternateProtocolMapping();
3599 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3600 ASSERT_TRUE(http_data.AllReadDataConsumed());
3601}
3602
Matt Menkeb32ba5122019-09-10 19:17:053603// Much like above test, but verifies that NetworkIsolationKey is respected.
3604TEST_P(QuicNetworkTransactionTest,
3605 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
Matt Menke4807a9a2020-11-21 00:14:413606 const SchemefulSite kSite1(GURL("https://foo.test/"));
3607 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
3608 const SchemefulSite kSite2(GURL("https://bar.test/"));
3609 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:053610
3611 base::test::ScopedFeatureList feature_list;
3612 feature_list.InitWithFeatures(
3613 // enabled_features
3614 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3615 features::kPartitionConnectionsByNetworkIsolationKey},
3616 // disabled_features
3617 {});
3618 // Since HttpServerProperties caches the feature value, have to create a new
3619 // one.
3620 http_server_properties_ = std::make_unique<HttpServerProperties>();
3621
Victor Vasilieva1e66d72019-12-05 17:55:383622 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
Matt Menkeb32ba5122019-09-10 19:17:053623
3624 // The request will initially go out over QUIC.
3625 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:563626 uint64_t packet_number = 1;
Zhongyi Shi1c022d22020-03-20 19:00:163627 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:253628 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:563629 quic_data.AddWrite(SYNCHRONOUS,
3630 ConstructInitialSettingsPacket(packet_number++));
3631 }
3632 quic_data.AddWrite(
3633 SYNCHRONOUS,
3634 ConstructClientRequestHeadersPacket(
3635 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3636 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163637 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:053638 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3639
3640 // Peer sending data from an non-existing stream causes this end to raise
3641 // error and close connection.
3642 quic_data.AddRead(
3643 ASYNC, ConstructServerRstPacket(
3644 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3645 quic::QUIC_STREAM_LAST_ERROR));
3646 std::string quic_error_details = "Data for nonexistent stream";
Nick Harper1ccb0ce2020-10-07 00:28:583647 quic::QuicErrorCode quic_error_code = quic::QUIC_INVALID_STREAM_ID;
3648 if (version_.HasIetfQuicFrames()) {
3649 quic_error_code = quic::QUIC_HTTP_STREAM_WRONG_DIRECTION;
3650 }
Renjie Tanga35322a2020-12-02 20:12:273651 quic_data.AddWrite(
3652 SYNCHRONOUS,
3653 ConstructClientAckAndConnectionClosePacket(
3654 packet_number++, 1, 1, quic_error_code, quic_error_details,
3655 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
3656 : quic::IETF_RST_STREAM));
Matt Menkeb32ba5122019-09-10 19:17:053657 quic_data.AddSocketDataToFactory(&socket_factory_);
3658
3659 // After that fails, it will be resent via TCP.
3660 MockWrite http_writes[] = {
3661 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3662 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3663 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3664
3665 MockRead http_reads[] = {
3666 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3667 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3668 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3669 SequencedSocketData http_data(http_reads, http_writes);
3670 socket_factory_.AddSocketDataProvider(&http_data);
3671 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3672
3673 // In order for a new QUIC session to be established via alternate-protocol
3674 // without racing an HTTP connection, we need the host resolution to happen
3675 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3676 // connection to the the server, in this test we require confirmation
3677 // before encrypting so the HTTP job will still start.
3678 host_resolver_.set_synchronous_mode(true);
3679 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3680 "");
3681
3682 CreateSession();
3683
3684 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3685 kNetworkIsolationKey1);
3686 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3687 kNetworkIsolationKey2);
3688
3689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3690 TestCompletionCallback callback;
3691 request_.network_isolation_key = kNetworkIsolationKey1;
3692 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3693 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3694
3695 // Pump the message loop to get the request started.
3696 base::RunLoop().RunUntilIdle();
3697 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283698 crypto_client_stream_factory_.last_stream()
3699 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:053700 quic_data.Resume();
3701
3702 // Run the QUIC session to completion.
3703 base::RunLoop().RunUntilIdle();
3704 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3705
3706 // Let the transaction proceed which will result in QUIC being marked
3707 // as broken and the request falling back to TCP.
3708 EXPECT_THAT(callback.WaitForResult(), IsOk());
3709 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3710 ASSERT_FALSE(http_data.AllReadDataConsumed());
3711
3712 // Read the response body over TCP.
3713 CheckResponseData(&trans, "hello world");
3714 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3715 ASSERT_TRUE(http_data.AllReadDataConsumed());
3716
3717 // The alternative service shouldhave been marked as broken under
3718 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3719 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3720 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3721
3722 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3723 AddHttpDataAndRunRequest();
3724 // Requests using other NetworkIsolationKeys can still use QUIC.
3725 request_.network_isolation_key = kNetworkIsolationKey2;
3726 AddQuicDataAndRunRequest();
3727
3728 // The last two requests should not have changed the alternative service
3729 // mappings.
3730 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3731 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3732}
3733
rch30943ee2017-06-12 21:28:443734// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3735// request is reset from, then QUIC will be marked as broken and the request
3736// retried over TCP.
3737TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443738 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593739 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133740 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443741 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3742
Zhongyi Shi1c022d22020-03-20 19:00:163743 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493744 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253745 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493746 quic_data.AddWrite(SYNCHRONOUS,
3747 ConstructInitialSettingsPacket(packet_num++));
3748 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023749 quic_data.AddWrite(
3750 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163751 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493752 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3753 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453754
Zhongyi Shi1c022d22020-03-20 19:00:163755 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553756 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443757
Fan Yang32c5a112018-12-10 20:06:333758 quic_data.AddRead(ASYNC,
3759 ConstructServerRstPacket(
3760 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3761 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443762
Bence Béky6e243aa2019-12-13 19:01:073763 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang248e36ea2020-06-26 00:12:343764 quic_data.AddWrite(
Renjie Tanga35322a2020-12-02 20:12:273765 SYNCHRONOUS,
3766 client_maker_->MakeRstAckAndDataPacket(
3767 packet_num++, true, GetNthClientInitiatedBidirectionalStreamId(0),
3768 quic::QUIC_HEADERS_TOO_LARGE, 1, 1, GetQpackDecoderStreamId(),
3769 false, StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:073770 }
3771
rch30943ee2017-06-12 21:28:443772 quic_data.AddRead(ASYNC, OK);
3773 quic_data.AddSocketDataToFactory(&socket_factory_);
3774
3775 // After that fails, it will be resent via TCP.
3776 MockWrite http_writes[] = {
3777 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3778 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3779 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3780
3781 MockRead http_reads[] = {
3782 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3783 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3784 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013785 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443786 socket_factory_.AddSocketDataProvider(&http_data);
3787 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3788
3789 // In order for a new QUIC session to be established via alternate-protocol
3790 // without racing an HTTP connection, we need the host resolution to happen
3791 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3792 // connection to the the server, in this test we require confirmation
3793 // before encrypting so the HTTP job will still start.
3794 host_resolver_.set_synchronous_mode(true);
3795 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3796 "");
rch30943ee2017-06-12 21:28:443797
3798 CreateSession();
3799
Ryan Hamilton9835e662018-08-02 05:36:273800 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443801
3802 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3803 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363804 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3806
3807 // Pump the message loop to get the request started.
3808 base::RunLoop().RunUntilIdle();
3809 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283810 crypto_client_stream_factory_.last_stream()
3811 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553812 quic_data.Resume();
rch30943ee2017-06-12 21:28:443813
3814 // Run the QUIC session to completion.
3815 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3816
3817 ExpectQuicAlternateProtocolMapping();
3818
3819 // Let the transaction proceed which will result in QUIC being marked
3820 // as broken and the request falling back to TCP.
3821 EXPECT_THAT(callback.WaitForResult(), IsOk());
3822
3823 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3824 ASSERT_FALSE(http_data.AllReadDataConsumed());
3825
3826 // Read the response body over TCP.
3827 CheckResponseData(&trans, "hello world");
3828 ExpectBrokenAlternateProtocolMapping();
3829 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3830 ASSERT_TRUE(http_data.AllReadDataConsumed());
3831}
3832
Ryan Hamilton6c2a2a82017-12-15 02:06:283833// Verify that when an origin has two alt-svc advertisements, one local and one
3834// remote, that when the local is broken the request will go over QUIC via
3835// the remote Alt-Svc.
3836// This is a regression test for crbug/825646.
3837TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:383838 context_.params()->allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:283839
3840 GURL origin1 = request_.url; // mail.example.org
3841 GURL origin2("https://www.example.org/");
3842 ASSERT_NE(origin1.host(), origin2.host());
3843
3844 scoped_refptr<X509Certificate> cert(
3845 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243846 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3847 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283848
3849 ProofVerifyDetailsChromium verify_details;
3850 verify_details.cert_verify_result.verified_cert = cert;
3851 verify_details.cert_verify_result.is_issued_by_known_root = true;
3852 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3853
Ryan Hamiltonabad59e2019-06-06 04:02:593854 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233855 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253856 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233857 mock_quic_data.AddWrite(SYNCHRONOUS,
3858 ConstructInitialSettingsPacket(packet_num++));
3859 }
Ryan Hamilton6c2a2a82017-12-15 02:06:283860 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233861 SYNCHRONOUS,
3862 ConstructClientRequestHeadersPacket(
3863 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3864 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433865 mock_quic_data.AddRead(
3866 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333867 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:023868 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433869 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333870 ASYNC, ConstructServerDataPacket(
3871 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:523872 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:233873 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:343874 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283875 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3876 mock_quic_data.AddRead(ASYNC, 0); // EOF
3877
3878 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:593879 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:283880 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3881 AddHangingNonAlternateProtocolSocketData();
3882
3883 CreateSession();
3884
3885 // Set up alternative service for |origin1|.
3886 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3887 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
3888 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3889 AlternativeServiceInfoVector alternative_services;
3890 alternative_services.push_back(
3891 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3892 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383893 context_.params()->supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:283894 alternative_services.push_back(
3895 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3896 remote_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383897 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:493898 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
3899 NetworkIsolationKey(),
3900 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:283901
Matt Menkeb32ba5122019-09-10 19:17:053902 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
3903 NetworkIsolationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:283904
3905 SendRequestAndExpectQuicResponse("hello!");
3906}
3907
Ryan Hamilton899c2e082019-11-14 01:22:023908// Verify that when multiple alternatives are broken,
3909// ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
3910// This is a regression test for crbug/1024613.
3911TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
3912 base::HistogramTester histogram_tester;
3913
3914 MockRead http_reads[] = {
3915 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
3916 MockRead("hello world"),
3917 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3918 MockRead(ASYNC, OK)};
3919
3920 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
3921 socket_factory_.AddSocketDataProvider(&http_data);
3922 AddCertificate(&ssl_data_);
3923 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3924
3925 GURL origin1 = request_.url; // mail.example.org
3926
3927 scoped_refptr<X509Certificate> cert(
3928 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
3929 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
3930
3931 ProofVerifyDetailsChromium verify_details;
3932 verify_details.cert_verify_result.verified_cert = cert;
3933 verify_details.cert_verify_result.is_issued_by_known_root = true;
3934 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3935
3936 CreateSession();
3937
3938 // Set up alternative service for |origin1|.
3939 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3940 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3941 AlternativeServiceInfoVector alternative_services;
3942 alternative_services.push_back(
3943 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3944 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383945 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:023946 alternative_services.push_back(
3947 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3948 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383949 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:023950 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
3951 NetworkIsolationKey(),
3952 alternative_services);
3953
3954 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
3955 NetworkIsolationKey());
3956
3957 SendRequestAndExpectHttpResponse("hello world");
3958
3959 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
3960 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
3961}
3962
rch30943ee2017-06-12 21:28:443963// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3964// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:053965// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:443966// connection instead of going back to the broken QUIC connection.
3967// This is a regression tests for crbug/731303.
3968TEST_P(QuicNetworkTransactionTest,
3969 ResetPooledAfterHandshakeConfirmedThenBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:383970 context_.params()->allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:443971
3972 GURL origin1 = request_.url;
3973 GURL origin2("https://www.example.org/");
3974 ASSERT_NE(origin1.host(), origin2.host());
3975
Ryan Hamiltonabad59e2019-06-06 04:02:593976 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:443977
3978 scoped_refptr<X509Certificate> cert(
3979 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243980 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3981 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:443982
3983 ProofVerifyDetailsChromium verify_details;
3984 verify_details.cert_verify_result.verified_cert = cert;
3985 verify_details.cert_verify_result.is_issued_by_known_root = true;
3986 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3987
Renjie Tangaadb84b2019-08-31 01:00:233988 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253989 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233990 mock_quic_data.AddWrite(SYNCHRONOUS,
3991 ConstructInitialSettingsPacket(packet_num++));
3992 }
rch30943ee2017-06-12 21:28:443993 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433994 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233995 SYNCHRONOUS,
3996 ConstructClientRequestHeadersPacket(
3997 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3998 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433999 mock_quic_data.AddRead(
4000 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334001 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024002 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434003 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334004 ASYNC, ConstructServerDataPacket(
4005 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524006 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234007 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344008 ConstructClientAckPacket(packet_num++, 2, 1));
rch30943ee2017-06-12 21:28:444009
4010 // Second request will go over the pooled QUIC connection, but will be
4011 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054012 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224013 version_,
4014 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4015 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054016 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174017 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224018 version_,
4019 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4020 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434021 mock_quic_data.AddWrite(
4022 SYNCHRONOUS,
4023 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234024 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4025 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024026 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334027 mock_quic_data.AddRead(
4028 ASYNC, ConstructServerRstPacket(
4029 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4030 quic::QUIC_HEADERS_TOO_LARGE));
Bence Béky6e243aa2019-12-13 19:01:074031
4032 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangcd594f32020-07-11 20:18:344033 mock_quic_data.AddWrite(
4034 SYNCHRONOUS,
Renjie Tanga35322a2020-12-02 20:12:274035 client_maker_->MakeRstAckAndDataPacket(
4036 packet_num++, /*include_version=*/true,
4037 GetNthClientInitiatedBidirectionalStreamId(1),
4038 quic::QUIC_HEADERS_TOO_LARGE, 3, 2, GetQpackDecoderStreamId(),
Renjie Tangcd594f32020-07-11 20:18:344039 /*fin=*/false, StreamCancellationQpackDecoderInstruction(1)));
Bence Béky6e243aa2019-12-13 19:01:074040 }
4041
rch30943ee2017-06-12 21:28:444042 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4043 mock_quic_data.AddRead(ASYNC, 0); // EOF
4044
4045 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4046
4047 // After that fails, it will be resent via TCP.
4048 MockWrite http_writes[] = {
4049 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4050 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4051 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4052
4053 MockRead http_reads[] = {
4054 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4055 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4056 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014057 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444058 socket_factory_.AddSocketDataProvider(&http_data);
4059 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4060
Ryan Hamilton6c2a2a82017-12-15 02:06:284061 // Then the next request to the second origin will be sent over TCP.
4062 socket_factory_.AddSocketDataProvider(&http_data);
4063 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444064
4065 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564066 QuicStreamFactoryPeer::SetAlarmFactory(
4067 session_->quic_stream_factory(),
4068 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224069 context_.clock()));
rch30943ee2017-06-12 21:28:444070
4071 // Set up alternative service for |origin1|.
4072 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244073 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494074 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074075 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4076 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:444077
4078 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244079 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494080 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074081 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4082 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344083
rch30943ee2017-06-12 21:28:444084 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524085 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444086 SendRequestAndExpectQuicResponse("hello!");
4087
4088 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524089 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:054090 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:444091 request_.url = origin2;
4092 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:054093 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
4094 alternative1, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244095 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:054096 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
4097 alternative2, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244098 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444099
Matt Menkeb32ba5122019-09-10 19:17:054100 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:444101 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284102 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444103}
4104
bnc8be55ebb2015-10-30 14:12:074105TEST_P(QuicNetworkTransactionTest,
4106 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564107 std::string altsvc_header =
4108 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4109 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074110 MockRead http_reads[] = {
4111 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4112 MockRead("hello world"),
4113 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4114 MockRead(ASYNC, OK)};
4115
Ryan Sleevib8d7ea02018-05-07 20:01:014116 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074117 socket_factory_.AddSocketDataProvider(&http_data);
4118 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4119 socket_factory_.AddSocketDataProvider(&http_data);
4120 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4121
rch3f4b8452016-02-23 16:59:324122 CreateSession();
bnc8be55ebb2015-10-30 14:12:074123
4124 SendRequestAndExpectHttpResponse("hello world");
4125 SendRequestAndExpectHttpResponse("hello world");
4126}
4127
Xida Chen9bfe0b62018-04-24 19:52:214128// When multiple alternative services are advertised, HttpStreamFactory should
4129// select the alternative service which uses existing QUIC session if available.
4130// If no existing QUIC session can be used, use the first alternative service
4131// from the list.
zhongyi32569c62016-01-08 02:54:304132TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:384133 context_.params()->allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524134 MockRead http_reads[] = {
4135 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294136 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524137 MockRead("hello world"),
4138 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4139 MockRead(ASYNC, OK)};
4140
Ryan Sleevib8d7ea02018-05-07 20:01:014141 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524142 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084143 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564144 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524145
zhongyi32569c62016-01-08 02:54:304146 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294147 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304148 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594149 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234150 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254151 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234152 mock_quic_data.AddWrite(SYNCHRONOUS,
4153 ConstructInitialSettingsPacket(packet_num++));
4154 }
rch5cb522462017-04-25 20:18:364155 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234156 SYNCHRONOUS,
4157 ConstructClientRequestHeadersPacket(
4158 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4159 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304160
4161 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294162 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4163 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434164 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024165 ASYNC, ConstructServerResponseHeadersPacket(
4166 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4167 GetResponseHeaders("200 OK", alt_svc_list)));
Zhongyi Shi32f2fd02018-04-16 18:23:434168 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334169 ASYNC, ConstructServerDataPacket(
4170 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524171 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234172 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344173 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:304174
4175 // Second QUIC request data.
4176 // Connection pooling, using existing session, no need to include version
4177 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584178 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234179 SYNCHRONOUS,
4180 ConstructClientRequestHeadersPacket(
4181 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4182 true, GetRequestHeaders("GET", "https", "/"),
4183 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434184 mock_quic_data.AddRead(
4185 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334186 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024187 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434188 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334189 ASYNC, ConstructServerDataPacket(
4190 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524191 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474192 mock_quic_data.AddWrite(SYNCHRONOUS,
4193 ConstructClientAckPacket(packet_num++, 4, 3));
bncc958faa2015-07-31 18:14:524194 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594195 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524196
4197 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4198
rtennetib8e80fb2016-05-16 00:12:094199 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324200 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564201 QuicStreamFactoryPeer::SetAlarmFactory(
4202 session_->quic_stream_factory(),
4203 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224204 context_.clock()));
bncc958faa2015-07-31 18:14:524205
4206 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304207
bnc359ed2a2016-04-29 20:43:454208 SendRequestAndExpectQuicResponse("hello!");
4209 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304210}
4211
Ryan Hamilton8d9ee76e2018-05-29 23:52:524212// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454213// even if alternative service destination is different.
4214TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Victor Vasilieva1e66d72019-12-05 17:55:384215 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594216 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454217
Renjie Tangaadb84b2019-08-31 01:00:234218 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254219 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234220 mock_quic_data.AddWrite(SYNCHRONOUS,
4221 ConstructInitialSettingsPacket(packet_num++));
4222 }
bnc359ed2a2016-04-29 20:43:454223 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434224 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234225 SYNCHRONOUS,
4226 ConstructClientRequestHeadersPacket(
4227 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4228 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434229 mock_quic_data.AddRead(
4230 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334231 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024232 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434233 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334234 ASYNC, ConstructServerDataPacket(
4235 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524236 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234237 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344238 ConstructClientAckPacket(packet_num++, 2, 1));
zhongyi32569c62016-01-08 02:54:304239
bnc359ed2a2016-04-29 20:43:454240 // Second request.
alyssar2adf3ac2016-05-03 17:12:584241 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234242 SYNCHRONOUS,
4243 ConstructClientRequestHeadersPacket(
4244 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4245 true, GetRequestHeaders("GET", "https", "/"),
4246 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434247 mock_quic_data.AddRead(
4248 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334249 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024250 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434251 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334252 ASYNC, ConstructServerDataPacket(
4253 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524254 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474255 mock_quic_data.AddWrite(SYNCHRONOUS,
4256 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:304257 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4258 mock_quic_data.AddRead(ASYNC, 0); // EOF
4259
4260 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454261
4262 AddHangingNonAlternateProtocolSocketData();
4263 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304264
rch3f4b8452016-02-23 16:59:324265 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564266 QuicStreamFactoryPeer::SetAlarmFactory(
4267 session_->quic_stream_factory(),
4268 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224269 context_.clock()));
zhongyi32569c62016-01-08 02:54:304270
bnc359ed2a2016-04-29 20:43:454271 const char destination1[] = "first.example.com";
4272 const char destination2[] = "second.example.com";
4273
4274 // Set up alternative service entry to destination1.
4275 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214276 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454277 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494278 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074279 server, NetworkIsolationKey(), alternative_service, expiration,
4280 supported_versions_);
bnc359ed2a2016-04-29 20:43:454281 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524282 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454283 SendRequestAndExpectQuicResponse("hello!");
4284
4285 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214286 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494287 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074288 server, NetworkIsolationKey(), alternative_service, expiration,
4289 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524290 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454291 // even though alternative service destination is different.
4292 SendRequestAndExpectQuicResponse("hello!");
4293}
4294
4295// Pool to existing session with matching destination and matching certificate
4296// even if origin is different, and even if the alternative service with
4297// matching destination is not the first one on the list.
4298TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Victor Vasilieva1e66d72019-12-05 17:55:384299 context_.params()->allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454300 GURL origin1 = request_.url;
4301 GURL origin2("https://www.example.org/");
4302 ASSERT_NE(origin1.host(), origin2.host());
4303
Ryan Hamiltonabad59e2019-06-06 04:02:594304 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454305
Renjie Tangaadb84b2019-08-31 01:00:234306 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254307 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234308 mock_quic_data.AddWrite(SYNCHRONOUS,
4309 ConstructInitialSettingsPacket(packet_num++));
4310 }
bnc359ed2a2016-04-29 20:43:454311 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434312 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234313 SYNCHRONOUS,
4314 ConstructClientRequestHeadersPacket(
4315 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4316 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434317 mock_quic_data.AddRead(
4318 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334319 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024320 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434321 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334322 ASYNC, ConstructServerDataPacket(
4323 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524324 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234325 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344326 ConstructClientAckPacket(packet_num++, 2, 1));
bnc359ed2a2016-04-29 20:43:454327
4328 // Second request.
Yixin Wang079ad542018-01-11 04:06:054329 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224330 version_,
4331 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4332 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054333 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174334 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224335 version_,
4336 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4337 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584338 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434339 SYNCHRONOUS,
4340 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234341 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4342 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024343 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434344 mock_quic_data.AddRead(
4345 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334346 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024347 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434348 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334349 ASYNC, ConstructServerDataPacket(
4350 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524351 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:474352 mock_quic_data.AddWrite(SYNCHRONOUS,
4353 ConstructClientAckPacket(packet_num++, 4, 3));
bnc359ed2a2016-04-29 20:43:454354 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4355 mock_quic_data.AddRead(ASYNC, 0); // EOF
4356
4357 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4358
4359 AddHangingNonAlternateProtocolSocketData();
4360 AddHangingNonAlternateProtocolSocketData();
4361
4362 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564363 QuicStreamFactoryPeer::SetAlarmFactory(
4364 session_->quic_stream_factory(),
4365 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224366 context_.clock()));
bnc359ed2a2016-04-29 20:43:454367
4368 const char destination1[] = "first.example.com";
4369 const char destination2[] = "second.example.com";
4370
4371 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214372 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454373 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494374 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074375 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4376 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454377
4378 // Set up multiple alternative service entries for |origin2|,
4379 // the first one with a different destination as for |origin1|,
4380 // the second one with the same. The second one should be used,
4381 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214382 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454383 AlternativeServiceInfoVector alternative_services;
4384 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214385 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4386 alternative_service2, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384387 context_.params()->supported_versions));
bnc359ed2a2016-04-29 20:43:454388 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214389 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4390 alternative_service1, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384391 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494392 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4393 NetworkIsolationKey(),
4394 alternative_services);
bnc359ed2a2016-04-29 20:43:454395 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524396 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454397 SendRequestAndExpectQuicResponse("hello!");
4398
4399 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524400 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454401 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584402
bnc359ed2a2016-04-29 20:43:454403 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304404}
4405
4406// Multiple origins have listed the same alternative services. When there's a
4407// existing QUIC session opened by a request to other origin,
4408// if the cert is valid, should select this QUIC session to make the request
4409// if this is also the first existing QUIC session.
4410TEST_P(QuicNetworkTransactionTest,
4411 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Victor Vasilieva1e66d72019-12-05 17:55:384412 context_.params()->allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294413 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304414
rch9ae5b3b2016-02-11 00:36:294415 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304416 MockRead http_reads[] = {
4417 MockRead("HTTP/1.1 200 OK\r\n"),
4418 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294419 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304420 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4421 MockRead(ASYNC, OK)};
4422
Ryan Sleevib8d7ea02018-05-07 20:01:014423 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304424 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084425 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304426 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4427
4428 // HTTP data for request to mail.example.org.
4429 MockRead http_reads2[] = {
4430 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294431 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304432 MockRead("hello world from mail.example.org"),
4433 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4434 MockRead(ASYNC, OK)};
4435
Ryan Sleevib8d7ea02018-05-07 20:01:014436 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304437 socket_factory_.AddSocketDataProvider(&http_data2);
4438 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4439
Yixin Wang079ad542018-01-11 04:06:054440 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:224441 version_,
4442 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4443 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054444 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584445 server_maker_.set_hostname("www.example.org");
Zhongyi Shi1c022d22020-03-20 19:00:164446 client_maker_->set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594447 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234448 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254449 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234450 mock_quic_data.AddWrite(SYNCHRONOUS,
4451 ConstructInitialSettingsPacket(packet_num++));
4452 }
zhongyi32569c62016-01-08 02:54:304453 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584454 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234455 SYNCHRONOUS,
4456 ConstructClientRequestHeadersPacket(
4457 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4458 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434459
4460 mock_quic_data.AddRead(
4461 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334462 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024463 GetResponseHeaders("200 OK")));
Fan Yang32c5a112018-12-10 20:06:334464 mock_quic_data.AddRead(
4465 ASYNC, ConstructServerDataPacket(
4466 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524467 ConstructDataFrame("hello from mail QUIC!")));
Renjie Tangaadb84b2019-08-31 01:00:234468 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344469 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434470 // Second QUIC request data.
4471 mock_quic_data.AddWrite(
4472 SYNCHRONOUS,
4473 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234474 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4475 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024476 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434477 mock_quic_data.AddRead(
4478 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334479 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024480 GetResponseHeaders("200 OK")));
Fan Yang32c5a112018-12-10 20:06:334481 mock_quic_data.AddRead(
4482 ASYNC, ConstructServerDataPacket(
4483 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:524484 ConstructDataFrame("hello from mail QUIC!")));
Renjie Tangb7afea82020-07-15 23:35:474485 mock_quic_data.AddWrite(SYNCHRONOUS,
4486 ConstructClientAckPacket(packet_num++, 4, 3));
zhongyi32569c62016-01-08 02:54:304487 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4488 mock_quic_data.AddRead(ASYNC, 0); // EOF
4489
4490 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304491
rtennetib8e80fb2016-05-16 00:12:094492 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324493 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564494 QuicStreamFactoryPeer::SetAlarmFactory(
4495 session_->quic_stream_factory(),
4496 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224497 context_.clock()));
zhongyi32569c62016-01-08 02:54:304498
4499 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294500 request_.url = GURL("https://www.example.org/");
4501 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304502 request_.url = GURL("https://mail.example.org/");
4503 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4504
rch9ae5b3b2016-02-11 00:36:294505 // Open a QUIC session to mail.example.org:443 when making request
4506 // to mail.example.org.
4507 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454508 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304509
rch9ae5b3b2016-02-11 00:36:294510 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304511 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454512 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524513}
4514
4515TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524516 MockRead http_reads[] = {
4517 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564518 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524519 MockRead("hello world"),
4520 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4521 MockRead(ASYNC, OK)};
4522
Ryan Sleevib8d7ea02018-05-07 20:01:014523 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524524 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084525 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564526 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524527
rtennetib8e80fb2016-05-16 00:12:094528 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324529 CreateSession();
bncc958faa2015-07-31 18:14:524530
4531 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454532
4533 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344534 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494535 http_server_properties_->GetAlternativeServiceInfos(
4536 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344537 ASSERT_EQ(1u, alternative_service_info_vector.size());
4538 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544539 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344540 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4541 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4542 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524543}
4544
4545TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524546 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564547 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4548 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524549 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4550 MockRead(ASYNC, OK)};
4551
Ryan Sleevib8d7ea02018-05-07 20:01:014552 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524553 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084554 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564555 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524556
Ryan Hamiltonabad59e2019-06-06 04:02:594557 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234558 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254559 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234560 mock_quic_data.AddWrite(SYNCHRONOUS,
4561 ConstructInitialSettingsPacket(packet_num++));
4562 }
rch5cb522462017-04-25 20:18:364563 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234564 SYNCHRONOUS,
4565 ConstructClientRequestHeadersPacket(
4566 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4567 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434568 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334569 ASYNC, ConstructServerResponseHeadersPacket(
4570 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4571 GetResponseHeaders("200 OK")));
4572 mock_quic_data.AddRead(
4573 ASYNC, ConstructServerDataPacket(
4574 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524575 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234576 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344577 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:524578 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4579 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524580
4581 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4582
rtennetib8e80fb2016-05-16 00:12:094583 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324584 CreateSession();
bncc958faa2015-07-31 18:14:524585
bnc3472afd2016-11-17 15:27:214586 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524587 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494588 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054589 alternative_service, NetworkIsolationKey());
Matt Menke3233d8f22019-08-20 21:01:494590 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054591 alternative_service, NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524592
4593 SendRequestAndExpectHttpResponse("hello world");
4594 SendRequestAndExpectQuicResponse("hello!");
4595
mmenkee24011922015-12-17 22:12:594596 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524597
Matt Menke3233d8f22019-08-20 21:01:494598 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054599 alternative_service, NetworkIsolationKey()));
Matt Menke19475f72019-08-21 18:57:444600 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4601 url::SchemeHostPort("https", request_.url.host(), 443),
4602 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524603}
4604
Matt Menkeb32ba5122019-09-10 19:17:054605TEST_P(QuicNetworkTransactionTest,
4606 ConfirmAlternativeServiceWithNetworkIsolationKey) {
Matt Menke4807a9a2020-11-21 00:14:414607 const SchemefulSite kSite1(GURL("https://foo.test/"));
4608 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
4609 const SchemefulSite kSite2(GURL("https://bar.test/"));
4610 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:054611
4612 base::test::ScopedFeatureList feature_list;
4613 feature_list.InitWithFeatures(
4614 // enabled_features
4615 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4616 features::kPartitionConnectionsByNetworkIsolationKey},
4617 // disabled_features
4618 {});
4619 // Since HttpServerProperties caches the feature value, have to create a new
4620 // one.
4621 http_server_properties_ = std::make_unique<HttpServerProperties>();
4622
4623 MockRead http_reads[] = {
4624 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4625 MockRead("hello world"),
4626 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4627 MockRead(ASYNC, OK)};
4628
4629 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4630 socket_factory_.AddSocketDataProvider(&http_data);
4631 AddCertificate(&ssl_data_);
4632 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4633
4634 MockQuicData mock_quic_data(version_);
4635 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254636 if (VersionUsesHttp3(version_.transport_version)) {
Matt Menkeb32ba5122019-09-10 19:17:054637 mock_quic_data.AddWrite(SYNCHRONOUS,
4638 ConstructInitialSettingsPacket(packet_num++));
4639 }
4640 mock_quic_data.AddWrite(
4641 SYNCHRONOUS,
4642 ConstructClientRequestHeadersPacket(
4643 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4644 true, GetRequestHeaders("GET", "https", "/")));
4645 mock_quic_data.AddRead(
4646 ASYNC, ConstructServerResponseHeadersPacket(
4647 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4648 GetResponseHeaders("200 OK")));
Matt Menkeb32ba5122019-09-10 19:17:054649 mock_quic_data.AddRead(
4650 ASYNC, ConstructServerDataPacket(
4651 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524652 ConstructDataFrame("hello!")));
Matt Menkeb32ba5122019-09-10 19:17:054653 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344654 ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menkeb32ba5122019-09-10 19:17:054655 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4656 mock_quic_data.AddRead(ASYNC, 0); // EOF
4657
4658 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4659
4660 CreateSession();
4661
4662 AlternativeService alternative_service(kProtoQUIC,
4663 HostPortPair::FromURL(request_.url));
4664 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4665 alternative_service, kNetworkIsolationKey1);
4666 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4667 alternative_service, kNetworkIsolationKey2);
4668 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4669 alternative_service, kNetworkIsolationKey1));
4670 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4671 alternative_service, kNetworkIsolationKey2));
4672
4673 request_.network_isolation_key = kNetworkIsolationKey1;
4674 SendRequestAndExpectHttpResponse("hello world");
4675 SendRequestAndExpectQuicResponse("hello!");
4676
4677 mock_quic_data.Resume();
4678
4679 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4680 alternative_service, kNetworkIsolationKey1));
4681 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4682 url::SchemeHostPort("https", request_.url.host(), 443),
4683 kNetworkIsolationKey1));
4684 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4685 alternative_service, kNetworkIsolationKey2));
4686 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4687 url::SchemeHostPort("https", request_.url.host(), 443),
4688 kNetworkIsolationKey2));
4689}
4690
bncc958faa2015-07-31 18:14:524691TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524692 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564693 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4694 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524695 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4696 MockRead(ASYNC, OK)};
4697
Ryan Sleevib8d7ea02018-05-07 20:01:014698 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524699 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564700 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524701
Ryan Hamiltonabad59e2019-06-06 04:02:594702 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234703 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254704 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234705 mock_quic_data.AddWrite(SYNCHRONOUS,
4706 ConstructInitialSettingsPacket(packet_num++));
4707 }
rch5cb522462017-04-25 20:18:364708 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234709 SYNCHRONOUS,
4710 ConstructClientRequestHeadersPacket(
4711 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4712 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434713 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334714 ASYNC, ConstructServerResponseHeadersPacket(
4715 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4716 GetResponseHeaders("200 OK")));
4717 mock_quic_data.AddRead(
4718 ASYNC, ConstructServerDataPacket(
4719 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524720 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234721 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344722 ConstructClientAckPacket(packet_num++, 2, 1));
bncc958faa2015-07-31 18:14:524723 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4724
4725 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4726
4727 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324728 CreateSession();
bncc958faa2015-07-31 18:14:524729
4730 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4731 SendRequestAndExpectHttpResponse("hello world");
4732}
4733
bnc1c196c6e2016-05-28 13:51:484734TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304735 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274736 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304737
4738 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564739 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294740 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564741 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304742
4743 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564744 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484745 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564746 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304747
Ryan Sleevib8d7ea02018-05-07 20:01:014748 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504749 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084750 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504751 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304752
4753 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454754 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304755 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454756 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304757 };
Ryan Sleevib8d7ea02018-05-07 20:01:014758 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504759 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304760
4761 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014762 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504763 socket_factory_.AddSocketDataProvider(&http_data2);
4764 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304765
bnc912a04b2016-04-20 14:19:504766 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304767
4768 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304769 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174770 ASSERT_TRUE(http_data.AllReadDataConsumed());
4771 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304772
4773 // Now run the second request in which the QUIC socket hangs,
4774 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304775 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454776 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304777
rch37de576c2015-05-17 20:28:174778 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4779 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454780 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304781}
4782
[email protected]1e960032013-12-20 19:00:204783TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594784 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164785 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494786 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254787 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:494788 mock_quic_data.AddWrite(SYNCHRONOUS,
4789 ConstructInitialSettingsPacket(packet_num++));
4790 }
Zhongyi Shi32f2fd02018-04-16 18:23:434791 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494792 SYNCHRONOUS,
4793 ConstructClientRequestHeadersPacket(
4794 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4795 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434796 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334797 ASYNC, ConstructServerResponseHeadersPacket(
4798 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4799 GetResponseHeaders("200 OK")));
4800 mock_quic_data.AddRead(
4801 ASYNC, ConstructServerDataPacket(
4802 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524803 ConstructDataFrame("hello!")));
Nick Harper1ccb0ce2020-10-07 00:28:584804 if (version_.UsesTls()) {
4805 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4806 }
Nick Harper057264a82019-09-12 23:33:494807 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344808 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:504809 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594810 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484811
rcha5399e02015-04-21 19:32:044812 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484813
rtennetib8e80fb2016-05-16 00:12:094814 // The non-alternate protocol job needs to hang in order to guarantee that
4815 // the alternate-protocol job will "win".
4816 AddHangingNonAlternateProtocolSocketData();
4817
rch3f4b8452016-02-23 16:59:324818 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274819 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194820 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304821
Matt Menke19475f72019-08-21 18:57:444822 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4823 url::SchemeHostPort("https", request_.url.host(), 443),
4824 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:484825}
4826
[email protected]1e960032013-12-20 19:00:204827TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594828 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164829 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494830 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:254831 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:494832 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:164833 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:494834 }
Fan Yang32c5a112018-12-10 20:06:334835 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:494836 SYNCHRONOUS,
4837 ConstructClientRequestHeadersPacket(
4838 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4839 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434840 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334841 ASYNC, ConstructServerResponseHeadersPacket(
4842 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4843 GetResponseHeaders("200 OK")));
4844 mock_quic_data.AddRead(
4845 ASYNC, ConstructServerDataPacket(
4846 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524847 ConstructDataFrame("hello!")));
Nick Harper1ccb0ce2020-10-07 00:28:584848 if (version_.UsesTls()) {
4849 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4850 }
Nick Harper057264a82019-09-12 23:33:494851 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344852 ConstructClientAckPacket(packet_number++, 2, 1));
rchb27683c2015-07-29 23:53:504853 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594854 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044855 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274856
4857 // In order for a new QUIC session to be established via alternate-protocol
4858 // without racing an HTTP connection, we need the host resolution to happen
4859 // synchronously.
4860 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294861 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564862 "");
[email protected]3a120a6b2013-06-25 01:08:274863
rtennetib8e80fb2016-05-16 00:12:094864 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324865 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274866 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274867 SendRequestAndExpectQuicResponse("hello!");
4868}
4869
[email protected]0fc924b2014-03-31 04:34:154870TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Nicolas Arciniegad2013f92020-02-07 23:00:564871 proxy_resolution_service_ =
4872 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
4873 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154874
4875 // Since we are using a proxy, the QUIC job will not succeed.
4876 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294877 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4878 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564879 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154880
4881 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564882 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484883 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564884 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154885
Ryan Sleevib8d7ea02018-05-07 20:01:014886 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154887 socket_factory_.AddSocketDataProvider(&http_data);
4888
4889 // In order for a new QUIC session to be established via alternate-protocol
4890 // without racing an HTTP connection, we need the host resolution to happen
4891 // synchronously.
4892 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294893 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564894 "");
[email protected]0fc924b2014-03-31 04:34:154895
rch9ae5b3b2016-02-11 00:36:294896 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324897 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274898 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154899 SendRequestAndExpectHttpResponse("hello world");
4900}
4901
[email protected]1e960032013-12-20 19:00:204902TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:594903 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234904 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:164905 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:254906 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234907 mock_quic_data.AddWrite(SYNCHRONOUS,
4908 ConstructInitialSettingsPacket(packet_num++));
4909 }
Zhongyi Shi1c022d22020-03-20 19:00:164910 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:364911 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234912 SYNCHRONOUS,
4913 ConstructClientRequestHeadersPacket(
4914 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4915 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434916 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334917 ASYNC, ConstructServerResponseHeadersPacket(
4918 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4919 GetResponseHeaders("200 OK")));
4920 mock_quic_data.AddRead(
4921 ASYNC, ConstructServerDataPacket(
4922 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:524923 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:234924 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:344925 ConstructClientAckPacket(packet_num++, 2, 1));
mmenkee24011922015-12-17 22:12:594926 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044927 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124928
rtennetib8e80fb2016-05-16 00:12:094929 // The non-alternate protocol job needs to hang in order to guarantee that
4930 // the alternate-protocol job will "win".
4931 AddHangingNonAlternateProtocolSocketData();
4932
[email protected]11c05872013-08-20 02:04:124933 // In order for a new QUIC session to be established via alternate-protocol
4934 // without racing an HTTP connection, we need the host resolution to happen
4935 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4936 // connection to the the server, in this test we require confirmation
4937 // before encrypting so the HTTP job will still start.
4938 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294939 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564940 "");
[email protected]11c05872013-08-20 02:04:124941
rch3f4b8452016-02-23 16:59:324942 CreateSession();
Matt Menkeb566c392019-09-11 23:22:434943 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
4944 false);
Ryan Hamilton9835e662018-08-02 05:36:274945 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:124946
bnc691fda62016-08-12 00:43:164947 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:124948 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364949 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014950 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:124951
Fan Yang3673cc72020-02-07 14:49:284952 crypto_client_stream_factory_.last_stream()
4953 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:014954 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:504955
bnc691fda62016-08-12 00:43:164956 CheckWasQuicResponse(&trans);
4957 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:124958}
4959
Steven Valdez58097ec32018-07-16 18:29:044960TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:014961 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594962 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:164963 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:254964 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:494965 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:164966 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:494967 }
Steven Valdez58097ec32018-07-16 18:29:044968 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014969 SYNCHRONOUS,
4970 ConstructClientRequestHeadersPacket(
4971 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4972 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334973 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024974 ASYNC, ConstructServerResponseHeadersPacket(
4975 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4976 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:074977 if (VersionUsesHttp3(version_.transport_version)) {
4978 mock_quic_data.AddWrite(
4979 SYNCHRONOUS,
4980 ConstructClientAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:344981 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, false,
Bence Béky6e243aa2019-12-13 19:01:074982 StreamCancellationQpackDecoderInstruction(0)));
4983 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:164984 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:074985 packet_number++, false,
4986 GetNthClientInitiatedBidirectionalStreamId(0),
4987 quic::QUIC_STREAM_CANCELLED));
4988 } else {
4989 mock_quic_data.AddWrite(
4990 SYNCHRONOUS,
4991 ConstructClientAckAndRstPacket(
4992 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:344993 quic::QUIC_STREAM_CANCELLED, 1, 1));
Bence Béky6e243aa2019-12-13 19:01:074994 }
Steven Valdez58097ec32018-07-16 18:29:044995
Zhongyi Shi1c022d22020-03-20 19:00:164996 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:044997
Steven Valdez58097ec32018-07-16 18:29:044998 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014999 SYNCHRONOUS,
5000 ConstructClientRequestHeadersPacket(
5001 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5002 true, GetRequestHeaders("GET", "https", "/"),
5003 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045004 mock_quic_data.AddRead(
5005 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335006 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025007 GetResponseHeaders("200 OK")));
Steven Valdez58097ec32018-07-16 18:29:045008 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335009 ASYNC, ConstructServerDataPacket(
5010 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:525011 ConstructDataFrame("hello!")));
Renjie Tangb7afea82020-07-15 23:35:475012 mock_quic_data.AddWrite(SYNCHRONOUS,
5013 ConstructClientAckPacket(packet_number++, 3, 1));
Steven Valdez58097ec32018-07-16 18:29:045014 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5015 mock_quic_data.AddRead(ASYNC, 0); // EOF
5016
5017 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5018
5019 // In order for a new QUIC session to be established via alternate-protocol
5020 // without racing an HTTP connection, we need the host resolution to happen
5021 // synchronously.
5022 host_resolver_.set_synchronous_mode(true);
5023 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5024 "");
Steven Valdez58097ec32018-07-16 18:29:045025
5026 AddHangingNonAlternateProtocolSocketData();
5027 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275028 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565029 QuicStreamFactoryPeer::SetAlarmFactory(
5030 session_->quic_stream_factory(),
5031 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225032 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045033
5034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5035 TestCompletionCallback callback;
5036 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5037 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5038
5039 // Confirm the handshake after the 425 Too Early.
5040 base::RunLoop().RunUntilIdle();
5041
5042 // The handshake hasn't been confirmed yet, so the retry should not have
5043 // succeeded.
5044 EXPECT_FALSE(callback.have_result());
5045
Fan Yang3673cc72020-02-07 14:49:285046 crypto_client_stream_factory_.last_stream()
5047 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:045048
5049 EXPECT_THAT(callback.WaitForResult(), IsOk());
5050 CheckWasQuicResponse(&trans);
5051 CheckResponseData(&trans, "hello!");
5052}
5053
5054TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015055 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595056 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165057 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255058 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495059 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:165060 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:495061 }
Steven Valdez58097ec32018-07-16 18:29:045062 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015063 SYNCHRONOUS,
5064 ConstructClientRequestHeadersPacket(
5065 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5066 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335067 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025068 ASYNC, ConstructServerResponseHeadersPacket(
5069 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5070 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075071 if (VersionUsesHttp3(version_.transport_version)) {
5072 mock_quic_data.AddWrite(
5073 SYNCHRONOUS,
5074 ConstructClientAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:345075 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, false,
Bence Béky6e243aa2019-12-13 19:01:075076 StreamCancellationQpackDecoderInstruction(0)));
5077 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165078 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075079 packet_number++, false,
5080 GetNthClientInitiatedBidirectionalStreamId(0),
5081 quic::QUIC_STREAM_CANCELLED));
5082 } else {
5083 mock_quic_data.AddWrite(
5084 SYNCHRONOUS,
5085 ConstructClientAckAndRstPacket(
5086 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:345087 quic::QUIC_STREAM_CANCELLED, 1, 1));
Bence Béky6e243aa2019-12-13 19:01:075088 }
Steven Valdez58097ec32018-07-16 18:29:045089
Zhongyi Shi1c022d22020-03-20 19:00:165090 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:045091
Steven Valdez58097ec32018-07-16 18:29:045092 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015093 SYNCHRONOUS,
5094 ConstructClientRequestHeadersPacket(
5095 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5096 true, GetRequestHeaders("GET", "https", "/"),
5097 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335098 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025099 ASYNC, ConstructServerResponseHeadersPacket(
5100 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5101 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075102 if (VersionUsesHttp3(version_.transport_version)) {
5103 mock_quic_data.AddWrite(
5104 SYNCHRONOUS,
5105 ConstructClientAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:345106 packet_number++, false, GetQpackDecoderStreamId(), 2, 1, false,
Renjie Tang248e36ea2020-06-26 00:12:345107 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:075108 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165109 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075110 packet_number++, false,
5111 GetNthClientInitiatedBidirectionalStreamId(1),
5112 quic::QUIC_STREAM_CANCELLED));
5113 } else {
5114 mock_quic_data.AddWrite(
5115 SYNCHRONOUS,
5116 ConstructClientAckAndRstPacket(
5117 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
Renjie Tangcd594f32020-07-11 20:18:345118 quic::QUIC_STREAM_CANCELLED, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:075119 }
Steven Valdez58097ec32018-07-16 18:29:045120 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5121 mock_quic_data.AddRead(ASYNC, 0); // EOF
5122
5123 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5124
5125 // In order for a new QUIC session to be established via alternate-protocol
5126 // without racing an HTTP connection, we need the host resolution to happen
5127 // synchronously.
5128 host_resolver_.set_synchronous_mode(true);
5129 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5130 "");
Steven Valdez58097ec32018-07-16 18:29:045131
5132 AddHangingNonAlternateProtocolSocketData();
5133 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275134 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565135 QuicStreamFactoryPeer::SetAlarmFactory(
5136 session_->quic_stream_factory(),
5137 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225138 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045139
5140 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5141 TestCompletionCallback callback;
5142 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5143 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5144
5145 // Confirm the handshake after the 425 Too Early.
5146 base::RunLoop().RunUntilIdle();
5147
5148 // The handshake hasn't been confirmed yet, so the retry should not have
5149 // succeeded.
5150 EXPECT_FALSE(callback.have_result());
5151
Fan Yang3673cc72020-02-07 14:49:285152 crypto_client_stream_factory_.last_stream()
5153 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:045154
5155 EXPECT_THAT(callback.WaitForResult(), IsOk());
5156 const HttpResponseInfo* response = trans.GetResponseInfo();
5157 ASSERT_TRUE(response != nullptr);
5158 ASSERT_TRUE(response->headers.get() != nullptr);
5159 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5160 EXPECT_TRUE(response->was_fetched_via_spdy);
5161 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085162 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5163 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045164}
5165
zhongyica364fbb2015-12-12 03:39:125166TEST_P(QuicNetworkTransactionTest,
5167 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Victor Vasilieva1e66d72019-12-05 17:55:385168 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595169 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235170 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165171 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255172 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235173 mock_quic_data.AddWrite(SYNCHRONOUS,
5174 ConstructInitialSettingsPacket(packet_num++));
5175 }
Zhongyi Shi1c022d22020-03-20 19:00:165176 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365177 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235178 SYNCHRONOUS,
5179 ConstructClientRequestHeadersPacket(
5180 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5181 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125182 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525183 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435184 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125185 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5186
5187 // The non-alternate protocol job needs to hang in order to guarantee that
5188 // the alternate-protocol job will "win".
5189 AddHangingNonAlternateProtocolSocketData();
5190
5191 // In order for a new QUIC session to be established via alternate-protocol
5192 // without racing an HTTP connection, we need the host resolution to happen
5193 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5194 // connection to the the server, in this test we require confirmation
5195 // before encrypting so the HTTP job will still start.
5196 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295197 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125198 "");
zhongyica364fbb2015-12-12 03:39:125199
rch3f4b8452016-02-23 16:59:325200 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435201 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5202 false);
Ryan Hamilton9835e662018-08-02 05:36:275203 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125204
bnc691fda62016-08-12 00:43:165205 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125206 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365207 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015208 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125209
Fan Yang3673cc72020-02-07 14:49:285210 crypto_client_stream_factory_.last_stream()
5211 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015212 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125213
5214 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525215 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125216
bnc691fda62016-08-12 00:43:165217 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125218 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525219 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5220 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125221}
5222
5223TEST_P(QuicNetworkTransactionTest,
5224 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Victor Vasilieva1e66d72019-12-05 17:55:385225 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595226 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235227 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165228 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255229 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235230 mock_quic_data.AddWrite(SYNCHRONOUS,
5231 ConstructInitialSettingsPacket(packet_num++));
5232 }
Zhongyi Shi1c022d22020-03-20 19:00:165233 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365234 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235235 SYNCHRONOUS,
5236 ConstructClientRequestHeadersPacket(
5237 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5238 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215239 // Peer sending data from an non-existing stream causes this end to raise
5240 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335241 mock_quic_data.AddRead(
5242 ASYNC, ConstructServerRstPacket(
5243 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5244 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215245 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:375246 mock_quic_data.AddWrite(
Renjie Tang248e36ea2020-06-26 00:12:345247 SYNCHRONOUS,
5248 ConstructClientAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:345249 packet_num++, 1, 1,
Renjie Tang248e36ea2020-06-26 00:12:345250 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
5251 : quic::QUIC_INVALID_STREAM_ID,
Renjie Tanga35322a2020-12-02 20:12:275252 quic_error_details,
5253 version_.HasIetfQuicFrames() ? quic::IETF_STOP_SENDING
5254 : quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125255 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5256
5257 // The non-alternate protocol job needs to hang in order to guarantee that
5258 // the alternate-protocol job will "win".
5259 AddHangingNonAlternateProtocolSocketData();
5260
5261 // In order for a new QUIC session to be established via alternate-protocol
5262 // without racing an HTTP connection, we need the host resolution to happen
5263 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5264 // connection to the the server, in this test we require confirmation
5265 // before encrypting so the HTTP job will still start.
5266 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295267 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125268 "");
zhongyica364fbb2015-12-12 03:39:125269
rch3f4b8452016-02-23 16:59:325270 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435271 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5272 false);
Ryan Hamilton9835e662018-08-02 05:36:275273 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125274
bnc691fda62016-08-12 00:43:165275 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125276 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365277 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015278 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125279
Fan Yang3673cc72020-02-07 14:49:285280 crypto_client_stream_factory_.last_stream()
5281 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015282 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125283 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525284 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125285
bnc691fda62016-08-12 00:43:165286 trans.PopulateNetErrorDetails(&details);
Renjie Tang248e36ea2020-06-26 00:12:345287 EXPECT_EQ(version_.HasIetfQuicFrames()
5288 ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
5289 : quic::QUIC_INVALID_STREAM_ID,
5290 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125291}
5292
Nick Harper057264a82019-09-12 23:33:495293TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:595294 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235295 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165296 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255297 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235298 mock_quic_data.AddWrite(SYNCHRONOUS,
5299 ConstructInitialSettingsPacket(packet_num++));
5300 }
Zhongyi Shi1c022d22020-03-20 19:00:165301 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365302 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235303 SYNCHRONOUS,
5304 ConstructClientRequestHeadersPacket(
5305 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5306 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485307 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335308 mock_quic_data.AddRead(
5309 ASYNC, ConstructServerResponseHeadersPacket(
5310 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5311 GetResponseHeaders("200 OK")));
5312 mock_quic_data.AddRead(
5313 ASYNC, ConstructServerRstPacket(
5314 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5315 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075316
5317 if (VersionUsesHttp3(version_.transport_version)) {
5318 mock_quic_data.AddWrite(
Renjie Tanga35322a2020-12-02 20:12:275319 SYNCHRONOUS,
5320 client_maker_->MakeAckRstAndDataPacket(
5321 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5322 quic::QUIC_STREAM_CANCELLED, 2, 1, GetQpackDecoderStreamId(), false,
5323 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:075324 } else {
5325 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345326 ConstructClientAckPacket(packet_num++, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:075327 }
rchcd5f1c62016-06-23 02:43:485328 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5329 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5330
5331 // The non-alternate protocol job needs to hang in order to guarantee that
5332 // the alternate-protocol job will "win".
5333 AddHangingNonAlternateProtocolSocketData();
5334
5335 // In order for a new QUIC session to be established via alternate-protocol
5336 // without racing an HTTP connection, we need the host resolution to happen
5337 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5338 // connection to the the server, in this test we require confirmation
5339 // before encrypting so the HTTP job will still start.
5340 host_resolver_.set_synchronous_mode(true);
5341 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5342 "");
rchcd5f1c62016-06-23 02:43:485343
5344 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435345 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5346 false);
Ryan Hamilton9835e662018-08-02 05:36:275347 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485348
bnc691fda62016-08-12 00:43:165349 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485350 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365351 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015352 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485353
Fan Yang3673cc72020-02-07 14:49:285354 crypto_client_stream_factory_.last_stream()
5355 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:485356 // Read the headers.
robpercival214763f2016-07-01 23:27:015357 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485358
bnc691fda62016-08-12 00:43:165359 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485360 ASSERT_TRUE(response != nullptr);
5361 ASSERT_TRUE(response->headers.get() != nullptr);
5362 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5363 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525364 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085365 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5366 response->connection_info);
rchcd5f1c62016-06-23 02:43:485367
5368 std::string response_data;
bnc691fda62016-08-12 00:43:165369 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485370}
5371
Nick Harper057264a82019-09-12 23:33:495372TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:385373 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595374 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235375 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165376 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255377 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235378 mock_quic_data.AddWrite(SYNCHRONOUS,
5379 ConstructInitialSettingsPacket(packet_num++));
5380 }
Zhongyi Shi1c022d22020-03-20 19:00:165381 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365382 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235383 SYNCHRONOUS,
5384 ConstructClientRequestHeadersPacket(
5385 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5386 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335387 mock_quic_data.AddRead(
5388 ASYNC, ConstructServerRstPacket(
5389 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5390 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075391
5392 if (VersionUsesHttp3(version_.transport_version)) {
5393 mock_quic_data.AddWrite(
Renjie Tanga35322a2020-12-02 20:12:275394 SYNCHRONOUS,
5395 client_maker_->MakeRstAckAndDataPacket(
5396 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5397 quic::QUIC_STREAM_CANCELLED, 1, 1, GetQpackDecoderStreamId(), false,
5398 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:075399 }
5400
rchcd5f1c62016-06-23 02:43:485401 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5402 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5403
5404 // The non-alternate protocol job needs to hang in order to guarantee that
5405 // the alternate-protocol job will "win".
5406 AddHangingNonAlternateProtocolSocketData();
5407
5408 // In order for a new QUIC session to be established via alternate-protocol
5409 // without racing an HTTP connection, we need the host resolution to happen
5410 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5411 // connection to the the server, in this test we require confirmation
5412 // before encrypting so the HTTP job will still start.
5413 host_resolver_.set_synchronous_mode(true);
5414 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5415 "");
rchcd5f1c62016-06-23 02:43:485416
5417 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435418 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5419 false);
Ryan Hamilton9835e662018-08-02 05:36:275420 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485421
bnc691fda62016-08-12 00:43:165422 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485423 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365424 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015425 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485426
Fan Yang3673cc72020-02-07 14:49:285427 crypto_client_stream_factory_.last_stream()
5428 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:485429 // Read the headers.
robpercival214763f2016-07-01 23:27:015430 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485431}
5432
[email protected]1e960032013-12-20 19:00:205433TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305434 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525435 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585436 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305437 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505438 MockRead(ASYNC, close->data(), close->length()),
5439 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5440 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305441 };
Ryan Sleevib8d7ea02018-05-07 20:01:015442 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305443 socket_factory_.AddSocketDataProvider(&quic_data);
5444
5445 // Main job which will succeed even though the alternate job fails.
5446 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025447 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5448 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5449 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305450
Ryan Sleevib8d7ea02018-05-07 20:01:015451 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305452 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565453 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305454
rch3f4b8452016-02-23 16:59:325455 CreateSession();
David Schinazic8281052019-01-24 06:14:175456 AddQuicAlternateProtocolMapping(
5457 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195458 SendRequestAndExpectHttpResponse("hello from http");
5459 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305460}
5461
Matt Menkeb32ba5122019-09-10 19:17:055462TEST_P(QuicNetworkTransactionTest,
5463 BrokenAlternateProtocolWithNetworkIsolationKey) {
Matt Menke4807a9a2020-11-21 00:14:415464 const SchemefulSite kSite1(GURL("https://foo.test/"));
5465 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
5466 const SchemefulSite kSite2(GURL("https://bar.test/"));
5467 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:055468
5469 base::test::ScopedFeatureList feature_list;
5470 feature_list.InitWithFeatures(
5471 // enabled_features
5472 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5473 features::kPartitionConnectionsByNetworkIsolationKey},
5474 // disabled_features
5475 {});
5476 // Since HttpServerProperties caches the feature value, have to create a new
5477 // one.
5478 http_server_properties_ = std::make_unique<HttpServerProperties>();
5479
5480 // Alternate-protocol job
5481 std::unique_ptr<quic::QuicEncryptedPacket> close(
5482 ConstructServerConnectionClosePacket(1));
5483 MockRead quic_reads[] = {
5484 MockRead(ASYNC, close->data(), close->length()),
5485 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5486 MockRead(ASYNC, OK), // EOF
5487 };
5488 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5489 socket_factory_.AddSocketDataProvider(&quic_data);
5490
5491 // Main job which will succeed even though the alternate job fails.
5492 MockRead http_reads[] = {
5493 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5494 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5495 MockRead(ASYNC, OK)};
5496
5497 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5498 socket_factory_.AddSocketDataProvider(&http_data);
5499 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5500
5501 CreateSession();
5502 AddQuicAlternateProtocolMapping(
5503 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5504 AddQuicAlternateProtocolMapping(
5505 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5506 request_.network_isolation_key = kNetworkIsolationKey1;
5507 SendRequestAndExpectHttpResponse("hello from http");
5508
5509 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5510 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5511}
5512
[email protected]1e960032013-12-20 19:00:205513TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595514 // Alternate-protocol job
5515 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025516 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595517 };
Ryan Sleevib8d7ea02018-05-07 20:01:015518 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595519 socket_factory_.AddSocketDataProvider(&quic_data);
5520
5521 // Main job which will succeed even though the alternate job fails.
5522 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025523 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5524 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5525 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595526
Ryan Sleevib8d7ea02018-05-07 20:01:015527 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595528 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565529 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595530
rch3f4b8452016-02-23 16:59:325531 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595532
Ryan Hamilton9835e662018-08-02 05:36:275533 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195534 SendRequestAndExpectHttpResponse("hello from http");
5535 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595536}
5537
[email protected]00c159f2014-05-21 22:38:165538TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535539 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165540 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025541 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165542 };
Ryan Sleevib8d7ea02018-05-07 20:01:015543 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165544 socket_factory_.AddSocketDataProvider(&quic_data);
5545
[email protected]eb71ab62014-05-23 07:57:535546 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165547 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025548 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165549 };
5550
Ryan Sleevib8d7ea02018-05-07 20:01:015551 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165552 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5553 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565554 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165555
rtennetib8e80fb2016-05-16 00:12:095556 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325557 CreateSession();
[email protected]00c159f2014-05-21 22:38:165558
Ryan Hamilton9835e662018-08-02 05:36:275559 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165560 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165561 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165562 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5564 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165565 ExpectQuicAlternateProtocolMapping();
5566}
5567
Zhongyi Shia0cef1082017-08-25 01:49:505568TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5569 // Tests that TCP job is delayed and QUIC job does not require confirmation
5570 // if QUIC was recently supported on the same IP on start.
5571
5572 // Set QUIC support on the last IP address, which is same with the local IP
5573 // address. Require confirmation mode will be turned off immediately when
5574 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435575 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5576 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:505577
Ryan Hamiltonabad59e2019-06-06 04:02:595578 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165579 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495580 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255581 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495582 mock_quic_data.AddWrite(SYNCHRONOUS,
5583 ConstructInitialSettingsPacket(packet_number++));
5584 }
Zhongyi Shi32f2fd02018-04-16 18:23:435585 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495586 SYNCHRONOUS,
5587 ConstructClientRequestHeadersPacket(
5588 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5589 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435590 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335591 ASYNC, ConstructServerResponseHeadersPacket(
5592 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5593 GetResponseHeaders("200 OK")));
5594 mock_quic_data.AddRead(
5595 ASYNC, ConstructServerDataPacket(
5596 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525597 ConstructDataFrame("hello!")));
Nick Harper1ccb0ce2020-10-07 00:28:585598 if (version_.UsesTls()) {
5599 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5600 }
Nick Harper057264a82019-09-12 23:33:495601 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345602 ConstructClientAckPacket(packet_number++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505603 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5604 mock_quic_data.AddRead(ASYNC, 0); // EOF
5605
5606 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5607 // No HTTP data is mocked as TCP job never starts in this case.
5608
5609 CreateSession();
5610 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:435611 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5612 false);
Zhongyi Shia0cef1082017-08-25 01:49:505613
Ryan Hamilton9835e662018-08-02 05:36:275614 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505615
5616 // Stall host resolution so that QUIC job will not succeed synchronously.
5617 // Socket will not be configured immediately and QUIC support is not sorted
5618 // out, TCP job will still be delayed as server properties indicates QUIC
5619 // support on last IP address.
5620 host_resolver_.set_synchronous_mode(false);
5621
5622 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5623 TestCompletionCallback callback;
5624 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5625 IsError(ERR_IO_PENDING));
5626 // Complete host resolution in next message loop so that QUIC job could
5627 // proceed.
5628 base::RunLoop().RunUntilIdle();
5629 EXPECT_THAT(callback.WaitForResult(), IsOk());
5630
5631 CheckWasQuicResponse(&trans);
5632 CheckResponseData(&trans, "hello!");
5633}
5634
5635TEST_P(QuicNetworkTransactionTest,
5636 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5637 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5638 // was recently supported on a different IP address on start.
5639
5640 // Set QUIC support on the last IP address, which is different with the local
5641 // IP address. Require confirmation mode will remain when local IP address is
5642 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435643 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5644 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:505645
Ryan Hamiltonabad59e2019-06-06 04:02:595646 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235647 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165648 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255649 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235650 mock_quic_data.AddWrite(SYNCHRONOUS,
5651 ConstructInitialSettingsPacket(packet_num++));
5652 }
Zhongyi Shi1c022d22020-03-20 19:00:165653 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:505654 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235655 SYNCHRONOUS,
5656 ConstructClientRequestHeadersPacket(
5657 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5658 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435659 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335660 ASYNC, ConstructServerResponseHeadersPacket(
5661 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5662 GetResponseHeaders("200 OK")));
5663 mock_quic_data.AddRead(
5664 ASYNC, ConstructServerDataPacket(
5665 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525666 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235667 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345668 ConstructClientAckPacket(packet_num++, 2, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505669 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5670 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5671 // No HTTP data is mocked as TCP job will be delayed and never starts.
5672
5673 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435674 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5675 false);
Ryan Hamilton9835e662018-08-02 05:36:275676 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505677
5678 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5679 // Socket will not be configured immediately and QUIC support is not sorted
5680 // out, TCP job will still be delayed as server properties indicates QUIC
5681 // support on last IP address.
5682 host_resolver_.set_synchronous_mode(false);
5683
5684 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5685 TestCompletionCallback callback;
5686 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5687 IsError(ERR_IO_PENDING));
5688
5689 // Complete host resolution in next message loop so that QUIC job could
5690 // proceed.
5691 base::RunLoop().RunUntilIdle();
5692 // Explicitly confirm the handshake so that QUIC job could succeed.
Fan Yang3673cc72020-02-07 14:49:285693 crypto_client_stream_factory_.last_stream()
5694 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia0cef1082017-08-25 01:49:505695 EXPECT_THAT(callback.WaitForResult(), IsOk());
5696
5697 CheckWasQuicResponse(&trans);
5698 CheckResponseData(&trans, "hello!");
5699}
5700
Ryan Hamilton75f197262017-08-17 14:00:075701TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5702 // Test that NetErrorDetails is correctly populated, even if the
5703 // handshake has not yet been confirmed and no stream has been created.
5704
5705 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595706 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075707 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5708 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5709 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5710
5711 // Main job will also fail.
5712 MockRead http_reads[] = {
5713 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5714 };
5715
Ryan Sleevib8d7ea02018-05-07 20:01:015716 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075717 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5718 socket_factory_.AddSocketDataProvider(&http_data);
5719 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5720
5721 AddHangingNonAlternateProtocolSocketData();
5722 CreateSession();
5723 // Require handshake confirmation to ensure that no QUIC streams are
5724 // created, and to ensure that the TCP job does not wait for the QUIC
5725 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:435726 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5727 false);
Ryan Hamilton75f197262017-08-17 14:00:075728
Ryan Hamilton9835e662018-08-02 05:36:275729 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5731 TestCompletionCallback callback;
5732 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5734 // Allow the TCP job to fail.
5735 base::RunLoop().RunUntilIdle();
5736 // Now let the QUIC job fail.
5737 mock_quic_data.Resume();
5738 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5739 ExpectQuicAlternateProtocolMapping();
5740 NetErrorDetails details;
5741 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525742 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075743}
5744
[email protected]1e960032013-12-20 19:00:205745TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455746 // Alternate-protocol job
5747 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025748 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455749 };
Ryan Sleevib8d7ea02018-05-07 20:01:015750 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455751 socket_factory_.AddSocketDataProvider(&quic_data);
5752
[email protected]c92c1b52014-05-31 04:16:065753 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015754 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065755 socket_factory_.AddSocketDataProvider(&quic_data2);
5756
[email protected]4d283b32013-10-17 12:57:275757 // Final job that will proceed when the QUIC job fails.
5758 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025759 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5760 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5761 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275762
Ryan Sleevib8d7ea02018-05-07 20:01:015763 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275764 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565765 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275766
rch3f4b8452016-02-23 16:59:325767 CreateSession();
[email protected]77c6c162013-08-17 02:57:455768
Ryan Hamilton9835e662018-08-02 05:36:275769 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455770
[email protected]4d283b32013-10-17 12:57:275771 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455772
5773 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275774
rch37de576c2015-05-17 20:28:175775 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5776 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455777}
5778
Matt Menkeb32ba5122019-09-10 19:17:055779TEST_P(QuicNetworkTransactionTest,
5780 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
5781 base::test::ScopedFeatureList feature_list;
5782 feature_list.InitWithFeatures(
5783 // enabled_features
5784 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5785 features::kPartitionConnectionsByNetworkIsolationKey},
5786 // disabled_features
5787 {});
5788 // Since HttpServerProperties caches the feature value, have to create a new
5789 // one.
5790 http_server_properties_ = std::make_unique<HttpServerProperties>();
5791
Matt Menke4807a9a2020-11-21 00:14:415792 const SchemefulSite kSite1(GURL("https://foo.test/"));
5793 const net::NetworkIsolationKey kNetworkIsolationKey1(kSite1, kSite1);
5794 const SchemefulSite kSite2(GURL("https://bar.test/"));
5795 const net::NetworkIsolationKey kNetworkIsolationKey2(kSite2, kSite2);
Matt Menkeb32ba5122019-09-10 19:17:055796
5797 // Alternate-protocol job
5798 MockRead quic_reads[] = {
5799 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5800 };
5801 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5802 socket_factory_.AddSocketDataProvider(&quic_data);
5803
5804 // Second Alternate-protocol job which will race with the TCP job.
5805 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
5806 socket_factory_.AddSocketDataProvider(&quic_data2);
5807
5808 // Final job that will proceed when the QUIC job fails.
5809 MockRead http_reads[] = {
5810 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5811 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5812 MockRead(ASYNC, OK)};
5813
5814 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5815 socket_factory_.AddSocketDataProvider(&http_data);
5816 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5817
5818 CreateSession();
5819
5820 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
5821 kNetworkIsolationKey1);
5822 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
5823 kNetworkIsolationKey2);
5824
5825 request_.network_isolation_key = kNetworkIsolationKey1;
5826 SendRequestAndExpectHttpResponse("hello from http");
5827 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5828 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
5829
5830 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5831 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5832
5833 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
5834 AddHttpDataAndRunRequest();
5835 // Requests using other NetworkIsolationKeys can still use QUIC.
5836 request_.network_isolation_key = kNetworkIsolationKey2;
5837 AddQuicDataAndRunRequest();
5838
5839 // The last two requests should not have changed the alternative service
5840 // mappings.
5841 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5842 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5843}
5844
[email protected]eb71ab62014-05-23 07:57:535845TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335846 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015847 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495848 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335849 socket_factory_.AddSocketDataProvider(&quic_data);
5850
5851 // Main job which will succeed even though the alternate job fails.
5852 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025853 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5854 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5855 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335856
Ryan Sleevib8d7ea02018-05-07 20:01:015857 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335858 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565859 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335860
rch3f4b8452016-02-23 16:59:325861 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275862 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335863 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535864
5865 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335866}
5867
[email protected]4fee9672014-01-08 14:47:155868TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltonabad59e2019-06-06 04:02:595869 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165870 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:175871 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045872 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155873
5874 // When the QUIC connection fails, we will try the request again over HTTP.
5875 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485876 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565877 MockRead("hello world"),
5878 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5879 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155880
Ryan Sleevib8d7ea02018-05-07 20:01:015881 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155882 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565883 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155884
5885 // In order for a new QUIC session to be established via alternate-protocol
5886 // without racing an HTTP connection, we need the host resolution to happen
5887 // synchronously.
5888 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295889 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565890 "");
[email protected]4fee9672014-01-08 14:47:155891
rch3f4b8452016-02-23 16:59:325892 CreateSession();
David Schinazic8281052019-01-24 06:14:175893 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5894 AddQuicAlternateProtocolMapping(
5895 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155896 SendRequestAndExpectHttpResponse("hello world");
5897}
5898
tbansalc3308d72016-08-27 10:25:045899TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltonabad59e2019-06-06 04:02:595900 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165901 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:175902 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335903 mock_quic_data.AddWrite(
5904 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5905 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5906 true, GetRequestHeaders("GET", "https", "/")));
Renjie Tangcd594f32020-07-11 20:18:345907 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1));
tbansalc3308d72016-08-27 10:25:045908 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5909
5910 // When the QUIC connection fails, we will try the request again over HTTP.
5911 MockRead http_reads[] = {
5912 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5913 MockRead("hello world"),
5914 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5915 MockRead(ASYNC, OK)};
5916
Ryan Sleevib8d7ea02018-05-07 20:01:015917 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045918 socket_factory_.AddSocketDataProvider(&http_data);
5919 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5920
5921 TestProxyDelegate test_proxy_delegate;
5922 const HostPortPair host_port_pair("myproxy.org", 443);
tbansalc3308d72016-08-27 10:25:045923
Nicolas Arciniegad2013f92020-02-07 23:00:565924 proxy_resolution_service_ =
5925 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Matt Menke7bc4def2020-07-29 20:54:515926 "QUIC myproxy.org:443; HTTPS myproxy.org:443",
5927 TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525928 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045929 request_.url = GURL("http://mail.example.org/");
5930
5931 // In order for a new QUIC session to be established via alternate-protocol
5932 // without racing an HTTP connection, we need the host resolution to happen
5933 // synchronously.
5934 host_resolver_.set_synchronous_mode(true);
5935 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045936
5937 CreateSession();
David Schinazic8281052019-01-24 06:14:175938 crypto_client_stream_factory_.set_handshake_mode(
5939 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045940 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595941 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165942 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045943}
5944
bnc508835902015-05-12 20:10:295945TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
Zhongyi Shi1c022d22020-03-20 19:00:165946 client_maker_->set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385947 EXPECT_FALSE(
5948 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:595949 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235950 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255951 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235952 mock_quic_data.AddWrite(SYNCHRONOUS,
5953 ConstructInitialSettingsPacket(packet_num++));
5954 }
rch5cb522462017-04-25 20:18:365955 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235956 SYNCHRONOUS,
5957 ConstructClientRequestHeadersPacket(
5958 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5959 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435960 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335961 ASYNC, ConstructServerResponseHeadersPacket(
5962 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5963 GetResponseHeaders("200 OK")));
5964 mock_quic_data.AddRead(
5965 ASYNC, ConstructServerDataPacket(
5966 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:525967 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:235968 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:345969 ConstructClientAckPacket(packet_num++, 2, 1));
rchb27683c2015-07-29 23:53:505970 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295971 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5972
bncb07c05532015-05-14 19:07:205973 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095974 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325975 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275976 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295977 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385978 EXPECT_TRUE(
5979 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295980}
5981
rtenneti56977812016-01-15 19:26:565982TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Victor Vasilieva1e66d72019-12-05 17:55:385983 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575984 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565985
Renjie Tangaadb84b2019-08-31 01:00:235986 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:255987 if (!VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:235988 mock_quic_data.AddRead(SYNCHRONOUS, OK);
5989 else
5990 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5991 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5992 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5993
5994 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5995 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
5996 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:015997 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:235998 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:565999
rtennetib8e80fb2016-05-16 00:12:096000 // The non-alternate protocol job needs to hang in order to guarantee that
6001 // the alternate-protocol job will "win".
6002 AddHangingNonAlternateProtocolSocketData();
6003
rtenneti56977812016-01-15 19:26:566004 CreateSession();
6005 request_.method = "POST";
6006 ChunkedUploadDataStream upload_data(0);
6007 upload_data.AppendData("1", 1, true);
6008
6009 request_.upload_data_stream = &upload_data;
6010
bnc691fda62016-08-12 00:43:166011 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566012 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166013 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566015 EXPECT_NE(OK, callback.WaitForResult());
6016}
6017
rche11300ef2016-09-02 01:44:286018TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Victor Vasilieva1e66d72019-12-05 17:55:386019 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286020 ScopedMockNetworkChangeNotifier network_change_notifier;
6021 MockNetworkChangeNotifier* mock_ncn =
6022 network_change_notifier.mock_network_change_notifier();
6023 mock_ncn->ForceNetworkHandlesSupported();
6024 mock_ncn->SetConnectedNetworksList(
6025 {kDefaultNetworkForTests, kNewNetworkForTests});
6026
Victor Vasilieva1e66d72019-12-05 17:55:386027 context_.params()->origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286028 HostPortPair::FromString("mail.example.org:443"));
Victor Vasilieva1e66d72019-12-05 17:55:386029 context_.params()->migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286030
Ryan Hamiltonabad59e2019-06-06 04:02:596031 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286032 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236033 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256034 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236035 socket_data.AddWrite(SYNCHRONOUS,
6036 ConstructInitialSettingsPacket(packet_num++));
6037 }
Fan Yang32c5a112018-12-10 20:06:336038 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236039 SYNCHRONOUS,
6040 ConstructClientRequestHeadersPacket(
6041 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6042 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:286043 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6044 socket_data.AddSocketDataToFactory(&socket_factory_);
6045
Ryan Hamiltonabad59e2019-06-06 04:02:596046 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286047 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6048 socket_data2.AddSocketDataToFactory(&socket_factory_);
6049
6050 // The non-alternate protocol job needs to hang in order to guarantee that
6051 // the alternate-protocol job will "win".
6052 AddHangingNonAlternateProtocolSocketData();
6053
6054 CreateSession();
6055 request_.method = "POST";
6056 ChunkedUploadDataStream upload_data(0);
6057
6058 request_.upload_data_stream = &upload_data;
6059
rdsmith1d343be52016-10-21 20:37:506060 std::unique_ptr<HttpNetworkTransaction> trans(
6061 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286062 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506063 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286064 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6065
6066 base::RunLoop().RunUntilIdle();
6067 upload_data.AppendData("1", 1, true);
6068 base::RunLoop().RunUntilIdle();
6069
6070 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506071 trans.reset();
rche11300ef2016-09-02 01:44:286072 session_.reset();
6073}
6074
Ryan Hamilton4b3574532017-10-30 20:17:256075TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386076 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256077 HostPortPair::FromString("mail.example.org:443"));
6078
Ryan Hamiltonabad59e2019-06-06 04:02:596079 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236080 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256081 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236082 socket_data.AddWrite(SYNCHRONOUS,
6083 ConstructInitialSettingsPacket(packet_num++));
6084 }
Ryan Hamilton4b3574532017-10-30 20:17:256085 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336086 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236087 SYNCHRONOUS,
6088 ConstructClientRequestHeadersPacket(
6089 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6090 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436091 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336092 ASYNC, ConstructServerResponseHeadersPacket(
6093 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6094 GetResponseHeaders("200 OK")));
6095 socket_data.AddRead(
6096 ASYNC, ConstructServerDataPacket(
6097 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526098 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:236099 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346100 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256101 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi1c022d22020-03-20 19:00:166102 socket_data.AddWrite(SYNCHRONOUS,
6103 client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:346104 packet_num++, false, 2, 1,
Zhongyi Shi1c022d22020-03-20 19:00:166105 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256106
6107 socket_data.AddSocketDataToFactory(&socket_factory_);
6108
6109 CreateSession();
6110
6111 SendRequestAndExpectQuicResponse("hello!");
6112 session_.reset();
6113}
6114
6115TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386116 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256117 HostPortPair::FromString("mail.example.org:443"));
6118
Ryan Hamiltonabad59e2019-06-06 04:02:596119 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236120 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256121 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236122 socket_data.AddWrite(SYNCHRONOUS,
6123 ConstructInitialSettingsPacket(packet_num++));
6124 }
Ryan Hamilton4b3574532017-10-30 20:17:256125 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336126 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236127 SYNCHRONOUS,
6128 ConstructClientRequestHeadersPacket(
6129 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6130 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436131 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336132 ASYNC, ConstructServerResponseHeadersPacket(
6133 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6134 GetResponseHeaders("200 OK")));
6135 socket_data.AddRead(
6136 ASYNC, ConstructServerDataPacket(
6137 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526138 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:236139 socket_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346140 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256141 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi1c022d22020-03-20 19:00:166142 socket_data.AddWrite(SYNCHRONOUS,
6143 client_maker_->MakeAckAndConnectionClosePacket(
Renjie Tangcd594f32020-07-11 20:18:346144 packet_num++, false, 2, 1,
Zhongyi Shi1c022d22020-03-20 19:00:166145 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256146
6147 socket_data.AddSocketDataToFactory(&socket_factory_);
6148
6149 CreateSession();
6150
6151 SendRequestAndExpectQuicResponse("hello!");
6152 session_.reset();
6153}
6154
Ryan Hamilton9edcf1a2017-11-22 05:55:176155TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386156 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6157 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256158 HostPortPair::FromString("mail.example.org:443"));
6159
Ryan Hamiltonabad59e2019-06-06 04:02:596160 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256161 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256162 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236163 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176164 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256165 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6166 }
6167 socket_data.AddSocketDataToFactory(&socket_factory_);
6168
6169 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176170 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176171 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6172 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256173
Victor Vasiliev7752898d2019-11-14 21:30:226174 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256175 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6176 TestCompletionCallback callback;
6177 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6178 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176179 while (!callback.have_result()) {
6180 base::RunLoop().RunUntilIdle();
6181 quic_task_runner_->RunUntilIdle();
6182 }
6183 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256184 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176185 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6186 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6187 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226188 EXPECT_TRUE(context_.clock()->Now() - start >
6189 quic::QuicTime::Delta::FromSeconds(4));
6190 EXPECT_TRUE(context_.clock()->Now() - start <
6191 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256192}
6193
Ryan Hamilton9edcf1a2017-11-22 05:55:176194TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386195 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6196 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256197 HostPortPair::FromString("mail.example.org:443"));
6198
Ryan Hamiltonabad59e2019-06-06 04:02:596199 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256200 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256201 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236202 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176203 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256204 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6205 }
6206 socket_data.AddSocketDataToFactory(&socket_factory_);
6207
6208 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176209 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176210 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6211 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256212
Victor Vasiliev7752898d2019-11-14 21:30:226213 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256214 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6215 TestCompletionCallback callback;
6216 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6217 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176218 while (!callback.have_result()) {
6219 base::RunLoop().RunUntilIdle();
6220 quic_task_runner_->RunUntilIdle();
6221 }
6222 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256223 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176224 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6225 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6226 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226227 EXPECT_TRUE(context_.clock()->Now() - start >
6228 quic::QuicTime::Delta::FromSeconds(4));
6229 EXPECT_TRUE(context_.clock()->Now() - start <
6230 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256231}
6232
Cherie Shi7596de632018-02-22 07:28:186233TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Victor Vasilieva1e66d72019-12-05 17:55:386234 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6235 context_.params()->origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186236 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev62c09dc2020-11-06 18:18:296237 const std::string error_details = base::StrCat(
6238 {"Write failed with error: ", base::NumberToString(ERR_MSG_TOO_BIG), " (",
6239 strerror(ERR_MSG_TOO_BIG), ")"});
Cherie Shi7596de632018-02-22 07:28:186240
Ryan Hamiltonabad59e2019-06-06 04:02:596241 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186242 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236243 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256244 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236245 socket_data.AddWrite(SYNCHRONOUS,
6246 ConstructInitialSettingsPacket(packet_num++));
6247 }
Cherie Shi7596de632018-02-22 07:28:186248 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6249 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526250 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236251 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:166252 client_maker_->MakeConnectionClosePacket(
Renjie Tangaadb84b2019-08-31 01:00:236253 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186254 socket_data.AddSocketDataToFactory(&socket_factory_);
6255
6256 CreateSession();
6257
6258 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6259 TestCompletionCallback callback;
6260 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6261 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6262 base::RunLoop().RunUntilIdle();
6263 ASSERT_TRUE(callback.have_result());
6264 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6265 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6266 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6267}
6268
ckrasic769733c2016-06-30 00:42:136269// Adds coverage to catch regression such as https://crbug.com/622043
6270TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Zhongyi Shi1c022d22020-03-20 19:00:166271 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
Ryan Hamilton6c6493102019-12-05 21:36:506272 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:386273 context_.params()->origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136274 HostPortPair::FromString("mail.example.org:443"));
6275
Ryan Hamiltonabad59e2019-06-06 04:02:596276 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236277 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:256278 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236279 mock_quic_data.AddWrite(
6280 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6281 }
Zhongyi Shi32f2fd02018-04-16 18:23:436282 mock_quic_data.AddWrite(
6283 SYNCHRONOUS,
6284 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336285 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026286 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436287 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:476288 ASYNC, ConstructServerPushPromisePacket(
6289 1, GetNthClientInitiatedBidirectionalStreamId(0),
6290 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6291 GetRequestHeaders("GET", "https", "/pushed.jpg")));
Haoyue Wang9d70d65c2020-05-29 22:45:346292 const bool should_send_priority_packet =
6293 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:346294 !VersionUsesHttp3(version_.transport_version);
6295 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346296 mock_quic_data.AddWrite(
6297 SYNCHRONOUS,
6298 ConstructClientAckAndPriorityPacket(
6299 client_packet_number++, false,
6300 /*largest_received=*/1, /*smallest_received=*/1,
6301 GetNthServerInitiatedUnidirectionalStreamId(0),
6302 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576303 }
Zhongyi Shi32f2fd02018-04-16 18:23:436304 mock_quic_data.AddRead(
6305 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336306 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026307 GetResponseHeaders("200 OK")));
Fan Yang32d79502020-06-24 22:36:006308 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346309 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346310 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346311 }
Zhongyi Shi32f2fd02018-04-16 18:23:436312 mock_quic_data.AddRead(
6313 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336314 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026315 false, GetResponseHeaders("200 OK")));
Fan Yang32d79502020-06-24 22:36:006316 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346317 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346318 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346319 }
Zhongyi Shi32f2fd02018-04-16 18:23:436320 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336321 ASYNC, ConstructServerDataPacket(
6322 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526323 ConstructDataFrame("hello!")));
Fan Yang32d79502020-06-24 22:36:006324 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346325 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346326 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:346327 }
Zhongyi Shi32f2fd02018-04-16 18:23:436328 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336329 ASYNC, ConstructServerDataPacket(
6330 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526331 ConstructDataFrame("and hello!")));
Fan Yang32d79502020-06-24 22:36:006332 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346333 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346334 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:346335 }
Renjie Tangee921d12020-02-06 00:41:496336 if (!VersionUsesHttp3(version_.transport_version)) {
6337 mock_quic_data.AddWrite(SYNCHRONOUS,
6338 ConstructClientAckAndRstPacket(
6339 client_packet_number++,
6340 GetNthServerInitiatedUnidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:346341 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
Renjie Tangee921d12020-02-06 00:41:496342 } else {
6343 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:166344 SYNCHRONOUS, client_maker_->MakeAckAndPriorityUpdatePacket(
Renjie Tangcd594f32020-07-11 20:18:346345 client_packet_number++, true, 5, 5, 3,
Renjie Tangee921d12020-02-06 00:41:496346 GetNthServerInitiatedUnidirectionalStreamId(0)));
6347 }
ckrasic769733c2016-06-30 00:42:136348 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6349 mock_quic_data.AddRead(ASYNC, 0); // EOF
6350 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6351
6352 // The non-alternate protocol job needs to hang in order to guarantee that
6353 // the alternate-protocol job will "win".
6354 AddHangingNonAlternateProtocolSocketData();
6355
6356 CreateSession();
6357
6358 // PUSH_PROMISE handling in the http layer gets exercised here.
6359 SendRequestAndExpectQuicResponse("hello!");
6360
6361 request_.url = GURL("https://mail.example.org/pushed.jpg");
6362 SendRequestAndExpectQuicResponse("and hello!");
6363
6364 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:546365 auto entries = net_log_.GetEntries();
ckrasic769733c2016-06-30 00:42:136366 EXPECT_LT(0u, entries.size());
6367
6368 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6369 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006370 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6371 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136372 EXPECT_LT(0, pos);
6373}
6374
Matt Menked804aaf2020-07-21 21:25:486375// Checks that if the same resource is pushed using two different
6376// NetworkIsolationKeys, both pushed resources are tracked independently, and
6377// NetworkIsolationKeys are respected.
6378TEST_P(QuicNetworkTransactionTest, QuicServerPushRespectsNetworkIsolationKey) {
6379 base::test::ScopedFeatureList feature_list;
6380 feature_list.InitAndEnableFeature(
6381 features::kPartitionConnectionsByNetworkIsolationKey);
6382 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
6383 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
6384 context_.params()->origins_to_force_quic_on.insert(
6385 HostPortPair::FromString("mail.example.org:443"));
6386
6387 MockQuicData mock_quic_data1(version_);
6388 uint64_t client_packet_number1 = 1;
6389 if (VersionUsesHttp3(version_.transport_version)) {
6390 mock_quic_data1.AddWrite(
6391 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number1++));
6392 }
6393 mock_quic_data1.AddWrite(
6394 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6395 client_packet_number1++,
6396 GetNthClientInitiatedBidirectionalStreamId(0), true,
6397 true, GetRequestHeaders("GET", "https", "/")));
6398 mock_quic_data1.AddRead(
6399 ASYNC, ConstructServerPushPromisePacket(
6400 1, GetNthClientInitiatedBidirectionalStreamId(0),
6401 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6402 GetRequestHeaders("GET", "https", "/pushed.jpg")));
6403 const bool should_send_priority_packet =
6404 client_headers_include_h2_stream_dependency_ &&
6405 !VersionUsesHttp3(version_.transport_version);
6406 if (should_send_priority_packet) {
6407 mock_quic_data1.AddWrite(
6408 SYNCHRONOUS,
6409 ConstructClientAckAndPriorityPacket(
6410 client_packet_number1++, false,
6411 /*largest_received=*/1, /*smallest_received=*/1,
6412 GetNthServerInitiatedUnidirectionalStreamId(0),
6413 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
6414 }
6415 mock_quic_data1.AddRead(
6416 ASYNC, ConstructServerResponseHeadersPacket(
6417 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6418 GetResponseHeaders("200 OK")));
6419 if (!should_send_priority_packet) {
6420 mock_quic_data1.AddWrite(
6421 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 2, 1));
6422 }
6423 mock_quic_data1.AddRead(
6424 ASYNC, ConstructServerResponseHeadersPacket(
6425 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6426 false, GetResponseHeaders("200 OK")));
6427 if (should_send_priority_packet) {
6428 mock_quic_data1.AddWrite(
6429 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 3, 1));
6430 }
Matt Menked804aaf2020-07-21 21:25:486431 mock_quic_data1.AddRead(
6432 ASYNC, ConstructServerDataPacket(
6433 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526434 ConstructDataFrame("hello1")));
Matt Menked804aaf2020-07-21 21:25:486435 if (!should_send_priority_packet) {
6436 mock_quic_data1.AddWrite(
6437 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 4, 3));
6438 }
Matt Menked804aaf2020-07-21 21:25:486439 mock_quic_data1.AddRead(
6440 ASYNC, ConstructServerDataPacket(
6441 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526442 ConstructDataFrame("and hello1")));
Matt Menked804aaf2020-07-21 21:25:486443 if (should_send_priority_packet) {
6444 mock_quic_data1.AddWrite(
6445 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number1++, 5, 3));
6446 }
6447 if (!VersionUsesHttp3(version_.transport_version)) {
6448 mock_quic_data1.AddWrite(SYNCHRONOUS,
6449 ConstructClientAckAndRstPacket(
6450 client_packet_number1++,
6451 GetNthServerInitiatedUnidirectionalStreamId(0),
6452 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
6453 } else {
6454 mock_quic_data1.AddWrite(
6455 SYNCHRONOUS, client_maker_->MakeAckAndPriorityUpdatePacket(
6456 client_packet_number1++, true, 5, 5, 3,
6457 GetNthServerInitiatedUnidirectionalStreamId(0)));
6458 }
6459 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6460 mock_quic_data1.AddRead(ASYNC, 0); // EOF
6461 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
6462
6463 QuicTestPacketMaker client_maker2(
6464 version_,
6465 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
6466 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
6467 client_headers_include_h2_stream_dependency_);
6468 client_maker2.set_max_allowed_push_id(quic::kMaxQuicStreamId);
6469 QuicTestPacketMaker server_maker2(
6470 version_,
6471 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
6472 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
6473 false);
6474 MockQuicData mock_quic_data2(version_);
6475 uint64_t client_packet_number2 = 1;
6476 if (VersionUsesHttp3(version_.transport_version)) {
6477 mock_quic_data2.AddWrite(
6478 SYNCHRONOUS,
6479 client_maker2.MakeInitialSettingsPacket(client_packet_number2++));
6480 }
6481 mock_quic_data2.AddWrite(
6482 SYNCHRONOUS,
6483 client_maker2.MakeRequestHeadersPacket(
6484 client_packet_number2++,
6485 GetNthClientInitiatedBidirectionalStreamId(0), true, true,
6486 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
6487 GetRequestHeaders("GET", "https", "/"), 0, nullptr));
6488 mock_quic_data2.AddRead(
6489 ASYNC, server_maker2.MakePushPromisePacket(
6490 1, GetNthClientInitiatedBidirectionalStreamId(0),
6491 GetNthServerInitiatedUnidirectionalStreamId(0), false, false,
6492 GetRequestHeaders("GET", "https", "/pushed.jpg"), nullptr));
6493 if (should_send_priority_packet) {
6494 mock_quic_data2.AddWrite(
6495 SYNCHRONOUS,
6496 client_maker2.MakeAckAndPriorityPacket(
6497 client_packet_number2++, false,
6498 /*largest_received=*/1, /*smallest_received=*/1,
6499 GetNthServerInitiatedUnidirectionalStreamId(0),
6500 GetNthClientInitiatedBidirectionalStreamId(0),
6501 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)));
6502 }
6503 mock_quic_data2.AddRead(
6504 ASYNC, server_maker2.MakeResponseHeadersPacket(
6505 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6506 GetResponseHeaders("200 OK"), nullptr));
6507 if (!should_send_priority_packet) {
6508 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6509 client_packet_number2++, 2, 1));
6510 }
6511 mock_quic_data2.AddRead(
6512 ASYNC, server_maker2.MakeResponseHeadersPacket(
6513 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6514 false, GetResponseHeaders("200 OK"), nullptr));
6515 if (should_send_priority_packet) {
6516 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6517 client_packet_number2++, 3, 1));
6518 }
Matt Menked804aaf2020-07-21 21:25:486519 mock_quic_data2.AddRead(
6520 ASYNC, server_maker2.MakeDataPacket(
6521 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526522 ConstructDataFrame("hello2")));
Matt Menked804aaf2020-07-21 21:25:486523 if (!should_send_priority_packet) {
6524 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6525 client_packet_number2++, 4, 3));
6526 }
Matt Menked804aaf2020-07-21 21:25:486527 mock_quic_data2.AddRead(
6528 ASYNC, server_maker2.MakeDataPacket(
6529 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526530 ConstructDataFrame("and hello2")));
Matt Menked804aaf2020-07-21 21:25:486531 if (should_send_priority_packet) {
6532 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeAckPacket(
6533 client_packet_number2++, 5, 3));
6534 }
6535 if (!VersionUsesHttp3(version_.transport_version)) {
6536 mock_quic_data2.AddWrite(SYNCHRONOUS,
6537 client_maker2.MakeAckAndRstPacket(
6538 client_packet_number2++, false,
6539 GetNthServerInitiatedUnidirectionalStreamId(0),
6540 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5));
6541 } else {
6542 mock_quic_data2.AddWrite(
6543 SYNCHRONOUS, client_maker2.MakeAckAndPriorityUpdatePacket(
6544 client_packet_number2++, true, 5, 5, 3,
6545 GetNthServerInitiatedUnidirectionalStreamId(0)));
6546 }
6547 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6548 mock_quic_data2.AddRead(ASYNC, 0); // EOF
6549 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
6550
6551 scoped_refptr<X509Certificate> cert(
6552 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
6553 verify_details_.cert_verify_result.verified_cert = cert;
6554 verify_details_.cert_verify_result.is_issued_by_known_root = true;
6555 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
6556
6557 // The non-alternate protocol jobs need to hang in order to guarantee that
6558 // the alternate-protocol job will "win". Use "AddTcpSocketDataProvider()", as
6559 // the connection requests may or may not actually make it to the socket
6560 // factory, there may or may not be a TCP connection made in between the two
6561 // QUIC connection attempts.
6562 StaticSocketDataProvider hanging_data1;
6563 hanging_data1.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
6564 socket_factory_.AddTcpSocketDataProvider(&hanging_data1);
6565 StaticSocketDataProvider hanging_data2;
6566 hanging_data2.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
6567 socket_factory_.AddTcpSocketDataProvider(&hanging_data2);
6568
6569 CreateSession();
6570
6571 NetworkIsolationKey network_isolation_key1 =
6572 NetworkIsolationKey::CreateTransient();
6573 NetworkIsolationKey network_isolation_key2 =
6574 NetworkIsolationKey::CreateTransient();
6575
6576 // Creates the first QUIC session, and triggers the first push.
6577 request_.network_isolation_key = network_isolation_key1;
6578 SendRequestAndExpectQuicResponse("hello1");
6579
6580 // Use a different NIK, which creates another QUIC session, triggering a
6581 // second push,
6582 request_.network_isolation_key = network_isolation_key2;
6583 SendRequestAndExpectQuicResponse("hello2");
6584
6585 // Use the second NIK again, should receive the push body from the second
6586 // session.
6587 request_.url = GURL("https://mail.example.org/pushed.jpg");
6588 SendRequestAndExpectQuicResponse("and hello2");
6589
6590 // Use the first NIK again, should receive the push body from the first
6591 // session.
6592 request_.network_isolation_key = network_isolation_key1;
6593 SendRequestAndExpectQuicResponse("and hello1");
6594}
6595
rch56ec40a2017-06-23 14:48:446596// Regression test for http://crbug.com/719461 in which a promised stream
6597// is closed before the pushed headers arrive, but after the connection
6598// is closed and before the callbacks are executed.
6599TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Zhongyi Shi1c022d22020-03-20 19:00:166600 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
Ryan Hamilton6c6493102019-12-05 21:36:506601 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:386602 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6603 context_.params()->origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446604 HostPortPair::FromString("mail.example.org:443"));
6605
Ryan Hamiltonabad59e2019-06-06 04:02:596606 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236607 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446608 // Initial SETTINGS frame.
Victor Vasiliev7da08172019-10-14 06:04:256609 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236610 mock_quic_data.AddWrite(
6611 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6612 }
rch56ec40a2017-06-23 14:48:446613 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436614 mock_quic_data.AddWrite(
6615 SYNCHRONOUS,
6616 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336617 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026618 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446619 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436620 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:476621 ASYNC, ConstructServerPushPromisePacket(
6622 1, GetNthClientInitiatedBidirectionalStreamId(0),
6623 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6624 GetRequestHeaders("GET", "https", "/pushed.jpg")));
Haoyue Wang9d70d65c2020-05-29 22:45:346625 const bool should_send_priority_packet =
6626 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:346627 !VersionUsesHttp3(version_.transport_version);
6628 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346629 mock_quic_data.AddWrite(
6630 SYNCHRONOUS,
6631 ConstructClientAckAndPriorityPacket(
6632 client_packet_number++, false,
6633 /*largest_received=*/1, /*smallest_received=*/1,
6634 GetNthServerInitiatedUnidirectionalStreamId(0),
6635 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576636 }
rch56ec40a2017-06-23 14:48:446637 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436638 mock_quic_data.AddRead(
6639 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336640 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026641 GetResponseHeaders("200 OK")));
Fan Yang32d79502020-06-24 22:36:006642 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346643 // Client ACKs the response headers.
6644 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346645 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346646 }
rch56ec40a2017-06-23 14:48:446647 // Response body for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436648 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336649 ASYNC, ConstructServerDataPacket(
6650 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526651 ConstructDataFrame("hello!")));
Fan Yang32d79502020-06-24 22:36:006652 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346653 // Client ACKs the response headers.
6654 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346655 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346656 }
rch56ec40a2017-06-23 14:48:446657 // Write error for the third request.
6658 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6659 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6660 mock_quic_data.AddRead(ASYNC, 0); // EOF
6661 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6662
6663 CreateSession();
6664
6665 // Send a request which triggers a push promise from the server.
6666 SendRequestAndExpectQuicResponse("hello!");
6667
6668 // Start a push transaction that will be cancelled after the connection
6669 // is closed, but before the callback is executed.
6670 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196671 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446672 session_.get());
6673 TestCompletionCallback callback2;
6674 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6676 base::RunLoop().RunUntilIdle();
6677
6678 // Cause the connection to close on a write error.
6679 HttpRequestInfo request3;
6680 request3.method = "GET";
6681 request3.url = GURL("https://mail.example.org/");
6682 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106683 request3.traffic_annotation =
6684 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446685 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6686 TestCompletionCallback callback3;
6687 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6688 IsError(ERR_IO_PENDING));
6689
6690 base::RunLoop().RunUntilIdle();
6691
6692 // When |trans2| is destroyed, the underlying stream will be closed.
6693 EXPECT_FALSE(callback2.have_result());
6694 trans2 = nullptr;
6695
6696 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6697}
6698
ckrasicda193a82016-07-09 00:39:366699TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Victor Vasilieva1e66d72019-12-05 17:55:386700 context_.params()->origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366701 HostPortPair::FromString("mail.example.org:443"));
6702
Ryan Hamiltonabad59e2019-06-06 04:02:596703 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:366704
Renjief49758b2019-01-11 23:32:416705 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:256706 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236707 mock_quic_data.AddWrite(
6708 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
6709 }
ckrasicda193a82016-07-09 00:39:366710
Bence Béky319388a882020-09-23 18:42:526711 mock_quic_data.AddWrite(
6712 SYNCHRONOUS,
6713 ConstructClientRequestHeadersAndDataFramesPacket(
6714 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6715 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
6716 0, nullptr, {ConstructDataFrame("1")}));
ckrasicda193a82016-07-09 00:39:366717
Zhongyi Shi32f2fd02018-04-16 18:23:436718 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336719 ASYNC, ConstructServerResponseHeadersPacket(
6720 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6721 GetResponseHeaders("200 OK")));
6722
6723 mock_quic_data.AddRead(
6724 ASYNC, ConstructServerDataPacket(
6725 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526726 ConstructDataFrame("hello!")));
ckrasicda193a82016-07-09 00:39:366727
Renjie Tangcd594f32020-07-11 20:18:346728 mock_quic_data.AddWrite(SYNCHRONOUS,
6729 ConstructClientAckPacket(write_packet_index++, 2, 1));
ckrasicda193a82016-07-09 00:39:366730
6731 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6732 mock_quic_data.AddRead(ASYNC, 0); // EOF
6733 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6734
6735 // The non-alternate protocol job needs to hang in order to guarantee that
6736 // the alternate-protocol job will "win".
6737 AddHangingNonAlternateProtocolSocketData();
6738
6739 CreateSession();
6740 request_.method = "POST";
6741 ChunkedUploadDataStream upload_data(0);
6742 upload_data.AppendData("1", 1, true);
6743
6744 request_.upload_data_stream = &upload_data;
6745
6746 SendRequestAndExpectQuicResponse("hello!");
6747}
6748
allada71b2efb2016-09-09 04:57:486749class QuicURLRequestContext : public URLRequestContext {
6750 public:
6751 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6752 MockClientSocketFactory* socket_factory)
6753 : storage_(this) {
6754 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076755 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046756 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486757 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046758 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596759 storage_.set_proxy_resolution_service(
Nicolas Arciniegad2013f92020-02-07 23:00:566760 ConfiguredProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076761 storage_.set_ssl_config_service(
6762 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486763 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:116764 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:486765 storage_.set_http_server_properties(
Matt Menke609160742019-08-02 18:47:266766 std::make_unique<HttpServerProperties>());
Matt Menkea9606a0eb2020-09-11 20:36:386767 storage_.set_job_factory(std::make_unique<URLRequestJobFactory>());
allada71b2efb2016-09-09 04:57:486768 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046769 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6770 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6771 false));
allada71b2efb2016-09-09 04:57:486772 }
6773
6774 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6775
6776 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6777
6778 private:
6779 MockClientSocketFactory* socket_factory_;
6780 URLRequestContextStorage storage_;
6781};
6782
6783TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
Victor Vasilieva1e66d72019-12-05 17:55:386784 context_.params()->origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486785 HostPortPair::FromString("mail.example.org:443"));
6786
Ryan Hamiltonabad59e2019-06-06 04:02:596787 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236788 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256789 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236790 mock_quic_data.AddWrite(SYNCHRONOUS,
6791 ConstructInitialSettingsPacket(packet_num++));
6792 }
Bence Béky4c325e52020-10-22 20:48:016793 spdy::Http2HeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486794 headers["user-agent"] = "";
6795 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336796 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236797 SYNCHRONOUS,
6798 ConstructClientRequestHeadersPacket(
6799 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6800 true, std::move(headers)));
allada71b2efb2016-09-09 04:57:486801
Fan Yang32c5a112018-12-10 20:06:336802 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026803 ASYNC, ConstructServerResponseHeadersPacket(
6804 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6805 GetResponseHeaders("200 OK")));
6806 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:456807 server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:256808 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:456809 ? GetNthClientInitiatedBidirectionalStreamId(0)
6810 : quic::QuicUtils::GetHeadersStreamId(
6811 version_.transport_version));
allada71b2efb2016-09-09 04:57:486812
ckrasicbf2f59c2017-05-04 23:54:366813 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336814 ASYNC, ConstructServerDataPacket(
6815 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176816 "Main Resource Data"));
Renjie Tangaadb84b2019-08-31 01:00:236817 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:346818 ConstructClientAckPacket(packet_num++, 2, 1));
allada71b2efb2016-09-09 04:57:486819
6820 mock_quic_data.AddRead(ASYNC, 0); // EOF
6821
6822 CreateSession();
6823
6824 TestDelegate delegate;
6825 QuicURLRequestContext quic_url_request_context(std::move(session_),
6826 &socket_factory_);
6827
6828 mock_quic_data.AddSocketDataToFactory(
6829 &quic_url_request_context.socket_factory());
6830 TestNetworkDelegate network_delegate;
6831 quic_url_request_context.set_network_delegate(&network_delegate);
6832
6833 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296834 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6835 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486836 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6837 &ssl_data_);
6838
6839 request->Start();
Wez2a31b222018-06-07 22:07:156840 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486841
6842 EXPECT_LT(0, request->GetTotalSentBytes());
6843 EXPECT_LT(0, request->GetTotalReceivedBytes());
allada71b2efb2016-09-09 04:57:486844 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6845 request->raw_header_size());
Wez0e717112018-06-18 23:09:226846
6847 // Pump the message loop to allow all data to be consumed.
6848 base::RunLoop().RunUntilIdle();
6849
allada71b2efb2016-09-09 04:57:486850 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6851 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6852}
6853
6854TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
Zhongyi Shi1c022d22020-03-20 19:00:166855 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
Ryan Hamilton6c6493102019-12-05 21:36:506856 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:386857 context_.params()->origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486858 HostPortPair::FromString("mail.example.org:443"));
6859
Ryan Hamiltonabad59e2019-06-06 04:02:596860 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236861 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:256862 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236863 mock_quic_data.AddWrite(
6864 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6865 }
Bence Béky4c325e52020-10-22 20:48:016866 spdy::Http2HeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486867 headers["user-agent"] = "";
6868 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436869 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336870 SYNCHRONOUS,
6871 ConstructClientRequestHeadersPacket(
6872 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026873 true, true, std::move(headers)));
allada71b2efb2016-09-09 04:57:486874
Fan Yang2330d182019-08-05 14:50:506875 const quic::QuicStreamOffset initial = server_maker_.stream_offset(
6876 GetNthClientInitiatedBidirectionalStreamId(0));
Zhongyi Shi32f2fd02018-04-16 18:23:436877 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:476878 ASYNC, ConstructServerPushPromisePacket(
6879 1, GetNthClientInitiatedBidirectionalStreamId(0),
6880 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6881 GetRequestHeaders("GET", "https", "/pushed.jpg")));
Fan Yang2330d182019-08-05 14:50:506882 quic::QuicStreamOffset push_promise_offset = 0;
Victor Vasiliev7da08172019-10-14 06:04:256883 if (VersionUsesHttp3(version_.transport_version)) {
Fan Yang2330d182019-08-05 14:50:506884 push_promise_offset = server_maker_.stream_offset(
6885 GetNthClientInitiatedBidirectionalStreamId(0)) -
6886 initial;
6887 }
allada71b2efb2016-09-09 04:57:486888
Haoyue Wang9d70d65c2020-05-29 22:45:346889 const bool should_send_priority_packet =
6890 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:346891 !VersionUsesHttp3(version_.transport_version);
6892 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346893 mock_quic_data.AddWrite(
6894 SYNCHRONOUS,
6895 ConstructClientAckAndPriorityPacket(
6896 client_packet_number++, false,
6897 /*largest_received=*/1, /*smallest_received=*/1,
6898 GetNthServerInitiatedUnidirectionalStreamId(0),
6899 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576900 }
6901
Ryan Hamiltone940bd12019-06-30 02:46:456902 const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:256903 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:456904 ? GetNthClientInitiatedBidirectionalStreamId(0)
6905 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Zhongyi Shi32f2fd02018-04-16 18:23:436906 mock_quic_data.AddRead(
6907 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336908 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026909 GetResponseHeaders("200 OK")));
Ryan Hamiltone940bd12019-06-30 02:46:456910 const quic::QuicStreamOffset final_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:256911 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:456912 ? GetNthClientInitiatedBidirectionalStreamId(0)
6913 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Ryan Hamilton0d65a8c2019-06-07 00:46:026914 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:456915 final_offset - initial_offset;
allada71b2efb2016-09-09 04:57:486916
Fan Yang32d79502020-06-24 22:36:006917 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346918 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346919 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346920 }
allada71b2efb2016-09-09 04:57:486921
ckrasicbf2f59c2017-05-04 23:54:366922 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436923 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336924 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026925 false, GetResponseHeaders("200 OK")));
Fan Yang32d79502020-06-24 22:36:006926 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346927 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346928 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:346929 }
Zhongyi Shi32f2fd02018-04-16 18:23:436930 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336931 ASYNC, ConstructServerDataPacket(
6932 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526933 ConstructDataFrame("Pushed Resource Data")));
allada71b2efb2016-09-09 04:57:486934
Fan Yang32d79502020-06-24 22:36:006935 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346936 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346937 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:346938 }
ckrasicbf2f59c2017-05-04 23:54:366939 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336940 ASYNC, ConstructServerDataPacket(
6941 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:526942 ConstructDataFrame("Main Resource Data")));
Fan Yang32d79502020-06-24 22:36:006943 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346944 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:346945 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:346946 }
allada71b2efb2016-09-09 04:57:486947
Zhongyi Shi32f2fd02018-04-16 18:23:436948 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486949
6950 CreateSession();
6951
6952 TestDelegate delegate;
6953 QuicURLRequestContext quic_url_request_context(std::move(session_),
6954 &socket_factory_);
6955
6956 mock_quic_data.AddSocketDataToFactory(
6957 &quic_url_request_context.socket_factory());
6958 TestNetworkDelegate network_delegate;
6959 quic_url_request_context.set_network_delegate(&network_delegate);
6960
6961 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296962 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6963 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486964 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6965 &ssl_data_);
6966
6967 request->Start();
Wez2a31b222018-06-07 22:07:156968 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486969
6970 EXPECT_LT(0, request->GetTotalSentBytes());
6971 EXPECT_LT(0, request->GetTotalReceivedBytes());
Fan Yang2330d182019-08-05 14:50:506972 EXPECT_EQ(
6973 static_cast<int>(expected_raw_header_response_size + push_promise_offset),
6974 request->raw_header_size());
Wez0e717112018-06-18 23:09:226975
6976 // Pump the message loop to allow all data to be consumed.
6977 base::RunLoop().RunUntilIdle();
6978
allada71b2efb2016-09-09 04:57:486979 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6980 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6981}
6982
Ryan Sleevia9d6aa62019-07-26 13:32:186983TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
6984 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:206985
6986 MockRead http_reads[] = {
6987 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6988 MockRead("hello world"),
6989 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6990 MockRead(ASYNC, OK)};
6991
Ryan Sleevib8d7ea02018-05-07 20:01:016992 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206993 socket_factory_.AddSocketDataProvider(&http_data);
6994 AddCertificate(&ssl_data_);
6995 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6996
Ryan Hamiltonabad59e2019-06-06 04:02:596997 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236998 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256999 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237000 mock_quic_data.AddWrite(SYNCHRONOUS,
7001 ConstructInitialSettingsPacket(packet_num++));
7002 }
Yixin Wang10f477ed2017-11-21 04:20:207003 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237004 SYNCHRONOUS,
7005 ConstructClientRequestHeadersPacket(
7006 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7007 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437008 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337009 ASYNC, ConstructServerResponseHeadersPacket(
7010 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7011 GetResponseHeaders("200 OK")));
7012 mock_quic_data.AddRead(
7013 ASYNC, ConstructServerDataPacket(
7014 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527015 ConstructDataFrame("hello!")));
Renjie Tangaadb84b2019-08-31 01:00:237016 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347017 ConstructClientAckPacket(packet_num++, 2, 1));
Yixin Wang10f477ed2017-11-21 04:20:207018 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7019 mock_quic_data.AddRead(ASYNC, 0); // EOF
7020
7021 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7022
7023 AddHangingNonAlternateProtocolSocketData();
7024 CreateSession();
7025
7026 SendRequestAndExpectHttpResponse("hello world");
7027 SendRequestAndExpectQuicResponse("hello!");
7028}
7029
Ryan Sleevia9d6aa62019-07-26 13:32:187030TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
7031 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:207032
7033 MockRead http_reads[] = {
7034 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7035 MockRead("hello world"),
7036 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7037 MockRead(ASYNC, OK)};
7038
Ryan Sleevib8d7ea02018-05-07 20:01:017039 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207040 socket_factory_.AddSocketDataProvider(&http_data);
7041 AddCertificate(&ssl_data_);
7042 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7043 socket_factory_.AddSocketDataProvider(&http_data);
7044 AddCertificate(&ssl_data_);
7045 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7046
7047 AddHangingNonAlternateProtocolSocketData();
7048 CreateSession();
7049
7050 SendRequestAndExpectHttpResponse("hello world");
7051 SendRequestAndExpectHttpResponse("hello world");
7052}
7053
bnc359ed2a2016-04-29 20:43:457054class QuicNetworkTransactionWithDestinationTest
7055 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:017056 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:057057 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:457058 protected:
7059 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:557060 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:057061 client_headers_include_h2_stream_dependency_(
7062 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:567063 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:457064 destination_type_(GetParam().destination_type),
bnc359ed2a2016-04-29 20:43:457065 ssl_config_service_(new SSLConfigServiceDefaults),
Nicolas Arciniegad2013f92020-02-07 23:00:567066 proxy_resolution_service_(
7067 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:117068 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Ryan Hamiltonf9a421f2020-01-31 21:09:527069 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:197070 FLAGS_quic_enable_http3_grease_randomness = false;
Ryan Hamiltonf9a421f2020-01-31 21:09:527071 }
bnc359ed2a2016-04-29 20:43:457072
7073 void SetUp() override {
7074 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557075 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457076
mmenke6ddfbea2017-05-31 21:48:417077 HttpNetworkSession::Params session_params;
7078 session_params.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:387079 context_.params()->allow_remote_alt_svc = true;
7080 context_.params()->supported_versions = supported_versions_;
7081 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:057082 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:417083
7084 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:457085
Victor Vasiliev7752898d2019-11-14 21:30:227086 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
bnc359ed2a2016-04-29 20:43:457087
7088 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277089 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:417090 session_context.quic_crypto_client_stream_factory =
7091 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:457092
Victor Vasiliev7752898d2019-11-14 21:30:227093 session_context.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:417094 session_context.client_socket_factory = &socket_factory_;
7095 session_context.host_resolver = &host_resolver_;
7096 session_context.cert_verifier = &cert_verifier_;
7097 session_context.transport_security_state = &transport_security_state_;
mmenke6ddfbea2017-05-31 21:48:417098 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
7099 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:457100 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:417101 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:597102 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:417103 session_context.http_auth_handler_factory = auth_handler_factory_.get();
7104 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:457105
mmenke6ddfbea2017-05-31 21:48:417106 session_.reset(new HttpNetworkSession(session_params, session_context));
Matt Menkeb566c392019-09-11 23:22:437107 session_->quic_stream_factory()
7108 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:457109 }
7110
7111 void TearDown() override {
7112 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7113 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557114 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457115 PlatformTest::TearDown();
7116 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557117 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:407118 session_.reset();
bnc359ed2a2016-04-29 20:43:457119 }
7120
zhongyie537a002017-06-27 16:48:217121 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:457122 HostPortPair destination;
7123 switch (destination_type_) {
7124 case SAME_AS_FIRST:
7125 destination = HostPortPair(origin1_, 443);
7126 break;
7127 case SAME_AS_SECOND:
7128 destination = HostPortPair(origin2_, 443);
7129 break;
7130 case DIFFERENT:
7131 destination = HostPortPair(kDifferentHostname, 443);
7132 break;
7133 }
bnc3472afd2016-11-17 15:27:217134 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:457135 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:217136 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:077137 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
7138 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:457139 }
7140
Ryan Hamilton8d9ee76e2018-05-29 23:52:527141 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237142 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527143 quic::QuicStreamId stream_id,
7144 bool should_include_version,
7145 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527146 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137147 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457148 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Bence Béky4c325e52020-10-22 20:48:017149 spdy::Http2HeaderBlock headers(
Ryan Hamilton0239aac2018-05-19 00:03:137150 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027151 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457152 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027153 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:457154 }
7155
Ryan Hamilton8d9ee76e2018-05-29 23:52:527156 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237157 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527158 quic::QuicStreamId stream_id,
7159 bool should_include_version,
7160 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587161 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:027162 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:457163 }
7164
Ryan Hamilton8d9ee76e2018-05-29 23:52:527165 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237166 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527167 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527168 QuicTestPacketMaker* maker) {
Bence Béky4c325e52020-10-22 20:48:017169 spdy::Http2HeaderBlock headers(maker->GetResponseHeaders("200 OK"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027170 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
7171 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:457172 }
7173
Ryan Hamilton8d9ee76e2018-05-29 23:52:527174 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237175 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527176 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457177 QuicTestPacketMaker* maker) {
Bence Béky319388a882020-09-23 18:42:527178 return maker->MakeDataPacket(
7179 packet_number, stream_id, false, true,
7180 ConstructDataFrameForVersion("hello", version_));
bnc359ed2a2016-04-29 20:43:457181 }
7182
Ryan Hamilton8d9ee76e2018-05-29 23:52:527183 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237184 uint64_t packet_number,
7185 uint64_t largest_received,
7186 uint64_t smallest_received,
bnc359ed2a2016-04-29 20:43:457187 QuicTestPacketMaker* maker) {
7188 return maker->MakeAckPacket(packet_number, largest_received,
Renjie Tangcd594f32020-07-11 20:18:347189 smallest_received);
bnc359ed2a2016-04-29 20:43:457190 }
7191
Ryan Hamilton8d9ee76e2018-05-29 23:52:527192 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237193 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:377194 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027195 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:377196 }
7197
bnc359ed2a2016-04-29 20:43:457198 void AddRefusedSocketData() {
7199 std::unique_ptr<StaticSocketDataProvider> refused_data(
7200 new StaticSocketDataProvider());
7201 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7202 refused_data->set_connect_data(refused_connect);
7203 socket_factory_.AddSocketDataProvider(refused_data.get());
7204 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7205 }
7206
7207 void AddHangingSocketData() {
7208 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7209 new StaticSocketDataProvider());
7210 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7211 hanging_data->set_connect_data(hanging_connect);
7212 socket_factory_.AddSocketDataProvider(hanging_data.get());
7213 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7214 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7215 }
7216
7217 bool AllDataConsumed() {
7218 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7219 if (!socket_data_ptr->AllReadDataConsumed() ||
7220 !socket_data_ptr->AllWriteDataConsumed()) {
7221 return false;
7222 }
7223 }
7224 return true;
7225 }
7226
7227 void SendRequestAndExpectQuicResponse(const std::string& host) {
7228 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7229 HttpRequestInfo request;
7230 std::string url("https://");
7231 url.append(host);
7232 request.url = GURL(url);
7233 request.load_flags = 0;
7234 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107235 request.traffic_annotation =
7236 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457237 TestCompletionCallback callback;
7238 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017239 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457240
7241 std::string response_data;
robpercival214763f2016-07-01 23:27:017242 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457243 EXPECT_EQ("hello", response_data);
7244
7245 const HttpResponseInfo* response = trans.GetResponseInfo();
7246 ASSERT_TRUE(response != nullptr);
7247 ASSERT_TRUE(response->headers.get() != nullptr);
7248 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7249 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527250 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:087251 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457252 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377253 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457254 }
7255
Fan Yang32c5a112018-12-10 20:06:337256 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567257 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7258 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367259 }
7260
Ryan Hamiltonf9a421f2020-01-31 21:09:527261 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Nick Harper23290b82019-05-02 00:02:567262 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057263 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567264 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457265 DestinationType destination_type_;
7266 std::string origin1_;
7267 std::string origin2_;
Victor Vasiliev7752898d2019-11-14 21:30:227268 MockQuicContext context_;
bnc359ed2a2016-04-29 20:43:457269 std::unique_ptr<HttpNetworkSession> session_;
7270 MockClientSocketFactory socket_factory_;
7271 MockHostResolver host_resolver_;
7272 MockCertVerifier cert_verifier_;
7273 TransportSecurityState transport_security_state_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237274 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457275 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077276 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:267277 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457278 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:267279 HttpServerProperties http_server_properties_;
Matt Muellerd9342e3a2019-11-26 01:41:147280 RecordingBoundTestNetLog net_log_;
bnc359ed2a2016-04-29 20:43:457281 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7282 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7283 static_socket_data_provider_vector_;
7284 SSLSocketDataProvider ssl_data_;
7285};
7286
Victor Costane635086f2019-01-27 05:20:307287INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7288 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:577289 ::testing::ValuesIn(GetPoolingTestParams()),
7290 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:457291
7292// A single QUIC request fails because the certificate does not match the origin
7293// hostname, regardless of whether it matches the alternative service hostname.
7294TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7295 if (destination_type_ == DIFFERENT)
7296 return;
7297
7298 GURL url("https://mail.example.com/");
7299 origin1_ = url.host();
7300
7301 // Not used for requests, but this provides a test case where the certificate
7302 // is valid for the hostname of the alternative service.
7303 origin2_ = "mail.example.org";
7304
zhongyie537a002017-06-27 16:48:217305 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457306
7307 scoped_refptr<X509Certificate> cert(
7308 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247309 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7310 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457311
7312 ProofVerifyDetailsChromium verify_details;
7313 verify_details.cert_verify_result.verified_cert = cert;
7314 verify_details.cert_verify_result.is_issued_by_known_root = true;
7315 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7316
Ryan Hamiltonabad59e2019-06-06 04:02:597317 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457318 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7319 mock_quic_data.AddRead(ASYNC, 0);
7320
7321 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7322
7323 AddRefusedSocketData();
7324
7325 HttpRequestInfo request;
7326 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107327 request.traffic_annotation =
7328 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457329
7330 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7331 TestCompletionCallback callback;
7332 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017333 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457334
7335 EXPECT_TRUE(AllDataConsumed());
7336}
7337
7338// First request opens QUIC session to alternative service. Second request
7339// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527340// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457341TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7342 origin1_ = "mail.example.org";
7343 origin2_ = "news.example.org";
7344
zhongyie537a002017-06-27 16:48:217345 SetQuicAlternativeService(origin1_);
7346 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457347
7348 scoped_refptr<X509Certificate> cert(
7349 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247350 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7351 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7352 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457353
7354 ProofVerifyDetailsChromium verify_details;
7355 verify_details.cert_verify_result.verified_cert = cert;
7356 verify_details.cert_verify_result.is_issued_by_known_root = true;
7357 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7358
Yixin Wang079ad542018-01-11 04:06:057359 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227360 version_,
7361 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7362 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057363 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177364 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227365 version_,
7366 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7367 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457368
Ryan Hamiltonabad59e2019-06-06 04:02:597369 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237370 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257371 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237372 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7373 packet_num++, &client_maker));
7374 }
Fan Yang32c5a112018-12-10 20:06:337375 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237376 SYNCHRONOUS,
7377 ConstructClientRequestHeadersPacket(
7378 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7379 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:027380 mock_quic_data.AddRead(
7381 ASYNC,
7382 ConstructServerResponseHeadersPacket(
7383 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437384 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337385 ASYNC,
7386 ConstructServerDataPacket(
7387 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237388 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347389 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457390
Yixin Wang079ad542018-01-11 04:06:057391 client_maker.set_hostname(origin2_);
7392 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457393
Zhongyi Shi32f2fd02018-04-16 18:23:437394 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027395 SYNCHRONOUS,
7396 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237397 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027398 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7399 mock_quic_data.AddRead(
7400 ASYNC,
7401 ConstructServerResponseHeadersPacket(
7402 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437403 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337404 ASYNC,
7405 ConstructServerDataPacket(
7406 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237407 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347408 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3, &client_maker));
bnc359ed2a2016-04-29 20:43:457409 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7410 mock_quic_data.AddRead(ASYNC, 0); // EOF
7411
7412 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7413
7414 AddHangingSocketData();
7415 AddHangingSocketData();
7416
Victor Vasiliev7752898d2019-11-14 21:30:227417 scoped_refptr<TestTaskRunner> quic_task_runner(
7418 new TestTaskRunner(context_.mock_clock()));
Fan Yangc9e00dc2018-10-09 14:17:567419 QuicStreamFactoryPeer::SetAlarmFactory(
7420 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097421 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Victor Vasiliev7752898d2019-11-14 21:30:227422 context_.clock()));
Fan Yangc9e00dc2018-10-09 14:17:567423
bnc359ed2a2016-04-29 20:43:457424 SendRequestAndExpectQuicResponse(origin1_);
7425 SendRequestAndExpectQuicResponse(origin2_);
7426
7427 EXPECT_TRUE(AllDataConsumed());
7428}
7429
7430// First request opens QUIC session to alternative service. Second request does
7431// not pool to it, even though destination matches, because certificate is not
7432// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527433// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457434TEST_P(QuicNetworkTransactionWithDestinationTest,
7435 DoNotPoolIfCertificateInvalid) {
7436 origin1_ = "news.example.org";
7437 origin2_ = "mail.example.com";
7438
zhongyie537a002017-06-27 16:48:217439 SetQuicAlternativeService(origin1_);
7440 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457441
7442 scoped_refptr<X509Certificate> cert1(
7443 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247444 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7445 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7446 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457447
7448 scoped_refptr<X509Certificate> cert2(
7449 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247450 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7451 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457452
7453 ProofVerifyDetailsChromium verify_details1;
7454 verify_details1.cert_verify_result.verified_cert = cert1;
7455 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7456 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7457
7458 ProofVerifyDetailsChromium verify_details2;
7459 verify_details2.cert_verify_result.verified_cert = cert2;
7460 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7461 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7462
Yixin Wang079ad542018-01-11 04:06:057463 QuicTestPacketMaker client_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227464 version_,
7465 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7466 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057467 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177468 QuicTestPacketMaker server_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227469 version_,
7470 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7471 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457472
Ryan Hamiltonabad59e2019-06-06 04:02:597473 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:237474 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257475 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237476 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7477 packet_num++, &client_maker1));
7478 }
Fan Yang32c5a112018-12-10 20:06:337479 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237480 SYNCHRONOUS,
7481 ConstructClientRequestHeadersPacket(
7482 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7483 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437484 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337485 ASYNC,
7486 ConstructServerResponseHeadersPacket(
7487 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437488 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337489 ASYNC,
7490 ConstructServerDataPacket(
7491 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437492 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237493 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347494 ConstructClientAckPacket(packet_num++, 2, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457495 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7496 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7497
7498 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7499
Yixin Wang079ad542018-01-11 04:06:057500 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227501 version_,
7502 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7503 context_.clock(), origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057504 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177505 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227506 version_,
7507 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7508 context_.clock(), origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457509
Ryan Hamiltonabad59e2019-06-06 04:02:597510 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:237511 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:257512 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237513 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7514 packet_num2++, &client_maker2));
7515 }
Fan Yang32c5a112018-12-10 20:06:337516 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237517 SYNCHRONOUS,
7518 ConstructClientRequestHeadersPacket(
7519 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7520 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437521 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337522 ASYNC,
7523 ConstructServerResponseHeadersPacket(
7524 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437525 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337526 ASYNC,
7527 ConstructServerDataPacket(
7528 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437529 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237530 SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347531 ConstructClientAckPacket(packet_num2++, 2, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457532 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7533 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7534
7535 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7536
bnc359ed2a2016-04-29 20:43:457537 SendRequestAndExpectQuicResponse(origin1_);
7538 SendRequestAndExpectQuicResponse(origin2_);
7539
7540 EXPECT_TRUE(AllDataConsumed());
7541}
7542
ckrasicdee37572017-04-06 22:42:277543// crbug.com/705109 - this confirms that matching request with a body
7544// triggers a crash (pre-fix).
7545TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Zhongyi Shi1c022d22020-03-20 19:00:167546 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
Ryan Hamilton6c6493102019-12-05 21:36:507547 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:387548 context_.params()->origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277549 HostPortPair::FromString("mail.example.org:443"));
7550
Ryan Hamiltonabad59e2019-06-06 04:02:597551 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237552 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257553 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237554 mock_quic_data.AddWrite(
7555 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7556 }
Zhongyi Shi32f2fd02018-04-16 18:23:437557 mock_quic_data.AddWrite(
7558 SYNCHRONOUS,
7559 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337560 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027561 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437562 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:477563 ASYNC, ConstructServerPushPromisePacket(
7564 1, GetNthClientInitiatedBidirectionalStreamId(0),
7565 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7566 GetRequestHeaders("GET", "https", "/pushed.jpg")));
Renjie Tang703fea92019-07-23 21:08:317567
Haoyue Wang9d70d65c2020-05-29 22:45:347568 const bool should_send_priority_packet =
7569 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:347570 !VersionUsesHttp3(version_.transport_version);
7571 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347572 mock_quic_data.AddWrite(
7573 SYNCHRONOUS,
7574 ConstructClientAckAndPriorityPacket(
7575 client_packet_number++, false,
7576 /*largest_received=*/1, /*smallest_received=*/1,
7577 GetNthServerInitiatedUnidirectionalStreamId(0),
7578 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577579 }
Zhongyi Shi32f2fd02018-04-16 18:23:437580 mock_quic_data.AddRead(
7581 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337582 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027583 GetResponseHeaders("200 OK")));
Fan Yang32d79502020-06-24 22:36:007584 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347585 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347586 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:347587 }
Zhongyi Shi32f2fd02018-04-16 18:23:437588 mock_quic_data.AddRead(
7589 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337590 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027591 false, GetResponseHeaders("200 OK")));
Fan Yang32d79502020-06-24 22:36:007592 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347593 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347594 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1));
Haoyue Wang9d70d65c2020-05-29 22:45:347595 }
Zhongyi Shi32f2fd02018-04-16 18:23:437596 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337597 ASYNC, ConstructServerDataPacket(
7598 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527599 ConstructDataFrame("hello!")));
Fan Yang32d79502020-06-24 22:36:007600 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347601 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347602 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:347603 }
Renjief49758b2019-01-11 23:32:417604
Zhongyi Shi32f2fd02018-04-16 18:23:437605 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337606 ASYNC, ConstructServerDataPacket(
7607 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527608 ConstructDataFrame("and hello!")));
Fan Yang32d79502020-06-24 22:36:007609 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347610 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347611 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3));
Haoyue Wang9d70d65c2020-05-29 22:45:347612 }
ckrasicdee37572017-04-06 22:42:277613
7614 // Because the matching request has a body, we will see the push
7615 // stream get cancelled, and the matching request go out on the
7616 // wire.
Fan Yang32d79502020-06-24 22:36:007617 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347618 mock_quic_data.AddWrite(
7619 SYNCHRONOUS,
7620 ConstructClientRstPacket(client_packet_number++,
7621 GetNthServerInitiatedUnidirectionalStreamId(0),
7622 quic::QUIC_STREAM_CANCELLED));
7623 } else {
7624 mock_quic_data.AddWrite(SYNCHRONOUS,
7625 ConstructClientAckAndRstPacket(
7626 client_packet_number++,
7627 GetNthServerInitiatedUnidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:347628 quic::QUIC_STREAM_CANCELLED, 5, 5));
Haoyue Wang9d70d65c2020-05-29 22:45:347629 }
Bence Béky319388a882020-09-23 18:42:527630 mock_quic_data.AddWrite(
7631 SYNCHRONOUS,
7632 ConstructClientRequestHeadersAndDataFramesPacket(
7633 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
7634 false, true, DEFAULT_PRIORITY,
7635 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7636 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7637 {ConstructDataFrame("1")}));
ckrasicdee37572017-04-06 22:42:277638
7639 // We see the same response as for the earlier pushed and cancelled
7640 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437641 mock_quic_data.AddRead(
7642 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337643 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027644 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:437645 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337646 ASYNC, ConstructServerDataPacket(
7647 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Bence Béky319388a882020-09-23 18:42:527648 ConstructDataFrame("and hello!")));
ckrasicdee37572017-04-06 22:42:277649
Yixin Wangb470bc882018-02-15 18:43:577650 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:347651 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6));
ckrasicdee37572017-04-06 22:42:277652 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7653 mock_quic_data.AddRead(ASYNC, 0); // EOF
7654 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7655
7656 // The non-alternate protocol job needs to hang in order to guarantee that
7657 // the alternate-protocol job will "win".
7658 AddHangingNonAlternateProtocolSocketData();
7659
7660 CreateSession();
7661
7662 // PUSH_PROMISE handling in the http layer gets exercised here.
7663 SendRequestAndExpectQuicResponse("hello!");
7664
7665 request_.url = GURL("https://mail.example.org/pushed.jpg");
7666 ChunkedUploadDataStream upload_data(0);
7667 upload_data.AppendData("1", 1, true);
7668 request_.upload_data_stream = &upload_data;
7669 SendRequestAndExpectQuicResponse("and hello!");
7670}
7671
Bence Béky7538a952018-02-01 16:59:527672// Regression test for https://crbug.com/797825: If pushed headers describe a
7673// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7674// not be called (otherwise a DCHECK fails).
7675TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Zhongyi Shi1c022d22020-03-20 19:00:167676 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
Ryan Hamilton6c6493102019-12-05 21:36:507677 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
7678
Bence Béky4c325e52020-10-22 20:48:017679 spdy::Http2HeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527680 pushed_request_headers[":authority"] = "";
7681 pushed_request_headers[":method"] = "GET";
7682 pushed_request_headers[":path"] = "/";
7683 pushed_request_headers[":scheme"] = "nosuchscheme";
7684
Victor Vasilieva1e66d72019-12-05 17:55:387685 context_.params()->origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:527686 HostPortPair::FromString("mail.example.org:443"));
7687
Ryan Hamiltonabad59e2019-06-06 04:02:597688 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:527689
Renjie Tangaadb84b2019-08-31 01:00:237690 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257691 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237692 mock_quic_data.AddWrite(SYNCHRONOUS,
7693 ConstructInitialSettingsPacket(packet_num++));
7694 }
Bence Béky7538a952018-02-01 16:59:527695 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237696 SYNCHRONOUS,
7697 ConstructClientRequestHeadersPacket(
7698 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7699 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:527700
Fan Yang32c5a112018-12-10 20:06:337701 mock_quic_data.AddRead(
7702 ASYNC, ConstructServerPushPromisePacket(
7703 1, GetNthClientInitiatedBidirectionalStreamId(0),
7704 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Renjie Tangb7afea82020-07-15 23:35:477705 std::move(pushed_request_headers)));
Renjie Tangcd594f32020-07-11 20:18:347706 mock_quic_data.AddWrite(
7707 SYNCHRONOUS,
7708 ConstructClientAckAndRstPacket(
7709 packet_num++, GetNthServerInitiatedUnidirectionalStreamId(0),
7710 quic::QUIC_INVALID_PROMISE_URL, 1, 1));
Bence Béky7538a952018-02-01 16:59:527711
Zhongyi Shi32f2fd02018-04-16 18:23:437712 mock_quic_data.AddRead(
7713 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337714 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027715 GetResponseHeaders("200 OK")));
Bence Béky7538a952018-02-01 16:59:527716
Zhongyi Shi32f2fd02018-04-16 18:23:437717 mock_quic_data.AddRead(
7718 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337719 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027720 false, GetResponseHeaders("200 OK")));
Renjie Tangcd594f32020-07-11 20:18:347721 mock_quic_data.AddWrite(SYNCHRONOUS,
7722 ConstructClientAckPacket(packet_num++, 3, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:437723 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337724 ASYNC, ConstructServerDataPacket(
7725 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:527726 ConstructDataFrame("hello!")));
Bence Béky7538a952018-02-01 16:59:527727
7728 mock_quic_data.AddRead(ASYNC, 0);
7729 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7730
7731 // The non-alternate protocol job needs to hang in order to guarantee that
7732 // the alternate-protocol job will "win".
7733 AddHangingNonAlternateProtocolSocketData();
7734
7735 CreateSession();
7736
7737 // PUSH_PROMISE handling in the http layer gets exercised here.
7738 SendRequestAndExpectQuicResponse("hello!");
7739
7740 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7741 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7742}
7743
Yixin Wang46a273ec302018-01-23 17:59:567744// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147745TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567746 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147747 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567748 proxy_resolution_service_ =
7749 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
7750 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567751
Ryan Hamiltonabad59e2019-06-06 04:02:597752 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237753 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257754 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237755 mock_quic_data.AddWrite(SYNCHRONOUS,
7756 ConstructInitialSettingsPacket(packet_num++));
7757 }
Fan Yang32c5a112018-12-10 20:06:337758 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237759 SYNCHRONOUS,
7760 ConstructClientRequestHeadersPacket(
7761 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:497762 false,
7763 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:577764 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:497765 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:237766 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337767 mock_quic_data.AddRead(
7768 ASYNC, ConstructServerResponseHeadersPacket(
7769 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7770 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567771
7772 const char get_request[] =
7773 "GET / HTTP/1.1\r\n"
7774 "Host: mail.example.org\r\n"
7775 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:527776 mock_quic_data.AddWrite(
7777 SYNCHRONOUS,
7778 ConstructClientAckAndDataPacket(
7779 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
7780 1, false, ConstructDataFrame(get_request)));
Renjief49758b2019-01-11 23:32:417781
Yixin Wang46a273ec302018-01-23 17:59:567782 const char get_response[] =
7783 "HTTP/1.1 200 OK\r\n"
7784 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437785 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337786 ASYNC, ConstructServerDataPacket(
7787 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527788 ConstructDataFrame(get_response)));
Fan Yang32c5a112018-12-10 20:06:337789 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417790 SYNCHRONOUS, ConstructServerDataPacket(
7791 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527792 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:237793 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347794 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:567795 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7796
Bence Béky6e243aa2019-12-13 19:01:077797 if (VersionUsesHttp3(version_.transport_version)) {
7798 mock_quic_data.AddWrite(
7799 SYNCHRONOUS, ConstructClientDataPacket(
7800 packet_num++, GetQpackDecoderStreamId(), true, false,
7801 StreamCancellationQpackDecoderInstruction(0)));
7802 }
7803
Yixin Wang46a273ec302018-01-23 17:59:567804 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417805 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237806 ConstructClientRstPacket(packet_num++,
7807 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417808 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567809
7810 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7811
7812 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7813
7814 CreateSession();
7815
7816 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097817 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567818 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567819 RunTransaction(&trans);
7820 CheckWasHttpResponse(&trans);
7821 CheckResponsePort(&trans, 70);
7822 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:567823 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7824
Cammie Smith Barnesbf91e2a2020-12-23 20:49:047825 // DNS aliases should be empty when using a proxy.
7826 EXPECT_TRUE(trans.GetResponseInfo()->dns_aliases.empty());
7827
Yixin Wang46a273ec302018-01-23 17:59:567828 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7829 // proxy socket to disconnect.
7830 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7831
7832 base::RunLoop().RunUntilIdle();
7833 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7834 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7835}
7836
7837// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147838TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567839 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147840 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567841 proxy_resolution_service_ =
7842 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
7843 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567844
Ryan Hamiltonabad59e2019-06-06 04:02:597845 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237846 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257847 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237848 mock_quic_data.AddWrite(SYNCHRONOUS,
7849 ConstructInitialSettingsPacket(packet_num++));
7850 }
Fan Yang32c5a112018-12-10 20:06:337851 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237852 SYNCHRONOUS,
7853 ConstructClientRequestHeadersPacket(
7854 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:497855 false,
7856 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:577857 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:497858 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:237859 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337860 mock_quic_data.AddRead(
7861 ASYNC, ConstructServerResponseHeadersPacket(
7862 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7863 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567864
7865 SpdyTestUtil spdy_util;
7866
Ryan Hamilton0239aac2018-05-19 00:03:137867 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567868 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:527869 mock_quic_data.AddWrite(
7870 SYNCHRONOUS,
7871 ConstructClientAckAndDataPacket(
7872 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
7873 1, false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Ryan Hamilton0239aac2018-05-19 00:03:137874 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567875 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:437876 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177877 ASYNC, ConstructServerDataPacket(
7878 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527879 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:567880
Ryan Hamilton0239aac2018-05-19 00:03:137881 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197882 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Zhongyi Shi32f2fd02018-04-16 18:23:437883 mock_quic_data.AddRead(
7884 SYNCHRONOUS,
7885 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337886 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527887 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Renjie Tangaadb84b2019-08-31 01:00:237888 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:347889 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:567890 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7891
Bence Béky6e243aa2019-12-13 19:01:077892 if (VersionUsesHttp3(version_.transport_version)) {
7893 mock_quic_data.AddWrite(
7894 SYNCHRONOUS, ConstructClientDataPacket(
7895 packet_num++, GetQpackDecoderStreamId(), true, false,
7896 StreamCancellationQpackDecoderInstruction(0)));
7897 }
7898
Yixin Wang46a273ec302018-01-23 17:59:567899 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437900 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237901 ConstructClientRstPacket(packet_num++,
7902 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417903 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567904
7905 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7906
7907 SSLSocketDataProvider ssl_data(ASYNC, OK);
7908 ssl_data.next_proto = kProtoHTTP2;
7909 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7910
7911 CreateSession();
7912
7913 request_.url = GURL("https://mail.example.org/");
7914 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:567915 RunTransaction(&trans);
7916 CheckWasSpdyResponse(&trans);
7917 CheckResponsePort(&trans, 70);
7918 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:567919 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7920
Wez0e717112018-06-18 23:09:227921 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7922 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567923 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7924
7925 base::RunLoop().RunUntilIdle();
7926 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7927 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7928}
7929
7930// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7931// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147932TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567933 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147934 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567935 proxy_resolution_service_ =
7936 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
7937 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567938
Ryan Hamiltonabad59e2019-06-06 04:02:597939 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:417940 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:257941 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237942 mock_quic_data.AddWrite(
7943 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7944 }
Fan Yang32c5a112018-12-10 20:06:337945 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417946 SYNCHRONOUS,
7947 ConstructClientRequestHeadersPacket(
7948 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangee921d12020-02-06 00:41:497949 true, false,
7950 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:577951 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:497952 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027953 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337954 mock_quic_data.AddRead(
7955 ASYNC, ConstructServerResponseHeadersPacket(
7956 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7957 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567958
Yixin Wang46a273ec302018-01-23 17:59:567959 const char get_request_1[] =
7960 "GET / HTTP/1.1\r\n"
7961 "Host: mail.example.org\r\n"
7962 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:527963 mock_quic_data.AddWrite(
7964 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7965 write_packet_index++, false,
7966 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
7967 false, ConstructDataFrame(get_request_1)));
Renjief49758b2019-01-11 23:32:417968
Yixin Wang46a273ec302018-01-23 17:59:567969 const char get_response_1[] =
7970 "HTTP/1.1 200 OK\r\n"
7971 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437972 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437973 ASYNC, ConstructServerDataPacket(
7974 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:527975 ConstructDataFrame(get_response_1)));
Yixin Wang46a273ec302018-01-23 17:59:567976
Fan Yang32c5a112018-12-10 20:06:337977 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177978 SYNCHRONOUS, ConstructServerDataPacket(
7979 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:527980 false, ConstructDataFrame("0123456789")));
Yixin Wang46a273ec302018-01-23 17:59:567981
Renjie Tangcd594f32020-07-11 20:18:347982 mock_quic_data.AddWrite(SYNCHRONOUS,
7983 ConstructClientAckPacket(write_packet_index++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:567984
7985 const char get_request_2[] =
7986 "GET /2 HTTP/1.1\r\n"
7987 "Host: mail.example.org\r\n"
7988 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:527989 mock_quic_data.AddWrite(
7990 SYNCHRONOUS,
7991 ConstructClientDataPacket(
7992 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7993 false, false, ConstructDataFrame(get_request_2)));
Yixin Wang46a273ec302018-01-23 17:59:567994
7995 const char get_response_2[] =
7996 "HTTP/1.1 200 OK\r\n"
7997 "Content-Length: 7\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437998 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437999 ASYNC, ConstructServerDataPacket(
8000 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:528001 ConstructDataFrame(get_response_2)));
Yixin Wang46a273ec302018-01-23 17:59:568002
Ryan Hamilton8d9ee76e2018-05-29 23:52:528003 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178004 SYNCHRONOUS, ConstructServerDataPacket(
8005 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:528006 false, ConstructDataFrame("0123456")));
Yixin Wang46a273ec302018-01-23 17:59:568007
Renjie Tangcd594f32020-07-11 20:18:348008 mock_quic_data.AddWrite(SYNCHRONOUS,
8009 ConstructClientAckPacket(write_packet_index++, 5, 4));
Yixin Wang46a273ec302018-01-23 17:59:568010 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8011
Bence Béky6e243aa2019-12-13 19:01:078012 if (VersionUsesHttp3(version_.transport_version)) {
8013 mock_quic_data.AddWrite(
8014 SYNCHRONOUS, ConstructClientDataPacket(
8015 write_packet_index++, GetQpackDecoderStreamId(), true,
8016 false, StreamCancellationQpackDecoderInstruction(0)));
8017 }
8018
Renjief49758b2019-01-11 23:32:418019 mock_quic_data.AddWrite(
8020 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418021 ConstructClientRstPacket(write_packet_index++,
8022 GetNthClientInitiatedBidirectionalStreamId(0),
8023 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568024
8025 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8026
8027 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8028
8029 CreateSession();
8030
8031 request_.url = GURL("https://mail.example.org/");
8032 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568033 RunTransaction(&trans_1);
8034 CheckWasHttpResponse(&trans_1);
8035 CheckResponsePort(&trans_1, 70);
8036 CheckResponseData(&trans_1, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568037 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8038
8039 request_.url = GURL("https://mail.example.org/2");
8040 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568041 RunTransaction(&trans_2);
8042 CheckWasHttpResponse(&trans_2);
8043 CheckResponsePort(&trans_2, 70);
8044 CheckResponseData(&trans_2, "0123456");
Yixin Wang46a273ec302018-01-23 17:59:568045 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8046
8047 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8048 // proxy socket to disconnect.
8049 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8050
8051 base::RunLoop().RunUntilIdle();
8052 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8053 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8054}
8055
8056// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
8057// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
8058// server is reused for the second request.
Bence Békyf6bb6b22020-04-17 20:22:118059TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:568060 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148061 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568062 proxy_resolution_service_ =
8063 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8064 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568065
Ryan Hamiltonabad59e2019-06-06 04:02:598066 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238067 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258068 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238069 mock_quic_data.AddWrite(SYNCHRONOUS,
8070 ConstructInitialSettingsPacket(packet_num++));
8071 }
Yixin Wang46a273ec302018-01-23 17:59:568072
8073 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:338074 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238075 SYNCHRONOUS,
8076 ConstructClientRequestHeadersPacket(
8077 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498078 false,
8079 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578080 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498081 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238082 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438083 mock_quic_data.AddRead(
8084 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338085 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028086 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568087
8088 // GET request, response, and data over QUIC tunnel for first request
8089 const char get_request[] =
8090 "GET / HTTP/1.1\r\n"
8091 "Host: mail.example.org\r\n"
8092 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:528093 mock_quic_data.AddWrite(
8094 SYNCHRONOUS,
8095 ConstructClientAckAndDataPacket(
8096 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0), 1,
8097 1, false, ConstructDataFrame(get_request)));
Renjief49758b2019-01-11 23:32:418098
Yixin Wang46a273ec302018-01-23 17:59:568099 const char get_response[] =
8100 "HTTP/1.1 200 OK\r\n"
8101 "Content-Length: 10\r\n\r\n";
8102 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338103 ASYNC, ConstructServerDataPacket(
8104 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Bence Béky319388a882020-09-23 18:42:528105 ConstructDataFrame(get_response)));
Fan Yang32c5a112018-12-10 20:06:338106 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418107 SYNCHRONOUS, ConstructServerDataPacket(
8108 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:528109 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238110 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348111 ConstructClientAckPacket(packet_num++, 3, 2));
Yixin Wang46a273ec302018-01-23 17:59:568112
8113 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438114 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238115 SYNCHRONOUS,
8116 ConstructClientRequestHeadersPacket(
8117 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Renjie Tangee921d12020-02-06 00:41:498118 false,
8119 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578120 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498121 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238122 ConnectRequestHeaders("different.example.org:443"),
8123 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438124 mock_quic_data.AddRead(
8125 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338126 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028127 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568128
8129 // GET request, response, and data over QUIC tunnel for second request
8130 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138131 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568132 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Bence Béky319388a882020-09-23 18:42:528133 mock_quic_data.AddWrite(
8134 SYNCHRONOUS,
8135 ConstructClientAckAndDataPacket(
8136 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 4,
8137 4, false, ConstructDataFrame({get_frame.data(), get_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:568138
Ryan Hamilton0239aac2018-05-19 00:03:138139 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568140 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:438141 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178142 ASYNC, ConstructServerDataPacket(
8143 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:528144 ConstructDataFrame({resp_frame.data(), resp_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:568145
Ryan Hamilton0239aac2018-05-19 00:03:138146 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198147 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Zhongyi Shi32f2fd02018-04-16 18:23:438148 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438149 ASYNC, ConstructServerDataPacket(
8150 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:528151 ConstructDataFrame({data_frame.data(), data_frame.size()})));
Yixin Wang46a273ec302018-01-23 17:59:568152
Renjie Tangaadb84b2019-08-31 01:00:238153 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348154 ConstructClientAckPacket(packet_num++, 6, 5));
Yixin Wang46a273ec302018-01-23 17:59:568155 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8156
Bence Béky6e243aa2019-12-13 19:01:078157 if (VersionUsesHttp3(version_.transport_version)) {
8158 mock_quic_data.AddWrite(
8159 SYNCHRONOUS, ConstructClientDataPacket(
8160 packet_num++, GetQpackDecoderStreamId(), true, false,
8161 StreamCancellationQpackDecoderInstruction(0)));
8162 }
8163
Yixin Wang46a273ec302018-01-23 17:59:568164 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418165 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238166 ConstructClientRstPacket(packet_num++,
8167 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418168 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:078169
8170 if (VersionUsesHttp3(version_.transport_version)) {
8171 mock_quic_data.AddWrite(
8172 SYNCHRONOUS, ConstructClientDataPacket(
8173 packet_num++, GetQpackDecoderStreamId(), true, false,
Bence Békyf6bb6b22020-04-17 20:22:118174 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078175 }
8176
Yixin Wang46a273ec302018-01-23 17:59:568177 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438178 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238179 ConstructClientRstPacket(packet_num++,
8180 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418181 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568182
8183 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8184
8185 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8186
8187 SSLSocketDataProvider ssl_data(ASYNC, OK);
8188 ssl_data.next_proto = kProtoHTTP2;
8189 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8190
8191 CreateSession();
8192
8193 request_.url = GURL("https://mail.example.org/");
8194 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568195 RunTransaction(&trans_1);
8196 CheckWasHttpResponse(&trans_1);
8197 CheckResponsePort(&trans_1, 70);
8198 CheckResponseData(&trans_1, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568199 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8200
8201 request_.url = GURL("https://different.example.org/");
8202 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568203 RunTransaction(&trans_2);
8204 CheckWasSpdyResponse(&trans_2);
8205 CheckResponsePort(&trans_2, 70);
8206 CheckResponseData(&trans_2, "0123456");
Yixin Wang46a273ec302018-01-23 17:59:568207 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8208
8209 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8210 // proxy socket to disconnect.
8211 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8212
8213 base::RunLoop().RunUntilIdle();
8214 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8215 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8216}
8217
8218// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148219TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568220 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148221 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568222 proxy_resolution_service_ =
8223 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8224 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568225
Ryan Hamiltonabad59e2019-06-06 04:02:598226 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238227 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258228 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238229 mock_quic_data.AddWrite(SYNCHRONOUS,
8230 ConstructInitialSettingsPacket(packet_num++));
8231 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:528232 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238233 SYNCHRONOUS,
8234 ConstructClientRequestHeadersPacket(
8235 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498236 false,
8237 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578238 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498239 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238240 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338241 mock_quic_data.AddRead(
8242 ASYNC, ConstructServerResponseHeadersPacket(
8243 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8244 GetResponseHeaders("500")));
8245 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:238246 mock_quic_data.AddWrite(
8247 SYNCHRONOUS,
8248 ConstructClientAckAndRstPacket(
8249 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:348250 quic::QUIC_STREAM_CANCELLED, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568251
8252 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8253
8254 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8255
8256 CreateSession();
8257
8258 request_.url = GURL("https://mail.example.org/");
8259 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568260 TestCompletionCallback callback;
8261 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8262 EXPECT_EQ(ERR_IO_PENDING, rv);
8263 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
Yixin Wang46a273ec302018-01-23 17:59:568264
8265 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8266 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8267}
8268
8269// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148270TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568271 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148272 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568273 proxy_resolution_service_ =
8274 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8275 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568276
Ryan Hamiltonabad59e2019-06-06 04:02:598277 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238278 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258279 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238280 mock_quic_data.AddWrite(SYNCHRONOUS,
8281 ConstructInitialSettingsPacket(packet_num++));
8282 }
Fan Yang32c5a112018-12-10 20:06:338283 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238284 SYNCHRONOUS,
8285 ConstructClientRequestHeadersPacket(
8286 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498287 false,
8288 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578289 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498290 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238291 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:568292 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8293
8294 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8295
8296 CreateSession();
8297
8298 request_.url = GURL("https://mail.example.org/");
8299 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568300 TestCompletionCallback callback;
8301 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8302 EXPECT_EQ(ERR_IO_PENDING, rv);
8303 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8304
8305 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8306 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8307}
8308
8309// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8310// host. Retries request and succeeds.
Bence Békyf6bb6b22020-04-17 20:22:118311TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568312 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148313 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568314 proxy_resolution_service_ =
8315 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8316 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568317
Ryan Hamiltonabad59e2019-06-06 04:02:598318 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238319 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258320 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238321 mock_quic_data.AddWrite(SYNCHRONOUS,
8322 ConstructInitialSettingsPacket(packet_num++));
8323 }
Fan Yang32c5a112018-12-10 20:06:338324 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238325 SYNCHRONOUS,
8326 ConstructClientRequestHeadersPacket(
8327 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498328 false,
8329 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578330 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498331 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238332 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438333 mock_quic_data.AddRead(
8334 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338335 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028336 GetResponseHeaders("200 OK")));
Bence Béky6e243aa2019-12-13 19:01:078337 if (VersionUsesHttp3(version_.transport_version)) {
8338 mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:348339 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8340 packet_num++, false, GetQpackDecoderStreamId(), 1, 1,
8341 false, StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:078342 mock_quic_data.AddWrite(
8343 SYNCHRONOUS,
8344 ConstructClientRstPacket(packet_num++,
8345 GetNthClientInitiatedBidirectionalStreamId(0),
8346 quic::QUIC_STREAM_CANCELLED));
8347 } else {
8348 mock_quic_data.AddWrite(
8349 SYNCHRONOUS,
8350 ConstructClientAckAndRstPacket(
8351 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangcd594f32020-07-11 20:18:348352 quic::QUIC_STREAM_CANCELLED, 1, 1));
Bence Béky6e243aa2019-12-13 19:01:078353 }
Yixin Wang46a273ec302018-01-23 17:59:568354
Zhongyi Shi32f2fd02018-04-16 18:23:438355 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238356 SYNCHRONOUS,
8357 ConstructClientRequestHeadersPacket(
8358 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Renjie Tangee921d12020-02-06 00:41:498359 false,
8360 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578361 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498362 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238363 ConnectRequestHeaders("mail.example.org:443"),
8364 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438365 mock_quic_data.AddRead(
8366 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338367 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028368 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568369
8370 const char get_request[] =
8371 "GET / HTTP/1.1\r\n"
8372 "Host: mail.example.org\r\n"
8373 "Connection: keep-alive\r\n\r\n";
Bence Béky319388a882020-09-23 18:42:528374 mock_quic_data.AddWrite(
8375 SYNCHRONOUS,
8376 ConstructClientAckAndDataPacket(
8377 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1), 2,
8378 2, false, ConstructDataFrame(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:568379 const char get_response[] =
8380 "HTTP/1.1 200 OK\r\n"
8381 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:438382 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338383 ASYNC, ConstructServerDataPacket(
8384 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Bence Béky319388a882020-09-23 18:42:528385 ConstructDataFrame(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528386
Fan Yang32c5a112018-12-10 20:06:338387 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418388 SYNCHRONOUS, ConstructServerDataPacket(
8389 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:528390 false, ConstructDataFrame("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238391 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348392 ConstructClientAckPacket(packet_num++, 4, 3));
Yixin Wang46a273ec302018-01-23 17:59:568393 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8394
Bence Béky6e243aa2019-12-13 19:01:078395 if (VersionUsesHttp3(version_.transport_version)) {
8396 mock_quic_data.AddWrite(
8397 SYNCHRONOUS, ConstructClientDataPacket(
8398 packet_num++, GetQpackDecoderStreamId(), true, false,
Bence Békyf6bb6b22020-04-17 20:22:118399 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078400 }
Yixin Wang46a273ec302018-01-23 17:59:568401 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418402 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238403 ConstructClientRstPacket(packet_num++,
8404 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418405 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568406
8407 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8408
8409 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8410 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8411
8412 SSLSocketDataProvider ssl_data(ASYNC, OK);
8413 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8414
8415 CreateSession();
8416
8417 request_.url = GURL("https://mail.example.org/");
8418 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568419 TestCompletionCallback callback;
8420 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8421 EXPECT_EQ(ERR_IO_PENDING, rv);
8422 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8423
8424 rv = trans.RestartIgnoringLastError(callback.callback());
8425 EXPECT_EQ(ERR_IO_PENDING, rv);
8426 EXPECT_EQ(OK, callback.WaitForResult());
8427
8428 CheckWasHttpResponse(&trans);
8429 CheckResponsePort(&trans, 70);
8430 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568431 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8432
8433 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8434 // proxy socket to disconnect.
8435 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8436
8437 base::RunLoop().RunUntilIdle();
8438 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8439 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8440}
8441
8442// Checks if a request's specified "user-agent" header shows up correctly in the
8443// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148444TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008445 const char kConfiguredUserAgent[] = "Configured User-Agent";
8446 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568447 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148448 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568449 proxy_resolution_service_ =
8450 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8451 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568452
Ryan Hamiltonabad59e2019-06-06 04:02:598453 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238454 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258455 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238456 mock_quic_data.AddWrite(SYNCHRONOUS,
8457 ConstructInitialSettingsPacket(packet_num++));
8458 }
Yixin Wang46a273ec302018-01-23 17:59:568459
Bence Béky4c325e52020-10-22 20:48:018460 spdy::Http2HeaderBlock headers =
8461 ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008462 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338463 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028464 SYNCHRONOUS,
8465 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238466 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498467 false,
8468 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578469 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498470 : HttpProxyConnectJob::kH2QuicTunnelPriority,
8471 std::move(headers), 0));
Yixin Wang46a273ec302018-01-23 17:59:568472 // Return an error, so the transaction stops here (this test isn't interested
8473 // in the rest).
8474 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8475
8476 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8477
Matt Menked732ea42019-03-08 12:05:008478 StaticHttpUserAgentSettings http_user_agent_settings(
8479 std::string() /* accept_language */, kConfiguredUserAgent);
8480 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568481 CreateSession();
8482
8483 request_.url = GURL("https://mail.example.org/");
8484 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008485 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568486 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568487 TestCompletionCallback callback;
8488 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8489 EXPECT_EQ(ERR_IO_PENDING, rv);
8490 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8491
8492 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8493 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8494}
8495
Yixin Wang00fc44c2018-01-23 21:12:208496// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8497// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148498TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208499 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148500 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568501 proxy_resolution_service_ =
8502 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8503 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208504
8505 const RequestPriority request_priority = MEDIUM;
8506
Ryan Hamiltonabad59e2019-06-06 04:02:598507 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238508 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258509 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238510 mock_quic_data.AddWrite(SYNCHRONOUS,
8511 ConstructInitialSettingsPacket(packet_num++));
8512 }
Zhongyi Shi32f2fd02018-04-16 18:23:438513 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238514 SYNCHRONOUS,
8515 ConstructClientRequestHeadersPacket(
8516 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498517 false,
8518 VersionUsesHttp3(version_.transport_version)
Bence Békyaef9661ed2020-10-16 13:22:578519 ? DEFAULT_PRIORITY
Renjie Tangee921d12020-02-06 00:41:498520 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238521 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:208522 // Return an error, so the transaction stops here (this test isn't interested
8523 // in the rest).
8524 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8525
8526 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8527
8528 CreateSession();
8529
8530 request_.url = GURL("https://mail.example.org/");
8531 HttpNetworkTransaction trans(request_priority, session_.get());
8532 TestCompletionCallback callback;
8533 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8534 EXPECT_EQ(ERR_IO_PENDING, rv);
8535 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8536
8537 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8538 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8539}
8540
Matt Menkeedaf3b82019-03-14 21:39:448541// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8542// HTTP/2 stream dependency and weights given the request priority.
8543TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8544 session_params_.enable_quic = true;
8545 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568546 proxy_resolution_service_ =
8547 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8548 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeedaf3b82019-03-14 21:39:448549
8550 const RequestPriority kRequestPriority = MEDIUM;
8551 const RequestPriority kRequestPriority2 = LOWEST;
8552
Ryan Hamiltonabad59e2019-06-06 04:02:598553 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:258554 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238555 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
8556 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8557 } else {
8558 mock_quic_data.AddWrite(
8559 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8560 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
8561 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8562 ConnectRequestHeaders("mail.example.org:443"), 0));
8563 }
Matt Menkeedaf3b82019-03-14 21:39:448564 // This should never be reached.
8565 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8566 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8567
8568 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:598569 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:448570 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8571 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8572
8573 int original_max_sockets_per_group =
8574 ClientSocketPoolManager::max_sockets_per_group(
8575 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8576 ClientSocketPoolManager::set_max_sockets_per_group(
8577 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8578 int original_max_sockets_per_pool =
8579 ClientSocketPoolManager::max_sockets_per_pool(
8580 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8581 ClientSocketPoolManager::set_max_sockets_per_pool(
8582 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8583 CreateSession();
8584
8585 request_.url = GURL("https://mail.example.org/");
8586 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8587 TestCompletionCallback callback;
8588 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8589 EXPECT_EQ(ERR_IO_PENDING, rv);
8590
8591 HttpRequestInfo request2;
8592 request2.url = GURL("https://mail.example.org/some/other/path/");
8593 request2.traffic_annotation =
8594 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8595
8596 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8597 TestCompletionCallback callback2;
8598 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8599 EXPECT_EQ(ERR_IO_PENDING, rv2);
8600
8601 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8602 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8603
8604 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8605
8606 ClientSocketPoolManager::set_max_sockets_per_pool(
8607 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8608 original_max_sockets_per_pool);
8609 ClientSocketPoolManager::set_max_sockets_per_group(
8610 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8611 original_max_sockets_per_group);
8612}
8613
Yixin Wang46a273ec302018-01-23 17:59:568614// Test the request-challenge-retry sequence for basic auth, over a QUIC
8615// connection when setting up a QUIC proxy tunnel.
Bence Békyf6bb6b22020-04-17 20:22:118616TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568617 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8618 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:568619
Yixin Wang46a273ec302018-01-23 17:59:568620 // On the second pass, the body read of the auth challenge is synchronous, so
8621 // IsConnectedAndIdle returns false. The socket should still be drained and
8622 // reused. See http://crbug.com/544255.
8623 for (int i = 0; i < 2; ++i) {
Bence Béky6e243aa2019-12-13 19:01:078624 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:228625 version_,
8626 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8627 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky6e243aa2019-12-13 19:01:078628 client_headers_include_h2_stream_dependency_);
8629 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:228630 version_,
8631 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8632 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Bence Béky6e243aa2019-12-13 19:01:078633 false);
Yixin Wang46a273ec302018-01-23 17:59:568634
8635 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148636 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568637 proxy_resolution_service_ =
Nicolas Arciniegad2013f92020-02-07 23:00:568638 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498639 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568640
Ryan Hamiltonabad59e2019-06-06 04:02:598641 MockQuicData mock_quic_data(version_);
Yixin Wang46a273ec302018-01-23 17:59:568642
Renjie Tangaadb84b2019-08-31 01:00:238643 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258644 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238645 mock_quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:078646 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Renjie Tangaadb84b2019-08-31 01:00:238647 }
Yixin Wang46a273ec302018-01-23 17:59:568648
8649 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438650 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:078651 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238652 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8653 false,
Renjie Tangee921d12020-02-06 00:41:498654 VersionUsesHttp3(version_.transport_version)
Dan Zhangfc4c085b2020-11-10 16:33:168655 ? quic::QuicStream::kDefaultUrgency
Renjie Tangee921d12020-02-06 00:41:498656 : ConvertRequestPriorityToQuicPriority(
8657 HttpProxyConnectJob::kH2QuicTunnelPriority),
Bence Béky6e243aa2019-12-13 19:01:078658 client_maker.ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028659 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568660
Bence Béky4c325e52020-10-22 20:48:018661 spdy::Http2HeaderBlock headers =
Bence Béky6e243aa2019-12-13 19:01:078662 server_maker.GetResponseHeaders("407 Proxy Authentication Required");
Yixin Wang46a273ec302018-01-23 17:59:568663 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8664 headers["content-length"] = "10";
8665 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078666 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338667 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028668 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568669
8670 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438671 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078672 ASYNC, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338673 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178674 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568675 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438676 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078677 SYNCHRONOUS, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338678 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:178679 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568680 }
Yixin Wang46a273ec302018-01-23 17:59:568681
Bence Béky7a45d4d2020-05-08 01:59:238682 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348683 client_maker.MakeAckPacket(packet_num++, 2, 1));
Bence Béky6e243aa2019-12-13 19:01:078684
8685 if (VersionUsesHttp3(version_.transport_version)) {
8686 mock_quic_data.AddWrite(
8687 SYNCHRONOUS,
8688 client_maker.MakeDataPacket(
8689 packet_num++, GetQpackDecoderStreamId(),
8690 /* should_include_version = */ true,
8691 /* fin = */ false, StreamCancellationQpackDecoderInstruction(0)));
8692 }
Yixin Wang46a273ec302018-01-23 17:59:568693
8694 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338695 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:078696 client_maker.MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:238697 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418698 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:188699 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568700
Bence Béky6e243aa2019-12-13 19:01:078701 headers = client_maker.ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:568702 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8703 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048704 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:078705 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238706 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8707 false,
Renjie Tangee921d12020-02-06 00:41:498708 VersionUsesHttp3(version_.transport_version)
Dan Zhangfc4c085b2020-11-10 16:33:168709 ? quic::QuicStream::kDefaultUrgency
Renjie Tangee921d12020-02-06 00:41:498710 : ConvertRequestPriorityToQuicPriority(
8711 HttpProxyConnectJob::kH2QuicTunnelPriority),
Matt Menke6e879bd2019-03-18 17:26:048712 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:028713 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568714
8715 // Response to wrong password
8716 headers =
Bence Béky6e243aa2019-12-13 19:01:078717 server_maker.GetResponseHeaders("407 Proxy Authentication Required");
Yixin Wang46a273ec302018-01-23 17:59:568718 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8719 headers["content-length"] = "10";
8720 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:078721 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338722 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028723 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568724 mock_quic_data.AddRead(SYNCHRONOUS,
8725 ERR_IO_PENDING); // No more data to read
8726
Bence Béky6e243aa2019-12-13 19:01:078727 if (VersionUsesHttp3(version_.transport_version)) {
8728 mock_quic_data.AddWrite(
8729 SYNCHRONOUS,
8730 client_maker.MakeAckAndDataPacket(
Renjie Tangcd594f32020-07-11 20:18:348731 packet_num++, false, GetQpackDecoderStreamId(), 3, 3, false,
Bence Békyf6bb6b22020-04-17 20:22:118732 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078733 mock_quic_data.AddWrite(SYNCHRONOUS,
8734 client_maker.MakeRstPacket(
8735 packet_num++, false,
8736 GetNthClientInitiatedBidirectionalStreamId(1),
8737 quic::QUIC_STREAM_CANCELLED));
8738 } else {
8739 mock_quic_data.AddWrite(SYNCHRONOUS,
8740 client_maker.MakeAckAndRstPacket(
8741 packet_num++, false,
8742 GetNthClientInitiatedBidirectionalStreamId(1),
Renjie Tangcd594f32020-07-11 20:18:348743 quic::QUIC_STREAM_CANCELLED, 3, 3));
Bence Béky6e243aa2019-12-13 19:01:078744 }
Yixin Wang46a273ec302018-01-23 17:59:568745
8746 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8747 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8748
8749 CreateSession();
8750
8751 request_.url = GURL("https://mail.example.org/");
8752 // Ensure that proxy authentication is attempted even
Matt Menke25eaa432020-08-25 00:10:008753 // when privacy mode is enabled.
8754 request_.privacy_mode = PRIVACY_MODE_ENABLED;
Yixin Wang46a273ec302018-01-23 17:59:568755 {
8756 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568757 RunTransaction(&trans);
8758
8759 const HttpResponseInfo* response = trans.GetResponseInfo();
8760 ASSERT_TRUE(response != nullptr);
8761 ASSERT_TRUE(response->headers.get() != nullptr);
8762 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8763 response->headers->GetStatusLine());
8764 EXPECT_TRUE(response->headers->IsKeepAlive());
8765 EXPECT_EQ(407, response->headers->response_code());
8766 EXPECT_EQ(10, response->headers->GetContentLength());
8767 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588768 base::Optional<AuthChallengeInfo> auth_challenge =
8769 response->auth_challenge;
8770 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568771 EXPECT_TRUE(auth_challenge->is_proxy);
8772 EXPECT_EQ("https://proxy.example.org:70",
8773 auth_challenge->challenger.Serialize());
8774 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8775 EXPECT_EQ("basic", auth_challenge->scheme);
8776
8777 TestCompletionCallback callback;
8778 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8779 callback.callback());
8780 EXPECT_EQ(ERR_IO_PENDING, rv);
8781 EXPECT_EQ(OK, callback.WaitForResult());
8782
8783 response = trans.GetResponseInfo();
8784 ASSERT_TRUE(response != nullptr);
8785 ASSERT_TRUE(response->headers.get() != nullptr);
8786 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8787 response->headers->GetStatusLine());
8788 EXPECT_TRUE(response->headers->IsKeepAlive());
8789 EXPECT_EQ(407, response->headers->response_code());
8790 EXPECT_EQ(10, response->headers->GetContentLength());
8791 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588792 auth_challenge = response->auth_challenge;
8793 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568794 EXPECT_TRUE(auth_challenge->is_proxy);
8795 EXPECT_EQ("https://proxy.example.org:70",
8796 auth_challenge->challenger.Serialize());
8797 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8798 EXPECT_EQ("basic", auth_challenge->scheme);
8799 }
8800 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8801 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8802 // reused because it's not connected).
8803 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8804 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8805 }
8806}
8807
Yixin Wang385652a2018-02-16 02:37:238808TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
Zhongyi Shi1c022d22020-03-20 19:00:168809 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
Ryan Hamilton6c6493102019-12-05 21:36:508810 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
8811
Yixin Wang385652a2018-02-16 02:37:238812 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8813 // in HEADERS frames for requests and PRIORITY frames).
David Schinazi84c58bb2020-06-04 20:14:338814 if (!client_headers_include_h2_stream_dependency_) {
Yixin Wang385652a2018-02-16 02:37:238815 return;
8816 }
8817
Victor Vasiliev7da08172019-10-14 06:04:258818 if (quic::VersionUsesHttp3(version_.transport_version)) {
Renjie Tangba21e032019-09-27 21:52:288819 // HTTP/3 currently doesn't support PRIORITY.
Ryan Hamiltone940bd12019-06-30 02:46:458820 return;
8821 }
8822
Victor Vasilieva1e66d72019-12-05 17:55:388823 context_.params()->origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:238824 HostPortPair::FromString("mail.example.org:443"));
8825
Fan Yang32c5a112018-12-10 20:06:338826 const quic::QuicStreamId client_stream_0 =
8827 GetNthClientInitiatedBidirectionalStreamId(0);
8828 const quic::QuicStreamId client_stream_1 =
8829 GetNthClientInitiatedBidirectionalStreamId(1);
8830 const quic::QuicStreamId client_stream_2 =
8831 GetNthClientInitiatedBidirectionalStreamId(2);
8832 const quic::QuicStreamId push_stream_0 =
8833 GetNthServerInitiatedUnidirectionalStreamId(0);
8834 const quic::QuicStreamId push_stream_1 =
8835 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238836
Ryan Hamiltonabad59e2019-06-06 04:02:598837 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238838 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258839 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238840 mock_quic_data.AddWrite(SYNCHRONOUS,
8841 ConstructInitialSettingsPacket(packet_num++));
8842 }
Yixin Wang385652a2018-02-16 02:37:238843
8844 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:238845 mock_quic_data.AddWrite(
8846 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8847 packet_num++, client_stream_0, true, true, HIGHEST,
8848 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:028849 mock_quic_data.AddWrite(
8850 SYNCHRONOUS,
8851 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238852 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028853 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
8854 mock_quic_data.AddWrite(
8855 SYNCHRONOUS,
8856 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238857 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028858 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:238859
8860 // Server replies "OK" for the three requests.
Ryan Hamilton0d65a8c2019-06-07 00:46:028861 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8862 1, client_stream_0, false, false,
8863 GetResponseHeaders("200 OK")));
8864 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8865 2, client_stream_1, false, false,
8866 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238867 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348868 ConstructClientAckPacket(packet_num++, 2, 1));
Ryan Hamilton0d65a8c2019-06-07 00:46:028869 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8870 3, client_stream_2, false, false,
8871 GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:238872
8873 // Server sends two push promises associated with |client_stream_0|; client
8874 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8875 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:028876 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:478877 ASYNC, ConstructServerPushPromisePacket(
8878 4, client_stream_0, push_stream_0, false,
8879 GetRequestHeaders("GET", "https", "/pushed_0.jpg")));
Yixin Wang385652a2018-02-16 02:37:238880 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438881 SYNCHRONOUS,
8882 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangcd594f32020-07-11 20:18:348883 packet_num++, false, 4, 3,
Zhongyi Shi32f2fd02018-04-16 18:23:438884 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:028885 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
8886 mock_quic_data.AddRead(
Renjie Tangb7afea82020-07-15 23:35:478887 ASYNC, ConstructServerPushPromisePacket(
8888 5, client_stream_0, push_stream_1, false,
8889 GetRequestHeaders("GET", "https", "/pushed_1.jpg")));
8890 mock_quic_data.AddWrite(SYNCHRONOUS,
8891 ConstructClientAckAndPriorityPacket(
8892 packet_num++, false,
8893 /*largest_received=*/5, /*smallest_received=*/4,
8894 push_stream_1, push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:238895
8896 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438897 mock_quic_data.AddRead(
8898 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:028899 6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:438900 mock_quic_data.AddRead(
8901 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:028902 7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
Renjie Tangcd594f32020-07-11 20:18:348903 mock_quic_data.AddWrite(SYNCHRONOUS,
8904 ConstructClientAckPacket(packet_num++, 7, 5));
Yixin Wang385652a2018-02-16 02:37:238905
8906 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8907 // priority updates to match the request's priority. Client sends PRIORITY
8908 // frames to inform server of new HTTP/2 stream dependencies.
Bence Béky319388a882020-09-23 18:42:528909 mock_quic_data.AddWrite(
8910 SYNCHRONOUS,
8911 ConstructClientPriorityFramesPacket(
8912 packet_num++, false,
8913 {{push_stream_1, client_stream_2,
8914 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8915 {push_stream_0, client_stream_0,
8916 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:238917
8918 // Server sends data for the three requests and the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438919 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178920 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Bence Béky319388a882020-09-23 18:42:528921 ConstructDataFrame("hello 0!")));
Zhongyi Shi32f2fd02018-04-16 18:23:438922 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178923 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Bence Béky319388a882020-09-23 18:42:528924 ConstructDataFrame("hello 1!")));
Renjie Tangaadb84b2019-08-31 01:00:238925 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348926 ConstructClientAckPacket(packet_num++, 9, 8));
Zhongyi Shi32f2fd02018-04-16 18:23:438927 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178928 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Bence Béky319388a882020-09-23 18:42:528929 ConstructDataFrame("hello 2!")));
8930 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
8931 11, push_stream_0, false, true,
8932 ConstructDataFrame("and hello 0!")));
Renjie Tangaadb84b2019-08-31 01:00:238933 mock_quic_data.AddWrite(SYNCHRONOUS,
Renjie Tangcd594f32020-07-11 20:18:348934 ConstructClientAckPacket(packet_num++, 11, 10));
Zhongyi Shi32f2fd02018-04-16 18:23:438935 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178936 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Bence Béky319388a882020-09-23 18:42:528937 ConstructDataFrame("and hello 1!")));
Yixin Wang385652a2018-02-16 02:37:238938
Yixin Wang385652a2018-02-16 02:37:238939 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8940 mock_quic_data.AddRead(ASYNC, 0); // EOF
8941 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8942
8943 // The non-alternate protocol job needs to hang in order to guarantee that
8944 // the alternate-protocol job will "win".
8945 AddHangingNonAlternateProtocolSocketData();
8946
8947 CreateSession();
8948
8949 request_.url = GURL("https://mail.example.org/0.jpg");
8950 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8951 TestCompletionCallback callback_0;
8952 EXPECT_EQ(ERR_IO_PENDING,
8953 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8954 base::RunLoop().RunUntilIdle();
8955
8956 request_.url = GURL("https://mail.example.org/1.jpg");
8957 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8958 TestCompletionCallback callback_1;
8959 EXPECT_EQ(ERR_IO_PENDING,
8960 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8961 base::RunLoop().RunUntilIdle();
8962
8963 request_.url = GURL("https://mail.example.org/2.jpg");
8964 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8965 TestCompletionCallback callback_2;
8966 EXPECT_EQ(ERR_IO_PENDING,
8967 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8968 base::RunLoop().RunUntilIdle();
8969
8970 // Client makes request that matches resource pushed in |pushed_stream_0|.
8971 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8972 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8973 TestCompletionCallback callback_3;
8974 EXPECT_EQ(ERR_IO_PENDING,
8975 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8976 base::RunLoop().RunUntilIdle();
8977
8978 EXPECT_TRUE(callback_0.have_result());
8979 EXPECT_EQ(OK, callback_0.WaitForResult());
8980 EXPECT_TRUE(callback_1.have_result());
8981 EXPECT_EQ(OK, callback_1.WaitForResult());
8982 EXPECT_TRUE(callback_2.have_result());
8983 EXPECT_EQ(OK, callback_2.WaitForResult());
8984
8985 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8986 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8987 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8988 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8989
8990 mock_quic_data.Resume();
8991 base::RunLoop().RunUntilIdle();
8992 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8993 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8994}
8995
Matt Menke26e41542019-06-05 01:09:518996// Test that NetworkIsolationKey is respected by QUIC connections, when
8997// kPartitionConnectionsByNetworkIsolationKey is enabled.
8998TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Matt Menke4807a9a2020-11-21 00:14:418999 const SchemefulSite kSite1(GURL("http://origin1/"));
9000 const SchemefulSite kSite2(GURL("http://origin2/"));
9001 NetworkIsolationKey network_isolation_key1(kSite1, kSite1);
9002 NetworkIsolationKey network_isolation_key2(kSite2, kSite2);
Matt Menke26e41542019-06-05 01:09:519003
Victor Vasilieva1e66d72019-12-05 17:55:389004 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519005 HostPortPair::FromString("mail.example.org:443"));
9006
9007 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
9008 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
9009 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
9010 // the same way as the HTTP over H2 proxy case.
9011 for (bool use_proxy : {false, true}) {
9012 SCOPED_TRACE(use_proxy);
9013
9014 if (use_proxy) {
9015 proxy_resolution_service_ =
Nicolas Arciniegad2013f92020-02-07 23:00:569016 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Matt Menke26e41542019-06-05 01:09:519017 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
9018 } else {
Nicolas Arciniegad2013f92020-02-07 23:00:569019 proxy_resolution_service_ =
9020 ConfiguredProxyResolutionService::CreateDirect();
Matt Menke26e41542019-06-05 01:09:519021 }
9022
9023 GURL url1;
9024 GURL url2;
9025 GURL url3;
9026 if (use_proxy) {
9027 url1 = GURL("http://mail.example.org/1");
9028 url2 = GURL("http://mail.example.org/2");
9029 url3 = GURL("http://mail.example.org/3");
9030 } else {
9031 url1 = GURL("https://mail.example.org/1");
9032 url2 = GURL("https://mail.example.org/2");
9033 url3 = GURL("https://mail.example.org/3");
9034 }
9035
9036 for (bool partition_connections : {false, true}) {
9037 SCOPED_TRACE(partition_connections);
9038
9039 base::test::ScopedFeatureList feature_list;
9040 if (partition_connections) {
9041 feature_list.InitAndEnableFeature(
9042 features::kPartitionConnectionsByNetworkIsolationKey);
9043 } else {
9044 feature_list.InitAndDisableFeature(
9045 features::kPartitionConnectionsByNetworkIsolationKey);
9046 }
9047
9048 // Reads and writes for the unpartitioned case, where only one socket is
9049 // used.
9050
Victor Vasilieva1e66d72019-12-05 17:55:389051 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519052 HostPortPair::FromString("mail.example.org:443"));
9053
Ryan Hamiltonabad59e2019-06-06 04:02:599054 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:519055 QuicTestPacketMaker client_maker1(
9056 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229057 quic::QuicUtils::CreateRandomConnectionId(
9058 context_.random_generator()),
9059 context_.clock(), kDefaultServerHostName,
9060 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519061 client_headers_include_h2_stream_dependency_);
9062 QuicTestPacketMaker server_maker1(
9063 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229064 quic::QuicUtils::CreateRandomConnectionId(
9065 context_.random_generator()),
9066 context_.clock(), kDefaultServerHostName,
9067 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519068
Renjie Tangaadb84b2019-08-31 01:00:239069 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259070 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239071 unpartitioned_mock_quic_data.AddWrite(
9072 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
9073 }
Matt Menke26e41542019-06-05 01:09:519074
9075 unpartitioned_mock_quic_data.AddWrite(
9076 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029077 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239078 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9079 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029080 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519081 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029082 ASYNC, server_maker1.MakeResponseHeadersPacket(
9083 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9084 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519085 unpartitioned_mock_quic_data.AddRead(
9086 ASYNC, server_maker1.MakeDataPacket(
9087 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529088 true, ConstructDataFrame("1")));
Matt Menke26e41542019-06-05 01:09:519089 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349090 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1));
Matt Menke26e41542019-06-05 01:09:519091
9092 unpartitioned_mock_quic_data.AddWrite(
9093 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029094 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239095 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
9096 false, true,
Matt Menke26e41542019-06-05 01:09:519097 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029098 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519099 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029100 ASYNC, server_maker1.MakeResponseHeadersPacket(
9101 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9102 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519103 unpartitioned_mock_quic_data.AddRead(
9104 ASYNC, server_maker1.MakeDataPacket(
9105 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:529106 true, ConstructDataFrame("2")));
Matt Menke26e41542019-06-05 01:09:519107 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangb7afea82020-07-15 23:35:479108 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 4, 3));
Matt Menke26e41542019-06-05 01:09:519109
9110 unpartitioned_mock_quic_data.AddWrite(
9111 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029112 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239113 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
9114 false, true,
Matt Menke26e41542019-06-05 01:09:519115 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029116 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519117 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029118 ASYNC, server_maker1.MakeResponseHeadersPacket(
9119 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
9120 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519121 unpartitioned_mock_quic_data.AddRead(
9122 ASYNC, server_maker1.MakeDataPacket(
9123 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Bence Béky319388a882020-09-23 18:42:529124 true, ConstructDataFrame("3")));
Matt Menke26e41542019-06-05 01:09:519125 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangb7afea82020-07-15 23:35:479126 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 6, 5));
Matt Menke26e41542019-06-05 01:09:519127
9128 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9129
9130 // Reads and writes for the partitioned case, where two sockets are used.
9131
Ryan Hamiltonabad59e2019-06-06 04:02:599132 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:519133 QuicTestPacketMaker client_maker2(
9134 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229135 quic::QuicUtils::CreateRandomConnectionId(
9136 context_.random_generator()),
9137 context_.clock(), kDefaultServerHostName,
9138 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519139 client_headers_include_h2_stream_dependency_);
9140 QuicTestPacketMaker server_maker2(
9141 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229142 quic::QuicUtils::CreateRandomConnectionId(
9143 context_.random_generator()),
9144 context_.clock(), kDefaultServerHostName,
9145 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519146
Renjie Tangaadb84b2019-08-31 01:00:239147 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259148 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239149 partitioned_mock_quic_data1.AddWrite(
9150 SYNCHRONOUS,
9151 client_maker2.MakeInitialSettingsPacket(packet_num2++));
9152 }
Matt Menke26e41542019-06-05 01:09:519153
9154 partitioned_mock_quic_data1.AddWrite(
9155 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029156 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239157 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
9158 true, true,
Matt Menke26e41542019-06-05 01:09:519159 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029160 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519161 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029162 ASYNC, server_maker2.MakeResponseHeadersPacket(
9163 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9164 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519165 partitioned_mock_quic_data1.AddRead(
9166 ASYNC, server_maker2.MakeDataPacket(
9167 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529168 true, ConstructDataFrame("1")));
Matt Menke26e41542019-06-05 01:09:519169 partitioned_mock_quic_data1.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349170 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 2, 1));
Matt Menke26e41542019-06-05 01:09:519171
9172 partitioned_mock_quic_data1.AddWrite(
9173 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029174 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239175 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
9176 false, true,
Matt Menke26e41542019-06-05 01:09:519177 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029178 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519179 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029180 ASYNC, server_maker2.MakeResponseHeadersPacket(
9181 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9182 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519183 partitioned_mock_quic_data1.AddRead(
9184 ASYNC, server_maker2.MakeDataPacket(
9185 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Bence Béky319388a882020-09-23 18:42:529186 true, ConstructDataFrame("3")));
Matt Menke26e41542019-06-05 01:09:519187 partitioned_mock_quic_data1.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349188 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 4, 3));
Matt Menke26e41542019-06-05 01:09:519189
9190 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9191
Ryan Hamiltonabad59e2019-06-06 04:02:599192 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:519193 QuicTestPacketMaker client_maker3(
9194 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229195 quic::QuicUtils::CreateRandomConnectionId(
9196 context_.random_generator()),
9197 context_.clock(), kDefaultServerHostName,
9198 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519199 client_headers_include_h2_stream_dependency_);
9200 QuicTestPacketMaker server_maker3(
9201 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229202 quic::QuicUtils::CreateRandomConnectionId(
9203 context_.random_generator()),
9204 context_.clock(), kDefaultServerHostName,
9205 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519206
Renjie Tangaadb84b2019-08-31 01:00:239207 int packet_num3 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259208 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239209 partitioned_mock_quic_data2.AddWrite(
9210 SYNCHRONOUS,
9211 client_maker3.MakeInitialSettingsPacket(packet_num3++));
9212 }
Matt Menke26e41542019-06-05 01:09:519213
9214 partitioned_mock_quic_data2.AddWrite(
9215 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029216 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239217 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9218 true, true,
Matt Menke26e41542019-06-05 01:09:519219 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029220 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519221 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029222 ASYNC, server_maker3.MakeResponseHeadersPacket(
9223 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9224 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519225 partitioned_mock_quic_data2.AddRead(
9226 ASYNC, server_maker3.MakeDataPacket(
9227 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529228 true, ConstructDataFrame("2")));
Matt Menke26e41542019-06-05 01:09:519229 partitioned_mock_quic_data2.AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349230 SYNCHRONOUS, client_maker3.MakeAckPacket(packet_num3++, 2, 1));
Matt Menke26e41542019-06-05 01:09:519231
9232 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9233
9234 if (partition_connections) {
9235 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9236 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9237 } else {
9238 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9239 }
9240
9241 CreateSession();
9242
9243 TestCompletionCallback callback;
9244 HttpRequestInfo request1;
9245 request1.method = "GET";
9246 request1.url = GURL(url1);
9247 request1.traffic_annotation =
9248 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9249 request1.network_isolation_key = network_isolation_key1;
9250 HttpNetworkTransaction trans1(LOWEST, session_.get());
9251 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9252 EXPECT_THAT(callback.GetResult(rv), IsOk());
9253 std::string response_data1;
9254 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9255 EXPECT_EQ("1", response_data1);
9256
9257 HttpRequestInfo request2;
9258 request2.method = "GET";
9259 request2.url = GURL(url2);
9260 request2.traffic_annotation =
9261 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9262 request2.network_isolation_key = network_isolation_key2;
9263 HttpNetworkTransaction trans2(LOWEST, session_.get());
9264 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9265 EXPECT_THAT(callback.GetResult(rv), IsOk());
9266 std::string response_data2;
9267 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9268 EXPECT_EQ("2", response_data2);
9269
9270 HttpRequestInfo request3;
9271 request3.method = "GET";
9272 request3.url = GURL(url3);
9273 request3.traffic_annotation =
9274 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9275 request3.network_isolation_key = network_isolation_key1;
9276 HttpNetworkTransaction trans3(LOWEST, session_.get());
9277 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9278 EXPECT_THAT(callback.GetResult(rv), IsOk());
9279 std::string response_data3;
9280 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9281 EXPECT_EQ("3", response_data3);
9282
9283 if (partition_connections) {
9284 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9285 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9286 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9287 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9288 } else {
9289 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9290 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9291 }
9292 }
9293 }
9294}
9295
9296// Test that two requests to the same origin over QUIC tunnels use different
9297// QUIC sessions if their NetworkIsolationKeys don't match, and
9298// kPartitionConnectionsByNetworkIsolationKey is enabled.
9299TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9300 base::test::ScopedFeatureList feature_list;
9301 feature_list.InitAndEnableFeature(
9302 features::kPartitionConnectionsByNetworkIsolationKey);
9303
9304 session_params_.enable_quic = true;
9305 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:569306 proxy_resolution_service_ =
9307 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
9308 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menke26e41542019-06-05 01:09:519309
9310 const char kGetRequest[] =
9311 "GET / HTTP/1.1\r\n"
9312 "Host: mail.example.org\r\n"
9313 "Connection: keep-alive\r\n\r\n";
9314 const char kGetResponse[] =
9315 "HTTP/1.1 200 OK\r\n"
9316 "Content-Length: 10\r\n\r\n";
9317
Ryan Hamiltonabad59e2019-06-06 04:02:599318 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9319 std::make_unique<MockQuicData>(version_),
9320 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519321
9322 for (int index : {0, 1}) {
9323 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229324 version_,
9325 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9326 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519327 client_headers_include_h2_stream_dependency_);
9328 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229329 version_,
9330 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9331 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9332 false);
Matt Menke26e41542019-06-05 01:09:519333
Renjie Tangaadb84b2019-08-31 01:00:239334 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259335 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239336 mock_quic_data[index]->AddWrite(
9337 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
9338 }
Matt Menke26e41542019-06-05 01:09:519339
Ryan Hamiltonabad59e2019-06-06 04:02:599340 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519341 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029342 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239343 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9344 false,
Renjie Tangee921d12020-02-06 00:41:499345 VersionUsesHttp3(version_.transport_version)
Dan Zhangfc4c085b2020-11-10 16:33:169346 ? quic::QuicStream::kDefaultUrgency
Renjie Tangee921d12020-02-06 00:41:499347 : ConvertRequestPriorityToQuicPriority(
9348 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:029349 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:599350 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029351 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:519352 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9353 false, GetResponseHeaders("200 OK"), nullptr));
9354
Bence Béky319388a882020-09-23 18:42:529355 mock_quic_data[index]->AddWrite(
9356 SYNCHRONOUS,
9357 client_maker.MakeAckAndDataPacket(
9358 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
9359 1, 1, false, ConstructDataFrame(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:519360
Ryan Hamiltonabad59e2019-06-06 04:02:599361 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519362 ASYNC, server_maker.MakeDataPacket(
9363 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529364 false, ConstructDataFrame(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599365 mock_quic_data[index]->AddRead(
Bence Béky319388a882020-09-23 18:42:529366 SYNCHRONOUS, server_maker.MakeDataPacket(
9367 3, GetNthClientInitiatedBidirectionalStreamId(0),
9368 false, false, ConstructDataFrame("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599369 mock_quic_data[index]->AddWrite(
Renjie Tangcd594f32020-07-11 20:18:349370 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2));
Ryan Hamiltonabad59e2019-06-06 04:02:599371 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9372 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:519373
Ryan Hamiltonabad59e2019-06-06 04:02:599374 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:519375 }
9376
9377 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9378 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9379 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9380
9381 CreateSession();
9382
9383 request_.url = GURL("https://mail.example.org/");
9384 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9385 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9386 RunTransaction(&trans);
9387 CheckResponseData(&trans, "0123456789");
9388
9389 HttpRequestInfo request2;
Matt Menke4807a9a2020-11-21 00:14:419390 const SchemefulSite kSite1(GURL("http://origin1/"));
9391 request_.network_isolation_key = NetworkIsolationKey(kSite1, kSite1);
Matt Menke26e41542019-06-05 01:09:519392 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9393 RunTransaction(&trans2);
9394 CheckResponseData(&trans2, "0123456789");
9395
Ryan Hamiltonabad59e2019-06-06 04:02:599396 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9397 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9398 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9399 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:519400}
9401
Yoichi Osato4c75c0c2020-06-24 08:03:579402TEST_P(QuicNetworkTransactionTest, AllowHTTP1FalseProhibitsH1) {
9403 MockRead http_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING),
9404 MockRead(ASYNC, OK)};
9405 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
9406 socket_factory_.AddSocketDataProvider(&http_data);
9407 AddCertificate(&ssl_data_);
9408 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9409
9410 CreateSession();
9411
9412 request_.method = "POST";
9413 UploadDataStreamNotAllowHTTP1 upload_data("");
9414 request_.upload_data_stream = &upload_data;
9415
9416 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9417 TestCompletionCallback callback;
9418 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9419 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9420 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_H2_OR_QUIC_REQUIRED));
9421}
9422
9423// Confirm mock class UploadDataStreamNotAllowHTTP1 can upload content over
9424// QUIC.
9425TEST_P(QuicNetworkTransactionTest, AllowHTTP1MockTest) {
9426 context_.params()->origins_to_force_quic_on.insert(
9427 HostPortPair::FromString("mail.example.org:443"));
9428
9429 MockQuicData mock_quic_data(version_);
9430 int write_packet_index = 1;
9431 if (VersionUsesHttp3(version_.transport_version)) {
9432 mock_quic_data.AddWrite(
9433 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9434 }
9435 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:529436 mock_quic_data.AddWrite(
9437 SYNCHRONOUS,
9438 ConstructClientRequestHeadersAndDataFramesPacket(
9439 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9440 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9441 0, nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:579442 mock_quic_data.AddRead(
9443 ASYNC, ConstructServerResponseHeadersPacket(
9444 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
9445 GetResponseHeaders("200 OK")));
9446
Yoichi Osato4c75c0c2020-06-24 08:03:579447 mock_quic_data.AddRead(
9448 ASYNC, ConstructServerDataPacket(
9449 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Bence Béky319388a882020-09-23 18:42:529450 ConstructDataFrame("hello!")));
Yoichi Osato4c75c0c2020-06-24 08:03:579451
Renjie Tangcd594f32020-07-11 20:18:349452 mock_quic_data.AddWrite(SYNCHRONOUS,
9453 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:579454
9455 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9456 mock_quic_data.AddRead(ASYNC, 0); // EOF
9457 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9458
9459 // The non-alternate protocol job needs to hang in order to guarantee that
9460 // the alternate-protocol job will "win".
9461 AddHangingNonAlternateProtocolSocketData();
9462
9463 CreateSession();
9464 request_.method = "POST";
9465 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9466 request_.upload_data_stream = &upload_data;
9467
9468 SendRequestAndExpectQuicResponse("hello!");
9469}
9470
9471TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadPauseAndResume) {
9472 context_.params()->origins_to_force_quic_on.insert(
9473 HostPortPair::FromString("mail.example.org:443"));
9474
9475 MockQuicData mock_quic_data(version_);
9476 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
9477 int write_packet_index = 1;
9478 mock_quic_data.AddWrite(
9479 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
9480 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
9481 if (VersionUsesHttp3(version_.transport_version)) {
9482 mock_quic_data.AddWrite(
9483 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9484 }
9485 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:529486 mock_quic_data.AddWrite(
9487 SYNCHRONOUS,
9488 ConstructClientRequestHeadersAndDataFramesPacket(
9489 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9490 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9491 0, nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:579492 mock_quic_data.AddRead(
9493 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
9494 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9495 false, GetResponseHeaders("200 OK")));
Yoichi Osato4c75c0c2020-06-24 08:03:579496 mock_quic_data.AddRead(
9497 SYNCHRONOUS, ConstructServerDataPacket(
9498 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529499 true, ConstructDataFrame("hello!")));
Yoichi Osato4c75c0c2020-06-24 08:03:579500
Renjie Tangcd594f32020-07-11 20:18:349501 mock_quic_data.AddWrite(SYNCHRONOUS,
9502 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:579503 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9504 mock_quic_data.AddRead(ASYNC, 0); // EOF
9505 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9506 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
9507
9508 CreateSession();
9509
9510 AddQuicAlternateProtocolMapping(
9511 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
9512
9513 // Set up request.
9514 request_.method = "POST";
9515 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9516 request_.upload_data_stream = &upload_data;
9517
9518 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9519 TestCompletionCallback callback;
9520 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9521 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9522 base::RunLoop().RunUntilIdle();
9523 // Resume QUIC job
9524 crypto_client_stream_factory_.last_stream()
9525 ->NotifySessionOneRttKeyAvailable();
9526 socket_data->Resume();
9527
9528 base::RunLoop().RunUntilIdle();
9529 CheckResponseData(&trans, "hello!");
9530}
9531
9532TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadFailH1AndResumeQuic) {
9533 // This test confirms failed main job should not bother quic job.
9534 MockRead http_reads[] = {
9535 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
9536 MockRead("1.1 Body"),
9537 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9538 MockRead(ASYNC, OK)};
9539 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
9540 socket_factory_.AddSocketDataProvider(&http_data);
9541 AddCertificate(&ssl_data_);
9542 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9543
9544 MockQuicData mock_quic_data(version_);
9545 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
9546 int write_packet_index = 1;
9547 mock_quic_data.AddWrite(
9548 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
9549 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
9550 if (VersionUsesHttp3(version_.transport_version)) {
9551 mock_quic_data.AddWrite(
9552 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9553 }
9554 const std::string upload_content = "foo";
Bence Béky319388a882020-09-23 18:42:529555 mock_quic_data.AddWrite(
9556 SYNCHRONOUS,
9557 ConstructClientRequestHeadersAndDataFramesPacket(
9558 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9559 true, true, DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"),
9560 0, nullptr, {ConstructDataFrame(upload_content)}));
Yoichi Osato4c75c0c2020-06-24 08:03:579561 mock_quic_data.AddRead(
9562 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
9563 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9564 false, GetResponseHeaders("200 OK")));
Yoichi Osato4c75c0c2020-06-24 08:03:579565 mock_quic_data.AddRead(
9566 SYNCHRONOUS, ConstructServerDataPacket(
9567 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Bence Béky319388a882020-09-23 18:42:529568 true, ConstructDataFrame("hello!")));
Renjie Tangcd594f32020-07-11 20:18:349569 mock_quic_data.AddWrite(SYNCHRONOUS,
9570 ConstructClientAckPacket(write_packet_index++, 2, 1));
Yoichi Osato4c75c0c2020-06-24 08:03:579571 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9572 mock_quic_data.AddRead(ASYNC, 0); // EOF
9573 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9574 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
9575
9576 // This packet won't be read because AllowHTTP1:false doesn't allow H/1
9577 // connection.
9578 MockRead http_reads2[] = {MockRead("HTTP/1.1 200 OK\r\n")};
9579 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
9580 socket_factory_.AddSocketDataProvider(&http_data2);
9581 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9582
9583 CreateSession();
9584
9585 // Send the first request via TCP and set up alternative service (QUIC) for
9586 // the origin.
9587 SendRequestAndExpectHttpResponse("1.1 Body");
9588
9589 // Settings to resume main H/1 job quickly while pausing quic job.
9590 AddQuicAlternateProtocolMapping(
9591 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
9592 ServerNetworkStats stats1;
9593 stats1.srtt = base::TimeDelta::FromMicroseconds(10);
9594 http_server_properties_->SetServerNetworkStats(
9595 url::SchemeHostPort(request_.url), NetworkIsolationKey(), stats1);
9596
9597 // Set up request.
9598 request_.method = "POST";
9599 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9600 request_.upload_data_stream = &upload_data;
9601
9602 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9603 TestCompletionCallback callback;
9604 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9606 // Confirm TCP job was resumed.
9607 // We can not check its failure because HttpStreamFactory::JobController.
9608 // main_job_net_error is not exposed.
9609 while (socket_factory_.mock_data().next_index() < 3u)
9610 base::RunLoop().RunUntilIdle();
9611 // Resume QUIC job.
9612 crypto_client_stream_factory_.last_stream()
9613 ->NotifySessionOneRttKeyAvailable();
9614 socket_data->Resume();
9615 base::RunLoop().RunUntilIdle();
9616 CheckResponseData(&trans, "hello!");
9617}
9618
Bence Békyc164e0d22020-09-22 20:08:599619TEST_P(QuicNetworkTransactionTest, IncorrectHttp3GoAway) {
9620 if (!version_.HasIetfQuicFrames()) {
9621 return;
9622 }
9623
9624 context_.params()->retry_without_alt_svc_on_quic_errors = false;
9625
9626 MockQuicData mock_quic_data(version_);
9627 int write_packet_number = 1;
9628 mock_quic_data.AddWrite(
9629 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number++));
9630 mock_quic_data.AddWrite(
9631 SYNCHRONOUS,
9632 ConstructClientRequestHeadersPacket(
9633 write_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
9634 true, true, GetRequestHeaders("GET", "https", "/")));
9635
9636 int read_packet_number = 1;
9637 mock_quic_data.AddRead(
9638 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number++));
9639 // The GOAWAY frame sent by the server MUST have a stream ID corresponding to
9640 // a client-initiated bidirectional stream. Any other kind of stream ID
9641 // should cause the client to close the connection.
9642 quic::GoAwayFrame goaway{3};
9643 std::unique_ptr<char[]> goaway_buffer;
9644 auto goaway_length =
9645 quic::HttpEncoder::SerializeGoAwayFrame(goaway, &goaway_buffer);
9646 const quic::QuicStreamId control_stream_id =
9647 quic::QuicUtils::GetFirstUnidirectionalStreamId(
9648 version_.transport_version, quic::Perspective::IS_SERVER);
9649 mock_quic_data.AddRead(
Victor Vasiliev47ecb6a2020-10-14 17:22:109650 ASYNC, ConstructServerDataPacket(
9651 read_packet_number++, control_stream_id, false, false,
9652 absl::string_view(goaway_buffer.get(), goaway_length)));
Bence Békyc164e0d22020-09-22 20:08:599653 mock_quic_data.AddWrite(
9654 SYNCHRONOUS,
9655 ConstructClientAckAndConnectionClosePacket(
9656 write_packet_number++, 2, 4, quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID,
9657 "GOAWAY with invalid stream ID", 0));
9658 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9659
9660 // In order for a new QUIC session to be established via alternate-protocol
9661 // without racing an HTTP connection, we need the host resolution to happen
9662 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
9663 // connection to the the server, in this test we require confirmation
9664 // before encrypting so the HTTP job will still start.
9665 host_resolver_.set_synchronous_mode(true);
9666 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
9667 "");
9668
9669 CreateSession();
9670 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9671
9672 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9673 TestCompletionCallback callback;
9674 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9675 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9676
9677 crypto_client_stream_factory_.last_stream()
9678 ->NotifySessionOneRttKeyAvailable();
9679 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
9680
9681 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9682 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9683
9684 NetErrorDetails details;
9685 trans.PopulateNetErrorDetails(&details);
9686 EXPECT_THAT(details.quic_connection_error,
9687 quic::test::IsError(quic::QUIC_HTTP_GOAWAY_INVALID_STREAM_ID));
9688}
9689
Bence Béky2ee18922020-09-25 12:11:329690TEST_P(QuicNetworkTransactionTest, RetryOnHttp3GoAway) {
9691 if (!version_.HasIetfQuicFrames()) {
9692 return;
9693 }
9694
9695 MockQuicData mock_quic_data1(version_);
9696 int write_packet_number1 = 1;
9697 mock_quic_data1.AddWrite(
9698 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_number1++));
9699 const quic::QuicStreamId stream_id1 =
9700 GetNthClientInitiatedBidirectionalStreamId(0);
9701 mock_quic_data1.AddWrite(SYNCHRONOUS,
9702 ConstructClientRequestHeadersPacket(
9703 write_packet_number1++, stream_id1, true, true,
9704 GetRequestHeaders("GET", "https", "/")));
9705 const quic::QuicStreamId stream_id2 =
9706 GetNthClientInitiatedBidirectionalStreamId(1);
9707 mock_quic_data1.AddWrite(SYNCHRONOUS,
9708 ConstructClientRequestHeadersPacket(
9709 write_packet_number1++, stream_id2, true, true,
9710 GetRequestHeaders("GET", "https", "/foo")));
9711
9712 int read_packet_number1 = 1;
9713 mock_quic_data1.AddRead(
9714 ASYNC, server_maker_.MakeInitialSettingsPacket(read_packet_number1++));
9715
9716 // GOAWAY with stream_id2 informs the client that stream_id2 (and streams with
9717 // larger IDs) have not been processed and can safely be retried.
9718 quic::GoAwayFrame goaway{stream_id2};
9719 std::unique_ptr<char[]> goaway_buffer;
9720 auto goaway_length =
9721 quic::HttpEncoder::SerializeGoAwayFrame(goaway, &goaway_buffer);
9722 const quic::QuicStreamId control_stream_id =
9723 quic::QuicUtils::GetFirstUnidirectionalStreamId(
9724 version_.transport_version, quic::Perspective::IS_SERVER);
9725 mock_quic_data1.AddRead(
Victor Vasiliev47ecb6a2020-10-14 17:22:109726 ASYNC, ConstructServerDataPacket(
9727 read_packet_number1++, control_stream_id, false, false,
9728 absl::string_view(goaway_buffer.get(), goaway_length)));
Bence Béky2ee18922020-09-25 12:11:329729 mock_quic_data1.AddWrite(
9730 ASYNC, ConstructClientAckPacket(write_packet_number1++, 2, 1));
9731
9732 // Response to first request is accepted after GOAWAY.
9733 mock_quic_data1.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9734 read_packet_number1++, stream_id1, false,
9735 false, GetResponseHeaders("200 OK")));
9736 mock_quic_data1.AddRead(
9737 ASYNC, ConstructServerDataPacket(
9738 read_packet_number1++, stream_id1, false, true,
9739 ConstructDataFrame("response on the first connection")));
9740 mock_quic_data1.AddWrite(
9741 ASYNC, ConstructClientAckPacket(write_packet_number1++, 4, 1));
Bence Békye7426ec2021-02-02 18:18:199742 // Make socket hang to make sure connection stays in connection pool.
9743 // This should not prevent the retry from opening a new connection.
9744 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING);
Bence Béky2ee18922020-09-25 12:11:329745 mock_quic_data1.AddRead(ASYNC, 0); // EOF
9746 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9747
9748 // Second request is retried on a new connection.
9749 MockQuicData mock_quic_data2(version_);
9750 QuicTestPacketMaker client_maker2(
9751 version_,
9752 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9753 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9754 client_headers_include_h2_stream_dependency_);
9755 int write_packet_number2 = 1;
9756 mock_quic_data2.AddWrite(SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(
9757 write_packet_number2++));
9758 spdy::SpdyPriority priority =
9759 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
9760 mock_quic_data2.AddWrite(
9761 SYNCHRONOUS, client_maker2.MakeRequestHeadersPacket(
9762 write_packet_number2++, stream_id1, true, true, priority,
9763 GetRequestHeaders("GET", "https", "/foo"), 0, nullptr));
9764
9765 QuicTestPacketMaker server_maker2(
9766 version_,
9767 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9768 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9769 false);
9770 int read_packet_number2 = 1;
9771 mock_quic_data2.AddRead(ASYNC,
9772 server_maker2.MakeResponseHeadersPacket(
9773 read_packet_number2++, stream_id1, false, false,
9774 GetResponseHeaders("200 OK"), nullptr));
9775 mock_quic_data2.AddRead(
9776 ASYNC, server_maker2.MakeDataPacket(
9777 read_packet_number2++, stream_id1, false, true,
9778 ConstructDataFrame("response on the second connection")));
9779 mock_quic_data2.AddWrite(
9780 ASYNC, client_maker2.MakeAckPacket(write_packet_number2++, 2, 1));
9781 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9782 mock_quic_data2.AddRead(ASYNC, 0); // EOF
9783 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9784
9785 AddHangingNonAlternateProtocolSocketData();
9786 CreateSession();
9787 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9788
9789 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session_.get());
9790 TestCompletionCallback callback1;
9791 int rv = trans1.Start(&request_, callback1.callback(), net_log_.bound());
9792 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9793 base::RunLoop().RunUntilIdle();
9794
9795 HttpRequestInfo request2;
9796 request2.method = "GET";
9797 std::string url("https://");
9798 url.append(kDefaultServerHostName);
9799 url.append("/foo");
9800 request2.url = GURL(url);
9801 request2.load_flags = 0;
9802 request2.traffic_annotation =
9803 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9804 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9805 TestCompletionCallback callback2;
9806 rv = trans2.Start(&request2, callback2.callback(), net_log_.bound());
9807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9808
9809 EXPECT_THAT(callback1.WaitForResult(), IsOk());
9810 CheckResponseData(&trans1, "response on the first connection");
9811
9812 EXPECT_THAT(callback2.WaitForResult(), IsOk());
9813 CheckResponseData(&trans2, "response on the second connection");
9814
Bence Békye7426ec2021-02-02 18:18:199815 mock_quic_data1.Resume();
Bence Béky2ee18922020-09-25 12:11:329816 mock_quic_data2.Resume();
9817 EXPECT_TRUE(mock_quic_data1.AllWriteDataConsumed());
9818 EXPECT_TRUE(mock_quic_data1.AllReadDataConsumed());
9819 EXPECT_TRUE(mock_quic_data2.AllWriteDataConsumed());
9820 EXPECT_TRUE(mock_quic_data2.AllReadDataConsumed());
9821}
9822
Yoichi Osato4c75c0c2020-06-24 08:03:579823// TODO(yoichio): Add the TCP job reuse case. See crrev.com/c/2174099.
9824
[email protected]61a527782013-02-21 03:58:009825} // namespace test
9826} // namespace net