blob: ba7eb42f107bef1daad8bfefea36d076ff1de648 [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"
zhongyie537a002017-06-27 16:48:2116#include "base/strings/string_number_conversions.h"
Bence Békyd74f4382018-02-20 18:26:1917#include "base/strings/string_piece.h"
bnc8be55ebb2015-10-30 14:12:0718#include "base/strings/stringprintf.h"
Devlin Cronine4bcb40e2018-06-05 18:02:4719#include "base/test/metrics/histogram_tester.h"
Matt Menke26e41542019-06-05 01:09:5120#include "base/test/scoped_feature_list.h"
rtenneti56977812016-01-15 19:26:5621#include "net/base/chunked_upload_data_stream.h"
Bence Békyd8a21fc32018-06-27 18:29:5822#include "net/base/completion_once_callback.h"
Matt Menke26e41542019-06-05 01:09:5123#include "net/base/features.h"
Tsuyoshi Horo01faed62019-02-20 22:11:3724#include "net/base/ip_endpoint.h"
mgershaf9a9232017-04-13 20:19:0325#include "net/base/mock_network_change_notifier.h"
Matt Menke9aa86262019-08-21 15:52:0726#include "net/base/network_isolation_key.h"
[email protected]61a527782013-02-21 03:58:0027#include "net/base/test_completion_callback.h"
tbansalc3308d72016-08-27 10:25:0428#include "net/base/test_proxy_delegate.h"
rsleevid6de8302016-06-21 01:33:2029#include "net/cert/ct_policy_enforcer.h"
[email protected]6e7845ae2013-03-29 21:48:1130#include "net/cert/mock_cert_verifier.h"
rtenneti052774e2015-11-24 21:00:1231#include "net/cert/multi_log_ct_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5332#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0033#include "net/http/http_auth_handler_factory.h"
34#include "net/http/http_network_session.h"
35#include "net/http/http_network_transaction.h"
Matt Menke6e879bd2019-03-18 17:26:0436#include "net/http/http_proxy_connect_job.h"
Matt Menke609160742019-08-02 18:47:2637#include "net/http/http_server_properties.h"
[email protected]61a527782013-02-21 03:58:0038#include "net/http/http_stream.h"
39#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1940#include "net/http/http_transaction_test_util.h"
Yoichi Osato4c75c0c2020-06-24 08:03:5741#include "net/http/test_upload_data_stream_not_allow_http1.h"
[email protected]b1c988b2013-06-13 06:48:1142#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0043#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5144#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4645#include "net/log/test_net_log_util.h"
Nicolas Arciniegad2013f92020-02-07 23:00:5646#include "net/proxy_resolution/configured_proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4047#include "net/proxy_resolution/proxy_config_service_fixed.h"
48#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0849#include "net/quic/crypto/proof_verifier_chromium.h"
50#include "net/quic/mock_crypto_client_stream_factory.h"
Victor Vasiliev7752898d2019-11-14 21:30:2251#include "net/quic/mock_quic_context.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0852#include "net/quic/mock_quic_data.h"
53#include "net/quic/quic_chromium_alarm_factory.h"
54#include "net/quic/quic_http_stream.h"
55#include "net/quic/quic_http_utils.h"
56#include "net/quic/quic_stream_factory_peer.h"
57#include "net/quic/quic_test_packet_maker.h"
58#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0059#include "net/socket/client_socket_factory.h"
60#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2161#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2862#include "net/socket/socket_performance_watcher.h"
63#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0064#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5865#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5766#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2967#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0168#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4369#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4070#include "net/test/test_with_task_environment.h"
Zhongyi Shid1c00fc42019-12-14 06:05:0971#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
72#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5173#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
74#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
75#include "net/third_party/quiche/src/quic/core/quic_framer.h"
76#include "net/third_party/quiche/src/quic/core/quic_utils.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5177#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
78#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
79#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
80#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
81#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
82#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1483#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
84#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2985#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0086#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4887#include "net/url_request/url_request.h"
88#include "net/url_request/url_request_job_factory_impl.h"
89#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0190#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0091#include "testing/gtest/include/gtest/gtest.h"
92#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4693#include "url/gurl.h"
Matt Menke3233d8f22019-08-20 21:01:4994#include "url/origin.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) {
Zhongyi Shid1c00fc42019-12-14 06:05:09129 return quiche::QuicheStrCat(
David Schinazi09e9a6012019-10-03 17:37:57130 ParsedQuicVersionToString(p.version), "_",
131 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
132 "Dependency");
133}
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 }
Zhongyi Shid1c00fc42019-12-14 06:05:09157 return quiche::QuicheStrCat(
David Schinazi09e9a6012019-10-03 17:37:57158 ParsedQuicVersionToString(p.version), "_", destination_string, "_",
159 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
160 "Dependency");
161}
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
[email protected]61a527782013-02-21 03:58:00217} // namespace
218
tbansal0f56a39a2016-04-07 22:03:38219class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40220 public:
tbansal180587c2017-02-16 15:13:23221 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
222 bool* rtt_notification_received)
223 : should_notify_updated_rtt_(should_notify_updated_rtt),
224 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38225 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40226
tbansal180587c2017-02-16 15:13:23227 bool ShouldNotifyUpdatedRTT() const override {
228 return *should_notify_updated_rtt_;
229 }
tbansalfdf5665b2015-09-21 22:46:40230
tbansal0f56a39a2016-04-07 22:03:38231 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
232 *rtt_notification_received_ = true;
233 }
234
235 void OnConnectionChanged() override {}
236
237 private:
tbansal180587c2017-02-16 15:13:23238 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38239 bool* rtt_notification_received_;
240
241 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
242};
243
244class TestSocketPerformanceWatcherFactory
245 : public SocketPerformanceWatcherFactory {
246 public:
247 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23248 : watcher_count_(0u),
249 should_notify_updated_rtt_(true),
250 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38251 ~TestSocketPerformanceWatcherFactory() override {}
252
253 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42254 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41255 const Protocol protocol,
256 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51257 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38258 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51259 }
260 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42261 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23262 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
263 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40264 }
265
tbansalc8a94ea2015-11-02 23:58:51266 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40267
tbansalc8a94ea2015-11-02 23:58:51268 bool rtt_notification_received() const { return rtt_notification_received_; }
269
tbansal180587c2017-02-16 15:13:23270 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
271 should_notify_updated_rtt_ = should_notify_updated_rtt;
272 }
273
tbansalc8a94ea2015-11-02 23:58:51274 private:
tbansal0f56a39a2016-04-07 22:03:38275 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23276 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51277 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38278
279 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51280};
281
Ryan Hamilton8d9ee76e2018-05-29 23:52:52282class QuicNetworkTransactionTest
283 : public PlatformTest,
David Schinazi09e9a6012019-10-03 17:37:57284 public ::testing::WithParamInterface<TestParams>,
Gabriel Charette694c3c332019-08-19 14:53:05285 public WithTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00286 protected:
[email protected]1c04f9522013-02-21 20:32:43287 QuicNetworkTransactionTest()
David Schinazi09e9a6012019-10-03 17:37:57288 : version_(GetParam().version),
289 client_headers_include_h2_stream_dependency_(
290 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:56291 supported_versions_(quic::test::SupportedVersions(version_)),
Zhongyi Shi1c022d22020-03-20 19:00:16292 client_maker_(new QuicTestPacketMaker(
293 version_,
294 quic::QuicUtils::CreateRandomConnectionId(
295 context_.random_generator()),
296 context_.clock(),
297 kDefaultServerHostName,
298 quic::Perspective::IS_CLIENT,
299 client_headers_include_h2_stream_dependency_)),
Victor Vasiliev7752898d2019-11-14 21:30:22300 server_maker_(version_,
301 quic::QuicUtils::CreateRandomConnectionId(
302 context_.random_generator()),
303 context_.clock(),
304 kDefaultServerHostName,
305 quic::Perspective::IS_SERVER,
306 false),
307 quic_task_runner_(new TestTaskRunner(context_.mock_clock())),
rtenneti052774e2015-11-24 21:00:12308 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43309 ssl_config_service_(new SSLConfigServiceDefaults),
Nicolas Arciniegad2013f92020-02-07 23:00:56310 proxy_resolution_service_(
311 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11312 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke3233d8f22019-08-20 21:01:49313 http_server_properties_(std::make_unique<HttpServerProperties>()),
rchf114d982015-10-21 01:34:56314 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:19315 FLAGS_quic_enable_http3_grease_randomness = false;
[email protected]aa9b14d2013-05-10 23:45:19316 request_.method = "GET";
rchf114d982015-10-21 01:34:56317 std::string url("https://");
bncb07c05532015-05-14 19:07:20318 url.append(kDefaultServerHostName);
319 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19320 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10321 request_.traffic_annotation =
322 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Victor Vasiliev7752898d2019-11-14 21:30:22323 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56324
325 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29326 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56327 verify_details_.cert_verify_result.verified_cert = cert;
328 verify_details_.cert_verify_result.is_issued_by_known_root = true;
329 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43330 }
[email protected]61a527782013-02-21 03:58:00331
dcheng67be2b1f2014-10-27 21:47:29332 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00333 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55334 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00335 }
336
dcheng67be2b1f2014-10-27 21:47:29337 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00338 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
339 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55340 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00341 PlatformTest::TearDown();
342 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55343 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40344 session_.reset();
[email protected]61a527782013-02-21 03:58:00345 }
346
Ryan Hamilton8d9ee76e2018-05-29 23:52:52347 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23348 ConstructClientConnectionClosePacket(uint64_t num) {
Zhongyi Shi1c022d22020-03-20 19:00:16349 return client_maker_->MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52350 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30351 }
352
Ryan Hamilton8d9ee76e2018-05-29 23:52:52353 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23354 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03355 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52356 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58357 }
358
Ryan Hamilton8d9ee76e2018-05-29 23:52:52359 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23360 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52361 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20362 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58363 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20364 }
365
Ryan Hamilton8d9ee76e2018-05-29 23:52:52366 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23367 uint64_t packet_number,
368 uint64_t largest_received,
369 uint64_t smallest_received,
370 uint64_t least_unacked) {
Zhongyi Shi1c022d22020-03-20 19:00:16371 return client_maker_->MakeAckPacket(packet_number, largest_received,
Bence Béky7a45d4d2020-05-08 01:59:23372 smallest_received, least_unacked);
fayang3bcb8b502016-12-07 21:44:37373 }
374
Ryan Hamilton8d9ee76e2018-05-29 23:52:52375 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23376 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52377 quic::QuicStreamId stream_id,
378 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23379 uint64_t largest_received,
380 uint64_t smallest_received,
381 uint64_t least_unacked) {
Bence Béky7a45d4d2020-05-08 01:59:23382 return client_maker_->MakeAckAndRstPacket(num, false, stream_id, error_code,
383 largest_received,
384 smallest_received, least_unacked);
zhongyi6b5a3892016-03-12 04:46:20385 }
386
Ryan Hamilton8d9ee76e2018-05-29 23:52:52387 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23388 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52389 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41390 quic::QuicRstStreamErrorCode error_code) {
Zhongyi Shi1c022d22020-03-20 19:00:16391 return client_maker_->MakeRstPacket(num, false, stream_id, error_code,
392 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56393 }
394
Ryan Hamilton8d9ee76e2018-05-29 23:52:52395 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23396 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
397 uint64_t largest_received,
398 uint64_t smallest_received,
399 uint64_t least_unacked) {
Zhongyi Shi1c022d22020-03-20 19:00:16400 return client_maker_->MakeAckPacket(packet_number, largest_received,
Bence Béky7a45d4d2020-05-08 01:59:23401 smallest_received, least_unacked);
[email protected]1e960032013-12-20 19:00:20402 }
[email protected]61a527782013-02-21 03:58:00403
Ryan Hamilton8d9ee76e2018-05-29 23:52:52404 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58405 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23406 uint64_t num,
Fan Yangac867502019-01-28 21:10:23407 uint64_t largest_received,
408 uint64_t smallest_received,
409 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52410 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29411 const std::string& quic_error_details,
412 uint64_t frame_type) {
Zhongyi Shi1c022d22020-03-20 19:00:16413 return client_maker_->MakeAckAndConnectionClosePacket(
Bence Békyde6290f2019-12-19 15:21:53414 num, false, largest_received, smallest_received, least_unacked,
415 quic_error, quic_error_details, frame_type);
zhongyica364fbb2015-12-12 03:39:12416 }
417
Ryan Hamilton8d9ee76e2018-05-29 23:52:52418 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23419 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12420 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52421 quic::QuicStreamId stream_id,
422 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58423 return server_maker_.MakeRstPacket(num, include_version, stream_id,
424 error_code);
zhongyica364fbb2015-12-12 03:39:12425 }
426
Ryan Hamilton8d9ee76e2018-05-29 23:52:52427 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02428 uint64_t packet_number) {
Zhongyi Shi1c022d22020-03-20 19:00:16429 return client_maker_->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37430 }
431
Ryan Hamilton8d9ee76e2018-05-29 23:52:52432 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23433 uint64_t packet_number,
434 uint64_t largest_received,
435 uint64_t smallest_received,
436 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37437 return server_maker_.MakeAckPacket(packet_number, largest_received,
Bence Béky7a45d4d2020-05-08 01:59:23438 smallest_received, least_unacked);
fayang3bcb8b502016-12-07 21:44:37439 }
440
Ryan Hamilton8d9ee76e2018-05-29 23:52:52441 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23442 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57443 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52444 quic::QuicStreamId id,
445 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02446 RequestPriority request_priority) {
Zhongyi Shi1c022d22020-03-20 19:00:16447 return client_maker_->MakePriorityPacket(
Yixin Wangb470bc882018-02-15 18:43:57448 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02449 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wang385652a2018-02-16 02:37:23450 }
451
Ryan Hamilton8d9ee76e2018-05-29 23:52:52452 std::unique_ptr<quic::QuicEncryptedPacket>
Haoyue Wang9d70d65c2020-05-29 22:45:34453 ConstructClientPriorityFramesPacket(
454 uint64_t packet_number,
455 bool should_include_version,
456 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
457 priority_frames) {
458 return client_maker_->MakeMultiplePriorityFramesPacket(
459 packet_number, should_include_version, priority_frames);
460 }
461
462 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25463 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23464 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23465 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23466 uint64_t largest_received,
467 uint64_t smallest_received,
468 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25469 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
Ryan Hamilton0d65a8c2019-06-07 00:46:02470 priority_frames) {
Zhongyi Shi1c022d22020-03-20 19:00:16471 return client_maker_->MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23472 packet_number, should_include_version, largest_received,
Ryan Hamilton0d65a8c2019-06-07 00:46:02473 smallest_received, least_unacked, priority_frames);
Yixin Wangb470bc882018-02-15 18:43:57474 }
475
Haoyue Wang9d70d65c2020-05-29 22:45:34476 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckAndPriorityPacket(
477 uint64_t packet_number,
478 bool should_include_version,
479 uint64_t largest_received,
480 uint64_t smallest_received,
481 quic::QuicStreamId id,
482 quic::QuicStreamId parent_stream_id,
483 RequestPriority request_priority) {
484 return client_maker_->MakeAckAndPriorityPacket(
485 packet_number, should_include_version, largest_received,
486 smallest_received, id, parent_stream_id,
487 ConvertRequestPriorityToQuicPriority(request_priority));
488 }
489
zhongyi32569c62016-01-08 02:54:30490 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13491 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
492 const std::string& scheme,
493 const std::string& path) {
Zhongyi Shi1c022d22020-03-20 19:00:16494 return GetRequestHeaders(method, scheme, path, client_maker_.get());
zhongyi32569c62016-01-08 02:54:30495 }
496
497 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13498 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
499 const std::string& scheme,
500 const std::string& path,
501 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50502 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00503 }
504
Ryan Hamilton0239aac2018-05-19 00:03:13505 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Zhongyi Shi1c022d22020-03-20 19:00:16506 return client_maker_->ConnectRequestHeaders(host_port);
Yixin Wang46a273ec302018-01-23 17:59:56507 }
508
Ryan Hamilton0239aac2018-05-19 00:03:13509 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58510 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00511 }
512
zhongyi32569c62016-01-08 02:54:30513 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13514 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
515 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58516 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30517 }
518
Ryan Hamilton8d9ee76e2018-05-29 23:52:52519 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23520 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52521 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05522 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00523 bool fin,
Zhongyi Shid1c00fc42019-12-14 06:05:09524 quiche::QuicheStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17525 return server_maker_.MakeDataPacket(packet_number, stream_id,
526 should_include_version, fin, data);
[email protected]61a527782013-02-21 03:58:00527 }
528
Ryan Hamilton8d9ee76e2018-05-29 23:52:52529 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23530 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52531 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36532 bool should_include_version,
533 bool fin,
Zhongyi Shid1c00fc42019-12-14 06:05:09534 quiche::QuicheStringPiece data) {
Zhongyi Shi1c022d22020-03-20 19:00:16535 return client_maker_->MakeDataPacket(packet_number, stream_id,
536 should_include_version, fin, data);
ckrasicda193a82016-07-09 00:39:36537 }
538
Ryan Hamilton8d9ee76e2018-05-29 23:52:52539 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23540 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56541 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52542 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23543 uint64_t largest_received,
544 uint64_t smallest_received,
545 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56546 bool fin,
Zhongyi Shid1c00fc42019-12-14 06:05:09547 quiche::QuicheStringPiece data) {
Zhongyi Shi1c022d22020-03-20 19:00:16548 return client_maker_->MakeAckAndDataPacket(
Yixin Wang46a273ec302018-01-23 17:59:56549 packet_number, include_version, stream_id, largest_received,
Ryan Hamilton7505eb92019-06-08 00:22:17550 smallest_received, least_unacked, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56551 }
552
Ryan Hamilton8d9ee76e2018-05-29 23:52:52553 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23554 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52555 quic::QuicStreamId stream_id,
556 bool should_include_version,
557 bool fin,
558 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56559 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
560 should_include_version, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02561 std::move(headers), 0);
Yixin Wang46a273ec302018-01-23 17:59:56562 }
563
Ryan Hamilton8d9ee76e2018-05-29 23:52:52564 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23565 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52566 quic::QuicStreamId stream_id,
567 bool should_include_version,
568 bool fin,
569 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02570 quic::QuicStreamId parent_stream_id) {
Yixin Wang46a273ec302018-01-23 17:59:56571 return ConstructClientRequestHeadersPacket(
572 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:02573 std::move(headers), parent_stream_id);
zhongyi32569c62016-01-08 02:54:30574 }
575
Ryan Hamilton8d9ee76e2018-05-29 23:52:52576 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23577 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52578 quic::QuicStreamId stream_id,
579 bool should_include_version,
580 bool fin,
581 RequestPriority request_priority,
582 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02583 quic::QuicStreamId parent_stream_id) {
Ryan Hamilton0239aac2018-05-19 00:03:13584 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56585 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16586 return client_maker_->MakeRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56587 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02588 std::move(headers), parent_stream_id, nullptr);
[email protected]61a527782013-02-21 03:58:00589 }
590
Ryan Hamilton8d9ee76e2018-05-29 23:52:52591 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25592 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23593 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52594 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25595 bool should_include_version,
596 bool fin,
597 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13598 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52599 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25600 size_t* spdy_headers_frame_length,
601 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13602 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25603 ConvertRequestPriorityToQuicPriority(request_priority);
Zhongyi Shi1c022d22020-03-20 19:00:16604 return client_maker_->MakeRequestHeadersAndMultipleDataFramesPacket(
Yixin Wange7ecc472018-03-06 19:00:25605 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02606 std::move(headers), parent_stream_id, spdy_headers_frame_length,
Yixin Wange7ecc472018-03-06 19:00:25607 data_writes);
608 }
609
Ryan Hamilton8d9ee76e2018-05-29 23:52:52610 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23611 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52612 quic::QuicStreamId stream_id,
613 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13614 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13615 spdy::SpdyHeaderBlock headers,
ckrasic769733c2016-06-30 00:42:13616 QuicTestPacketMaker* maker) {
617 return maker->MakePushPromisePacket(
618 packet_number, stream_id, promised_stream_id, should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02619 false, std::move(headers), nullptr);
ckrasic769733c2016-06-30 00:42:13620 }
621
Ryan Hamilton8d9ee76e2018-05-29 23:52:52622 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23623 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52624 quic::QuicStreamId stream_id,
625 bool should_include_version,
626 bool fin,
627 spdy::SpdyHeaderBlock headers) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02628 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
629 should_include_version, fin,
630 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30631 }
632
Victor Vasiliev076657c2019-03-12 02:46:43633 std::string ConstructDataHeader(size_t body_len) {
Nick Harperc6cb7a612020-02-24 20:03:32634 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:41635 return "";
636 }
Renjief49758b2019-01-11 23:32:41637 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:57638 auto header_length =
639 quic::HttpEncoder::SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43640 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41641 }
642
Nick Harper23290b82019-05-02 00:02:56643 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41644 session_params_.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:38645 context_.params()->supported_versions = supported_versions;
Victor Vasilieva1e66d72019-12-05 17:55:38646 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:05647 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00648
Victor Vasiliev7752898d2019-11-14 21:30:22649 session_context_.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:41650 session_context_.client_socket_factory = &socket_factory_;
651 session_context_.quic_crypto_client_stream_factory =
652 &crypto_client_stream_factory_;
653 session_context_.host_resolver = &host_resolver_;
654 session_context_.cert_verifier = &cert_verifier_;
655 session_context_.transport_security_state = &transport_security_state_;
656 session_context_.cert_transparency_verifier =
657 cert_transparency_verifier_.get();
658 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
659 session_context_.socket_performance_watcher_factory =
660 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59661 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41662 session_context_.ssl_config_service = ssl_config_service_.get();
663 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49664 session_context_.http_server_properties = http_server_properties_.get();
mmenke6ddfbea2017-05-31 21:48:41665 session_context_.net_log = net_log_.bound().net_log();
666
667 session_.reset(new HttpNetworkSession(session_params_, session_context_));
Matt Menkeb566c392019-09-11 23:22:43668 session_->quic_stream_factory()
669 ->set_is_quic_known_to_work_on_current_network(true);
Yixin Wang46a273ec302018-01-23 17:59:56670 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
671 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00672 }
673
zhongyi86838d52017-06-30 01:19:44674 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21675
David Schinazif832cb82019-11-08 22:25:27676 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
Zhongyi Shi1c022d22020-03-20 19:00:16677 const std::string& status_line,
678 const quic::ParsedQuicVersion& version) {
[email protected]aa9b14d2013-05-10 23:45:19679 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42680 ASSERT_TRUE(response != nullptr);
681 ASSERT_TRUE(response->headers.get() != nullptr);
David Schinazif832cb82019-11-08 22:25:27682 EXPECT_EQ(status_line, response->headers->GetStatusLine());
[email protected]aa9b14d2013-05-10 23:45:19683 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52684 EXPECT_TRUE(response->was_alpn_negotiated);
Zhongyi Shi1c022d22020-03-20 19:00:16685 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version),
[email protected]aa9b14d2013-05-10 23:45:19686 response->connection_info);
687 }
688
Zhongyi Shi1c022d22020-03-20 19:00:16689 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
690 const std::string& status_line) {
691 CheckWasQuicResponse(trans, status_line, version_);
692 }
693
David Schinazif832cb82019-11-08 22:25:27694 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
Zhongyi Shi1c022d22020-03-20 19:00:16695 CheckWasQuicResponse(trans, "HTTP/1.1 200 OK", version_);
David Schinazif832cb82019-11-08 22:25:27696 }
697
bnc691fda62016-08-12 00:43:16698 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41699 const HttpResponseInfo* response = trans->GetResponseInfo();
700 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37701 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41702 }
703
bnc691fda62016-08-12 00:43:16704 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19705 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42706 ASSERT_TRUE(response != nullptr);
707 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19708 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
709 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52710 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52711 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19712 response->connection_info);
713 }
714
Yixin Wang46a273ec302018-01-23 17:59:56715 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
716 const HttpResponseInfo* response = trans->GetResponseInfo();
717 ASSERT_TRUE(response != nullptr);
718 ASSERT_TRUE(response->headers.get() != nullptr);
719 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
720 EXPECT_TRUE(response->was_fetched_via_spdy);
721 EXPECT_TRUE(response->was_alpn_negotiated);
722 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
723 response->connection_info);
724 }
725
bnc691fda62016-08-12 00:43:16726 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19727 const std::string& expected) {
728 std::string response_data;
bnc691fda62016-08-12 00:43:16729 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19730 EXPECT_EQ(expected, response_data);
731 }
732
bnc691fda62016-08-12 00:43:16733 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19734 TestCompletionCallback callback;
735 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01736 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
737 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19738 }
739
740 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16741 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
742 RunTransaction(&trans);
743 CheckWasHttpResponse(&trans);
744 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19745 }
746
tbansalc3308d72016-08-27 10:25:04747 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
748 bool used_proxy,
749 uint16_t port) {
750 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalc3308d72016-08-27 10:25:04751 RunTransaction(&trans);
752 CheckWasHttpResponse(&trans);
753 CheckResponsePort(&trans, port);
754 CheckResponseData(&trans, expected);
tbansal2ecbbc72016-10-06 17:15:47755 if (used_proxy) {
756 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
757 } else {
758 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
759 }
tbansalc3308d72016-08-27 10:25:04760 }
David Schinazif832cb82019-11-08 22:25:27761 void SendRequestAndExpectQuicResponse(const std::string& expected,
762 const std::string& status_line) {
763 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443,
764 status_line);
765 }
tbansalc3308d72016-08-27 10:25:04766
[email protected]aa9b14d2013-05-10 23:45:19767 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56768 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12769 }
770
bnc62a44f022015-04-02 15:59:41771 void SendRequestAndExpectQuicResponseFromProxyOnPort(
772 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46773 uint16_t port) {
bnc62a44f022015-04-02 15:59:41774 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19775 }
776
777 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05778 MockCryptoClientStream::HandshakeMode handshake_mode,
779 const NetworkIsolationKey& network_isolation_key =
780 NetworkIsolationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19781 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46782 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21783 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12784 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49785 http_server_properties_->SetQuicAlternativeService(
Matt Menkeb32ba5122019-09-10 19:17:05786 server, network_isolation_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07787 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19788 }
789
rchbe69cb902016-02-11 01:10:48790 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27791 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48792 const HostPortPair& alternative) {
793 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46794 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21795 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48796 alternative.port());
797 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49798 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07799 server, NetworkIsolationKey(), alternative_service, expiration,
800 supported_versions_);
rchbe69cb902016-02-11 01:10:48801 }
802
Matt Menkeb32ba5122019-09-10 19:17:05803 void ExpectBrokenAlternateProtocolMapping(
804 const NetworkIsolationKey& network_isolation_key =
805 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46806 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34807 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49808 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05809 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34810 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49811 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05812 alternative_service_info_vector[0].alternative_service(),
813 network_isolation_key));
[email protected]aa9b14d2013-05-10 23:45:19814 }
815
Matt Menkeb32ba5122019-09-10 19:17:05816 void ExpectQuicAlternateProtocolMapping(
817 const NetworkIsolationKey& network_isolation_key =
818 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46819 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34820 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49821 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05822 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34823 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54824 EXPECT_EQ(
825 kProtoQUIC,
826 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49827 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05828 alternative_service_info_vector[0].alternative_service(),
829 network_isolation_key));
[email protected]4d590c9c2014-05-02 05:14:33830 }
831
[email protected]aa9b14d2013-05-10 23:45:19832 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42833 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30834 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30835 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30836 hanging_data->set_connect_data(hanging_connect);
837 hanging_data_.push_back(std::move(hanging_data));
838 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56839 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19840 }
841
Zhongyi Shia6b68d112018-09-24 07:49:03842 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Victor Vasilieva1e66d72019-12-05 17:55:38843 context_.params()->migrate_sessions_on_network_change_v2 = true;
844 context_.params()->migrate_sessions_early_v2 = true;
845 context_.params()->retry_on_alternate_network_before_handshake = true;
Zhongyi Shia6b68d112018-09-24 07:49:03846 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
847 MockNetworkChangeNotifier* mock_ncn =
848 scoped_mock_change_notifier_->mock_network_change_notifier();
849 mock_ncn->ForceNetworkHandlesSupported();
850 mock_ncn->SetConnectedNetworksList(
851 {kDefaultNetworkForTests, kNewNetworkForTests});
852 }
853
tbansalc3308d72016-08-27 10:25:04854 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
855 // alternative proxy. Verifies that if the alternative proxy job returns
856 // |error_code|, the request is fetched successfully by the main job.
857 void TestAlternativeProxy(int error_code) {
858 // Use a non-cryptographic scheme for the request URL since this request
859 // will be fetched via proxy with QUIC as the alternative service.
860 request_.url = GURL("http://example.org/");
861 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27862 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04863 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27864 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04865 };
866
Ryan Sleevib8d7ea02018-05-07 20:01:01867 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04868 socket_factory_.AddSocketDataProvider(&quic_data);
869
870 // Main job succeeds and the alternative job fails.
871 // Add data for two requests that will be read by the main job.
872 MockRead http_reads_1[] = {
873 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
874 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
875 MockRead(ASYNC, OK)};
876
877 MockRead http_reads_2[] = {
878 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
879 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
880 MockRead(ASYNC, OK)};
881
Ryan Sleevib8d7ea02018-05-07 20:01:01882 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
883 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04884 socket_factory_.AddSocketDataProvider(&http_data_1);
885 socket_factory_.AddSocketDataProvider(&http_data_2);
886 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
887 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
888
889 TestProxyDelegate test_proxy_delegate;
890 // Proxy URL is different from the request URL.
891 test_proxy_delegate.set_alternative_proxy_server(
892 ProxyServer::FromPacString("QUIC myproxy.org:443"));
893
Lily Houghton8c2f97d2018-01-22 05:06:59894 proxy_resolution_service_ =
Nicolas Arciniegad2013f92020-02-07 23:00:56895 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49896 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52897 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04898
899 CreateSession();
900 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
901
902 // The first request should be fetched via the HTTPS proxy.
903 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
904
Reilly Grant89a7e512018-01-20 01:57:16905 // Since the main job succeeded only the alternative proxy server should be
906 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59907 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16908 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04909
910 // Verify that the second request completes successfully, and the
911 // alternative proxy server job is not started.
912 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
913 }
914
Matt Menkeb32ba5122019-09-10 19:17:05915 // Adds a new socket data provider for an HTTP request, and runs a request,
916 // expecting it to be used.
917 void AddHttpDataAndRunRequest() {
918 MockWrite http_writes[] = {
919 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
920 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
921 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
922
923 MockRead http_reads[] = {
924 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
925 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
926 MockRead(SYNCHRONOUS, 5, "http used"),
927 // Connection closed.
928 MockRead(SYNCHRONOUS, OK, 6)};
929 SequencedSocketData http_data(http_reads, http_writes);
930 socket_factory_.AddSocketDataProvider(&http_data);
931 SSLSocketDataProvider ssl_data(ASYNC, OK);
932 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
933 SendRequestAndExpectHttpResponse("http used");
934 EXPECT_TRUE(http_data.AllWriteDataConsumed());
935 EXPECT_TRUE(http_data.AllReadDataConsumed());
936 }
937
938 // Adds a new socket data provider for a QUIC request, and runs a request,
939 // expecting it to be used. The new QUIC session is not closed.
940 void AddQuicDataAndRunRequest() {
941 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22942 version_,
943 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
944 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menkeb32ba5122019-09-10 19:17:05945 client_headers_include_h2_stream_dependency_);
946 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22947 version_,
948 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
949 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
950 false);
Matt Menkeb32ba5122019-09-10 19:17:05951 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56952 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05953 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:25954 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:56955 quic_data.AddWrite(
956 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_number++));
957 }
Matt Menkeb32ba5122019-09-10 19:17:05958 quic_data.AddWrite(
959 SYNCHRONOUS,
960 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56961 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
962 true, true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Matt Menkeb32ba5122019-09-10 19:17:05963 GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
964 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
965 quic_data.AddRead(
966 ASYNC, server_maker.MakeResponseHeadersPacket(
967 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
968 false, server_maker.GetResponseHeaders("200 OK"), nullptr));
969 std::string header = ConstructDataHeader(9);
970 quic_data.AddRead(
971 ASYNC, server_maker.MakeDataPacket(
972 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
973 true, header + "quic used"));
974 // Don't care about the final ack.
975 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
976 // No more data to read.
977 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
978 quic_data.AddSocketDataToFactory(&socket_factory_);
979 SendRequestAndExpectQuicResponse("quic used");
980
981 EXPECT_TRUE(quic_data.AllReadDataConsumed());
982 }
983
Bence Béky6e243aa2019-12-13 19:01:07984 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56985 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
986 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36987 }
988
Bence Béky6e243aa2019-12-13 19:01:07989 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56990 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
991 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36992 }
993
Bence Béky6e243aa2019-12-13 19:01:07994 quic::QuicStreamId GetQpackDecoderStreamId() const {
995 return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
996 version_.transport_version, 1);
997 }
998
999 std::string StreamCancellationQpackDecoderInstruction(int n) const {
Ian Swettb70d9f8f2020-04-10 23:38:431000 return StreamCancellationQpackDecoderInstruction(n, true);
1001 }
1002
1003 std::string StreamCancellationQpackDecoderInstruction(
1004 int n,
1005 bool create_stream) const {
Bence Béky6e243aa2019-12-13 19:01:071006 const quic::QuicStreamId cancelled_stream_id =
1007 GetNthClientInitiatedBidirectionalStreamId(n);
1008 EXPECT_LT(cancelled_stream_id, 63u);
1009
1010 const unsigned char opcode = 0x40;
Ian Swettb70d9f8f2020-04-10 23:38:431011 if (create_stream) {
1012 return {0x03, opcode | static_cast<unsigned char>(cancelled_stream_id)};
1013 } else {
1014 return {opcode | static_cast<unsigned char>(cancelled_stream_id)};
1015 }
Bence Béky6e243aa2019-12-13 19:01:071016 }
1017
Bence Béky230ac612017-08-30 19:17:081018 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:491019 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:081020 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:491021 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:081022 }
1023
Zhongyi Shi1c022d22020-03-20 19:00:161024 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1025 const std::string& expected,
1026 bool used_proxy,
1027 uint16_t port,
1028 const std::string& status_line,
1029 const quic::ParsedQuicVersion& version) {
1030 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Zhongyi Shi1c022d22020-03-20 19:00:161031 RunTransaction(&trans);
1032 CheckWasQuicResponse(&trans, status_line, version);
1033 CheckResponsePort(&trans, port);
1034 CheckResponseData(&trans, expected);
Zhongyi Shi1c022d22020-03-20 19:00:161035 if (used_proxy) {
1036 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
1037 } else {
1038 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1039 }
1040 }
1041
Nick Harper23290b82019-05-02 00:02:561042 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:051043 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:561044 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:011045 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Victor Vasiliev7752898d2019-11-14 21:30:221046 MockQuicContext context_;
Zhongyi Shi1c022d22020-03-20 19:00:161047 std::unique_ptr<QuicTestPacketMaker> client_maker_;
alyssar2adf3ac2016-05-03 17:12:581048 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:091049 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:421050 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:001051 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:561052 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:051053 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:431054 MockHostResolver host_resolver_;
1055 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:111056 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:421057 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:231058 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:381059 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:071060 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:261061 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:421062 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:491063 std::unique_ptr<HttpServerProperties> http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:411064 HttpNetworkSession::Params session_params_;
1065 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:191066 HttpRequestInfo request_;
Matt Muellerd9342e3a2019-11-26 01:41:141067 RecordingBoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:421068 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:561069 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:031070 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:121071
1072 private:
1073 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1074 const std::string& expected,
bnc62a44f022015-04-02 15:59:411075 bool used_proxy,
David Schinazif832cb82019-11-08 22:25:271076 uint16_t port,
1077 const std::string& status_line) {
Zhongyi Shi1c022d22020-03-20 19:00:161078 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
1079 status_line, version_);
tbansal7cec3812015-02-05 21:25:121080 }
David Schinazif832cb82019-11-08 22:25:271081
1082 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1083 const std::string& expected,
1084 bool used_proxy,
1085 uint16_t port) {
1086 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
Zhongyi Shi1c022d22020-03-20 19:00:161087 "HTTP/1.1 200 OK", version_);
David Schinazif832cb82019-11-08 22:25:271088 }
[email protected]61a527782013-02-21 03:58:001089};
1090
David Schinazi09e9a6012019-10-03 17:37:571091INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1092 QuicNetworkTransactionTest,
1093 ::testing::ValuesIn(GetTestParams()),
1094 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201095
Shivani Sharma8ae506c2019-07-21 21:08:271096// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
1097// kAppendInitiatingFrameOriginToNetworkIsolationKey.
1098
Ryan Hamiltona64a5bcf2017-11-30 07:35:281099TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:381100 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281101 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381102 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281103 HostPortPair::FromString("mail.example.org:443"));
1104 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271105 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281106
Ryan Hamiltonabad59e2019-06-06 04:02:591107 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251108 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231109 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281110 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1111 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1112 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1113
1114 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1115
1116 CreateSession();
1117
1118 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1119 TestCompletionCallback callback;
1120 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1121 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1122 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1123
1124 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1125 -ERR_INTERNET_DISCONNECTED, 1);
1126 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1127 -ERR_INTERNET_DISCONNECTED, 1);
1128}
1129
1130TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Victor Vasilieva1e66d72019-12-05 17:55:381131 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281132 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381133 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281134 HostPortPair::FromString("mail.example.org:443"));
1135 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271136 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281137
Ryan Hamiltonabad59e2019-06-06 04:02:591138 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251139 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231140 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281141 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1142 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1143 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1144
1145 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1146
1147 CreateSession();
1148
1149 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1150 TestCompletionCallback callback;
1151 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1152 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1153 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1154
1155 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1156 -ERR_INTERNET_DISCONNECTED, 1);
1157 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1158 -ERR_INTERNET_DISCONNECTED, 1);
1159}
1160
tbansal180587c2017-02-16 15:13:231161TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381162 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231163 HostPortPair::FromString("mail.example.org:443"));
1164
Ryan Hamiltonabad59e2019-06-06 04:02:591165 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231166 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251167 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231168 mock_quic_data.AddWrite(SYNCHRONOUS,
1169 ConstructInitialSettingsPacket(packet_num++));
1170 }
rch5cb522462017-04-25 20:18:361171 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231172 SYNCHRONOUS,
1173 ConstructClientRequestHeadersPacket(
1174 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1175 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431176 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331177 ASYNC, ConstructServerResponseHeadersPacket(
1178 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1179 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431180 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331181 mock_quic_data.AddRead(
1182 ASYNC, ConstructServerDataPacket(
1183 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171184 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231185 mock_quic_data.AddWrite(SYNCHRONOUS,
1186 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231187 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1188
1189 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1190
1191 CreateSession();
1192 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1193
1194 EXPECT_FALSE(
1195 test_socket_performance_watcher_factory_.rtt_notification_received());
1196 SendRequestAndExpectQuicResponse("hello!");
1197 EXPECT_TRUE(
1198 test_socket_performance_watcher_factory_.rtt_notification_received());
1199}
1200
1201TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381202 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231203 HostPortPair::FromString("mail.example.org:443"));
1204
Ryan Hamiltonabad59e2019-06-06 04:02:591205 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231206 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251207 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231208 mock_quic_data.AddWrite(SYNCHRONOUS,
1209 ConstructInitialSettingsPacket(packet_num++));
1210 }
rch5cb522462017-04-25 20:18:361211 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231212 SYNCHRONOUS,
1213 ConstructClientRequestHeadersPacket(
1214 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1215 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431216 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331217 ASYNC, ConstructServerResponseHeadersPacket(
1218 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1219 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431220 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331221 mock_quic_data.AddRead(
1222 ASYNC, ConstructServerDataPacket(
1223 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171224 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231225 mock_quic_data.AddWrite(SYNCHRONOUS,
1226 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231227 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1228
1229 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1230
1231 CreateSession();
1232 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1233
1234 EXPECT_FALSE(
1235 test_socket_performance_watcher_factory_.rtt_notification_received());
1236 SendRequestAndExpectQuicResponse("hello!");
1237 EXPECT_FALSE(
1238 test_socket_performance_watcher_factory_.rtt_notification_received());
1239}
1240
[email protected]1e960032013-12-20 19:00:201241TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:381242 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571243 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471244
Ryan Hamiltonabad59e2019-06-06 04:02:591245 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231246 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251247 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231248 mock_quic_data.AddWrite(SYNCHRONOUS,
1249 ConstructInitialSettingsPacket(packet_num++));
1250 }
rch5cb522462017-04-25 20:18:361251 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231252 SYNCHRONOUS,
1253 ConstructClientRequestHeadersPacket(
1254 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1255 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431256 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331257 ASYNC, ConstructServerResponseHeadersPacket(
1258 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1259 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431260 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331261 mock_quic_data.AddRead(
1262 ASYNC, ConstructServerDataPacket(
1263 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171264 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231265 mock_quic_data.AddWrite(SYNCHRONOUS,
1266 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591267 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471268
rcha5399e02015-04-21 19:32:041269 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471270
[email protected]4dca587c2013-03-07 16:54:471271 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471272
[email protected]aa9b14d2013-05-10 23:45:191273 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471274
[email protected]98b20ce2013-05-10 05:55:261275 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:541276 auto entries = net_log_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261277 EXPECT_LT(0u, entries.size());
1278
1279 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291280 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001281 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1282 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261283 EXPECT_LT(0, pos);
1284
rchfd527212015-08-25 00:41:261285 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291286 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261287 entries, 0,
mikecirone8b85c432016-09-08 19:11:001288 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1289 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261290 EXPECT_LT(0, pos);
1291
Eric Roman79cc7552019-07-19 02:17:541292 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261293
rchfd527212015-08-25 00:41:261294 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1295 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001296 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1297 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261298 EXPECT_LT(0, pos);
1299
[email protected]98b20ce2013-05-10 05:55:261300 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291301 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001302 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1303 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261304 EXPECT_LT(0, pos);
1305
Eric Roman79cc7552019-07-19 02:17:541306 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Victor Vasiliev7da08172019-10-14 06:04:251307 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451308 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1309 static_cast<quic::QuicStreamId>(log_stream_id));
1310 } else {
1311 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1312 static_cast<quic::QuicStreamId>(log_stream_id));
1313 }
[email protected]4dca587c2013-03-07 16:54:471314}
1315
Bence Békyb6300042020-01-28 21:18:201316// Regression test for https://crbug.com/1043531.
1317TEST_P(QuicNetworkTransactionTest, ResetOnEmptyResponseHeaders) {
1318 if (!quic::VersionUsesHttp3(version_.transport_version)) {
1319 return;
1320 }
1321
1322 context_.params()->origins_to_force_quic_on.insert(
1323 HostPortPair::FromString("mail.example.org:443"));
1324
1325 MockQuicData mock_quic_data(version_);
1326 int write_packet_num = 1;
1327 mock_quic_data.AddWrite(SYNCHRONOUS,
1328 ConstructInitialSettingsPacket(write_packet_num++));
1329 mock_quic_data.AddWrite(
1330 SYNCHRONOUS,
1331 ConstructClientRequestHeadersPacket(
1332 write_packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1333 true, true, GetRequestHeaders("GET", "https", "/")));
1334
1335 const quic::QuicStreamId request_stream_id =
1336 GetNthClientInitiatedBidirectionalStreamId(0);
1337 spdy::SpdyHeaderBlock empty_response_headers;
1338 const std::string response_data = server_maker_.QpackEncodeHeaders(
1339 request_stream_id, std::move(empty_response_headers), nullptr);
1340 uint64_t read_packet_num = 1;
1341 mock_quic_data.AddRead(
1342 ASYNC, ConstructServerDataPacket(read_packet_num++, request_stream_id,
1343 false, false, response_data));
1344 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1345
1346 mock_quic_data.AddWrite(
1347 ASYNC,
1348 ConstructClientAckAndDataPacket(
1349 write_packet_num++, true, GetQpackDecoderStreamId(), 1, 1, 1, false,
1350 StreamCancellationQpackDecoderInstruction(request_stream_id)));
1351
1352 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1353
1354 CreateSession();
1355
1356 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1357 TestCompletionCallback callback;
1358 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1359 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1360 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_INVALID_RESPONSE));
1361}
1362
rchbd089ab2017-05-26 23:05:041363TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381364 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041365 HostPortPair::FromString("mail.example.org:443"));
1366
Ryan Hamiltonabad59e2019-06-06 04:02:591367 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231368 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251369 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231370 mock_quic_data.AddWrite(SYNCHRONOUS,
1371 ConstructInitialSettingsPacket(packet_num++));
1372 }
rchbd089ab2017-05-26 23:05:041373 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231374 SYNCHRONOUS,
1375 ConstructClientRequestHeadersPacket(
1376 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1377 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0239aac2018-05-19 00:03:131378 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041379 response_headers["key1"] = std::string(30000, 'A');
1380 response_headers["key2"] = std::string(30000, 'A');
1381 response_headers["key3"] = std::string(30000, 'A');
1382 response_headers["key4"] = std::string(30000, 'A');
1383 response_headers["key5"] = std::string(30000, 'A');
1384 response_headers["key6"] = std::string(30000, 'A');
1385 response_headers["key7"] = std::string(30000, 'A');
1386 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451387 quic::QuicStreamId stream_id;
1388 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251389 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451390 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281391 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451392 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451393 } else {
1394 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1395 spdy::SpdyHeadersIR headers_frame(
1396 GetNthClientInitiatedBidirectionalStreamId(0),
1397 std::move(response_headers));
1398 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1399 spdy::SpdySerializedFrame spdy_frame =
1400 response_framer.SerializeFrame(headers_frame);
1401 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1402 }
rchbd089ab2017-05-26 23:05:041403
Fan Yangac867502019-01-28 21:10:231404 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041405 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451406 for (size_t offset = 0; offset < response_data.length();
1407 offset += chunk_size) {
1408 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431409 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451410 ASYNC, ConstructServerDataPacket(
1411 packet_number++, stream_id, false, false,
1412 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041413 }
1414
Victor Vasiliev076657c2019-03-12 02:46:431415 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041416 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331417 ASYNC, ConstructServerDataPacket(
1418 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171419 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041420 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431421 mock_quic_data.AddWrite(ASYNC,
Renjie Tangaadb84b2019-08-31 01:00:231422 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1423 mock_quic_data.AddWrite(
1424 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041425
1426 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1427
1428 CreateSession();
1429
1430 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421431 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1432 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041433}
1434
1435TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381436 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1437 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041438 HostPortPair::FromString("mail.example.org:443"));
1439
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 }
rchbd089ab2017-05-26 23:05:041446 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", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451451
Ryan Hamilton0239aac2018-05-19 00:03:131452 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041453 response_headers["key1"] = std::string(30000, 'A');
1454 response_headers["key2"] = std::string(30000, 'A');
1455 response_headers["key3"] = std::string(30000, 'A');
1456 response_headers["key4"] = std::string(30000, 'A');
1457 response_headers["key5"] = std::string(30000, 'A');
1458 response_headers["key6"] = std::string(30000, 'A');
1459 response_headers["key7"] = std::string(30000, 'A');
1460 response_headers["key8"] = std::string(30000, 'A');
1461 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451462
1463 quic::QuicStreamId stream_id;
1464 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251465 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451466 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281467 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451468 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451469 } else {
1470 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1471 spdy::SpdyHeadersIR headers_frame(
1472 GetNthClientInitiatedBidirectionalStreamId(0),
1473 std::move(response_headers));
1474 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1475 spdy::SpdySerializedFrame spdy_frame =
1476 response_framer.SerializeFrame(headers_frame);
1477 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1478 }
rchbd089ab2017-05-26 23:05:041479
Fan Yangac867502019-01-28 21:10:231480 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041481 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451482 for (size_t offset = 0; offset < response_data.length();
1483 offset += chunk_size) {
1484 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431485 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451486 ASYNC, ConstructServerDataPacket(
1487 packet_number++, stream_id, false, false,
1488 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041489 }
1490
Victor Vasiliev076657c2019-03-12 02:46:431491 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411492
rchbd089ab2017-05-26 23:05:041493 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331494 ASYNC, ConstructServerDataPacket(
1495 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171496 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041497 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:231498 mock_quic_data.AddWrite(ASYNC,
1499 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431500 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331501 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231502 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:331503 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041504
1505 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1506
1507 CreateSession();
1508
1509 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1510 TestCompletionCallback callback;
1511 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1512 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1513 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1514}
1515
rcha2bd44b2016-07-02 00:42:551516TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Victor Vasilieva1e66d72019-12-05 17:55:381517 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551518
Ryan Hamilton9835e662018-08-02 05:36:271519 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551520
Ryan Hamiltonabad59e2019-06-06 04:02:591521 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231522 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251523 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231524 mock_quic_data.AddWrite(SYNCHRONOUS,
1525 ConstructInitialSettingsPacket(packet_num++));
1526 }
rch5cb522462017-04-25 20:18:361527 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231528 SYNCHRONOUS,
1529 ConstructClientRequestHeadersPacket(
1530 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1531 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431532 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331533 ASYNC, ConstructServerResponseHeadersPacket(
1534 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1535 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431536 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331537 mock_quic_data.AddRead(
1538 ASYNC, ConstructServerDataPacket(
1539 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171540 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231541 mock_quic_data.AddWrite(SYNCHRONOUS,
1542 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551543 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1544
1545 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1546
1547 CreateSession();
1548
1549 SendRequestAndExpectQuicResponse("hello!");
1550 EXPECT_TRUE(
1551 test_socket_performance_watcher_factory_.rtt_notification_received());
1552}
1553
David Schinazif832cb82019-11-08 22:25:271554// Regression test for https://crbug.com/695225
1555TEST_P(QuicNetworkTransactionTest, 408Response) {
Victor Vasilieva1e66d72019-12-05 17:55:381556 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
David Schinazif832cb82019-11-08 22:25:271557
1558 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1559
1560 MockQuicData mock_quic_data(version_);
1561 int packet_num = 1;
1562 if (VersionUsesHttp3(version_.transport_version)) {
1563 mock_quic_data.AddWrite(SYNCHRONOUS,
1564 ConstructInitialSettingsPacket(packet_num++));
1565 }
1566 mock_quic_data.AddWrite(
1567 SYNCHRONOUS,
1568 ConstructClientRequestHeadersPacket(
1569 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1570 true, GetRequestHeaders("GET", "https", "/")));
1571 mock_quic_data.AddRead(
1572 ASYNC, ConstructServerResponseHeadersPacket(
1573 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1574 GetResponseHeaders("408 Request Timeout")));
1575 std::string header = ConstructDataHeader(6);
1576 mock_quic_data.AddRead(
1577 ASYNC, ConstructServerDataPacket(
1578 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1579 header + "hello!"));
1580 mock_quic_data.AddWrite(SYNCHRONOUS,
1581 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1582 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1583
1584 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1585
1586 CreateSession();
1587
1588 SendRequestAndExpectQuicResponse("hello!", "HTTP/1.1 408 Request Timeout");
1589}
1590
[email protected]cf3e3cd62014-02-05 16:16:161591TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411592 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561593 proxy_resolution_service_ =
1594 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
1595 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161596
Ryan Hamiltonabad59e2019-06-06 04:02:591597 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231598 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251599 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231600 mock_quic_data.AddWrite(SYNCHRONOUS,
1601 ConstructInitialSettingsPacket(packet_num++));
1602 }
rch5cb522462017-04-25 20:18:361603 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231604 SYNCHRONOUS,
1605 ConstructClientRequestHeadersPacket(
1606 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1607 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431608 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331609 ASYNC, ConstructServerResponseHeadersPacket(
1610 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1611 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431612 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331613 mock_quic_data.AddRead(
1614 ASYNC, ConstructServerDataPacket(
1615 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171616 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231617 mock_quic_data.AddWrite(SYNCHRONOUS,
1618 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501619 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591620 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161621
rcha5399e02015-04-21 19:32:041622 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161623
tbansal0f56a39a2016-04-07 22:03:381624 EXPECT_FALSE(
1625 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161626 // There is no need to set up an alternate protocol job, because
1627 // no attempt will be made to speak to the proxy over TCP.
1628
rch9ae5b3b2016-02-11 00:36:291629 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161630 CreateSession();
1631
bnc62a44f022015-04-02 15:59:411632 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381633 EXPECT_TRUE(
1634 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161635}
1636
bnc313ba9c2015-06-11 15:42:311637// Regression test for https://crbug.com/492458. Test that for an HTTP
1638// connection through a QUIC proxy, the certificate exhibited by the proxy is
1639// checked against the proxy hostname, not the origin hostname.
1640TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291641 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311642 const std::string proxy_host = "www.example.org";
1643
mmenke6ddfbea2017-05-31 21:48:411644 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561645 proxy_resolution_service_ =
1646 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
1647 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311648
Zhongyi Shi1c022d22020-03-20 19:00:161649 client_maker_->set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591650 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231651 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251652 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231653 mock_quic_data.AddWrite(SYNCHRONOUS,
1654 ConstructInitialSettingsPacket(packet_num++));
1655 }
rch5cb522462017-04-25 20:18:361656 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231657 SYNCHRONOUS,
1658 ConstructClientRequestHeadersPacket(
1659 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1660 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431661 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331662 ASYNC, ConstructServerResponseHeadersPacket(
1663 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1664 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431665 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331666 mock_quic_data.AddRead(
1667 ASYNC, ConstructServerDataPacket(
1668 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171669 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231670 mock_quic_data.AddWrite(SYNCHRONOUS,
1671 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501672 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591673 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311674 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1675
1676 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291677 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311678 ASSERT_TRUE(cert.get());
1679 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241680 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1681 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311682 ProofVerifyDetailsChromium verify_details;
1683 verify_details.cert_verify_result.verified_cert = cert;
1684 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561685 ProofVerifyDetailsChromium verify_details2;
1686 verify_details2.cert_verify_result.verified_cert = cert;
1687 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311688
1689 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091690 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321691 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271692 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311693 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1694}
1695
rchbe69cb902016-02-11 01:10:481696TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Victor Vasilieva1e66d72019-12-05 17:55:381697 context_.params()->allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481698 HostPortPair origin("www.example.org", 443);
1699 HostPortPair alternative("mail.example.org", 443);
1700
1701 base::FilePath certs_dir = GetTestCertsDirectory();
1702 scoped_refptr<X509Certificate> cert(
1703 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1704 ASSERT_TRUE(cert.get());
1705 // TODO(rch): the connection should be "to" the origin, so if the cert is
1706 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241707 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1708 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481709 ProofVerifyDetailsChromium verify_details;
1710 verify_details.cert_verify_result.verified_cert = cert;
1711 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1712
Zhongyi Shi1c022d22020-03-20 19:00:161713 client_maker_->set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591714 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021715
Renjie Tangaadb84b2019-08-31 01:00:231716 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251717 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231718 mock_quic_data.AddWrite(SYNCHRONOUS,
1719 ConstructInitialSettingsPacket(packet_num++));
1720 }
rch5cb522462017-04-25 20:18:361721 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231722 SYNCHRONOUS,
1723 ConstructClientRequestHeadersPacket(
1724 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1725 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431726 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331727 ASYNC, ConstructServerResponseHeadersPacket(
1728 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1729 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431730 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331731 mock_quic_data.AddRead(
1732 ASYNC, ConstructServerDataPacket(
1733 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171734 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231735 mock_quic_data.AddWrite(SYNCHRONOUS,
1736 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481737 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1738 mock_quic_data.AddRead(ASYNC, 0);
1739 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1740
1741 request_.url = GURL("https://" + origin.host());
1742 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271743 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091744 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321745 CreateSession();
rchbe69cb902016-02-11 01:10:481746
1747 SendRequestAndExpectQuicResponse("hello!");
1748}
1749
zhongyief3f4ce52017-07-05 23:53:281750TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
David Schinazi84c58bb2020-06-04 20:14:331751 quic::ParsedQuicVersion unsupported_version =
1752 quic::ParsedQuicVersion::Unsupported();
Bence Békyb89104962020-01-24 00:05:171753 // Add support for another QUIC version besides |version_|. Also find an
zhongyief3f4ce52017-07-05 23:53:281754 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561755 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281756 if (version == version_)
1757 continue;
1758 if (supported_versions_.size() != 2) {
1759 supported_versions_.push_back(version);
1760 continue;
1761 }
1762 unsupported_version = version;
1763 break;
1764 }
Bence Békyb89104962020-01-24 00:05:171765 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:331766 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), unsupported_version);
zhongyief3f4ce52017-07-05 23:53:281767
1768 // Set up alternative service to use QUIC with a version that is not
1769 // supported.
1770 url::SchemeHostPort server(request_.url);
1771 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1772 443);
1773 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491774 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071775 server, NetworkIsolationKey(), alternative_service, expiration,
1776 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281777
1778 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491779 http_server_properties_->GetAlternativeServiceInfos(
1780 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281781 EXPECT_EQ(1u, alt_svc_info_vector.size());
1782 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1783 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1784 EXPECT_EQ(unsupported_version,
1785 alt_svc_info_vector[0].advertised_versions()[0]);
1786
1787 // First request should still be sent via TCP as the QUIC version advertised
1788 // in the stored AlternativeService is not supported by the client. However,
1789 // the response from the server will advertise new Alt-Svc with supported
1790 // versions.
David Schinazifbd4c432020-04-07 19:23:551791 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyief3f4ce52017-07-05 23:53:281792 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:171793 MockRead("HTTP/1.1 200 OK\r\n"),
1794 MockRead(altsvc_header.c_str()),
1795 MockRead("\r\n"),
zhongyief3f4ce52017-07-05 23:53:281796 MockRead("hello world"),
1797 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1798 MockRead(ASYNC, OK)};
1799
Ryan Sleevib8d7ea02018-05-07 20:01:011800 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281801 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081802 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281803 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1804
1805 // Second request should be sent via QUIC as a new list of verions supported
1806 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591807 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231808 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251809 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231810 mock_quic_data.AddWrite(SYNCHRONOUS,
1811 ConstructInitialSettingsPacket(packet_num++));
1812 }
zhongyief3f4ce52017-07-05 23:53:281813 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231814 SYNCHRONOUS,
1815 ConstructClientRequestHeadersPacket(
1816 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1817 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431818 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331819 ASYNC, ConstructServerResponseHeadersPacket(
1820 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1821 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431822 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331823 mock_quic_data.AddRead(
1824 ASYNC, ConstructServerDataPacket(
1825 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171826 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231827 mock_quic_data.AddWrite(SYNCHRONOUS,
1828 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281829 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1830 mock_quic_data.AddRead(ASYNC, 0); // EOF
1831
1832 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1833
1834 AddHangingNonAlternateProtocolSocketData();
1835
1836 CreateSession(supported_versions_);
1837
1838 SendRequestAndExpectHttpResponse("hello world");
1839 SendRequestAndExpectQuicResponse("hello!");
1840
1841 // Check alternative service list is updated with new versions.
1842 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491843 session_->http_server_properties()->GetAlternativeServiceInfos(
1844 server, NetworkIsolationKey());
David Schinazi84c58bb2020-06-04 20:14:331845 // Versions that support the legacy Google-specific Alt-Svc format are sent in
1846 // a single Alt-Svc entry, therefore they are accumulated in a single
1847 // AlternativeServiceInfo, whereas more recent versions all have their own
1848 // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
Bence Békyb89104962020-01-24 00:05:171849 quic::ParsedQuicVersionVector alt_svc_negotiated_versions;
1850 for (const auto& alt_svc_info : alt_svc_info_vector) {
1851 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
1852 for (const auto& version : alt_svc_info.advertised_versions()) {
David Schinazifbd4c432020-04-07 19:23:551853 if (std::find(alt_svc_negotiated_versions.begin(),
1854 alt_svc_negotiated_versions.end(),
1855 version) == alt_svc_negotiated_versions.end()) {
1856 alt_svc_negotiated_versions.push_back(version);
1857 }
Bence Békyb89104962020-01-24 00:05:171858 }
1859 }
1860
1861 ASSERT_EQ(supported_versions_.size(), alt_svc_negotiated_versions.size());
1862 auto version_compare = [](const quic::ParsedQuicVersion& a,
1863 const quic::ParsedQuicVersion& b) {
1864 return std::tie(a.transport_version, a.handshake_protocol) <
1865 std::tie(b.transport_version, b.handshake_protocol);
1866 };
1867 std::sort(supported_versions_.begin(), supported_versions_.end(),
1868 version_compare);
1869 std::sort(alt_svc_negotiated_versions.begin(),
1870 alt_svc_negotiated_versions.end(), version_compare);
1871 EXPECT_TRUE(std::equal(supported_versions_.begin(), supported_versions_.end(),
1872 alt_svc_negotiated_versions.begin()));
zhongyief3f4ce52017-07-05 23:53:281873}
1874
bncaccd4962017-04-06 21:00:261875// Regression test for https://crbug.com/546991.
1876// The server might not be able to serve a request on an alternative connection,
1877// and might send a 421 Misdirected Request response status to indicate this.
1878// HttpNetworkTransaction should reset the request and retry without using
1879// alternative services.
1880TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1881 // Set up alternative service to use QUIC.
1882 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1883 // that overrides |enable_alternative_services|.
1884 url::SchemeHostPort server(request_.url);
1885 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1886 443);
1887 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491888 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071889 server, NetworkIsolationKey(), alternative_service, expiration,
1890 supported_versions_);
bncaccd4962017-04-06 21:00:261891
davidbena4449722017-05-05 23:30:531892 // First try: The alternative job uses QUIC and reports an HTTP 421
1893 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1894 // paused at Connect(), so it will never exit the socket pool. This ensures
1895 // that the alternate job always wins the race and keeps whether the
1896 // |http_data| exits the socket pool before the main job is aborted
1897 // deterministic. The first main job gets aborted without the socket pool ever
1898 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591899 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231900 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251901 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231902 mock_quic_data.AddWrite(SYNCHRONOUS,
1903 ConstructInitialSettingsPacket(packet_num++));
1904 }
rch5cb522462017-04-25 20:18:361905 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231906 SYNCHRONOUS,
1907 ConstructClientRequestHeadersPacket(
1908 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1909 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331910 mock_quic_data.AddRead(
1911 ASYNC, ConstructServerResponseHeadersPacket(
1912 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021913 GetResponseHeaders("421")));
bncaccd4962017-04-06 21:00:261914 mock_quic_data.AddRead(ASYNC, OK);
1915 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1916
davidbena4449722017-05-05 23:30:531917 // Second try: The main job uses TCP, and there is no alternate job. Once the
1918 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1919 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261920 // Note that if there was an alternative QUIC Job created for the second try,
1921 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1922 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531923 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1924 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1925 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1926 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1927 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1928 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011929 reads, writes);
bncaccd4962017-04-06 21:00:261930 socket_factory_.AddSocketDataProvider(&http_data);
1931 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1932
bncaccd4962017-04-06 21:00:261933 CreateSession();
1934 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531935
1936 // Run until |mock_quic_data| has failed and |http_data| has paused.
1937 TestCompletionCallback callback;
1938 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1939 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1940 base::RunLoop().RunUntilIdle();
1941
1942 // |mock_quic_data| must have run to completion.
1943 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1944 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1945
1946 // Now that the QUIC data has been consumed, unblock |http_data|.
1947 http_data.socket()->OnConnectComplete(MockConnect());
1948
1949 // The retry logic must hide the 421 status. The transaction succeeds on
1950 // |http_data|.
1951 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261952 CheckWasHttpResponse(&trans);
1953 CheckResponsePort(&trans, 443);
1954 CheckResponseData(&trans, "hello!");
1955}
1956
[email protected]1e960032013-12-20 19:00:201957TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Victor Vasilieva1e66d72019-12-05 17:55:381958 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571959 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301960
Ryan Hamiltonabad59e2019-06-06 04:02:591961 MockQuicData mock_quic_data1(version_);
Victor Vasiliev7da08172019-10-14 06:04:251962 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231963 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401964 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Zhongyi Shi1c022d22020-03-20 19:00:161965 client_maker_->Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591966 MockQuicData mock_quic_data2(version_);
Victor Vasiliev7da08172019-10-14 06:04:251967 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231968 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301969 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401970 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431971 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401972
1973 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1974 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301975
1976 CreateSession();
1977
tbansal0f56a39a2016-04-07 22:03:381978 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401979 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161980 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401981 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161982 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1984 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381985 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531986
1987 NetErrorDetails details;
1988 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521989 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401990 }
[email protected]cebe3282013-05-22 23:49:301991}
1992
tbansalc8a94ea2015-11-02 23:58:511993TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1994 // Attempt to "force" quic on 443, which will not be honored.
Victor Vasilieva1e66d72019-12-05 17:55:381995 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571996 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511997
1998 MockRead http_reads[] = {
1999 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
2000 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2001 MockRead(ASYNC, OK)};
2002
Ryan Sleevib8d7ea02018-05-07 20:01:012003 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:512004 socket_factory_.AddSocketDataProvider(&data);
2005 SSLSocketDataProvider ssl(ASYNC, OK);
2006 socket_factory_.AddSSLSocketDataProvider(&ssl);
2007
2008 CreateSession();
2009
2010 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:382011 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:512012}
2013
bncc958faa2015-07-31 18:14:522014TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:522015 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:562016 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
2017 MockRead("hello world"),
bncc958faa2015-07-31 18:14:522018 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2019 MockRead(ASYNC, OK)};
2020
Ryan Sleevib8d7ea02018-05-07 20:01:012021 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:522022 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082023 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:562024 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:522025
Ryan Hamiltonabad59e2019-06-06 04:02:592026 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232027 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252028 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232029 mock_quic_data.AddWrite(SYNCHRONOUS,
2030 ConstructInitialSettingsPacket(packet_num++));
2031 }
rch5cb522462017-04-25 20:18:362032 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232033 SYNCHRONOUS,
2034 ConstructClientRequestHeadersPacket(
2035 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2036 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432037 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332038 ASYNC, ConstructServerResponseHeadersPacket(
2039 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2040 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432041 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332042 mock_quic_data.AddRead(
2043 ASYNC, ConstructServerDataPacket(
2044 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172045 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232046 mock_quic_data.AddWrite(SYNCHRONOUS,
2047 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:522048 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592049 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:522050
2051 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2052
rtennetib8e80fb2016-05-16 00:12:092053 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322054 CreateSession();
bncc958faa2015-07-31 18:14:522055
2056 SendRequestAndExpectHttpResponse("hello world");
2057 SendRequestAndExpectQuicResponse("hello!");
2058}
2059
Ryan Hamilton64f21d52019-08-31 07:10:512060TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
2061 std::string alt_svc_header =
2062 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
2063 MockRead http_reads[] = {
2064 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
2065 MockRead("hello world"),
2066 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2067 MockRead(ASYNC, OK)};
2068
2069 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2070 socket_factory_.AddSocketDataProvider(&http_data);
2071 AddCertificate(&ssl_data_);
2072 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2073
2074 MockQuicData mock_quic_data(version_);
2075 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252076 if (VersionUsesHttp3(version_.transport_version)) {
Ryan Hamilton64f21d52019-08-31 07:10:512077 mock_quic_data.AddWrite(SYNCHRONOUS,
2078 ConstructInitialSettingsPacket(packet_num++));
2079 }
2080 mock_quic_data.AddWrite(
2081 SYNCHRONOUS,
2082 ConstructClientRequestHeadersPacket(
2083 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2084 true, GetRequestHeaders("GET", "https", "/")));
2085 mock_quic_data.AddRead(
2086 ASYNC, ConstructServerResponseHeadersPacket(
2087 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2088 GetResponseHeaders("200 OK")));
2089 std::string header = ConstructDataHeader(6);
2090 mock_quic_data.AddRead(
2091 ASYNC, ConstructServerDataPacket(
2092 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2093 header + "hello!"));
2094 mock_quic_data.AddWrite(SYNCHRONOUS,
2095 ConstructClientAckPacket(packet_num++, 2, 1, 1));
2096 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2097 mock_quic_data.AddRead(ASYNC, 0); // EOF
2098
2099 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2100
2101 AddHangingNonAlternateProtocolSocketData();
2102 CreateSession();
2103
2104 SendRequestAndExpectHttpResponse("hello world");
2105 SendRequestAndExpectQuicResponse("hello!");
2106}
2107
Matt Menke3233d8f22019-08-20 21:01:492108// Much like above, but makes sure NetworkIsolationKey is respected.
2109TEST_P(QuicNetworkTransactionTest,
2110 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
2111 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:052112 feature_list.InitWithFeatures(
2113 // enabled_features
2114 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2115 features::kPartitionConnectionsByNetworkIsolationKey},
2116 // disabled_features
2117 {});
Matt Menke3233d8f22019-08-20 21:01:492118 // Since HttpServerProperties caches the feature value, have to create a new
2119 // one.
2120 http_server_properties_ = std::make_unique<HttpServerProperties>();
2121
2122 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2123 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2124 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2125 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2126
2127 MockRead http_reads[] = {
2128 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
2129 MockRead("hello world"),
2130 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2131 MockRead(ASYNC, OK)};
2132
2133 AddCertificate(&ssl_data_);
2134
2135 // Request with empty NetworkIsolationKey.
2136 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2137 socket_factory_.AddSocketDataProvider(&http_data1);
2138 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2139
2140 // First request with kNetworkIsolationKey1.
2141 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2142 socket_factory_.AddSocketDataProvider(&http_data2);
2143 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2144
2145 // Request with kNetworkIsolationKey2.
2146 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2147 socket_factory_.AddSocketDataProvider(&http_data3);
2148 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2149
2150 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2151 // alternative service infrmation has been received in this context before.
2152 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232153 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252154 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232155 mock_quic_data.AddWrite(SYNCHRONOUS,
2156 ConstructInitialSettingsPacket(packet_num++));
2157 }
Matt Menke3233d8f22019-08-20 21:01:492158 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232159 SYNCHRONOUS,
2160 ConstructClientRequestHeadersPacket(
2161 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2162 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492163 mock_quic_data.AddRead(
2164 ASYNC, ConstructServerResponseHeadersPacket(
2165 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2166 GetResponseHeaders("200 OK")));
2167 std::string header = ConstructDataHeader(6);
2168 mock_quic_data.AddRead(
2169 ASYNC, ConstructServerDataPacket(
2170 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2171 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232172 mock_quic_data.AddWrite(SYNCHRONOUS,
2173 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke3233d8f22019-08-20 21:01:492174 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2175 mock_quic_data.AddRead(ASYNC, 0); // EOF
2176
2177 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2178
2179 AddHangingNonAlternateProtocolSocketData();
2180 CreateSession();
2181
2182 // This is first so that the test fails if alternative service info is
2183 // written with the right NetworkIsolationKey, but always queried with an
2184 // empty one.
2185 request_.network_isolation_key = NetworkIsolationKey();
2186 SendRequestAndExpectHttpResponse("hello world");
2187 request_.network_isolation_key = kNetworkIsolationKey1;
2188 SendRequestAndExpectHttpResponse("hello world");
2189 request_.network_isolation_key = kNetworkIsolationKey2;
2190 SendRequestAndExpectHttpResponse("hello world");
2191
2192 // Only use QUIC when using a NetworkIsolationKey which has been used when
2193 // alternative service information was received.
2194 request_.network_isolation_key = kNetworkIsolationKey1;
2195 SendRequestAndExpectQuicResponse("hello!");
2196}
2197
zhongyia00ca012017-07-06 23:36:392198TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
2199 // Both server advertises and client supports two QUIC versions.
2200 // Only |version_| is advertised and supported.
2201 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2202 // PacketMakers are using |version_|.
2203
2204 // Add support for another QUIC version besides |version_| on the client side.
2205 // Also find a different version advertised by the server.
David Schinazi84c58bb2020-06-04 20:14:332206 quic::ParsedQuicVersion advertised_version_2 =
2207 quic::ParsedQuicVersion::Unsupported();
Nick Harper23290b82019-05-02 00:02:562208 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392209 if (version == version_)
2210 continue;
2211 if (supported_versions_.size() != 2) {
2212 supported_versions_.push_back(version);
2213 continue;
2214 }
2215 advertised_version_2 = version;
2216 break;
2217 }
Bence Békyb89104962020-01-24 00:05:172218 ASSERT_EQ(2u, supported_versions_.size());
David Schinazi84c58bb2020-06-04 20:14:332219 ASSERT_NE(quic::ParsedQuicVersion::Unsupported(), advertised_version_2);
zhongyia00ca012017-07-06 23:36:392220
Bence Békyb89104962020-01-24 00:05:172221 std::string QuicAltSvcWithVersionHeader =
2222 base::StringPrintf("Alt-Svc: %s=\":443\", %s=\":443\"\r\n\r\n",
2223 quic::AlpnForVersion(advertised_version_2).c_str(),
2224 quic::AlpnForVersion(version_).c_str());
zhongyia00ca012017-07-06 23:36:392225
2226 MockRead http_reads[] = {
2227 MockRead("HTTP/1.1 200 OK\r\n"),
2228 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2229 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2230 MockRead(ASYNC, OK)};
2231
Ryan Sleevib8d7ea02018-05-07 20:01:012232 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392233 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082234 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392235 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2236
Ryan Hamiltonabad59e2019-06-06 04:02:592237 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232238 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252239 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232240 mock_quic_data.AddWrite(SYNCHRONOUS,
2241 ConstructInitialSettingsPacket(packet_num++));
2242 }
zhongyia00ca012017-07-06 23:36:392243 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232244 SYNCHRONOUS,
2245 ConstructClientRequestHeadersPacket(
2246 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2247 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432248 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332249 ASYNC, ConstructServerResponseHeadersPacket(
2250 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2251 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432252 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332253 mock_quic_data.AddRead(
2254 ASYNC, ConstructServerDataPacket(
2255 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172256 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232257 mock_quic_data.AddWrite(SYNCHRONOUS,
2258 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392259 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2260 mock_quic_data.AddRead(ASYNC, 0); // EOF
2261
2262 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2263
2264 AddHangingNonAlternateProtocolSocketData();
2265 CreateSession(supported_versions_);
2266
2267 SendRequestAndExpectHttpResponse("hello world");
2268 SendRequestAndExpectQuicResponse("hello!");
2269}
2270
Zhongyi Shi1c022d22020-03-20 19:00:162271TEST_P(QuicNetworkTransactionTest,
2272 PickQuicVersionWhenMultipleVersionsAreSupported) {
2273 // Client and server both support more than one QUIC_VERSION.
2274 // Client prefers |version_|, and then common_version_2.
2275 // Server prefers common_version_2, and then |version_|.
David Schinazifbd4c432020-04-07 19:23:552276 // We should honor the server's preference.
Zhongyi Shi1c022d22020-03-20 19:00:162277 // The picked version is verified via checking the version used by the
2278 // TestPacketMakers and the response.
Bence Békyb89104962020-01-24 00:05:172279
Zhongyi Shi1c022d22020-03-20 19:00:162280 // Find an alternative commonly supported version other than |version_|.
David Schinazi84c58bb2020-06-04 20:14:332281 quic::ParsedQuicVersion common_version_2 =
2282 quic::ParsedQuicVersion::Unsupported();
2283 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
2284 if (version != version_) {
Zhongyi Shi1c022d22020-03-20 19:00:162285 common_version_2 = version;
2286 break;
2287 }
zhongyia00ca012017-07-06 23:36:392288 }
David Schinazi84c58bb2020-06-04 20:14:332289 ASSERT_NE(common_version_2, quic::ParsedQuicVersion::Unsupported());
zhongyia00ca012017-07-06 23:36:392290
Zhongyi Shi1c022d22020-03-20 19:00:162291 // Setting up client's preference list: {|version_|, |common_version_2|}.
2292 supported_versions_.clear();
2293 supported_versions_.push_back(version_);
2294 supported_versions_.push_back(common_version_2);
zhongyia00ca012017-07-06 23:36:392295
Zhongyi Shi1c022d22020-03-20 19:00:162296 // Setting up server's Alt-Svc header in the following preference order:
2297 // |common_version_2|, |version_|.
2298 std::string QuicAltSvcWithVersionHeader;
David Schinazi84c58bb2020-06-04 20:14:332299 quic::ParsedQuicVersion picked_version =
2300 quic::ParsedQuicVersion::Unsupported();
2301 QuicAltSvcWithVersionHeader =
2302 "Alt-Svc: " + quic::AlpnForVersion(common_version_2) +
2303 "=\":443\"; ma=3600, " + quic::AlpnForVersion(version_) +
2304 "=\":443\"; ma=3600\r\n\r\n";
2305 picked_version = common_version_2; // Use server's preference.
zhongyia00ca012017-07-06 23:36:392306
2307 MockRead http_reads[] = {
2308 MockRead("HTTP/1.1 200 OK\r\n"),
2309 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2310 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2311 MockRead(ASYNC, OK)};
2312
Ryan Sleevib8d7ea02018-05-07 20:01:012313 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392314 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082315 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392316 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2317
Zhongyi Shi1c022d22020-03-20 19:00:162318 MockQuicData mock_quic_data(picked_version);
2319
2320 // Reset QuicTestPacket makers as the version picked may not be |version_|.
2321 client_maker_.reset(new QuicTestPacketMaker(
2322 picked_version,
2323 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2324 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
2325 client_headers_include_h2_stream_dependency_));
2326 QuicTestPacketMaker server_maker(
2327 picked_version,
2328 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
2329 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
2330 false);
2331
Renjie Tangaadb84b2019-08-31 01:00:232332 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:162333 if (VersionUsesHttp3(picked_version.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232334 mock_quic_data.AddWrite(SYNCHRONOUS,
2335 ConstructInitialSettingsPacket(packet_num++));
2336 }
Zhongyi Shi1c022d22020-03-20 19:00:162337
2338 quic::QuicStreamId client_stream_0 =
2339 quic::test::GetNthClientInitiatedBidirectionalStreamId(
2340 picked_version.transport_version, 0);
2341 mock_quic_data.AddWrite(SYNCHRONOUS,
2342 ConstructClientRequestHeadersPacket(
2343 packet_num++, client_stream_0, true, true,
2344 GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432345 mock_quic_data.AddRead(
Zhongyi Shi1c022d22020-03-20 19:00:162346 ASYNC, server_maker.MakeResponseHeadersPacket(
2347 1, client_stream_0, false, false,
2348 server_maker.GetResponseHeaders("200 OK"), nullptr));
2349 std::string header("");
2350 if (VersionUsesHttp3(picked_version.transport_version)) {
2351 std::unique_ptr<char[]> buffer;
2352 auto header_length =
2353 quic::HttpEncoder::SerializeDataFrameHeader(6, &buffer);
2354 header = std::string(buffer.get(), header_length);
2355 }
2356
Fan Yang32c5a112018-12-10 20:06:332357 mock_quic_data.AddRead(
Zhongyi Shi1c022d22020-03-20 19:00:162358 ASYNC, server_maker.MakeDataPacket(2, client_stream_0, false, true,
2359 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232360 mock_quic_data.AddWrite(SYNCHRONOUS,
2361 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392362 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2363 mock_quic_data.AddRead(ASYNC, 0); // EOF
2364
2365 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2366
2367 AddHangingNonAlternateProtocolSocketData();
2368 CreateSession(supported_versions_);
2369
2370 SendRequestAndExpectHttpResponse("hello world");
Zhongyi Shi1c022d22020-03-20 19:00:162371 SendRequestAndExpectQuicResponseMaybeFromProxy(
2372 "hello!", false, 443, "HTTP/1.1 200 OK", picked_version);
zhongyia00ca012017-07-06 23:36:392373}
2374
rchf47265dc2016-03-21 21:33:122375TEST_P(QuicNetworkTransactionTest,
2376 UseAlternativeServiceWithProbabilityForQuic) {
2377 MockRead http_reads[] = {
2378 MockRead("HTTP/1.1 200 OK\r\n"),
2379 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
2380 MockRead("hello world"),
2381 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2382 MockRead(ASYNC, OK)};
2383
Ryan Sleevib8d7ea02018-05-07 20:01:012384 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:122385 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082386 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:122387 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2388
Ryan Hamiltonabad59e2019-06-06 04:02:592389 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232390 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252391 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232392 mock_quic_data.AddWrite(SYNCHRONOUS,
2393 ConstructInitialSettingsPacket(packet_num++));
2394 }
rch5cb522462017-04-25 20:18:362395 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232396 SYNCHRONOUS,
2397 ConstructClientRequestHeadersPacket(
2398 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2399 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432400 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332401 ASYNC, ConstructServerResponseHeadersPacket(
2402 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2403 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432404 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332405 mock_quic_data.AddRead(
2406 ASYNC, ConstructServerDataPacket(
2407 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172408 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232409 mock_quic_data.AddWrite(SYNCHRONOUS,
2410 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchf47265dc2016-03-21 21:33:122411 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2412 mock_quic_data.AddRead(ASYNC, 0); // EOF
2413
2414 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2415
rtennetib8e80fb2016-05-16 00:12:092416 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:122417 CreateSession();
2418
2419 SendRequestAndExpectHttpResponse("hello world");
2420 SendRequestAndExpectQuicResponse("hello!");
2421}
2422
zhongyi3d4a55e72016-04-22 20:36:462423TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2424 MockRead http_reads[] = {
2425 MockRead("HTTP/1.1 200 OK\r\n"),
2426 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2427 MockRead("hello world"),
2428 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2429 MockRead(ASYNC, OK)};
2430
Ryan Sleevib8d7ea02018-05-07 20:01:012431 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462432 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082433 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462434 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2435
2436 CreateSession();
bncb26024382016-06-29 02:39:452437 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462438 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452439 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462440 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402441 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462442 session_->http_server_properties();
2443 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2444 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2445 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462446 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492447 2u, http_server_properties
2448 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2449 .size());
bncb26024382016-06-29 02:39:452450 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492451 http_server_properties
2452 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2453 .empty());
zhongyi3d4a55e72016-04-22 20:36:462454}
2455
2456TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2457 MockRead http_reads[] = {
2458 MockRead("HTTP/1.1 200 OK\r\n"),
2459 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2460 MockRead("hello world"),
2461 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2462 MockRead(ASYNC, OK)};
2463
Ryan Sleevib8d7ea02018-05-07 20:01:012464 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082465 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462466
2467 socket_factory_.AddSocketDataProvider(&http_data);
2468 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2469 socket_factory_.AddSocketDataProvider(&http_data);
2470 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2471
2472 CreateSession();
2473
2474 // Send https request and set alternative services if response header
2475 // advertises alternative service for mail.example.org.
2476 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402477 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462478 session_->http_server_properties();
2479
2480 const url::SchemeHostPort https_server(request_.url);
2481 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342482 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492483 2u, http_server_properties
2484 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2485 .size());
zhongyi3d4a55e72016-04-22 20:36:462486
2487 // Send http request to the same origin but with diffrent scheme, should not
2488 // use QUIC.
2489 request_.url = GURL("http://mail.example.org:443");
2490 SendRequestAndExpectHttpResponse("hello world");
2491}
2492
zhongyie537a002017-06-27 16:48:212493TEST_P(QuicNetworkTransactionTest,
2494 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442495 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562496 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Bence Békyb89104962020-01-24 00:05:172497 if (version != version_) {
2498 supported_versions_.push_back(version);
2499 break;
2500 }
zhongyi86838d52017-06-30 01:19:442501 }
2502
David Schinazifbd4c432020-04-07 19:23:552503 std::string altsvc_header = GenerateQuicAltSvcHeader(supported_versions_);
zhongyie537a002017-06-27 16:48:212504 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:172505 MockRead("HTTP/1.1 200 OK\r\n"),
2506 MockRead(altsvc_header.c_str()),
2507 MockRead("\r\n"),
zhongyie537a002017-06-27 16:48:212508 MockRead("hello world"),
2509 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2510 MockRead(ASYNC, OK)};
2511
Ryan Sleevib8d7ea02018-05-07 20:01:012512 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212513 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082514 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212515 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2516
Ryan Hamiltonabad59e2019-06-06 04:02:592517 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232518 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252519 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232520 mock_quic_data.AddWrite(SYNCHRONOUS,
2521 ConstructInitialSettingsPacket(packet_num++));
2522 }
zhongyie537a002017-06-27 16:48:212523 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232524 SYNCHRONOUS,
2525 ConstructClientRequestHeadersPacket(
2526 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2527 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432528 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332529 ASYNC, ConstructServerResponseHeadersPacket(
2530 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2531 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432532 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332533 mock_quic_data.AddRead(
2534 ASYNC, ConstructServerDataPacket(
2535 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172536 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232537 mock_quic_data.AddWrite(SYNCHRONOUS,
2538 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212539 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2540 mock_quic_data.AddRead(ASYNC, 0); // EOF
2541
2542 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2543
2544 AddHangingNonAlternateProtocolSocketData();
2545
zhongyi86838d52017-06-30 01:19:442546 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212547
2548 SendRequestAndExpectHttpResponse("hello world");
2549 SendRequestAndExpectQuicResponse("hello!");
2550
Bence Békyb89104962020-01-24 00:05:172551 // Alt-Svc header contains all possible versions, so alternative services
2552 // should contain all of |supported_versions_|.
zhongyie537a002017-06-27 16:48:212553 const url::SchemeHostPort https_server(request_.url);
2554 const AlternativeServiceInfoVector alt_svc_info_vector =
2555 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492556 https_server, NetworkIsolationKey());
David Schinazi84c58bb2020-06-04 20:14:332557 // Versions that support the legacy Google-specific Alt-Svc format are sent in
2558 // a single Alt-Svc entry, therefore they are accumulated in a single
2559 // AlternativeServiceInfo, whereas more recent versions all have their own
2560 // Alt-Svc entry and AlternativeServiceInfo entry. Flatten to compare.
Bence Békyb89104962020-01-24 00:05:172561 quic::ParsedQuicVersionVector alt_svc_negotiated_versions;
2562 for (const auto& alt_svc_info : alt_svc_info_vector) {
2563 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
2564 for (const auto& version : alt_svc_info.advertised_versions()) {
David Schinazifbd4c432020-04-07 19:23:552565 if (std::find(alt_svc_negotiated_versions.begin(),
2566 alt_svc_negotiated_versions.end(),
2567 version) == alt_svc_negotiated_versions.end()) {
2568 alt_svc_negotiated_versions.push_back(version);
2569 }
Bence Békyb89104962020-01-24 00:05:172570 }
2571 }
2572
2573 ASSERT_EQ(supported_versions_.size(), alt_svc_negotiated_versions.size());
2574 auto version_compare = [](const quic::ParsedQuicVersion& a,
2575 const quic::ParsedQuicVersion& b) {
2576 return std::tie(a.transport_version, a.handshake_protocol) <
2577 std::tie(b.transport_version, b.handshake_protocol);
2578 };
2579 std::sort(supported_versions_.begin(), supported_versions_.end(),
2580 version_compare);
2581 std::sort(alt_svc_negotiated_versions.begin(),
2582 alt_svc_negotiated_versions.end(), version_compare);
2583 EXPECT_TRUE(std::equal(supported_versions_.begin(), supported_versions_.end(),
2584 alt_svc_negotiated_versions.begin()));
zhongyie537a002017-06-27 16:48:212585}
2586
danzh3134c2562016-08-12 14:07:522587TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562588 std::string altsvc_header = base::StringPrintf(
Bence Békyb89104962020-01-24 00:05:172589 "Alt-Svc: %s=\":443\"\r\n\r\n", quic::AlpnForVersion(version_).c_str());
bnc8be55ebb2015-10-30 14:12:072590 MockRead http_reads[] = {
2591 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2592 MockRead("hello world"),
2593 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2594 MockRead(ASYNC, OK)};
2595
Ryan Sleevib8d7ea02018-05-07 20:01:012596 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072597 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082598 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072599 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2600
Ryan Hamiltonabad59e2019-06-06 04:02:592601 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232602 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252603 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232604 mock_quic_data.AddWrite(SYNCHRONOUS,
2605 ConstructInitialSettingsPacket(packet_num++));
2606 }
rch5cb522462017-04-25 20:18:362607 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232608 SYNCHRONOUS,
2609 ConstructClientRequestHeadersPacket(
2610 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2611 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432612 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332613 ASYNC, ConstructServerResponseHeadersPacket(
2614 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2615 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432616 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332617 mock_quic_data.AddRead(
2618 ASYNC, ConstructServerDataPacket(
2619 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172620 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232621 mock_quic_data.AddWrite(SYNCHRONOUS,
2622 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072623 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592624 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072625
2626 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2627
rtennetib8e80fb2016-05-16 00:12:092628 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322629 CreateSession();
bnc8be55ebb2015-10-30 14:12:072630
2631 SendRequestAndExpectHttpResponse("hello world");
2632 SendRequestAndExpectQuicResponse("hello!");
2633}
2634
zhongyi6b5a3892016-03-12 04:46:202635TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harperc6cb7a612020-02-24 20:03:322636 if (version_.HasIetfQuicFrames()) {
Renjie Tangba21e032019-09-27 21:52:282637 // GoAway is not available under version 99
Frank Kastenholz6e4c5382018-06-21 23:00:092638 return;
2639 }
Ryan Hamiltonabad59e2019-06-06 04:02:592640 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232641 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252642 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232643 mock_quic_data.AddWrite(SYNCHRONOUS,
2644 ConstructInitialSettingsPacket(packet_num++));
2645 }
rch5cb522462017-04-25 20:18:362646 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232647 SYNCHRONOUS,
2648 ConstructClientRequestHeadersPacket(
2649 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2650 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332651 mock_quic_data.AddRead(
2652 ASYNC, ConstructServerResponseHeadersPacket(
2653 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2654 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202655 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522656 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432657 mock_quic_data.AddRead(SYNCHRONOUS,
2658 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522659 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432660 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232661 mock_quic_data.AddWrite(SYNCHRONOUS,
2662 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432663 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332664 mock_quic_data.AddRead(
2665 SYNCHRONOUS, ConstructServerDataPacket(
2666 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:172667 true, header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232668 mock_quic_data.AddWrite(
2669 SYNCHRONOUS,
2670 ConstructClientAckAndRstPacket(
2671 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2672 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202673 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2674 mock_quic_data.AddRead(ASYNC, 0); // EOF
2675
2676 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2677
2678 // The non-alternate protocol job needs to hang in order to guarantee that
2679 // the alternate-protocol job will "win".
2680 AddHangingNonAlternateProtocolSocketData();
2681
2682 // In order for a new QUIC session to be established via alternate-protocol
2683 // without racing an HTTP connection, we need the host resolution to happen
2684 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2685 // connection to the the server, in this test we require confirmation
2686 // before encrypting so the HTTP job will still start.
2687 host_resolver_.set_synchronous_mode(true);
2688 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2689 "");
zhongyi6b5a3892016-03-12 04:46:202690
2691 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432692 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2693 false);
Ryan Hamilton9835e662018-08-02 05:36:272694 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202695
bnc691fda62016-08-12 00:43:162696 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202697 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362698 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012699 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202700
Fan Yang3673cc72020-02-07 14:49:282701 crypto_client_stream_factory_.last_stream()
2702 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:012703 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202704
2705 // Check whether this transaction is correctly marked as received a go-away
2706 // because of migrating port.
2707 NetErrorDetails details;
2708 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162709 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202710 EXPECT_TRUE(details.quic_port_migration_detected);
2711}
2712
Zhongyi Shia6b68d112018-09-24 07:49:032713// This test verifies that a new QUIC connection will be attempted on the
2714// alternate network if the original QUIC connection fails with idle timeout
2715// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2716// alternate network as well, QUIC is marked as broken and the brokenness will
2717// not expire when default network changes.
Renjie Tangb6fc5e02020-06-30 00:48:342718// TODO(fayang): Add time driven idle network detection test.
2719TEST_P(QuicNetworkTransactionTest,
2720 DISABLED_QuicFailsOnBothNetworksWhileTCPSucceeds) {
2721 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432722 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
Renjie Tang3d8a6ddd2019-11-20 00:18:432723 return;
2724 }
Zhongyi Shia6b68d112018-09-24 07:49:032725 SetUpTestForRetryConnectionOnAlternateNetwork();
2726
Zhongyi Shi1c022d22020-03-20 19:00:162727 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032728
2729 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592730 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032731 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2732 int packet_num = 1;
2733 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162734 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:032735 // Retranmit the handshake messages.
2736 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162737 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032738 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162739 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032740 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162741 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032742 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162743 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032744 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2745 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162746 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:032747 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522748 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:032749 quic_data.AddSocketDataToFactory(&socket_factory_);
2750
2751 // Add successful TCP data so that TCP job will succeed.
2752 MockWrite http_writes[] = {
2753 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2754 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2755 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2756
2757 MockRead http_reads[] = {
2758 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2759 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2760 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2761 SequencedSocketData http_data(http_reads, http_writes);
2762 socket_factory_.AddSocketDataProvider(&http_data);
2763 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2764
2765 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592766 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032767 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2768 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2769 quic_data2.AddSocketDataToFactory(&socket_factory_);
2770
2771 // Resolve the host resolution synchronously.
2772 host_resolver_.set_synchronous_mode(true);
2773 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2774 "");
Zhongyi Shia6b68d112018-09-24 07:49:032775
2776 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432777 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2778 false);
Zhongyi Shia6b68d112018-09-24 07:49:032779 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032780 QuicStreamFactoryPeer::SetAlarmFactory(
2781 session_->quic_stream_factory(),
2782 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222783 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032784 // Add alternate protocol mapping to race QUIC and TCP.
2785 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2786 // peer.
2787 AddQuicAlternateProtocolMapping(
2788 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2789
2790 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2791 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362792 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032793 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2794
2795 // Pump the message loop to get the request started.
2796 // Request will be served with TCP job.
2797 base::RunLoop().RunUntilIdle();
2798 EXPECT_THAT(callback.WaitForResult(), IsOk());
2799 CheckResponseData(&trans, "TCP succeeds");
2800
Zhongyi Shia6b68d112018-09-24 07:49:032801 // Fast forward to idle timeout the original connection. A new connection will
2802 // be kicked off on the alternate network.
2803 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2804 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2805 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2806
2807 // Run the message loop to execute posted tasks, which will report job status.
2808 base::RunLoop().RunUntilIdle();
2809
2810 // Verify that QUIC is marked as broken.
2811 ExpectBrokenAlternateProtocolMapping();
2812
2813 // Deliver a message to notify the new network becomes default, the brokenness
2814 // will not expire as QUIC is broken on both networks.
2815 scoped_mock_change_notifier_->mock_network_change_notifier()
2816 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2817 ExpectBrokenAlternateProtocolMapping();
2818
2819 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2820 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2821}
2822
2823// This test verifies that a new QUIC connection will be attempted on the
2824// alternate network if the original QUIC connection fails with idle timeout
2825// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2826// alternate network, QUIC is marked as broken. The brokenness will expire when
2827// the default network changes.
Renjie Tangb6fc5e02020-06-30 00:48:342828// TODO(fayang): Add time driven idle network detection test.
2829TEST_P(QuicNetworkTransactionTest,
2830 DISABLED_RetryOnAlternateNetworkWhileTCPSucceeds) {
2831 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432832 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
Renjie Tang3d8a6ddd2019-11-20 00:18:432833 return;
2834 }
2835
Zhongyi Shia6b68d112018-09-24 07:49:032836 SetUpTestForRetryConnectionOnAlternateNetwork();
2837
Zhongyi Shi1c022d22020-03-20 19:00:162838 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032839
2840 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592841 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032842 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2843 int packet_num = 1;
2844 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162845 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:032846 // Retranmit the handshake messages.
2847 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162848 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032849 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162850 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032851 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162852 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032853 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162854 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032855 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2856 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162857 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:032858 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522859 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:032860 quic_data.AddSocketDataToFactory(&socket_factory_);
2861
2862 // Add successful TCP data so that TCP job will succeed.
2863 MockWrite http_writes[] = {
2864 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2865 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2866 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2867
2868 MockRead http_reads[] = {
2869 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2870 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2871 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2872 SequencedSocketData http_data(http_reads, http_writes);
2873 socket_factory_.AddSocketDataProvider(&http_data);
2874 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2875
2876 // Quic connection will be retried on the alternate network after the initial
2877 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592878 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032879 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2880 quic_data2.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162881 client_maker_->MakeDummyCHLOPacket(1)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:032882
Zhongyi Shi1c022d22020-03-20 19:00:162883 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252884 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232885 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032886 quic_data2.AddSocketDataToFactory(&socket_factory_);
2887
2888 // Resolve the host resolution synchronously.
2889 host_resolver_.set_synchronous_mode(true);
2890 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2891 "");
Zhongyi Shia6b68d112018-09-24 07:49:032892
2893 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432894 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2895 false);
Zhongyi Shia6b68d112018-09-24 07:49:032896 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032897 QuicStreamFactoryPeer::SetAlarmFactory(
2898 session_->quic_stream_factory(),
2899 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222900 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032901 // Add alternate protocol mapping to race QUIC and TCP.
2902 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2903 // peer.
2904 AddQuicAlternateProtocolMapping(
2905 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2906
2907 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2908 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362909 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032910 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2911
2912 // Pump the message loop to get the request started.
2913 // Request will be served with TCP job.
2914 base::RunLoop().RunUntilIdle();
2915 EXPECT_THAT(callback.WaitForResult(), IsOk());
2916 CheckResponseData(&trans, "TCP succeeds");
2917
Zhongyi Shia6b68d112018-09-24 07:49:032918 // Fast forward to idle timeout the original connection. A new connection will
2919 // be kicked off on the alternate network.
2920 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2921 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2922 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2923
2924 // The second connection hasn't finish handshake, verify that QUIC is not
2925 // marked as broken.
2926 ExpectQuicAlternateProtocolMapping();
2927 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:282928 crypto_client_stream_factory_.last_stream()
2929 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia6b68d112018-09-24 07:49:032930 // Run message loop to execute posted tasks, which will notify JoController
2931 // about the orphaned job status.
2932 base::RunLoop().RunUntilIdle();
2933
2934 // Verify that QUIC is marked as broken.
2935 ExpectBrokenAlternateProtocolMapping();
2936
2937 // Deliver a message to notify the new network becomes default, the previous
2938 // brokenness will be clear as the brokenness is bond with old default
2939 // network.
2940 scoped_mock_change_notifier_->mock_network_change_notifier()
2941 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2942 ExpectQuicAlternateProtocolMapping();
2943
2944 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2945 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2946}
2947
Matt Menkeb32ba5122019-09-10 19:17:052948// Much like above test, but verifies NetworkIsolationKeys are respected.
Renjie Tangb6fc5e02020-06-30 00:48:342949// TODO(fayang): Add time driven idle network detection test.
2950TEST_P(
2951 QuicNetworkTransactionTest,
2952 DISABLED_RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
2953 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432954 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
Renjie Tang3d8a6ddd2019-11-20 00:18:432955 return;
2956 }
2957
Matt Menkeb32ba5122019-09-10 19:17:052958 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2959 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2960 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2961 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2962
2963 base::test::ScopedFeatureList feature_list;
2964 feature_list.InitWithFeatures(
2965 // enabled_features
2966 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2967 // Need to partition connections by NetworkIsolationKey for
2968 // QuicSessionAliasKey to include NetworkIsolationKeys.
2969 features::kPartitionConnectionsByNetworkIsolationKey},
2970 // disabled_features
2971 {});
2972 // Since HttpServerProperties caches the feature value, have to create a new
2973 // one.
2974 http_server_properties_ = std::make_unique<HttpServerProperties>();
2975
2976 SetUpTestForRetryConnectionOnAlternateNetwork();
2977
Zhongyi Shi1c022d22020-03-20 19:00:162978 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Matt Menkeb32ba5122019-09-10 19:17:052979
2980 // The request will initially go out over QUIC.
2981 MockQuicData quic_data(version_);
2982 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2983 int packet_num = 1;
2984 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162985 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Matt Menkeb32ba5122019-09-10 19:17:052986 // Retranmit the handshake messages.
2987 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162988 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052989 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162990 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052991 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162992 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052993 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162994 client_maker_->MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052995 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2996 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:162997 client_maker_->MakeConnectionClosePacket(
Matt Menkeb32ba5122019-09-10 19:17:052998 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522999 "No recent network activity after 4s. Timeout:4s"));
Matt Menkeb32ba5122019-09-10 19:17:053000 quic_data.AddSocketDataToFactory(&socket_factory_);
3001
3002 // Add successful TCP data so that TCP job will succeed.
3003 MockWrite http_writes[] = {
3004 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3005 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3006 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3007
3008 MockRead http_reads[] = {
3009 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3010 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3011 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
3012 SequencedSocketData http_data(http_reads, http_writes);
3013 socket_factory_.AddSocketDataProvider(&http_data);
3014 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3015
3016 // Quic connection will be retried on the alternate network after the initial
3017 // one fails on the default network.
3018 MockQuicData quic_data2(version_);
3019 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
3020 quic_data2.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163021 client_maker_->MakeDummyCHLOPacket(1)); // CHLO
Matt Menkeb32ba5122019-09-10 19:17:053022
Zhongyi Shi1c022d22020-03-20 19:00:163023 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253024 if (VersionUsesHttp3(version_.transport_version))
Matt Menkeb32ba5122019-09-10 19:17:053025 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
3026 quic_data2.AddSocketDataToFactory(&socket_factory_);
3027
3028 // Resolve the host resolution synchronously.
3029 host_resolver_.set_synchronous_mode(true);
3030 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3031 "");
3032
3033 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433034 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3035 false);
Matt Menkeb32ba5122019-09-10 19:17:053036 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
3037 QuicStreamFactoryPeer::SetAlarmFactory(
3038 session_->quic_stream_factory(),
3039 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223040 context_.clock()));
Matt Menkeb32ba5122019-09-10 19:17:053041 // Add alternate protocol mapping to race QUIC and TCP.
3042 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3043 // peer.
3044 AddQuicAlternateProtocolMapping(
3045 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
3046 AddQuicAlternateProtocolMapping(
3047 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
3048
3049 request_.network_isolation_key = kNetworkIsolationKey1;
3050 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3051 TestCompletionCallback callback;
3052 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3053 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3054
3055 // Pump the message loop to get the request started.
3056 // Request will be served with TCP job.
3057 base::RunLoop().RunUntilIdle();
3058 EXPECT_THAT(callback.WaitForResult(), IsOk());
3059 CheckResponseData(&trans, "TCP succeeds");
3060
3061 // Fast forward to idle timeout the original connection. A new connection will
3062 // be kicked off on the alternate network.
3063 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3064 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3065 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3066
3067 // The second connection hasn't finish handshake, verify that QUIC is not
3068 // marked as broken.
3069 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
3070 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3071 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:283072 crypto_client_stream_factory_.last_stream()
3073 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:053074 // Run message loop to execute posted tasks, which will notify JoController
3075 // about the orphaned job status.
3076 base::RunLoop().RunUntilIdle();
3077
3078 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
3079 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3080 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3081
3082 // Deliver a message to notify the new network becomes default, the previous
3083 // brokenness will be clear as the brokenness is bond with old default
3084 // network.
3085 scoped_mock_change_notifier_->mock_network_change_notifier()
3086 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3087 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
3088 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3089
3090 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3091 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3092}
3093
Zhongyi Shia6b68d112018-09-24 07:49:033094// This test verifies that a new QUIC connection will be attempted on the
3095// alternate network if the original QUIC connection fails with idle timeout
3096// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
3097// alternative network succeeds, QUIC is not marked as broken.
Renjie Tangb6fc5e02020-06-30 00:48:343098// TODO(fayang): Add time driven idle network detection test.
3099TEST_P(QuicNetworkTransactionTest,
3100 DISABLED_RetryOnAlternateNetworkWhileTCPHanging) {
3101 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433102 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
Renjie Tang3d8a6ddd2019-11-20 00:18:433103 return;
3104 }
3105
Zhongyi Shia6b68d112018-09-24 07:49:033106 SetUpTestForRetryConnectionOnAlternateNetwork();
3107
Zhongyi Shi1c022d22020-03-20 19:00:163108 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:033109
3110 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593111 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:033112 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
3113 int packet_num = 1;
3114 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163115 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:033116 // Retranmit the handshake messages.
3117 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163118 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033119 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163120 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033121 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163122 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033123 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163124 client_maker_->MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033125 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
3126 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163127 client_maker_->MakeConnectionClosePacket(
Zhongyi Shia6b68d112018-09-24 07:49:033128 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523129 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:033130 quic_data.AddSocketDataToFactory(&socket_factory_);
3131
3132 // Add hanging TCP data so that TCP job will never succeeded.
3133 AddHangingNonAlternateProtocolSocketData();
3134
3135 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:593136 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:233137 packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:163138 quic_data2.AddWrite(
3139 SYNCHRONOUS,
3140 client_maker_->MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:033141
Victor Vasiliev076657c2019-03-12 02:46:433142 const std::string body = "hello!";
3143 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:413144
Zhongyi Shi1c022d22020-03-20 19:00:163145 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253146 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233147 quic_data2.AddWrite(SYNCHRONOUS,
3148 ConstructInitialSettingsPacket(packet_num++));
3149 }
Zhongyi Shia6b68d112018-09-24 07:49:033150 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233151 SYNCHRONOUS,
3152 ConstructClientRequestHeadersPacket(
3153 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3154 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:033155 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333156 ASYNC, ConstructServerResponseHeadersPacket(
3157 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
3158 GetResponseHeaders("200 OK")));
3159 quic_data2.AddRead(
3160 ASYNC, ConstructServerDataPacket(
3161 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173162 header + body));
Renjie Tangaadb84b2019-08-31 01:00:233163 quic_data2.AddWrite(SYNCHRONOUS,
3164 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia6b68d112018-09-24 07:49:033165 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
3166 quic_data2.AddSocketDataToFactory(&socket_factory_);
3167
3168 // Resolve the host resolution synchronously.
3169 host_resolver_.set_synchronous_mode(true);
3170 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3171 "");
Zhongyi Shia6b68d112018-09-24 07:49:033172
3173 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433174 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3175 false);
Zhongyi Shia6b68d112018-09-24 07:49:033176 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:033177 QuicStreamFactoryPeer::SetAlarmFactory(
3178 session_->quic_stream_factory(),
3179 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223180 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:033181 // Add alternate protocol mapping to race QUIC and TCP.
3182 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3183 // peer.
3184 AddQuicAlternateProtocolMapping(
3185 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3186
3187 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3188 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363189 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:033190 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3191
3192 // Pump the message loop to get the request started.
3193 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:033194
3195 // Fast forward to idle timeout the original connection. A new connection will
3196 // be kicked off on the alternate network.
3197 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3198 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3199 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3200
3201 // Verify that QUIC is not marked as broken.
3202 ExpectQuicAlternateProtocolMapping();
3203 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:283204 crypto_client_stream_factory_.last_stream()
3205 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia6b68d112018-09-24 07:49:033206
3207 // Read the response.
3208 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:413209 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:033210 // Verify that QUIC is not marked as broken.
3211 ExpectQuicAlternateProtocolMapping();
3212
3213 // Deliver a message to notify the new network becomes default.
3214 scoped_mock_change_notifier_->mock_network_change_notifier()
3215 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3216 ExpectQuicAlternateProtocolMapping();
3217 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3218 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3219}
3220
rch9ecde09b2017-04-08 00:18:233221// Verify that if a QUIC connection times out, the QuicHttpStream will
3222// return QUIC_PROTOCOL_ERROR.
3223TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
David Schinazi84c58bb2020-06-04 20:14:333224 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433225 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3226 return;
3227 }
3228
Victor Vasilieva1e66d72019-12-05 17:55:383229 context_.params()->retry_without_alt_svc_on_quic_errors = false;
3230 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:233231
3232 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593233 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133234 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233235 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3236
Zhongyi Shi1c022d22020-03-20 19:00:163237 client_maker_->set_save_packet_frames(true);
3238 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493239 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253240 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493241 quic_data.AddWrite(SYNCHRONOUS,
3242 ConstructInitialSettingsPacket(packet_num++));
3243 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023244 quic_data.AddWrite(
3245 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163246 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493247 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3248 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453249
Zhongyi Shi1c022d22020-03-20 19:00:163250 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233251
Victor Vasiliev7da08172019-10-14 06:04:253252 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493253 // TLP 1
Zhongyi Shi1c022d22020-03-20 19:00:163254 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493255 1, packet_num++, true));
3256 // TLP 2
Zhongyi Shi1c022d22020-03-20 19:00:163257 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493258 2, packet_num++, true));
3259 // RTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163260 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493261 1, packet_num++, true));
Zhongyi Shi1c022d22020-03-20 19:00:163262 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493263 2, packet_num++, true));
3264 // RTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163265 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493266 1, packet_num++, true));
Zhongyi Shi1c022d22020-03-20 19:00:163267 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493268 2, packet_num++, true));
3269 // RTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163270 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493271 1, packet_num++, true));
Zhongyi Shi1c022d22020-03-20 19:00:163272 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493273 2, packet_num++, true));
Ryan Hamilton3cc2c152019-07-09 19:36:013274
Findit2403b85d2019-11-19 05:06:373275 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163276 client_maker_->MakeConnectionClosePacket(
Findit2403b85d2019-11-19 05:06:373277 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523278 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493279 } else {
3280 // Settings were sent in the request packet so there is only 1 packet to
3281 // retransmit.
3282 // TLP 1
Zhongyi Shi1c022d22020-03-20 19:00:163283 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493284 1, packet_num++, true));
3285 // TLP 2
Zhongyi Shi1c022d22020-03-20 19:00:163286 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493287 1, packet_num++, true));
3288 // RTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163289 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493290 1, packet_num++, true));
3291 // RTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163292 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493293 1, packet_num++, true));
3294 // RTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163295 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493296 1, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373297
Nick Harper057264a82019-09-12 23:33:493298 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163299 client_maker_->MakeConnectionClosePacket(
Nick Harper057264a82019-09-12 23:33:493300 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523301 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493302 }
Fan Yang928f1632017-12-14 18:55:223303
rch9ecde09b2017-04-08 00:18:233304 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3305 quic_data.AddRead(ASYNC, OK);
3306 quic_data.AddSocketDataToFactory(&socket_factory_);
3307
3308 // In order for a new QUIC session to be established via alternate-protocol
3309 // without racing an HTTP connection, we need the host resolution to happen
3310 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3311 // connection to the the server, in this test we require confirmation
3312 // before encrypting so the HTTP job will still start.
3313 host_resolver_.set_synchronous_mode(true);
3314 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3315 "");
rch9ecde09b2017-04-08 00:18:233316
3317 CreateSession();
3318 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233319 QuicStreamFactoryPeer::SetAlarmFactory(
3320 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193321 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223322 context_.clock()));
rch9ecde09b2017-04-08 00:18:233323
Ryan Hamilton9835e662018-08-02 05:36:273324 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233325
3326 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3327 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363328 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3330
3331 // Pump the message loop to get the request started.
3332 base::RunLoop().RunUntilIdle();
3333 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283334 crypto_client_stream_factory_.last_stream()
3335 ->NotifySessionOneRttKeyAvailable();
rch9ecde09b2017-04-08 00:18:233336
3337 // Run the QUIC session to completion.
3338 quic_task_runner_->RunUntilIdle();
3339
3340 ExpectQuicAlternateProtocolMapping();
3341 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3342 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3343}
3344
David Schinazi7e980ab2020-05-13 20:26:553345// TODO(fayang): Add time driven TOO_MANY_RTOS test.
rch9ecde09b2017-04-08 00:18:233346
rch2f2991c2017-04-13 19:28:173347// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3348// the request fails with QUIC_PROTOCOL_ERROR.
3349TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:383350 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173351 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593352 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:163353 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493354 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253355 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493356 quic_data.AddWrite(SYNCHRONOUS,
3357 ConstructInitialSettingsPacket(packet_num++));
3358 }
3359 quic_data.AddWrite(
3360 SYNCHRONOUS,
3361 ConstructClientRequestHeadersPacket(
3362 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3363 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163364 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553365 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173366 // Peer sending data from an non-existing stream causes this end to raise
3367 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333368 quic_data.AddRead(
3369 ASYNC, ConstructServerRstPacket(
3370 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3371 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173372 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:343373 quic_data.AddWrite(
3374 SYNCHRONOUS,
3375 ConstructClientAckAndConnectionClosePacket(
3376 packet_num++, 1, 1, 1,
3377 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
3378 : quic::QUIC_INVALID_STREAM_ID,
3379 quic_error_details, quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173380 quic_data.AddSocketDataToFactory(&socket_factory_);
3381
3382 // In order for a new QUIC session to be established via alternate-protocol
3383 // without racing an HTTP connection, we need the host resolution to happen
3384 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3385 // connection to the the server, in this test we require confirmation
3386 // before encrypting so the HTTP job will still start.
3387 host_resolver_.set_synchronous_mode(true);
3388 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3389 "");
rch2f2991c2017-04-13 19:28:173390
3391 CreateSession();
3392
Ryan Hamilton9835e662018-08-02 05:36:273393 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173394
3395 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3396 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363397 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173398 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3399
3400 // Pump the message loop to get the request started.
3401 base::RunLoop().RunUntilIdle();
3402 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283403 crypto_client_stream_factory_.last_stream()
3404 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:173405
3406 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553407 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173408
3409 // Run the QUIC session to completion.
3410 base::RunLoop().RunUntilIdle();
3411 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3412 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3413
3414 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3415 ExpectQuicAlternateProtocolMapping();
3416 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3417}
3418
rch2f2991c2017-04-13 19:28:173419// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3420// connection times out, then QUIC will be marked as broken and the request
3421// retried over TCP.
3422TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
David Schinazi84c58bb2020-06-04 20:14:333423 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433424 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3425 return;
3426 }
3427
Victor Vasilieva1e66d72019-12-05 17:55:383428 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173429
3430 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593431 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133432 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173433 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3434
Zhongyi Shi1c022d22020-03-20 19:00:163435 client_maker_->set_save_packet_frames(true);
3436 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493437 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253438 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493439 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163440 client_maker_->MakeInitialSettingsPacket(packet_num++));
Nick Harper057264a82019-09-12 23:33:493441 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023442 quic_data.AddWrite(
3443 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163444 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493445 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3446 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453447
Zhongyi Shi1c022d22020-03-20 19:00:163448 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253449 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493450 // TLP 1
Zhongyi Shi1c022d22020-03-20 19:00:163451 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493452 1, packet_num++, true));
3453 // TLP 2
Zhongyi Shi1c022d22020-03-20 19:00:163454 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493455 2, packet_num++, true));
3456 // RTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163457 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493458 1, packet_num++, true));
Zhongyi Shi1c022d22020-03-20 19:00:163459 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493460 2, packet_num++, true));
3461 // RTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163462 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493463 1, packet_num++, true));
Zhongyi Shi1c022d22020-03-20 19:00:163464 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493465 2, packet_num++, true));
3466 // RTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163467 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493468 1, packet_num++, true));
Zhongyi Shi1c022d22020-03-20 19:00:163469 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493470 2, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373471
3472 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163473 client_maker_->MakeConnectionClosePacket(
Findit2403b85d2019-11-19 05:06:373474 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523475 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493476 } else {
3477 // TLP 1
Zhongyi Shi1c022d22020-03-20 19:00:163478 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493479 1, packet_num++, true));
3480 // TLP 2
Zhongyi Shi1c022d22020-03-20 19:00:163481 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493482 1, packet_num++, true));
3483 // RTO 1
Zhongyi Shi1c022d22020-03-20 19:00:163484 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493485 1, packet_num++, true));
3486 // RTO 2
Zhongyi Shi1c022d22020-03-20 19:00:163487 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493488 1, packet_num++, true));
3489 // RTO 3
Zhongyi Shi1c022d22020-03-20 19:00:163490 quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeRetransmissionPacket(
Nick Harper057264a82019-09-12 23:33:493491 1, packet_num++, true));
3492
3493 quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163494 client_maker_->MakeConnectionClosePacket(
Nick Harper057264a82019-09-12 23:33:493495 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523496 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493497 }
Fan Yang928f1632017-12-14 18:55:223498
rch2f2991c2017-04-13 19:28:173499 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3500 quic_data.AddRead(ASYNC, OK);
3501 quic_data.AddSocketDataToFactory(&socket_factory_);
3502
3503 // After that fails, it will be resent via TCP.
3504 MockWrite http_writes[] = {
3505 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3506 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3507 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3508
3509 MockRead http_reads[] = {
3510 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3511 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3512 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013513 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173514 socket_factory_.AddSocketDataProvider(&http_data);
3515 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3516
3517 // In order for a new QUIC session to be established via alternate-protocol
3518 // without racing an HTTP connection, we need the host resolution to happen
3519 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3520 // connection to the the server, in this test we require confirmation
3521 // before encrypting so the HTTP job will still start.
3522 host_resolver_.set_synchronous_mode(true);
3523 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3524 "");
rch2f2991c2017-04-13 19:28:173525
3526 CreateSession();
3527 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173528 QuicStreamFactoryPeer::SetAlarmFactory(
3529 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193530 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223531 context_.clock()));
rch2f2991c2017-04-13 19:28:173532
Ryan Hamilton9835e662018-08-02 05:36:273533 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173534
3535 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3536 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363537 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173538 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3539
3540 // Pump the message loop to get the request started.
3541 base::RunLoop().RunUntilIdle();
3542 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283543 crypto_client_stream_factory_.last_stream()
3544 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:173545
3546 // Run the QUIC session to completion.
3547 quic_task_runner_->RunUntilIdle();
3548 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3549
3550 ExpectQuicAlternateProtocolMapping();
3551
3552 // Let the transaction proceed which will result in QUIC being marked
3553 // as broken and the request falling back to TCP.
3554 EXPECT_THAT(callback.WaitForResult(), IsOk());
3555
3556 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3557 ASSERT_FALSE(http_data.AllReadDataConsumed());
3558
3559 // Read the response body over TCP.
3560 CheckResponseData(&trans, "hello world");
3561 ExpectBrokenAlternateProtocolMapping();
3562 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3563 ASSERT_TRUE(http_data.AllReadDataConsumed());
3564}
3565
rch2f2991c2017-04-13 19:28:173566// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3567// protocol error occurs after the handshake is confirmed, the request
3568// retried over TCP and the QUIC will be marked as broken.
3569TEST_P(QuicNetworkTransactionTest,
3570 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:383571 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173572
3573 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593574 MockQuicData quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:163575 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493576 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253577 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493578 quic_data.AddWrite(SYNCHRONOUS,
3579 ConstructInitialSettingsPacket(packet_num++));
3580 }
3581 quic_data.AddWrite(
3582 SYNCHRONOUS,
3583 ConstructClientRequestHeadersPacket(
3584 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3585 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163586 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553587 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3588
rch2f2991c2017-04-13 19:28:173589 // Peer sending data from an non-existing stream causes this end to raise
3590 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333591 quic_data.AddRead(
3592 ASYNC, ConstructServerRstPacket(
3593 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3594 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173595 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tang248e36ea2020-06-26 00:12:343596 quic_data.AddWrite(
3597 SYNCHRONOUS,
3598 ConstructClientAckAndConnectionClosePacket(
3599 packet_num++, 1, 1, 1,
3600 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
3601 : quic::QUIC_INVALID_STREAM_ID,
3602 quic_error_details, quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173603 quic_data.AddSocketDataToFactory(&socket_factory_);
3604
3605 // After that fails, it will be resent via TCP.
3606 MockWrite http_writes[] = {
3607 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3608 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3609 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3610
3611 MockRead http_reads[] = {
3612 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3613 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3614 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013615 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173616 socket_factory_.AddSocketDataProvider(&http_data);
3617 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3618
3619 // In order for a new QUIC session to be established via alternate-protocol
3620 // without racing an HTTP connection, we need the host resolution to happen
3621 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3622 // connection to the the server, in this test we require confirmation
3623 // before encrypting so the HTTP job will still start.
3624 host_resolver_.set_synchronous_mode(true);
3625 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3626 "");
rch2f2991c2017-04-13 19:28:173627
3628 CreateSession();
3629
Ryan Hamilton9835e662018-08-02 05:36:273630 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173631
3632 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3633 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363634 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3636
3637 // Pump the message loop to get the request started.
3638 base::RunLoop().RunUntilIdle();
3639 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283640 crypto_client_stream_factory_.last_stream()
3641 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553642 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173643
3644 // Run the QUIC session to completion.
3645 base::RunLoop().RunUntilIdle();
3646 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3647
3648 ExpectQuicAlternateProtocolMapping();
3649
3650 // Let the transaction proceed which will result in QUIC being marked
3651 // as broken and the request falling back to TCP.
3652 EXPECT_THAT(callback.WaitForResult(), IsOk());
3653
3654 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3655 ASSERT_FALSE(http_data.AllReadDataConsumed());
3656
3657 // Read the response body over TCP.
3658 CheckResponseData(&trans, "hello world");
3659 ExpectBrokenAlternateProtocolMapping();
3660 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3661 ASSERT_TRUE(http_data.AllReadDataConsumed());
3662}
3663
Matt Menkeb32ba5122019-09-10 19:17:053664// Much like above test, but verifies that NetworkIsolationKey is respected.
3665TEST_P(QuicNetworkTransactionTest,
3666 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
David Schinazi84c58bb2020-06-04 20:14:333667 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433668 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3669 return;
3670 }
3671
Matt Menkeb32ba5122019-09-10 19:17:053672 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
3673 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
3674 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
3675 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
3676
3677 base::test::ScopedFeatureList feature_list;
3678 feature_list.InitWithFeatures(
3679 // enabled_features
3680 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3681 features::kPartitionConnectionsByNetworkIsolationKey},
3682 // disabled_features
3683 {});
3684 // Since HttpServerProperties caches the feature value, have to create a new
3685 // one.
3686 http_server_properties_ = std::make_unique<HttpServerProperties>();
3687
Victor Vasilieva1e66d72019-12-05 17:55:383688 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
Matt Menkeb32ba5122019-09-10 19:17:053689
3690 // The request will initially go out over QUIC.
3691 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:563692 uint64_t packet_number = 1;
Zhongyi Shi1c022d22020-03-20 19:00:163693 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:253694 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:563695 quic_data.AddWrite(SYNCHRONOUS,
3696 ConstructInitialSettingsPacket(packet_number++));
3697 }
3698 quic_data.AddWrite(
3699 SYNCHRONOUS,
3700 ConstructClientRequestHeadersPacket(
3701 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3702 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi1c022d22020-03-20 19:00:163703 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:053704 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3705
3706 // Peer sending data from an non-existing stream causes this end to raise
3707 // error and close connection.
3708 quic_data.AddRead(
3709 ASYNC, ConstructServerRstPacket(
3710 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3711 quic::QUIC_STREAM_LAST_ERROR));
3712 std::string quic_error_details = "Data for nonexistent stream";
Bence Békyde6290f2019-12-19 15:21:533713 quic_data.AddWrite(SYNCHRONOUS,
3714 ConstructClientAckAndConnectionClosePacket(
3715 packet_number++, 1, 1, 1, quic::QUIC_INVALID_STREAM_ID,
3716 quic_error_details, quic::IETF_RST_STREAM));
Matt Menkeb32ba5122019-09-10 19:17:053717 quic_data.AddSocketDataToFactory(&socket_factory_);
3718
3719 // After that fails, it will be resent via TCP.
3720 MockWrite http_writes[] = {
3721 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3722 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3723 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3724
3725 MockRead http_reads[] = {
3726 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3727 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3728 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3729 SequencedSocketData http_data(http_reads, http_writes);
3730 socket_factory_.AddSocketDataProvider(&http_data);
3731 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3732
3733 // In order for a new QUIC session to be established via alternate-protocol
3734 // without racing an HTTP connection, we need the host resolution to happen
3735 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3736 // connection to the the server, in this test we require confirmation
3737 // before encrypting so the HTTP job will still start.
3738 host_resolver_.set_synchronous_mode(true);
3739 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3740 "");
3741
3742 CreateSession();
3743
3744 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3745 kNetworkIsolationKey1);
3746 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3747 kNetworkIsolationKey2);
3748
3749 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3750 TestCompletionCallback callback;
3751 request_.network_isolation_key = kNetworkIsolationKey1;
3752 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3753 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3754
3755 // Pump the message loop to get the request started.
3756 base::RunLoop().RunUntilIdle();
3757 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283758 crypto_client_stream_factory_.last_stream()
3759 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:053760 quic_data.Resume();
3761
3762 // Run the QUIC session to completion.
3763 base::RunLoop().RunUntilIdle();
3764 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3765
3766 // Let the transaction proceed which will result in QUIC being marked
3767 // as broken and the request falling back to TCP.
3768 EXPECT_THAT(callback.WaitForResult(), IsOk());
3769 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3770 ASSERT_FALSE(http_data.AllReadDataConsumed());
3771
3772 // Read the response body over TCP.
3773 CheckResponseData(&trans, "hello world");
3774 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3775 ASSERT_TRUE(http_data.AllReadDataConsumed());
3776
3777 // The alternative service shouldhave been marked as broken under
3778 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3779 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3780 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3781
3782 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3783 AddHttpDataAndRunRequest();
3784 // Requests using other NetworkIsolationKeys can still use QUIC.
3785 request_.network_isolation_key = kNetworkIsolationKey2;
3786 AddQuicDataAndRunRequest();
3787
3788 // The last two requests should not have changed the alternative service
3789 // mappings.
3790 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3791 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3792}
3793
rch30943ee2017-06-12 21:28:443794// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3795// request is reset from, then QUIC will be marked as broken and the request
3796// retried over TCP.
3797TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443798 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593799 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133800 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443801 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3802
Zhongyi Shi1c022d22020-03-20 19:00:163803 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493804 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253805 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493806 quic_data.AddWrite(SYNCHRONOUS,
3807 ConstructInitialSettingsPacket(packet_num++));
3808 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023809 quic_data.AddWrite(
3810 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:163811 client_maker_->MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493812 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3813 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453814
Zhongyi Shi1c022d22020-03-20 19:00:163815 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553816 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443817
Fan Yang32c5a112018-12-10 20:06:333818 quic_data.AddRead(ASYNC,
3819 ConstructServerRstPacket(
3820 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3821 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443822
Bence Béky6e243aa2019-12-13 19:01:073823 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang248e36ea2020-06-26 00:12:343824 quic_data.AddWrite(
3825 SYNCHRONOUS, ConstructClientAckAndDataPacket(
3826 packet_num++, true, GetQpackDecoderStreamId(), 1, 1, 1,
3827 false, StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:073828 }
3829
rch30943ee2017-06-12 21:28:443830 quic_data.AddRead(ASYNC, OK);
3831 quic_data.AddSocketDataToFactory(&socket_factory_);
3832
3833 // After that fails, it will be resent via TCP.
3834 MockWrite http_writes[] = {
3835 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3836 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3837 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3838
3839 MockRead http_reads[] = {
3840 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3841 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3842 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013843 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443844 socket_factory_.AddSocketDataProvider(&http_data);
3845 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3846
3847 // In order for a new QUIC session to be established via alternate-protocol
3848 // without racing an HTTP connection, we need the host resolution to happen
3849 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3850 // connection to the the server, in this test we require confirmation
3851 // before encrypting so the HTTP job will still start.
3852 host_resolver_.set_synchronous_mode(true);
3853 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3854 "");
rch30943ee2017-06-12 21:28:443855
3856 CreateSession();
3857
Ryan Hamilton9835e662018-08-02 05:36:273858 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443859
3860 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3861 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363862 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3864
3865 // Pump the message loop to get the request started.
3866 base::RunLoop().RunUntilIdle();
3867 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283868 crypto_client_stream_factory_.last_stream()
3869 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553870 quic_data.Resume();
rch30943ee2017-06-12 21:28:443871
3872 // Run the QUIC session to completion.
3873 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3874
3875 ExpectQuicAlternateProtocolMapping();
3876
3877 // Let the transaction proceed which will result in QUIC being marked
3878 // as broken and the request falling back to TCP.
3879 EXPECT_THAT(callback.WaitForResult(), IsOk());
3880
3881 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3882 ASSERT_FALSE(http_data.AllReadDataConsumed());
3883
3884 // Read the response body over TCP.
3885 CheckResponseData(&trans, "hello world");
3886 ExpectBrokenAlternateProtocolMapping();
3887 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3888 ASSERT_TRUE(http_data.AllReadDataConsumed());
3889}
3890
Ryan Hamilton6c2a2a82017-12-15 02:06:283891// Verify that when an origin has two alt-svc advertisements, one local and one
3892// remote, that when the local is broken the request will go over QUIC via
3893// the remote Alt-Svc.
3894// This is a regression test for crbug/825646.
3895TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:383896 context_.params()->allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:283897
3898 GURL origin1 = request_.url; // mail.example.org
3899 GURL origin2("https://www.example.org/");
3900 ASSERT_NE(origin1.host(), origin2.host());
3901
3902 scoped_refptr<X509Certificate> cert(
3903 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243904 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3905 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283906
3907 ProofVerifyDetailsChromium verify_details;
3908 verify_details.cert_verify_result.verified_cert = cert;
3909 verify_details.cert_verify_result.is_issued_by_known_root = true;
3910 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3911
Ryan Hamiltonabad59e2019-06-06 04:02:593912 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233913 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253914 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233915 mock_quic_data.AddWrite(SYNCHRONOUS,
3916 ConstructInitialSettingsPacket(packet_num++));
3917 }
Ryan Hamilton6c2a2a82017-12-15 02:06:283918 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233919 SYNCHRONOUS,
3920 ConstructClientRequestHeadersPacket(
3921 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3922 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433923 mock_quic_data.AddRead(
3924 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333925 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:023926 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:433927 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433928 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333929 ASYNC, ConstructServerDataPacket(
3930 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173931 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:233932 mock_quic_data.AddWrite(SYNCHRONOUS,
3933 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283934 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3935 mock_quic_data.AddRead(ASYNC, 0); // EOF
3936
3937 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:593938 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:283939 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3940 AddHangingNonAlternateProtocolSocketData();
3941
3942 CreateSession();
3943
3944 // Set up alternative service for |origin1|.
3945 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3946 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
3947 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3948 AlternativeServiceInfoVector alternative_services;
3949 alternative_services.push_back(
3950 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3951 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383952 context_.params()->supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:283953 alternative_services.push_back(
3954 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3955 remote_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:383956 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:493957 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
3958 NetworkIsolationKey(),
3959 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:283960
Matt Menkeb32ba5122019-09-10 19:17:053961 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
3962 NetworkIsolationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:283963
3964 SendRequestAndExpectQuicResponse("hello!");
3965}
3966
Ryan Hamilton899c2e082019-11-14 01:22:023967// Verify that when multiple alternatives are broken,
3968// ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
3969// This is a regression test for crbug/1024613.
3970TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
3971 base::HistogramTester histogram_tester;
3972
3973 MockRead http_reads[] = {
3974 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
3975 MockRead("hello world"),
3976 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3977 MockRead(ASYNC, OK)};
3978
3979 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
3980 socket_factory_.AddSocketDataProvider(&http_data);
3981 AddCertificate(&ssl_data_);
3982 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3983
3984 GURL origin1 = request_.url; // mail.example.org
3985
3986 scoped_refptr<X509Certificate> cert(
3987 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
3988 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
3989
3990 ProofVerifyDetailsChromium verify_details;
3991 verify_details.cert_verify_result.verified_cert = cert;
3992 verify_details.cert_verify_result.is_issued_by_known_root = true;
3993 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3994
3995 CreateSession();
3996
3997 // Set up alternative service for |origin1|.
3998 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3999 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4000 AlternativeServiceInfoVector alternative_services;
4001 alternative_services.push_back(
4002 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4003 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384004 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024005 alternative_services.push_back(
4006 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4007 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384008 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024009 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4010 NetworkIsolationKey(),
4011 alternative_services);
4012
4013 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4014 NetworkIsolationKey());
4015
4016 SendRequestAndExpectHttpResponse("hello world");
4017
4018 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
4019 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
4020}
4021
rch30943ee2017-06-12 21:28:444022// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4023// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:054024// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:444025// connection instead of going back to the broken QUIC connection.
4026// This is a regression tests for crbug/731303.
4027TEST_P(QuicNetworkTransactionTest,
4028 ResetPooledAfterHandshakeConfirmedThenBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:384029 context_.params()->allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444030
4031 GURL origin1 = request_.url;
4032 GURL origin2("https://www.example.org/");
4033 ASSERT_NE(origin1.host(), origin2.host());
4034
Ryan Hamiltonabad59e2019-06-06 04:02:594035 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:444036
4037 scoped_refptr<X509Certificate> cert(
4038 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244039 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4040 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444041
4042 ProofVerifyDetailsChromium verify_details;
4043 verify_details.cert_verify_result.verified_cert = cert;
4044 verify_details.cert_verify_result.is_issued_by_known_root = true;
4045 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4046
Renjie Tangaadb84b2019-08-31 01:00:234047 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254048 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234049 mock_quic_data.AddWrite(SYNCHRONOUS,
4050 ConstructInitialSettingsPacket(packet_num++));
4051 }
rch30943ee2017-06-12 21:28:444052 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434053 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234054 SYNCHRONOUS,
4055 ConstructClientRequestHeadersPacket(
4056 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4057 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434058 mock_quic_data.AddRead(
4059 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334060 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024061 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434062 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434063 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334064 ASYNC, ConstructServerDataPacket(
4065 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174066 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234067 mock_quic_data.AddWrite(SYNCHRONOUS,
4068 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rch30943ee2017-06-12 21:28:444069
4070 // Second request will go over the pooled QUIC connection, but will be
4071 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054072 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224073 version_,
4074 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4075 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054076 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174077 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224078 version_,
4079 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4080 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434081 mock_quic_data.AddWrite(
4082 SYNCHRONOUS,
4083 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234084 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4085 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024086 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334087 mock_quic_data.AddRead(
4088 ASYNC, ConstructServerRstPacket(
4089 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4090 quic::QUIC_HEADERS_TOO_LARGE));
Bence Béky6e243aa2019-12-13 19:01:074091
4092 if (VersionUsesHttp3(version_.transport_version)) {
Haoyue Wang9d70d65c2020-05-29 22:45:344093 mock_quic_data.AddWrite(
4094 SYNCHRONOUS,
4095 ConstructClientAckAndDataPacket(
4096 packet_num++, /*include_version=*/true, GetQpackDecoderStreamId(),
4097 3, 2, 1,
4098 /*fin=*/false, StreamCancellationQpackDecoderInstruction(1)));
Bence Béky6e243aa2019-12-13 19:01:074099 }
4100
rch30943ee2017-06-12 21:28:444101 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4102 mock_quic_data.AddRead(ASYNC, 0); // EOF
4103
4104 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4105
4106 // After that fails, it will be resent via TCP.
4107 MockWrite http_writes[] = {
4108 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4109 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4110 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4111
4112 MockRead http_reads[] = {
4113 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4114 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4115 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014116 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444117 socket_factory_.AddSocketDataProvider(&http_data);
4118 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4119
Ryan Hamilton6c2a2a82017-12-15 02:06:284120 // Then the next request to the second origin will be sent over TCP.
4121 socket_factory_.AddSocketDataProvider(&http_data);
4122 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444123
4124 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564125 QuicStreamFactoryPeer::SetAlarmFactory(
4126 session_->quic_stream_factory(),
4127 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224128 context_.clock()));
rch30943ee2017-06-12 21:28:444129
4130 // Set up alternative service for |origin1|.
4131 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244132 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494133 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074134 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4135 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:444136
4137 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244138 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494139 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074140 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4141 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344142
rch30943ee2017-06-12 21:28:444143 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524144 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444145 SendRequestAndExpectQuicResponse("hello!");
4146
4147 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524148 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:054149 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:444150 request_.url = origin2;
4151 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:054152 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
4153 alternative1, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244154 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:054155 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
4156 alternative2, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244157 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444158
Matt Menkeb32ba5122019-09-10 19:17:054159 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:444160 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284161 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444162}
4163
bnc8be55ebb2015-10-30 14:12:074164TEST_P(QuicNetworkTransactionTest,
4165 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564166 std::string altsvc_header =
4167 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4168 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074169 MockRead http_reads[] = {
4170 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4171 MockRead("hello world"),
4172 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4173 MockRead(ASYNC, OK)};
4174
Ryan Sleevib8d7ea02018-05-07 20:01:014175 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074176 socket_factory_.AddSocketDataProvider(&http_data);
4177 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4178 socket_factory_.AddSocketDataProvider(&http_data);
4179 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4180
rch3f4b8452016-02-23 16:59:324181 CreateSession();
bnc8be55ebb2015-10-30 14:12:074182
4183 SendRequestAndExpectHttpResponse("hello world");
4184 SendRequestAndExpectHttpResponse("hello world");
4185}
4186
Xida Chen9bfe0b62018-04-24 19:52:214187// When multiple alternative services are advertised, HttpStreamFactory should
4188// select the alternative service which uses existing QUIC session if available.
4189// If no existing QUIC session can be used, use the first alternative service
4190// from the list.
zhongyi32569c62016-01-08 02:54:304191TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:384192 context_.params()->allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524193 MockRead http_reads[] = {
4194 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294195 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524196 MockRead("hello world"),
4197 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4198 MockRead(ASYNC, OK)};
4199
Ryan Sleevib8d7ea02018-05-07 20:01:014200 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524201 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084202 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564203 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524204
zhongyi32569c62016-01-08 02:54:304205 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294206 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304207 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594208 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234209 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254210 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234211 mock_quic_data.AddWrite(SYNCHRONOUS,
4212 ConstructInitialSettingsPacket(packet_num++));
4213 }
rch5cb522462017-04-25 20:18:364214 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234215 SYNCHRONOUS,
4216 ConstructClientRequestHeadersPacket(
4217 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4218 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304219
4220 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294221 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4222 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434223 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024224 ASYNC, ConstructServerResponseHeadersPacket(
4225 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4226 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434227 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434228 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334229 ASYNC, ConstructServerDataPacket(
4230 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174231 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234232 mock_quic_data.AddWrite(SYNCHRONOUS,
4233 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304234
4235 // Second QUIC request data.
4236 // Connection pooling, using existing session, no need to include version
4237 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584238 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234239 SYNCHRONOUS,
4240 ConstructClientRequestHeadersPacket(
4241 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4242 true, GetRequestHeaders("GET", "https", "/"),
4243 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434244 mock_quic_data.AddRead(
4245 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334246 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024247 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434248 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334249 ASYNC, ConstructServerDataPacket(
4250 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174251 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434252 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234253 SYNCHRONOUS,
4254 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bncc958faa2015-07-31 18:14:524255 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594256 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524257
4258 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4259
rtennetib8e80fb2016-05-16 00:12:094260 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324261 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564262 QuicStreamFactoryPeer::SetAlarmFactory(
4263 session_->quic_stream_factory(),
4264 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224265 context_.clock()));
bncc958faa2015-07-31 18:14:524266
4267 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304268
bnc359ed2a2016-04-29 20:43:454269 SendRequestAndExpectQuicResponse("hello!");
4270 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304271}
4272
tbansal6490783c2016-09-20 17:55:274273// Check that an existing QUIC connection to an alternative proxy server is
4274// used.
4275TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4276 base::HistogramTester histogram_tester;
4277
tbansal6490783c2016-09-20 17:55:274278 // First QUIC request data.
4279 // Open a session to foo.example.org:443 using the first entry of the
4280 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594281 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234282 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254283 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234284 mock_quic_data.AddWrite(SYNCHRONOUS,
4285 ConstructInitialSettingsPacket(packet_num++));
4286 }
rch5cb522462017-04-25 20:18:364287 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234288 SYNCHRONOUS,
4289 ConstructClientRequestHeadersPacket(
4290 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4291 true, GetRequestHeaders("GET", "http", "/")));
tbansal6490783c2016-09-20 17:55:274292
4293 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434294 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024295 ASYNC, ConstructServerResponseHeadersPacket(
4296 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4297 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434298 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434299 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334300 ASYNC, ConstructServerDataPacket(
4301 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174302 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234303 mock_quic_data.AddWrite(SYNCHRONOUS,
4304 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274305
4306 // Second QUIC request data.
4307 // Connection pooling, using existing session, no need to include version
4308 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274309 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234310 SYNCHRONOUS,
4311 ConstructClientRequestHeadersPacket(
4312 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4313 true, GetRequestHeaders("GET", "http", "/"),
4314 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434315 mock_quic_data.AddRead(
4316 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334317 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024318 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434319 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334320 ASYNC, ConstructServerDataPacket(
4321 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174322 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434323 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234324 SYNCHRONOUS,
4325 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274326 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4327 mock_quic_data.AddRead(ASYNC, 0); // EOF
4328
4329 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4330
4331 AddHangingNonAlternateProtocolSocketData();
4332
4333 TestProxyDelegate test_proxy_delegate;
4334
Nicolas Arciniegad2013f92020-02-07 23:00:564335 proxy_resolution_service_ =
4336 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
4337 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274338
4339 test_proxy_delegate.set_alternative_proxy_server(
4340 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524341 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274342
4343 request_.url = GURL("http://mail.example.org/");
4344
4345 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564346 QuicStreamFactoryPeer::SetAlarmFactory(
4347 session_->quic_stream_factory(),
4348 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224349 context_.clock()));
tbansal6490783c2016-09-20 17:55:274350
4351 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4352 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4353 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4354 1);
4355
4356 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4357 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4358 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4359 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4360 1);
4361}
4362
Ryan Hamilton8d9ee76e2018-05-29 23:52:524363// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454364// even if alternative service destination is different.
4365TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Victor Vasilieva1e66d72019-12-05 17:55:384366 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594367 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454368
Renjie Tangaadb84b2019-08-31 01:00:234369 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254370 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234371 mock_quic_data.AddWrite(SYNCHRONOUS,
4372 ConstructInitialSettingsPacket(packet_num++));
4373 }
bnc359ed2a2016-04-29 20:43:454374 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434375 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234376 SYNCHRONOUS,
4377 ConstructClientRequestHeadersPacket(
4378 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4379 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434380 mock_quic_data.AddRead(
4381 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334382 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024383 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434384 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434385 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334386 ASYNC, ConstructServerDataPacket(
4387 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174388 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234389 mock_quic_data.AddWrite(SYNCHRONOUS,
4390 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304391
bnc359ed2a2016-04-29 20:43:454392 // Second request.
alyssar2adf3ac2016-05-03 17:12:584393 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234394 SYNCHRONOUS,
4395 ConstructClientRequestHeadersPacket(
4396 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4397 true, GetRequestHeaders("GET", "https", "/"),
4398 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434399 mock_quic_data.AddRead(
4400 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334401 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024402 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434403 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334404 ASYNC, ConstructServerDataPacket(
4405 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174406 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434407 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234408 SYNCHRONOUS,
4409 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304410 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4411 mock_quic_data.AddRead(ASYNC, 0); // EOF
4412
4413 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454414
4415 AddHangingNonAlternateProtocolSocketData();
4416 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304417
rch3f4b8452016-02-23 16:59:324418 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564419 QuicStreamFactoryPeer::SetAlarmFactory(
4420 session_->quic_stream_factory(),
4421 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224422 context_.clock()));
zhongyi32569c62016-01-08 02:54:304423
bnc359ed2a2016-04-29 20:43:454424 const char destination1[] = "first.example.com";
4425 const char destination2[] = "second.example.com";
4426
4427 // Set up alternative service entry to destination1.
4428 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214429 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454430 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494431 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074432 server, NetworkIsolationKey(), alternative_service, expiration,
4433 supported_versions_);
bnc359ed2a2016-04-29 20:43:454434 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524435 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454436 SendRequestAndExpectQuicResponse("hello!");
4437
4438 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214439 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494440 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074441 server, NetworkIsolationKey(), alternative_service, expiration,
4442 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524443 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454444 // even though alternative service destination is different.
4445 SendRequestAndExpectQuicResponse("hello!");
4446}
4447
4448// Pool to existing session with matching destination and matching certificate
4449// even if origin is different, and even if the alternative service with
4450// matching destination is not the first one on the list.
4451TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Victor Vasilieva1e66d72019-12-05 17:55:384452 context_.params()->allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454453 GURL origin1 = request_.url;
4454 GURL origin2("https://www.example.org/");
4455 ASSERT_NE(origin1.host(), origin2.host());
4456
Ryan Hamiltonabad59e2019-06-06 04:02:594457 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454458
Renjie Tangaadb84b2019-08-31 01:00:234459 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254460 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234461 mock_quic_data.AddWrite(SYNCHRONOUS,
4462 ConstructInitialSettingsPacket(packet_num++));
4463 }
bnc359ed2a2016-04-29 20:43:454464 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434465 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234466 SYNCHRONOUS,
4467 ConstructClientRequestHeadersPacket(
4468 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4469 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434470 mock_quic_data.AddRead(
4471 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334472 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024473 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434474 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434475 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334476 ASYNC, ConstructServerDataPacket(
4477 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174478 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234479 mock_quic_data.AddWrite(SYNCHRONOUS,
4480 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454481
4482 // Second request.
Yixin Wang079ad542018-01-11 04:06:054483 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224484 version_,
4485 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4486 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054487 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174488 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224489 version_,
4490 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4491 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584492 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434493 SYNCHRONOUS,
4494 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234495 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4496 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024497 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434498 mock_quic_data.AddRead(
4499 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334500 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024501 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434502 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334503 ASYNC, ConstructServerDataPacket(
4504 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174505 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434506 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234507 SYNCHRONOUS,
4508 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454509 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4510 mock_quic_data.AddRead(ASYNC, 0); // EOF
4511
4512 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4513
4514 AddHangingNonAlternateProtocolSocketData();
4515 AddHangingNonAlternateProtocolSocketData();
4516
4517 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564518 QuicStreamFactoryPeer::SetAlarmFactory(
4519 session_->quic_stream_factory(),
4520 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224521 context_.clock()));
bnc359ed2a2016-04-29 20:43:454522
4523 const char destination1[] = "first.example.com";
4524 const char destination2[] = "second.example.com";
4525
4526 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214527 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454528 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494529 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074530 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4531 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454532
4533 // Set up multiple alternative service entries for |origin2|,
4534 // the first one with a different destination as for |origin1|,
4535 // the second one with the same. The second one should be used,
4536 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214537 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454538 AlternativeServiceInfoVector alternative_services;
4539 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214540 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4541 alternative_service2, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384542 context_.params()->supported_versions));
bnc359ed2a2016-04-29 20:43:454543 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214544 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4545 alternative_service1, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384546 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494547 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4548 NetworkIsolationKey(),
4549 alternative_services);
bnc359ed2a2016-04-29 20:43:454550 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524551 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454552 SendRequestAndExpectQuicResponse("hello!");
4553
4554 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524555 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454556 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584557
bnc359ed2a2016-04-29 20:43:454558 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304559}
4560
4561// Multiple origins have listed the same alternative services. When there's a
4562// existing QUIC session opened by a request to other origin,
4563// if the cert is valid, should select this QUIC session to make the request
4564// if this is also the first existing QUIC session.
4565TEST_P(QuicNetworkTransactionTest,
4566 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Victor Vasilieva1e66d72019-12-05 17:55:384567 context_.params()->allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294568 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304569
rch9ae5b3b2016-02-11 00:36:294570 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304571 MockRead http_reads[] = {
4572 MockRead("HTTP/1.1 200 OK\r\n"),
4573 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294574 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304575 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4576 MockRead(ASYNC, OK)};
4577
Ryan Sleevib8d7ea02018-05-07 20:01:014578 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304579 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084580 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304581 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4582
4583 // HTTP data for request to mail.example.org.
4584 MockRead http_reads2[] = {
4585 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294586 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304587 MockRead("hello world from mail.example.org"),
4588 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4589 MockRead(ASYNC, OK)};
4590
Ryan Sleevib8d7ea02018-05-07 20:01:014591 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304592 socket_factory_.AddSocketDataProvider(&http_data2);
4593 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4594
Yixin Wang079ad542018-01-11 04:06:054595 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:224596 version_,
4597 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4598 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054599 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584600 server_maker_.set_hostname("www.example.org");
Zhongyi Shi1c022d22020-03-20 19:00:164601 client_maker_->set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594602 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234603 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254604 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234605 mock_quic_data.AddWrite(SYNCHRONOUS,
4606 ConstructInitialSettingsPacket(packet_num++));
4607 }
zhongyi32569c62016-01-08 02:54:304608 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584609 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234610 SYNCHRONOUS,
4611 ConstructClientRequestHeadersPacket(
4612 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4613 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434614
4615 mock_quic_data.AddRead(
4616 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334617 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024618 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434619 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334620 mock_quic_data.AddRead(
4621 ASYNC, ConstructServerDataPacket(
4622 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174623 header + "hello from mail QUIC!"));
Renjie Tangaadb84b2019-08-31 01:00:234624 mock_quic_data.AddWrite(SYNCHRONOUS,
4625 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434626 // Second QUIC request data.
4627 mock_quic_data.AddWrite(
4628 SYNCHRONOUS,
4629 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234630 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4631 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024632 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434633 mock_quic_data.AddRead(
4634 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334635 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024636 GetResponseHeaders("200 OK")));
Fan Yang32c5a112018-12-10 20:06:334637 mock_quic_data.AddRead(
4638 ASYNC, ConstructServerDataPacket(
4639 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174640 header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434641 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234642 SYNCHRONOUS,
4643 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304644 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4645 mock_quic_data.AddRead(ASYNC, 0); // EOF
4646
4647 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304648
rtennetib8e80fb2016-05-16 00:12:094649 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324650 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564651 QuicStreamFactoryPeer::SetAlarmFactory(
4652 session_->quic_stream_factory(),
4653 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224654 context_.clock()));
zhongyi32569c62016-01-08 02:54:304655
4656 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294657 request_.url = GURL("https://www.example.org/");
4658 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304659 request_.url = GURL("https://mail.example.org/");
4660 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4661
rch9ae5b3b2016-02-11 00:36:294662 // Open a QUIC session to mail.example.org:443 when making request
4663 // to mail.example.org.
4664 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454665 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304666
rch9ae5b3b2016-02-11 00:36:294667 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304668 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454669 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524670}
4671
4672TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524673 MockRead http_reads[] = {
4674 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564675 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524676 MockRead("hello world"),
4677 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4678 MockRead(ASYNC, OK)};
4679
Ryan Sleevib8d7ea02018-05-07 20:01:014680 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524681 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084682 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564683 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524684
rtennetib8e80fb2016-05-16 00:12:094685 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324686 CreateSession();
bncc958faa2015-07-31 18:14:524687
4688 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454689
4690 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344691 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494692 http_server_properties_->GetAlternativeServiceInfos(
4693 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344694 ASSERT_EQ(1u, alternative_service_info_vector.size());
4695 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544696 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344697 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4698 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4699 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524700}
4701
4702TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524703 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564704 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4705 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524706 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4707 MockRead(ASYNC, OK)};
4708
Ryan Sleevib8d7ea02018-05-07 20:01:014709 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524710 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084711 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564712 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524713
Ryan Hamiltonabad59e2019-06-06 04:02:594714 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234715 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254716 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234717 mock_quic_data.AddWrite(SYNCHRONOUS,
4718 ConstructInitialSettingsPacket(packet_num++));
4719 }
rch5cb522462017-04-25 20:18:364720 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234721 SYNCHRONOUS,
4722 ConstructClientRequestHeadersPacket(
4723 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4724 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434725 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334726 ASYNC, ConstructServerResponseHeadersPacket(
4727 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4728 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434729 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334730 mock_quic_data.AddRead(
4731 ASYNC, ConstructServerDataPacket(
4732 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174733 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234734 mock_quic_data.AddWrite(SYNCHRONOUS,
4735 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524736 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4737 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524738
4739 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4740
rtennetib8e80fb2016-05-16 00:12:094741 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324742 CreateSession();
bncc958faa2015-07-31 18:14:524743
bnc3472afd2016-11-17 15:27:214744 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524745 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494746 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054747 alternative_service, NetworkIsolationKey());
Matt Menke3233d8f22019-08-20 21:01:494748 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054749 alternative_service, NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524750
4751 SendRequestAndExpectHttpResponse("hello world");
4752 SendRequestAndExpectQuicResponse("hello!");
4753
mmenkee24011922015-12-17 22:12:594754 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524755
Matt Menke3233d8f22019-08-20 21:01:494756 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054757 alternative_service, NetworkIsolationKey()));
Matt Menke19475f72019-08-21 18:57:444758 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4759 url::SchemeHostPort("https", request_.url.host(), 443),
4760 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524761}
4762
Matt Menkeb32ba5122019-09-10 19:17:054763TEST_P(QuicNetworkTransactionTest,
4764 ConfirmAlternativeServiceWithNetworkIsolationKey) {
4765 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
4766 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
4767 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
4768 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
4769
4770 base::test::ScopedFeatureList feature_list;
4771 feature_list.InitWithFeatures(
4772 // enabled_features
4773 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4774 features::kPartitionConnectionsByNetworkIsolationKey},
4775 // disabled_features
4776 {});
4777 // Since HttpServerProperties caches the feature value, have to create a new
4778 // one.
4779 http_server_properties_ = std::make_unique<HttpServerProperties>();
4780
4781 MockRead http_reads[] = {
4782 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4783 MockRead("hello world"),
4784 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4785 MockRead(ASYNC, OK)};
4786
4787 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4788 socket_factory_.AddSocketDataProvider(&http_data);
4789 AddCertificate(&ssl_data_);
4790 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4791
4792 MockQuicData mock_quic_data(version_);
4793 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254794 if (VersionUsesHttp3(version_.transport_version)) {
Matt Menkeb32ba5122019-09-10 19:17:054795 mock_quic_data.AddWrite(SYNCHRONOUS,
4796 ConstructInitialSettingsPacket(packet_num++));
4797 }
4798 mock_quic_data.AddWrite(
4799 SYNCHRONOUS,
4800 ConstructClientRequestHeadersPacket(
4801 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4802 true, GetRequestHeaders("GET", "https", "/")));
4803 mock_quic_data.AddRead(
4804 ASYNC, ConstructServerResponseHeadersPacket(
4805 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4806 GetResponseHeaders("200 OK")));
4807 std::string header = ConstructDataHeader(6);
4808 mock_quic_data.AddRead(
4809 ASYNC, ConstructServerDataPacket(
4810 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4811 header + "hello!"));
4812 mock_quic_data.AddWrite(SYNCHRONOUS,
4813 ConstructClientAckPacket(packet_num++, 2, 1, 1));
4814 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4815 mock_quic_data.AddRead(ASYNC, 0); // EOF
4816
4817 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4818
4819 CreateSession();
4820
4821 AlternativeService alternative_service(kProtoQUIC,
4822 HostPortPair::FromURL(request_.url));
4823 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4824 alternative_service, kNetworkIsolationKey1);
4825 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4826 alternative_service, kNetworkIsolationKey2);
4827 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4828 alternative_service, kNetworkIsolationKey1));
4829 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4830 alternative_service, kNetworkIsolationKey2));
4831
4832 request_.network_isolation_key = kNetworkIsolationKey1;
4833 SendRequestAndExpectHttpResponse("hello world");
4834 SendRequestAndExpectQuicResponse("hello!");
4835
4836 mock_quic_data.Resume();
4837
4838 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4839 alternative_service, kNetworkIsolationKey1));
4840 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4841 url::SchemeHostPort("https", request_.url.host(), 443),
4842 kNetworkIsolationKey1));
4843 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4844 alternative_service, kNetworkIsolationKey2));
4845 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4846 url::SchemeHostPort("https", request_.url.host(), 443),
4847 kNetworkIsolationKey2));
4848}
4849
bncc958faa2015-07-31 18:14:524850TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524851 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564852 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4853 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524854 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4855 MockRead(ASYNC, OK)};
4856
Ryan Sleevib8d7ea02018-05-07 20:01:014857 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524858 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564859 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524860
Ryan Hamiltonabad59e2019-06-06 04:02:594861 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234862 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254863 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234864 mock_quic_data.AddWrite(SYNCHRONOUS,
4865 ConstructInitialSettingsPacket(packet_num++));
4866 }
rch5cb522462017-04-25 20:18:364867 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234868 SYNCHRONOUS,
4869 ConstructClientRequestHeadersPacket(
4870 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4871 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434872 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334873 ASYNC, ConstructServerResponseHeadersPacket(
4874 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4875 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434876 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334877 mock_quic_data.AddRead(
4878 ASYNC, ConstructServerDataPacket(
4879 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174880 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234881 mock_quic_data.AddWrite(SYNCHRONOUS,
4882 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524883 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4884
4885 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4886
4887 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324888 CreateSession();
bncc958faa2015-07-31 18:14:524889
4890 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4891 SendRequestAndExpectHttpResponse("hello world");
4892}
4893
tbansalc3308d72016-08-27 10:25:044894// Tests that the connection to an HTTPS proxy is raced with an available
4895// alternative proxy server.
4896TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274897 base::HistogramTester histogram_tester;
Nicolas Arciniegad2013f92020-02-07 23:00:564898 proxy_resolution_service_ =
4899 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
4900 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044901
Ryan Hamiltonabad59e2019-06-06 04:02:594902 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234903 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254904 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234905 mock_quic_data.AddWrite(SYNCHRONOUS,
4906 ConstructInitialSettingsPacket(packet_num++));
4907 }
rch5cb522462017-04-25 20:18:364908 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234909 SYNCHRONOUS,
4910 ConstructClientRequestHeadersPacket(
4911 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4912 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434913 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334914 ASYNC, ConstructServerResponseHeadersPacket(
4915 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4916 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434917 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334918 mock_quic_data.AddRead(
4919 ASYNC, ConstructServerDataPacket(
4920 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174921 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234922 mock_quic_data.AddWrite(SYNCHRONOUS,
4923 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044924 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4925 mock_quic_data.AddRead(ASYNC, 0); // EOF
4926
4927 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4928
4929 // There is no need to set up main job, because no attempt will be made to
4930 // speak to the proxy over TCP.
4931 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044932 TestProxyDelegate test_proxy_delegate;
4933 const HostPortPair host_port_pair("mail.example.org", 443);
4934
4935 test_proxy_delegate.set_alternative_proxy_server(
4936 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524937 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044938 CreateSession();
4939 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4940
4941 // The main job needs to hang in order to guarantee that the alternative
4942 // proxy server job will "win".
4943 AddHangingNonAlternateProtocolSocketData();
4944
4945 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4946
4947 // Verify that the alternative proxy server is not marked as broken.
4948 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4949
4950 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594951 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274952
4953 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4954 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4955 1);
tbansalc3308d72016-08-27 10:25:044956}
4957
bnc1c196c6e2016-05-28 13:51:484958TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304959 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274960 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304961
4962 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564963 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294964 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564965 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304966
4967 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564968 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484969 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564970 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304971
Ryan Sleevib8d7ea02018-05-07 20:01:014972 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504973 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084974 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504975 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304976
4977 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454978 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304979 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454980 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304981 };
Ryan Sleevib8d7ea02018-05-07 20:01:014982 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504983 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304984
4985 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014986 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504987 socket_factory_.AddSocketDataProvider(&http_data2);
4988 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304989
bnc912a04b2016-04-20 14:19:504990 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304991
4992 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304993 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174994 ASSERT_TRUE(http_data.AllReadDataConsumed());
4995 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304996
4997 // Now run the second request in which the QUIC socket hangs,
4998 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304999 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:455000 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:305001
rch37de576c2015-05-17 20:28:175002 ASSERT_TRUE(http_data2.AllReadDataConsumed());
5003 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:455004 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305005}
5006
[email protected]1e960032013-12-20 19:00:205007TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
David Schinazi84c58bb2020-06-04 20:14:335008 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435009 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5010 return;
5011 }
5012
Ryan Hamiltonabad59e2019-06-06 04:02:595013 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165014 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495015 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255016 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495017 mock_quic_data.AddWrite(SYNCHRONOUS,
5018 ConstructInitialSettingsPacket(packet_num++));
5019 }
Zhongyi Shi32f2fd02018-04-16 18:23:435020 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495021 SYNCHRONOUS,
5022 ConstructClientRequestHeadersPacket(
5023 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5024 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435025 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335026 ASYNC, ConstructServerResponseHeadersPacket(
5027 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5028 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435029 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335030 mock_quic_data.AddRead(
5031 ASYNC, ConstructServerDataPacket(
5032 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175033 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495034 mock_quic_data.AddWrite(SYNCHRONOUS,
5035 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505036 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595037 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:485038
rcha5399e02015-04-21 19:32:045039 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:485040
rtennetib8e80fb2016-05-16 00:12:095041 // The non-alternate protocol job needs to hang in order to guarantee that
5042 // the alternate-protocol job will "win".
5043 AddHangingNonAlternateProtocolSocketData();
5044
rch3f4b8452016-02-23 16:59:325045 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275046 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:195047 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:305048
Matt Menke19475f72019-08-21 18:57:445049 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5050 url::SchemeHostPort("https", request_.url.host(), 443),
5051 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:485052}
5053
[email protected]1e960032013-12-20 19:00:205054TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
David Schinazi84c58bb2020-06-04 20:14:335055 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435056 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5057 return;
5058 }
5059
Ryan Hamiltonabad59e2019-06-06 04:02:595060 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165061 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495062 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255063 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495064 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:165065 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:495066 }
Fan Yang32c5a112018-12-10 20:06:335067 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495068 SYNCHRONOUS,
5069 ConstructClientRequestHeadersPacket(
5070 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5071 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435072 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335073 ASYNC, ConstructServerResponseHeadersPacket(
5074 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5075 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435076 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335077 mock_quic_data.AddRead(
5078 ASYNC, ConstructServerDataPacket(
5079 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175080 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495081 mock_quic_data.AddWrite(SYNCHRONOUS,
5082 ConstructClientAckPacket(packet_number++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505083 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595084 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:045085 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275086
5087 // In order for a new QUIC session to be established via alternate-protocol
5088 // without racing an HTTP connection, we need the host resolution to happen
5089 // synchronously.
5090 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295091 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565092 "");
[email protected]3a120a6b2013-06-25 01:08:275093
rtennetib8e80fb2016-05-16 00:12:095094 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325095 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275096 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:275097 SendRequestAndExpectQuicResponse("hello!");
5098}
5099
[email protected]0fc924b2014-03-31 04:34:155100TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Nicolas Arciniegad2013f92020-02-07 23:00:565101 proxy_resolution_service_ =
5102 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
5103 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155104
5105 // Since we are using a proxy, the QUIC job will not succeed.
5106 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295107 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5108 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565109 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155110
5111 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565112 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485113 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565114 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155115
Ryan Sleevib8d7ea02018-05-07 20:01:015116 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155117 socket_factory_.AddSocketDataProvider(&http_data);
5118
5119 // In order for a new QUIC session to be established via alternate-protocol
5120 // without racing an HTTP connection, we need the host resolution to happen
5121 // synchronously.
5122 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295123 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565124 "");
[email protected]0fc924b2014-03-31 04:34:155125
rch9ae5b3b2016-02-11 00:36:295126 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325127 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275128 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155129 SendRequestAndExpectHttpResponse("hello world");
5130}
5131
[email protected]1e960032013-12-20 19:00:205132TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:595133 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235134 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165135 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255136 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235137 mock_quic_data.AddWrite(SYNCHRONOUS,
5138 ConstructInitialSettingsPacket(packet_num++));
5139 }
Zhongyi Shi1c022d22020-03-20 19:00:165140 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365141 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235142 SYNCHRONOUS,
5143 ConstructClientRequestHeadersPacket(
5144 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5145 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435146 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335147 ASYNC, ConstructServerResponseHeadersPacket(
5148 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5149 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435150 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335151 mock_quic_data.AddRead(
5152 ASYNC, ConstructServerDataPacket(
5153 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175154 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235155 mock_quic_data.AddWrite(SYNCHRONOUS,
5156 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595157 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045158 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125159
rtennetib8e80fb2016-05-16 00:12:095160 // The non-alternate protocol job needs to hang in order to guarantee that
5161 // the alternate-protocol job will "win".
5162 AddHangingNonAlternateProtocolSocketData();
5163
[email protected]11c05872013-08-20 02:04:125164 // In order for a new QUIC session to be established via alternate-protocol
5165 // without racing an HTTP connection, we need the host resolution to happen
5166 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5167 // connection to the the server, in this test we require confirmation
5168 // before encrypting so the HTTP job will still start.
5169 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295170 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565171 "");
[email protected]11c05872013-08-20 02:04:125172
rch3f4b8452016-02-23 16:59:325173 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435174 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5175 false);
Ryan Hamilton9835e662018-08-02 05:36:275176 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125177
bnc691fda62016-08-12 00:43:165178 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125179 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365180 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015181 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125182
Fan Yang3673cc72020-02-07 14:49:285183 crypto_client_stream_factory_.last_stream()
5184 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015185 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505186
bnc691fda62016-08-12 00:43:165187 CheckWasQuicResponse(&trans);
5188 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125189}
5190
Steven Valdez58097ec32018-07-16 18:29:045191TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015192 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595193 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165194 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255195 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495196 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:165197 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:495198 }
Steven Valdez58097ec32018-07-16 18:29:045199 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015200 SYNCHRONOUS,
5201 ConstructClientRequestHeadersPacket(
5202 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5203 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335204 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025205 ASYNC, ConstructServerResponseHeadersPacket(
5206 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5207 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075208 if (VersionUsesHttp3(version_.transport_version)) {
5209 mock_quic_data.AddWrite(
5210 SYNCHRONOUS,
5211 ConstructClientAckAndDataPacket(
5212 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
5213 StreamCancellationQpackDecoderInstruction(0)));
5214 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165215 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075216 packet_number++, false,
5217 GetNthClientInitiatedBidirectionalStreamId(0),
5218 quic::QUIC_STREAM_CANCELLED));
5219 } else {
5220 mock_quic_data.AddWrite(
5221 SYNCHRONOUS,
5222 ConstructClientAckAndRstPacket(
5223 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5224 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
5225 }
Steven Valdez58097ec32018-07-16 18:29:045226
Zhongyi Shi1c022d22020-03-20 19:00:165227 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:045228
Steven Valdez58097ec32018-07-16 18:29:045229 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015230 SYNCHRONOUS,
5231 ConstructClientRequestHeadersPacket(
5232 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5233 true, GetRequestHeaders("GET", "https", "/"),
5234 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045235 mock_quic_data.AddRead(
5236 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335237 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025238 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435239 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045240 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335241 ASYNC, ConstructServerDataPacket(
5242 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175243 header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045244 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015245 SYNCHRONOUS,
5246 ConstructClientAckAndConnectionClosePacket(packet_number++, 3, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045247 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5248 mock_quic_data.AddRead(ASYNC, 0); // EOF
5249
5250 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5251
5252 // In order for a new QUIC session to be established via alternate-protocol
5253 // without racing an HTTP connection, we need the host resolution to happen
5254 // synchronously.
5255 host_resolver_.set_synchronous_mode(true);
5256 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5257 "");
Steven Valdez58097ec32018-07-16 18:29:045258
5259 AddHangingNonAlternateProtocolSocketData();
5260 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275261 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565262 QuicStreamFactoryPeer::SetAlarmFactory(
5263 session_->quic_stream_factory(),
5264 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225265 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045266
5267 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5268 TestCompletionCallback callback;
5269 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5270 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5271
5272 // Confirm the handshake after the 425 Too Early.
5273 base::RunLoop().RunUntilIdle();
5274
5275 // The handshake hasn't been confirmed yet, so the retry should not have
5276 // succeeded.
5277 EXPECT_FALSE(callback.have_result());
5278
Fan Yang3673cc72020-02-07 14:49:285279 crypto_client_stream_factory_.last_stream()
5280 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:045281
5282 EXPECT_THAT(callback.WaitForResult(), IsOk());
5283 CheckWasQuicResponse(&trans);
5284 CheckResponseData(&trans, "hello!");
5285}
5286
5287TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015288 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595289 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165290 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255291 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495292 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:165293 SYNCHRONOUS, client_maker_->MakeInitialSettingsPacket(packet_number++));
Nick Harper057264a82019-09-12 23:33:495294 }
Steven Valdez58097ec32018-07-16 18:29:045295 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015296 SYNCHRONOUS,
5297 ConstructClientRequestHeadersPacket(
5298 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5299 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335300 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025301 ASYNC, ConstructServerResponseHeadersPacket(
5302 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5303 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075304 if (VersionUsesHttp3(version_.transport_version)) {
5305 mock_quic_data.AddWrite(
5306 SYNCHRONOUS,
5307 ConstructClientAckAndDataPacket(
5308 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
5309 StreamCancellationQpackDecoderInstruction(0)));
5310 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165311 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075312 packet_number++, false,
5313 GetNthClientInitiatedBidirectionalStreamId(0),
5314 quic::QUIC_STREAM_CANCELLED));
5315 } else {
5316 mock_quic_data.AddWrite(
5317 SYNCHRONOUS,
5318 ConstructClientAckAndRstPacket(
5319 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5320 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
5321 }
Steven Valdez58097ec32018-07-16 18:29:045322
Zhongyi Shi1c022d22020-03-20 19:00:165323 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Steven Valdez58097ec32018-07-16 18:29:045324
Steven Valdez58097ec32018-07-16 18:29:045325 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015326 SYNCHRONOUS,
5327 ConstructClientRequestHeadersPacket(
5328 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5329 true, GetRequestHeaders("GET", "https", "/"),
5330 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335331 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025332 ASYNC, ConstructServerResponseHeadersPacket(
5333 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5334 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075335 if (VersionUsesHttp3(version_.transport_version)) {
5336 mock_quic_data.AddWrite(
5337 SYNCHRONOUS,
5338 ConstructClientAckAndDataPacket(
5339 packet_number++, false, GetQpackDecoderStreamId(), 2, 1, 1, false,
Renjie Tang248e36ea2020-06-26 00:12:345340 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:075341 mock_quic_data.AddWrite(SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:165342 client_maker_->MakeRstPacket(
Bence Béky6e243aa2019-12-13 19:01:075343 packet_number++, false,
5344 GetNthClientInitiatedBidirectionalStreamId(1),
5345 quic::QUIC_STREAM_CANCELLED));
5346 } else {
5347 mock_quic_data.AddWrite(
5348 SYNCHRONOUS,
5349 ConstructClientAckAndRstPacket(
5350 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
5351 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
5352 }
Steven Valdez58097ec32018-07-16 18:29:045353 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5354 mock_quic_data.AddRead(ASYNC, 0); // EOF
5355
5356 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5357
5358 // In order for a new QUIC session to be established via alternate-protocol
5359 // without racing an HTTP connection, we need the host resolution to happen
5360 // synchronously.
5361 host_resolver_.set_synchronous_mode(true);
5362 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5363 "");
Steven Valdez58097ec32018-07-16 18:29:045364
5365 AddHangingNonAlternateProtocolSocketData();
5366 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275367 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565368 QuicStreamFactoryPeer::SetAlarmFactory(
5369 session_->quic_stream_factory(),
5370 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225371 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045372
5373 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5374 TestCompletionCallback callback;
5375 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5376 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5377
5378 // Confirm the handshake after the 425 Too Early.
5379 base::RunLoop().RunUntilIdle();
5380
5381 // The handshake hasn't been confirmed yet, so the retry should not have
5382 // succeeded.
5383 EXPECT_FALSE(callback.have_result());
5384
Fan Yang3673cc72020-02-07 14:49:285385 crypto_client_stream_factory_.last_stream()
5386 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:045387
5388 EXPECT_THAT(callback.WaitForResult(), IsOk());
5389 const HttpResponseInfo* response = trans.GetResponseInfo();
5390 ASSERT_TRUE(response != nullptr);
5391 ASSERT_TRUE(response->headers.get() != nullptr);
5392 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5393 EXPECT_TRUE(response->was_fetched_via_spdy);
5394 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085395 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5396 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045397}
5398
zhongyica364fbb2015-12-12 03:39:125399TEST_P(QuicNetworkTransactionTest,
5400 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Victor Vasilieva1e66d72019-12-05 17:55:385401 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595402 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235403 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165404 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255405 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235406 mock_quic_data.AddWrite(SYNCHRONOUS,
5407 ConstructInitialSettingsPacket(packet_num++));
5408 }
Zhongyi Shi1c022d22020-03-20 19:00:165409 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365410 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235411 SYNCHRONOUS,
5412 ConstructClientRequestHeadersPacket(
5413 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5414 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125415 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525416 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435417 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125418 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5419
5420 // The non-alternate protocol job needs to hang in order to guarantee that
5421 // the alternate-protocol job will "win".
5422 AddHangingNonAlternateProtocolSocketData();
5423
5424 // In order for a new QUIC session to be established via alternate-protocol
5425 // without racing an HTTP connection, we need the host resolution to happen
5426 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5427 // connection to the the server, in this test we require confirmation
5428 // before encrypting so the HTTP job will still start.
5429 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295430 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125431 "");
zhongyica364fbb2015-12-12 03:39:125432
rch3f4b8452016-02-23 16:59:325433 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435434 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5435 false);
Ryan Hamilton9835e662018-08-02 05:36:275436 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125437
bnc691fda62016-08-12 00:43:165438 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125439 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365440 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015441 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125442
Fan Yang3673cc72020-02-07 14:49:285443 crypto_client_stream_factory_.last_stream()
5444 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015445 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125446
5447 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525448 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125449
bnc691fda62016-08-12 00:43:165450 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125451 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525452 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5453 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125454}
5455
5456TEST_P(QuicNetworkTransactionTest,
5457 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Victor Vasilieva1e66d72019-12-05 17:55:385458 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595459 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235460 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165461 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255462 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235463 mock_quic_data.AddWrite(SYNCHRONOUS,
5464 ConstructInitialSettingsPacket(packet_num++));
5465 }
Zhongyi Shi1c022d22020-03-20 19:00:165466 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365467 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235468 SYNCHRONOUS,
5469 ConstructClientRequestHeadersPacket(
5470 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5471 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215472 // Peer sending data from an non-existing stream causes this end to raise
5473 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335474 mock_quic_data.AddRead(
5475 ASYNC, ConstructServerRstPacket(
5476 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5477 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215478 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:375479 mock_quic_data.AddWrite(
Renjie Tang248e36ea2020-06-26 00:12:345480 SYNCHRONOUS,
5481 ConstructClientAckAndConnectionClosePacket(
5482 packet_num++, 1, 1, 1,
5483 version_.HasIetfQuicFrames() ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
5484 : quic::QUIC_INVALID_STREAM_ID,
5485 quic_error_details, quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125486 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5487
5488 // The non-alternate protocol job needs to hang in order to guarantee that
5489 // the alternate-protocol job will "win".
5490 AddHangingNonAlternateProtocolSocketData();
5491
5492 // In order for a new QUIC session to be established via alternate-protocol
5493 // without racing an HTTP connection, we need the host resolution to happen
5494 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5495 // connection to the the server, in this test we require confirmation
5496 // before encrypting so the HTTP job will still start.
5497 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295498 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125499 "");
zhongyica364fbb2015-12-12 03:39:125500
rch3f4b8452016-02-23 16:59:325501 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435502 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5503 false);
Ryan Hamilton9835e662018-08-02 05:36:275504 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125505
bnc691fda62016-08-12 00:43:165506 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125507 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365508 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015509 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125510
Fan Yang3673cc72020-02-07 14:49:285511 crypto_client_stream_factory_.last_stream()
5512 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015513 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125514 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525515 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125516
bnc691fda62016-08-12 00:43:165517 trans.PopulateNetErrorDetails(&details);
Renjie Tang248e36ea2020-06-26 00:12:345518 EXPECT_EQ(version_.HasIetfQuicFrames()
5519 ? quic::QUIC_HTTP_STREAM_WRONG_DIRECTION
5520 : quic::QUIC_INVALID_STREAM_ID,
5521 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125522}
5523
Nick Harper057264a82019-09-12 23:33:495524TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:595525 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235526 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165527 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255528 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235529 mock_quic_data.AddWrite(SYNCHRONOUS,
5530 ConstructInitialSettingsPacket(packet_num++));
5531 }
Zhongyi Shi1c022d22020-03-20 19:00:165532 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365533 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235534 SYNCHRONOUS,
5535 ConstructClientRequestHeadersPacket(
5536 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5537 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485538 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335539 mock_quic_data.AddRead(
5540 ASYNC, ConstructServerResponseHeadersPacket(
5541 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5542 GetResponseHeaders("200 OK")));
5543 mock_quic_data.AddRead(
5544 ASYNC, ConstructServerRstPacket(
5545 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5546 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075547
5548 if (VersionUsesHttp3(version_.transport_version)) {
5549 mock_quic_data.AddWrite(
5550 SYNCHRONOUS,
5551 ConstructClientAckAndDataPacket(
5552 packet_num++, false, GetQpackDecoderStreamId(), 2, 1, 1, false,
5553 StreamCancellationQpackDecoderInstruction(0)));
5554 } else {
5555 mock_quic_data.AddWrite(SYNCHRONOUS,
5556 ConstructClientAckPacket(packet_num++, 2, 1, 1));
5557 }
rchcd5f1c62016-06-23 02:43:485558 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5559 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5560
5561 // The non-alternate protocol job needs to hang in order to guarantee that
5562 // the alternate-protocol job will "win".
5563 AddHangingNonAlternateProtocolSocketData();
5564
5565 // In order for a new QUIC session to be established via alternate-protocol
5566 // without racing an HTTP connection, we need the host resolution to happen
5567 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5568 // connection to the the server, in this test we require confirmation
5569 // before encrypting so the HTTP job will still start.
5570 host_resolver_.set_synchronous_mode(true);
5571 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5572 "");
rchcd5f1c62016-06-23 02:43:485573
5574 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435575 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5576 false);
Ryan Hamilton9835e662018-08-02 05:36:275577 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485578
bnc691fda62016-08-12 00:43:165579 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485580 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365581 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015582 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485583
Fan Yang3673cc72020-02-07 14:49:285584 crypto_client_stream_factory_.last_stream()
5585 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:485586 // Read the headers.
robpercival214763f2016-07-01 23:27:015587 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485588
bnc691fda62016-08-12 00:43:165589 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485590 ASSERT_TRUE(response != nullptr);
5591 ASSERT_TRUE(response->headers.get() != nullptr);
5592 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5593 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525594 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085595 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5596 response->connection_info);
rchcd5f1c62016-06-23 02:43:485597
5598 std::string response_data;
bnc691fda62016-08-12 00:43:165599 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485600}
5601
Nick Harper057264a82019-09-12 23:33:495602TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:385603 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595604 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235605 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165606 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255607 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235608 mock_quic_data.AddWrite(SYNCHRONOUS,
5609 ConstructInitialSettingsPacket(packet_num++));
5610 }
Zhongyi Shi1c022d22020-03-20 19:00:165611 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365612 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235613 SYNCHRONOUS,
5614 ConstructClientRequestHeadersPacket(
5615 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5616 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335617 mock_quic_data.AddRead(
5618 ASYNC, ConstructServerRstPacket(
5619 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5620 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075621
5622 if (VersionUsesHttp3(version_.transport_version)) {
5623 mock_quic_data.AddWrite(
Renjie Tang248e36ea2020-06-26 00:12:345624 SYNCHRONOUS,
5625 ConstructClientAckAndDataPacket(
5626 packet_num++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
5627 StreamCancellationQpackDecoderInstruction(0)));
Bence Béky6e243aa2019-12-13 19:01:075628 }
5629
rchcd5f1c62016-06-23 02:43:485630 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5631 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5632
5633 // The non-alternate protocol job needs to hang in order to guarantee that
5634 // the alternate-protocol job will "win".
5635 AddHangingNonAlternateProtocolSocketData();
5636
5637 // In order for a new QUIC session to be established via alternate-protocol
5638 // without racing an HTTP connection, we need the host resolution to happen
5639 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5640 // connection to the the server, in this test we require confirmation
5641 // before encrypting so the HTTP job will still start.
5642 host_resolver_.set_synchronous_mode(true);
5643 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5644 "");
rchcd5f1c62016-06-23 02:43:485645
5646 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435647 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5648 false);
Ryan Hamilton9835e662018-08-02 05:36:275649 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485650
bnc691fda62016-08-12 00:43:165651 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485652 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365653 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015654 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485655
Fan Yang3673cc72020-02-07 14:49:285656 crypto_client_stream_factory_.last_stream()
5657 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:485658 // Read the headers.
robpercival214763f2016-07-01 23:27:015659 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485660}
5661
[email protected]1e960032013-12-20 19:00:205662TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305663 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525664 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585665 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305666 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505667 MockRead(ASYNC, close->data(), close->length()),
5668 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5669 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305670 };
Ryan Sleevib8d7ea02018-05-07 20:01:015671 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305672 socket_factory_.AddSocketDataProvider(&quic_data);
5673
5674 // Main job which will succeed even though the alternate job fails.
5675 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025676 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5677 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5678 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305679
Ryan Sleevib8d7ea02018-05-07 20:01:015680 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305681 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565682 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305683
rch3f4b8452016-02-23 16:59:325684 CreateSession();
David Schinazic8281052019-01-24 06:14:175685 AddQuicAlternateProtocolMapping(
5686 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195687 SendRequestAndExpectHttpResponse("hello from http");
5688 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305689}
5690
Matt Menkeb32ba5122019-09-10 19:17:055691TEST_P(QuicNetworkTransactionTest,
5692 BrokenAlternateProtocolWithNetworkIsolationKey) {
5693 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5694 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5695 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5696 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5697
5698 base::test::ScopedFeatureList feature_list;
5699 feature_list.InitWithFeatures(
5700 // enabled_features
5701 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5702 features::kPartitionConnectionsByNetworkIsolationKey},
5703 // disabled_features
5704 {});
5705 // Since HttpServerProperties caches the feature value, have to create a new
5706 // one.
5707 http_server_properties_ = std::make_unique<HttpServerProperties>();
5708
5709 // Alternate-protocol job
5710 std::unique_ptr<quic::QuicEncryptedPacket> close(
5711 ConstructServerConnectionClosePacket(1));
5712 MockRead quic_reads[] = {
5713 MockRead(ASYNC, close->data(), close->length()),
5714 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5715 MockRead(ASYNC, OK), // EOF
5716 };
5717 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5718 socket_factory_.AddSocketDataProvider(&quic_data);
5719
5720 // Main job which will succeed even though the alternate job fails.
5721 MockRead http_reads[] = {
5722 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5723 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5724 MockRead(ASYNC, OK)};
5725
5726 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5727 socket_factory_.AddSocketDataProvider(&http_data);
5728 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5729
5730 CreateSession();
5731 AddQuicAlternateProtocolMapping(
5732 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5733 AddQuicAlternateProtocolMapping(
5734 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5735 request_.network_isolation_key = kNetworkIsolationKey1;
5736 SendRequestAndExpectHttpResponse("hello from http");
5737
5738 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5739 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5740}
5741
[email protected]1e960032013-12-20 19:00:205742TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595743 // Alternate-protocol job
5744 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025745 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595746 };
Ryan Sleevib8d7ea02018-05-07 20:01:015747 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595748 socket_factory_.AddSocketDataProvider(&quic_data);
5749
5750 // Main job which will succeed even though the alternate job fails.
5751 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025752 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5753 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5754 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595755
Ryan Sleevib8d7ea02018-05-07 20:01:015756 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595757 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565758 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595759
rch3f4b8452016-02-23 16:59:325760 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595761
Ryan Hamilton9835e662018-08-02 05:36:275762 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195763 SendRequestAndExpectHttpResponse("hello from http");
5764 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595765}
5766
[email protected]00c159f2014-05-21 22:38:165767TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535768 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165769 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025770 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165771 };
Ryan Sleevib8d7ea02018-05-07 20:01:015772 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165773 socket_factory_.AddSocketDataProvider(&quic_data);
5774
[email protected]eb71ab62014-05-23 07:57:535775 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165776 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025777 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165778 };
5779
Ryan Sleevib8d7ea02018-05-07 20:01:015780 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165781 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5782 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565783 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165784
rtennetib8e80fb2016-05-16 00:12:095785 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325786 CreateSession();
[email protected]00c159f2014-05-21 22:38:165787
Ryan Hamilton9835e662018-08-02 05:36:275788 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165789 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165790 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165791 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015792 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5793 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165794 ExpectQuicAlternateProtocolMapping();
5795}
5796
Zhongyi Shia0cef1082017-08-25 01:49:505797TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
David Schinazi84c58bb2020-06-04 20:14:335798 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435799 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5800 return;
5801 }
5802
Zhongyi Shia0cef1082017-08-25 01:49:505803 // Tests that TCP job is delayed and QUIC job does not require confirmation
5804 // if QUIC was recently supported on the same IP on start.
5805
5806 // Set QUIC support on the last IP address, which is same with the local IP
5807 // address. Require confirmation mode will be turned off immediately when
5808 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435809 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5810 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:505811
Ryan Hamiltonabad59e2019-06-06 04:02:595812 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:165813 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495814 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255815 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495816 mock_quic_data.AddWrite(SYNCHRONOUS,
5817 ConstructInitialSettingsPacket(packet_number++));
5818 }
Zhongyi Shi32f2fd02018-04-16 18:23:435819 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495820 SYNCHRONOUS,
5821 ConstructClientRequestHeadersPacket(
5822 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5823 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435824 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335825 ASYNC, ConstructServerResponseHeadersPacket(
5826 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5827 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435828 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335829 mock_quic_data.AddRead(
5830 ASYNC, ConstructServerDataPacket(
5831 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175832 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495833 mock_quic_data.AddWrite(SYNCHRONOUS,
5834 ConstructClientAckPacket(packet_number++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505835 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5836 mock_quic_data.AddRead(ASYNC, 0); // EOF
5837
5838 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5839 // No HTTP data is mocked as TCP job never starts in this case.
5840
5841 CreateSession();
5842 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:435843 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5844 false);
Zhongyi Shia0cef1082017-08-25 01:49:505845
Ryan Hamilton9835e662018-08-02 05:36:275846 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505847
5848 // Stall host resolution so that QUIC job will not succeed synchronously.
5849 // Socket will not be configured immediately and QUIC support is not sorted
5850 // out, TCP job will still be delayed as server properties indicates QUIC
5851 // support on last IP address.
5852 host_resolver_.set_synchronous_mode(false);
5853
5854 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5855 TestCompletionCallback callback;
5856 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5857 IsError(ERR_IO_PENDING));
5858 // Complete host resolution in next message loop so that QUIC job could
5859 // proceed.
5860 base::RunLoop().RunUntilIdle();
5861 EXPECT_THAT(callback.WaitForResult(), IsOk());
5862
5863 CheckWasQuicResponse(&trans);
5864 CheckResponseData(&trans, "hello!");
5865}
5866
5867TEST_P(QuicNetworkTransactionTest,
5868 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5869 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5870 // was recently supported on a different IP address on start.
5871
5872 // Set QUIC support on the last IP address, which is different with the local
5873 // IP address. Require confirmation mode will remain when local IP address is
5874 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435875 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5876 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:505877
Ryan Hamiltonabad59e2019-06-06 04:02:595878 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235879 int packet_num = 1;
Zhongyi Shi1c022d22020-03-20 19:00:165880 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255881 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235882 mock_quic_data.AddWrite(SYNCHRONOUS,
5883 ConstructInitialSettingsPacket(packet_num++));
5884 }
Zhongyi Shi1c022d22020-03-20 19:00:165885 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:505886 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235887 SYNCHRONOUS,
5888 ConstructClientRequestHeadersPacket(
5889 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5890 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435891 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335892 ASYNC, ConstructServerResponseHeadersPacket(
5893 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5894 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435895 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335896 mock_quic_data.AddRead(
5897 ASYNC, ConstructServerDataPacket(
5898 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175899 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235900 mock_quic_data.AddWrite(SYNCHRONOUS,
5901 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505902 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5903 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5904 // No HTTP data is mocked as TCP job will be delayed and never starts.
5905
5906 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435907 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5908 false);
Ryan Hamilton9835e662018-08-02 05:36:275909 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505910
5911 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5912 // Socket will not be configured immediately and QUIC support is not sorted
5913 // out, TCP job will still be delayed as server properties indicates QUIC
5914 // support on last IP address.
5915 host_resolver_.set_synchronous_mode(false);
5916
5917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5918 TestCompletionCallback callback;
5919 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5920 IsError(ERR_IO_PENDING));
5921
5922 // Complete host resolution in next message loop so that QUIC job could
5923 // proceed.
5924 base::RunLoop().RunUntilIdle();
5925 // Explicitly confirm the handshake so that QUIC job could succeed.
Fan Yang3673cc72020-02-07 14:49:285926 crypto_client_stream_factory_.last_stream()
5927 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia0cef1082017-08-25 01:49:505928 EXPECT_THAT(callback.WaitForResult(), IsOk());
5929
5930 CheckWasQuicResponse(&trans);
5931 CheckResponseData(&trans, "hello!");
5932}
5933
Ryan Hamilton75f197262017-08-17 14:00:075934TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5935 // Test that NetErrorDetails is correctly populated, even if the
5936 // handshake has not yet been confirmed and no stream has been created.
5937
5938 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595939 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075940 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5941 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5942 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5943
5944 // Main job will also fail.
5945 MockRead http_reads[] = {
5946 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5947 };
5948
Ryan Sleevib8d7ea02018-05-07 20:01:015949 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075950 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5951 socket_factory_.AddSocketDataProvider(&http_data);
5952 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5953
5954 AddHangingNonAlternateProtocolSocketData();
5955 CreateSession();
5956 // Require handshake confirmation to ensure that no QUIC streams are
5957 // created, and to ensure that the TCP job does not wait for the QUIC
5958 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:435959 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5960 false);
Ryan Hamilton75f197262017-08-17 14:00:075961
Ryan Hamilton9835e662018-08-02 05:36:275962 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075963 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5964 TestCompletionCallback callback;
5965 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5966 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5967 // Allow the TCP job to fail.
5968 base::RunLoop().RunUntilIdle();
5969 // Now let the QUIC job fail.
5970 mock_quic_data.Resume();
5971 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5972 ExpectQuicAlternateProtocolMapping();
5973 NetErrorDetails details;
5974 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525975 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075976}
5977
[email protected]1e960032013-12-20 19:00:205978TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455979 // Alternate-protocol job
5980 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025981 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455982 };
Ryan Sleevib8d7ea02018-05-07 20:01:015983 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455984 socket_factory_.AddSocketDataProvider(&quic_data);
5985
[email protected]c92c1b52014-05-31 04:16:065986 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015987 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065988 socket_factory_.AddSocketDataProvider(&quic_data2);
5989
[email protected]4d283b32013-10-17 12:57:275990 // Final job that will proceed when the QUIC job fails.
5991 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025992 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5993 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5994 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275995
Ryan Sleevib8d7ea02018-05-07 20:01:015996 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275997 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565998 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275999
rch3f4b8452016-02-23 16:59:326000 CreateSession();
[email protected]77c6c162013-08-17 02:57:456001
Ryan Hamilton9835e662018-08-02 05:36:276002 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:456003
[email protected]4d283b32013-10-17 12:57:276004 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:456005
6006 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:276007
rch37de576c2015-05-17 20:28:176008 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6009 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:456010}
6011
Matt Menkeb32ba5122019-09-10 19:17:056012TEST_P(QuicNetworkTransactionTest,
6013 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
David Schinazi84c58bb2020-06-04 20:14:336014 if (version_.UsesTls()) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436015 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6016 return;
6017 }
6018
Matt Menkeb32ba5122019-09-10 19:17:056019 base::test::ScopedFeatureList feature_list;
6020 feature_list.InitWithFeatures(
6021 // enabled_features
6022 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
6023 features::kPartitionConnectionsByNetworkIsolationKey},
6024 // disabled_features
6025 {});
6026 // Since HttpServerProperties caches the feature value, have to create a new
6027 // one.
6028 http_server_properties_ = std::make_unique<HttpServerProperties>();
6029
6030 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
6031 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
6032 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
6033 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
6034
6035 // Alternate-protocol job
6036 MockRead quic_reads[] = {
6037 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
6038 };
6039 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
6040 socket_factory_.AddSocketDataProvider(&quic_data);
6041
6042 // Second Alternate-protocol job which will race with the TCP job.
6043 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
6044 socket_factory_.AddSocketDataProvider(&quic_data2);
6045
6046 // Final job that will proceed when the QUIC job fails.
6047 MockRead http_reads[] = {
6048 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6049 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6050 MockRead(ASYNC, OK)};
6051
6052 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
6053 socket_factory_.AddSocketDataProvider(&http_data);
6054 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6055
6056 CreateSession();
6057
6058 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6059 kNetworkIsolationKey1);
6060 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6061 kNetworkIsolationKey2);
6062
6063 request_.network_isolation_key = kNetworkIsolationKey1;
6064 SendRequestAndExpectHttpResponse("hello from http");
6065 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6066 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
6067
6068 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6069 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6070
6071 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
6072 AddHttpDataAndRunRequest();
6073 // Requests using other NetworkIsolationKeys can still use QUIC.
6074 request_.network_isolation_key = kNetworkIsolationKey2;
6075 AddQuicDataAndRunRequest();
6076
6077 // The last two requests should not have changed the alternative service
6078 // mappings.
6079 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6080 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6081}
6082
[email protected]93b31772014-06-19 08:03:356083TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:036084 // Alternate-protocol job
6085 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:596086 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:036087 };
Ryan Sleevib8d7ea02018-05-07 20:01:016088 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036089 socket_factory_.AddSocketDataProvider(&quic_data);
6090
6091 // Main job that will proceed when the QUIC job fails.
6092 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026093 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6094 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6095 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:036096
Ryan Sleevib8d7ea02018-05-07 20:01:016097 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036098 socket_factory_.AddSocketDataProvider(&http_data);
6099
rtennetib8e80fb2016-05-16 00:12:096100 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326101 CreateSession();
[email protected]65768442014-06-06 23:37:036102
Ryan Hamilton9835e662018-08-02 05:36:276103 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:036104
6105 SendRequestAndExpectHttpResponse("hello from http");
6106}
6107
[email protected]eb71ab62014-05-23 07:57:536108TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:336109 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:016110 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:496111 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:336112 socket_factory_.AddSocketDataProvider(&quic_data);
6113
6114 // Main job which will succeed even though the alternate job fails.
6115 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026116 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6117 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6118 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:336119
Ryan Sleevib8d7ea02018-05-07 20:01:016120 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:336121 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566122 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:336123
rch3f4b8452016-02-23 16:59:326124 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276125 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:336126 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:536127
6128 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:336129}
6130
[email protected]4fee9672014-01-08 14:47:156131TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltonabad59e2019-06-06 04:02:596132 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:166133 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:176134 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:046135 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:156136
6137 // When the QUIC connection fails, we will try the request again over HTTP.
6138 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:486139 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:566140 MockRead("hello world"),
6141 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6142 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:156143
Ryan Sleevib8d7ea02018-05-07 20:01:016144 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:156145 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566146 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:156147
6148 // In order for a new QUIC session to be established via alternate-protocol
6149 // without racing an HTTP connection, we need the host resolution to happen
6150 // synchronously.
6151 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:296152 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:566153 "");
[email protected]4fee9672014-01-08 14:47:156154
rch3f4b8452016-02-23 16:59:326155 CreateSession();
David Schinazic8281052019-01-24 06:14:176156 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
6157 AddQuicAlternateProtocolMapping(
6158 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:156159 SendRequestAndExpectHttpResponse("hello world");
6160}
6161
tbansalc3308d72016-08-27 10:25:046162// For an alternative proxy that supports QUIC, test that the request is
6163// successfully fetched by the main job when the alternate proxy job encounters
6164// an error.
6165TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
6166 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
6167}
6168TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
6169 TestAlternativeProxy(ERR_CONNECTION_FAILED);
6170}
6171TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
6172 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
6173}
6174TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
6175 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
6176}
6177TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
6178 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
6179}
6180TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
6181 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
6182}
6183TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
6184 TestAlternativeProxy(ERR_IO_PENDING);
6185}
6186TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
6187 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
6188}
6189
6190TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltonabad59e2019-06-06 04:02:596191 MockQuicData mock_quic_data(version_);
Zhongyi Shi1c022d22020-03-20 19:00:166192 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_->MakeDummyCHLOPacket(1));
David Schinazic8281052019-01-24 06:14:176193 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:336194 mock_quic_data.AddWrite(
6195 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6196 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
6197 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436198 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:046199 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6200
6201 // When the QUIC connection fails, we will try the request again over HTTP.
6202 MockRead http_reads[] = {
6203 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6204 MockRead("hello world"),
6205 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6206 MockRead(ASYNC, OK)};
6207
Ryan Sleevib8d7ea02018-05-07 20:01:016208 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:046209 socket_factory_.AddSocketDataProvider(&http_data);
6210 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6211
6212 TestProxyDelegate test_proxy_delegate;
6213 const HostPortPair host_port_pair("myproxy.org", 443);
6214 test_proxy_delegate.set_alternative_proxy_server(
6215 ProxyServer::FromPacString("QUIC myproxy.org:443"));
6216 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6217
Nicolas Arciniegad2013f92020-02-07 23:00:566218 proxy_resolution_service_ =
6219 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
6220 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526221 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046222 request_.url = GURL("http://mail.example.org/");
6223
6224 // In order for a new QUIC session to be established via alternate-protocol
6225 // without racing an HTTP connection, we need the host resolution to happen
6226 // synchronously.
6227 host_resolver_.set_synchronous_mode(true);
6228 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:046229
6230 CreateSession();
David Schinazic8281052019-01-24 06:14:176231 crypto_client_stream_factory_.set_handshake_mode(
6232 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:046233 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596234 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166235 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046236}
6237
bnc508835902015-05-12 20:10:296238TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
Zhongyi Shi1c022d22020-03-20 19:00:166239 client_maker_->set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386240 EXPECT_FALSE(
6241 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:596242 MockQuicData mock_quic_data(version_);
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 mock_quic_data.AddWrite(SYNCHRONOUS,
6246 ConstructInitialSettingsPacket(packet_num++));
6247 }
rch5cb522462017-04-25 20:18:366248 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236249 SYNCHRONOUS,
6250 ConstructClientRequestHeadersPacket(
6251 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6252 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436253 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336254 ASYNC, ConstructServerResponseHeadersPacket(
6255 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6256 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436257 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336258 mock_quic_data.AddRead(
6259 ASYNC, ConstructServerDataPacket(
6260 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176261 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236262 mock_quic_data.AddWrite(SYNCHRONOUS,
6263 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:506264 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296265 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6266
bncb07c05532015-05-14 19:07:206267 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096268 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326269 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276270 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296271 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386272 EXPECT_TRUE(
6273 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296274}
6275
zhongyi363c91c2017-03-23 23:16:086276// TODO(zhongyi): disabled this broken test as it was not testing the correct
6277// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
6278TEST_P(QuicNetworkTransactionTest,
6279 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:276280 base::HistogramTester histogram_tester;
Nicolas Arciniegad2013f92020-02-07 23:00:566281 proxy_resolution_service_ =
6282 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
6283 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:046284
6285 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:046286
6287 test_proxy_delegate.set_alternative_proxy_server(
6288 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:526289 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046290
6291 request_.url = GURL("http://mail.example.org/");
6292
6293 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6294 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016295 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:046296 socket_factory_.AddSocketDataProvider(&socket_data);
6297
6298 // The non-alternate protocol job needs to hang in order to guarantee that
6299 // the alternate-protocol job will "win".
6300 AddHangingNonAlternateProtocolSocketData();
6301
6302 CreateSession();
6303 request_.method = "POST";
6304 ChunkedUploadDataStream upload_data(0);
6305 upload_data.AppendData("1", 1, true);
6306
6307 request_.upload_data_stream = &upload_data;
6308
6309 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6310 TestCompletionCallback callback;
6311 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6312 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6313 EXPECT_NE(OK, callback.WaitForResult());
6314
6315 // Verify that the alternative proxy server is not marked as broken.
6316 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6317
6318 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596319 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276320
6321 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6322 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6323 1);
tbansalc3308d72016-08-27 10:25:046324}
6325
rtenneti56977812016-01-15 19:26:566326TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Victor Vasilieva1e66d72019-12-05 17:55:386327 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576328 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566329
Renjie Tangaadb84b2019-08-31 01:00:236330 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:256331 if (!VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236332 mock_quic_data.AddRead(SYNCHRONOUS, OK);
6333 else
6334 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6335 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6336 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6337
6338 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6339 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
6340 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:016341 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:236342 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:566343
rtennetib8e80fb2016-05-16 00:12:096344 // The non-alternate protocol job needs to hang in order to guarantee that
6345 // the alternate-protocol job will "win".
6346 AddHangingNonAlternateProtocolSocketData();
6347
rtenneti56977812016-01-15 19:26:566348 CreateSession();
6349 request_.method = "POST";
6350 ChunkedUploadDataStream upload_data(0);
6351 upload_data.AppendData("1", 1, true);
6352
6353 request_.upload_data_stream = &upload_data;
6354
bnc691fda62016-08-12 00:43:166355 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566356 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166357 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016358 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566359 EXPECT_NE(OK, callback.WaitForResult());
6360}
6361
rche11300ef2016-09-02 01:44:286362TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Victor Vasilieva1e66d72019-12-05 17:55:386363 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286364 ScopedMockNetworkChangeNotifier network_change_notifier;
6365 MockNetworkChangeNotifier* mock_ncn =
6366 network_change_notifier.mock_network_change_notifier();
6367 mock_ncn->ForceNetworkHandlesSupported();
6368 mock_ncn->SetConnectedNetworksList(
6369 {kDefaultNetworkForTests, kNewNetworkForTests});
6370
Victor Vasilieva1e66d72019-12-05 17:55:386371 context_.params()->origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286372 HostPortPair::FromString("mail.example.org:443"));
Victor Vasilieva1e66d72019-12-05 17:55:386373 context_.params()->migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286374
Ryan Hamiltonabad59e2019-06-06 04:02:596375 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286376 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236377 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256378 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236379 socket_data.AddWrite(SYNCHRONOUS,
6380 ConstructInitialSettingsPacket(packet_num++));
6381 }
Fan Yang32c5a112018-12-10 20:06:336382 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236383 SYNCHRONOUS,
6384 ConstructClientRequestHeadersPacket(
6385 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6386 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:286387 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6388 socket_data.AddSocketDataToFactory(&socket_factory_);
6389
Ryan Hamiltonabad59e2019-06-06 04:02:596390 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286391 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6392 socket_data2.AddSocketDataToFactory(&socket_factory_);
6393
6394 // The non-alternate protocol job needs to hang in order to guarantee that
6395 // the alternate-protocol job will "win".
6396 AddHangingNonAlternateProtocolSocketData();
6397
6398 CreateSession();
6399 request_.method = "POST";
6400 ChunkedUploadDataStream upload_data(0);
6401
6402 request_.upload_data_stream = &upload_data;
6403
rdsmith1d343be52016-10-21 20:37:506404 std::unique_ptr<HttpNetworkTransaction> trans(
6405 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286406 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506407 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286408 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6409
6410 base::RunLoop().RunUntilIdle();
6411 upload_data.AppendData("1", 1, true);
6412 base::RunLoop().RunUntilIdle();
6413
6414 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506415 trans.reset();
rche11300ef2016-09-02 01:44:286416 session_.reset();
6417}
6418
Ryan Hamilton4b3574532017-10-30 20:17:256419TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386420 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256421 HostPortPair::FromString("mail.example.org:443"));
6422
Ryan Hamiltonabad59e2019-06-06 04:02:596423 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236424 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256425 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236426 socket_data.AddWrite(SYNCHRONOUS,
6427 ConstructInitialSettingsPacket(packet_num++));
6428 }
Ryan Hamilton4b3574532017-10-30 20:17:256429 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336430 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236431 SYNCHRONOUS,
6432 ConstructClientRequestHeadersPacket(
6433 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6434 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436435 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336436 ASYNC, ConstructServerResponseHeadersPacket(
6437 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6438 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436439 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336440 socket_data.AddRead(
6441 ASYNC, ConstructServerDataPacket(
6442 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176443 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236444 socket_data.AddWrite(SYNCHRONOUS,
6445 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256446 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi1c022d22020-03-20 19:00:166447 socket_data.AddWrite(SYNCHRONOUS,
6448 client_maker_->MakeAckAndConnectionClosePacket(
6449 packet_num++, false, 2, 1, 1,
6450 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256451
6452 socket_data.AddSocketDataToFactory(&socket_factory_);
6453
6454 CreateSession();
6455
6456 SendRequestAndExpectQuicResponse("hello!");
6457 session_.reset();
6458}
6459
6460TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386461 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256462 HostPortPair::FromString("mail.example.org:443"));
6463
Ryan Hamiltonabad59e2019-06-06 04:02:596464 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236465 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256466 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236467 socket_data.AddWrite(SYNCHRONOUS,
6468 ConstructInitialSettingsPacket(packet_num++));
6469 }
Ryan Hamilton4b3574532017-10-30 20:17:256470 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336471 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236472 SYNCHRONOUS,
6473 ConstructClientRequestHeadersPacket(
6474 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6475 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436476 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336477 ASYNC, ConstructServerResponseHeadersPacket(
6478 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6479 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436480 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336481 socket_data.AddRead(
6482 ASYNC, ConstructServerDataPacket(
6483 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176484 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236485 socket_data.AddWrite(SYNCHRONOUS,
6486 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256487 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi1c022d22020-03-20 19:00:166488 socket_data.AddWrite(SYNCHRONOUS,
6489 client_maker_->MakeAckAndConnectionClosePacket(
6490 packet_num++, false, 2, 1, 1,
6491 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256492
6493 socket_data.AddSocketDataToFactory(&socket_factory_);
6494
6495 CreateSession();
6496
6497 SendRequestAndExpectQuicResponse("hello!");
6498 session_.reset();
6499}
6500
Ryan Hamilton9edcf1a2017-11-22 05:55:176501TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386502 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6503 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256504 HostPortPair::FromString("mail.example.org:443"));
6505
Ryan Hamiltonabad59e2019-06-06 04:02:596506 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256507 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256508 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236509 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176510 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256511 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6512 }
6513 socket_data.AddSocketDataToFactory(&socket_factory_);
6514
6515 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176516 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176517 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6518 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256519
Victor Vasiliev7752898d2019-11-14 21:30:226520 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256521 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6522 TestCompletionCallback callback;
6523 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6524 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176525 while (!callback.have_result()) {
6526 base::RunLoop().RunUntilIdle();
6527 quic_task_runner_->RunUntilIdle();
6528 }
6529 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256530 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176531 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6532 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6533 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226534 EXPECT_TRUE(context_.clock()->Now() - start >
6535 quic::QuicTime::Delta::FromSeconds(4));
6536 EXPECT_TRUE(context_.clock()->Now() - start <
6537 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256538}
6539
Ryan Hamilton9edcf1a2017-11-22 05:55:176540TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386541 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6542 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256543 HostPortPair::FromString("mail.example.org:443"));
6544
Ryan Hamiltonabad59e2019-06-06 04:02:596545 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256546 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256547 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236548 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176549 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256550 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6551 }
6552 socket_data.AddSocketDataToFactory(&socket_factory_);
6553
6554 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176555 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176556 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6557 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256558
Victor Vasiliev7752898d2019-11-14 21:30:226559 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256560 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6561 TestCompletionCallback callback;
6562 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176564 while (!callback.have_result()) {
6565 base::RunLoop().RunUntilIdle();
6566 quic_task_runner_->RunUntilIdle();
6567 }
6568 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256569 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176570 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6571 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6572 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226573 EXPECT_TRUE(context_.clock()->Now() - start >
6574 quic::QuicTime::Delta::FromSeconds(4));
6575 EXPECT_TRUE(context_.clock()->Now() - start <
6576 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256577}
6578
Cherie Shi7596de632018-02-22 07:28:186579TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Victor Vasilieva1e66d72019-12-05 17:55:386580 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6581 context_.params()->origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186582 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436583 const std::string error_details =
Zhongyi Shid1c00fc42019-12-14 06:05:096584 quiche::QuicheStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6585 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186586
Ryan Hamiltonabad59e2019-06-06 04:02:596587 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186588 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236589 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256590 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236591 socket_data.AddWrite(SYNCHRONOUS,
6592 ConstructInitialSettingsPacket(packet_num++));
6593 }
Cherie Shi7596de632018-02-22 07:28:186594 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6595 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526596 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236597 SYNCHRONOUS,
Zhongyi Shi1c022d22020-03-20 19:00:166598 client_maker_->MakeConnectionClosePacket(
Renjie Tangaadb84b2019-08-31 01:00:236599 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186600 socket_data.AddSocketDataToFactory(&socket_factory_);
6601
6602 CreateSession();
6603
6604 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6605 TestCompletionCallback callback;
6606 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6607 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6608 base::RunLoop().RunUntilIdle();
6609 ASSERT_TRUE(callback.have_result());
6610 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6611 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6612 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6613}
6614
ckrasic769733c2016-06-30 00:42:136615// Adds coverage to catch regression such as https://crbug.com/622043
6616TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Zhongyi Shi1c022d22020-03-20 19:00:166617 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
Ryan Hamilton6c6493102019-12-05 21:36:506618 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:386619 context_.params()->origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136620 HostPortPair::FromString("mail.example.org:443"));
6621
Ryan Hamiltonabad59e2019-06-06 04:02:596622 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236623 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:256624 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236625 mock_quic_data.AddWrite(
6626 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6627 }
Zhongyi Shi32f2fd02018-04-16 18:23:436628 mock_quic_data.AddWrite(
6629 SYNCHRONOUS,
6630 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336631 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026632 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436633 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026634 ASYNC,
6635 ConstructServerPushPromisePacket(
6636 1, GetNthClientInitiatedBidirectionalStreamId(0),
6637 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6638 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Haoyue Wang9d70d65c2020-05-29 22:45:346639 const bool should_send_priority_packet =
6640 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:346641 !VersionUsesHttp3(version_.transport_version);
6642 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346643 mock_quic_data.AddWrite(
6644 SYNCHRONOUS,
6645 ConstructClientAckAndPriorityPacket(
6646 client_packet_number++, false,
6647 /*largest_received=*/1, /*smallest_received=*/1,
6648 GetNthServerInitiatedUnidirectionalStreamId(0),
6649 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576650 }
Zhongyi Shi32f2fd02018-04-16 18:23:436651 mock_quic_data.AddRead(
6652 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336653 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026654 GetResponseHeaders("200 OK")));
Fan Yang32d79502020-06-24 22:36:006655 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346656 mock_quic_data.AddWrite(
6657 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6658 }
Zhongyi Shi32f2fd02018-04-16 18:23:436659 mock_quic_data.AddRead(
6660 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336661 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026662 false, GetResponseHeaders("200 OK")));
Fan Yang32d79502020-06-24 22:36:006663 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346664 mock_quic_data.AddWrite(
6665 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1, 1));
6666 }
Victor Vasiliev076657c2019-03-12 02:46:436667 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436668 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336669 ASYNC, ConstructServerDataPacket(
6670 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176671 header + "hello!"));
Fan Yang32d79502020-06-24 22:36:006672 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346673 mock_quic_data.AddWrite(
6674 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
6675 }
Victor Vasiliev076657c2019-03-12 02:46:436676 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436677 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336678 ASYNC, ConstructServerDataPacket(
6679 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176680 header2 + "and hello!"));
Fan Yang32d79502020-06-24 22:36:006681 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346682 mock_quic_data.AddWrite(
6683 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3, 1));
6684 }
Renjie Tangee921d12020-02-06 00:41:496685 if (!VersionUsesHttp3(version_.transport_version)) {
6686 mock_quic_data.AddWrite(SYNCHRONOUS,
6687 ConstructClientAckAndRstPacket(
6688 client_packet_number++,
6689 GetNthServerInitiatedUnidirectionalStreamId(0),
6690 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
6691 } else {
6692 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:166693 SYNCHRONOUS, client_maker_->MakeAckAndPriorityUpdatePacket(
Renjie Tangee921d12020-02-06 00:41:496694 client_packet_number++, true, 5, 5, 1, 3,
6695 GetNthServerInitiatedUnidirectionalStreamId(0)));
6696 }
ckrasic769733c2016-06-30 00:42:136697 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6698 mock_quic_data.AddRead(ASYNC, 0); // EOF
6699 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6700
6701 // The non-alternate protocol job needs to hang in order to guarantee that
6702 // the alternate-protocol job will "win".
6703 AddHangingNonAlternateProtocolSocketData();
6704
6705 CreateSession();
6706
6707 // PUSH_PROMISE handling in the http layer gets exercised here.
6708 SendRequestAndExpectQuicResponse("hello!");
6709
6710 request_.url = GURL("https://mail.example.org/pushed.jpg");
6711 SendRequestAndExpectQuicResponse("and hello!");
6712
6713 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:546714 auto entries = net_log_.GetEntries();
ckrasic769733c2016-06-30 00:42:136715 EXPECT_LT(0u, entries.size());
6716
6717 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6718 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006719 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6720 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136721 EXPECT_LT(0, pos);
6722}
6723
rch56ec40a2017-06-23 14:48:446724// Regression test for http://crbug.com/719461 in which a promised stream
6725// is closed before the pushed headers arrive, but after the connection
6726// is closed and before the callbacks are executed.
6727TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Zhongyi Shi1c022d22020-03-20 19:00:166728 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
Ryan Hamilton6c6493102019-12-05 21:36:506729 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:386730 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6731 context_.params()->origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446732 HostPortPair::FromString("mail.example.org:443"));
6733
Ryan Hamiltonabad59e2019-06-06 04:02:596734 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236735 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446736 // Initial SETTINGS frame.
Victor Vasiliev7da08172019-10-14 06:04:256737 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236738 mock_quic_data.AddWrite(
6739 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6740 }
rch56ec40a2017-06-23 14:48:446741 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436742 mock_quic_data.AddWrite(
6743 SYNCHRONOUS,
6744 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336745 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026746 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446747 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436748 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026749 ASYNC,
6750 ConstructServerPushPromisePacket(
6751 1, GetNthClientInitiatedBidirectionalStreamId(0),
6752 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6753 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Haoyue Wang9d70d65c2020-05-29 22:45:346754 const bool should_send_priority_packet =
6755 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:346756 !VersionUsesHttp3(version_.transport_version);
6757 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346758 mock_quic_data.AddWrite(
6759 SYNCHRONOUS,
6760 ConstructClientAckAndPriorityPacket(
6761 client_packet_number++, false,
6762 /*largest_received=*/1, /*smallest_received=*/1,
6763 GetNthServerInitiatedUnidirectionalStreamId(0),
6764 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576765 }
rch56ec40a2017-06-23 14:48:446766 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436767 mock_quic_data.AddRead(
6768 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336769 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026770 GetResponseHeaders("200 OK")));
Fan Yang32d79502020-06-24 22:36:006771 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346772 // Client ACKs the response headers.
6773 mock_quic_data.AddWrite(
6774 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6775 }
rch56ec40a2017-06-23 14:48:446776 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:436777 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436778 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336779 ASYNC, ConstructServerDataPacket(
6780 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176781 header + "hello!"));
Fan Yang32d79502020-06-24 22:36:006782 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:346783 // Client ACKs the response headers.
6784 mock_quic_data.AddWrite(
6785 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1, 1));
6786 }
rch56ec40a2017-06-23 14:48:446787 // Write error for the third request.
6788 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6789 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6790 mock_quic_data.AddRead(ASYNC, 0); // EOF
6791 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6792
6793 CreateSession();
6794
6795 // Send a request which triggers a push promise from the server.
6796 SendRequestAndExpectQuicResponse("hello!");
6797
6798 // Start a push transaction that will be cancelled after the connection
6799 // is closed, but before the callback is executed.
6800 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196801 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446802 session_.get());
6803 TestCompletionCallback callback2;
6804 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6805 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6806 base::RunLoop().RunUntilIdle();
6807
6808 // Cause the connection to close on a write error.
6809 HttpRequestInfo request3;
6810 request3.method = "GET";
6811 request3.url = GURL("https://mail.example.org/");
6812 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106813 request3.traffic_annotation =
6814 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446815 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6816 TestCompletionCallback callback3;
6817 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6818 IsError(ERR_IO_PENDING));
6819
6820 base::RunLoop().RunUntilIdle();
6821
6822 // When |trans2| is destroyed, the underlying stream will be closed.
6823 EXPECT_FALSE(callback2.have_result());
6824 trans2 = nullptr;
6825
6826 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6827}
6828
ckrasicda193a82016-07-09 00:39:366829TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Victor Vasilieva1e66d72019-12-05 17:55:386830 context_.params()->origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366831 HostPortPair::FromString("mail.example.org:443"));
6832
Ryan Hamiltonabad59e2019-06-06 04:02:596833 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:366834
Renjief49758b2019-01-11 23:32:416835 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:256836 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236837 mock_quic_data.AddWrite(
6838 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
6839 }
ckrasicda193a82016-07-09 00:39:366840
Victor Vasiliev076657c2019-03-12 02:46:436841 std::string header = ConstructDataHeader(1);
Nick Harperc6cb7a612020-02-24 20:03:326842 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:416843 mock_quic_data.AddWrite(
6844 SYNCHRONOUS,
6845 ConstructClientRequestHeadersAndDataFramesPacket(
6846 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6847 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:026848 GetRequestHeaders("POST", "https", "/"), 0, nullptr, {"1"}));
Renjief49758b2019-01-11 23:32:416849 } else {
6850 mock_quic_data.AddWrite(
6851 SYNCHRONOUS,
6852 ConstructClientRequestHeadersAndDataFramesPacket(
6853 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6854 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:026855 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
Renjief49758b2019-01-11 23:32:416856 {header, "1"}));
6857 }
ckrasicda193a82016-07-09 00:39:366858
Zhongyi Shi32f2fd02018-04-16 18:23:436859 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336860 ASYNC, ConstructServerResponseHeadersPacket(
6861 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6862 GetResponseHeaders("200 OK")));
6863
Victor Vasiliev076657c2019-03-12 02:46:436864 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336865 mock_quic_data.AddRead(
6866 ASYNC, ConstructServerDataPacket(
6867 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176868 header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366869
Renjief49758b2019-01-11 23:32:416870 mock_quic_data.AddWrite(
6871 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366872
6873 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6874 mock_quic_data.AddRead(ASYNC, 0); // EOF
6875 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6876
6877 // The non-alternate protocol job needs to hang in order to guarantee that
6878 // the alternate-protocol job will "win".
6879 AddHangingNonAlternateProtocolSocketData();
6880
6881 CreateSession();
6882 request_.method = "POST";
6883 ChunkedUploadDataStream upload_data(0);
6884 upload_data.AppendData("1", 1, true);
6885
6886 request_.upload_data_stream = &upload_data;
6887
6888 SendRequestAndExpectQuicResponse("hello!");
6889}
6890
allada71b2efb2016-09-09 04:57:486891class QuicURLRequestContext : public URLRequestContext {
6892 public:
6893 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6894 MockClientSocketFactory* socket_factory)
6895 : storage_(this) {
6896 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076897 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046898 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486899 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046900 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596901 storage_.set_proxy_resolution_service(
Nicolas Arciniegad2013f92020-02-07 23:00:566902 ConfiguredProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076903 storage_.set_ssl_config_service(
6904 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486905 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:116906 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:486907 storage_.set_http_server_properties(
Matt Menke609160742019-08-02 18:47:266908 std::make_unique<HttpServerProperties>());
Bence Béky8f9d7d3952017-10-09 19:58:046909 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486910 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046911 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6912 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6913 false));
allada71b2efb2016-09-09 04:57:486914 }
6915
6916 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6917
6918 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6919
6920 private:
6921 MockClientSocketFactory* socket_factory_;
6922 URLRequestContextStorage storage_;
6923};
6924
6925TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
Victor Vasilieva1e66d72019-12-05 17:55:386926 context_.params()->origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486927 HostPortPair::FromString("mail.example.org:443"));
6928
Ryan Hamiltonabad59e2019-06-06 04:02:596929 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236930 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256931 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236932 mock_quic_data.AddWrite(SYNCHRONOUS,
6933 ConstructInitialSettingsPacket(packet_num++));
6934 }
Ryan Hamilton0239aac2018-05-19 00:03:136935 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486936 headers["user-agent"] = "";
6937 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336938 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236939 SYNCHRONOUS,
6940 ConstructClientRequestHeadersPacket(
6941 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6942 true, std::move(headers)));
allada71b2efb2016-09-09 04:57:486943
Fan Yang32c5a112018-12-10 20:06:336944 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026945 ASYNC, ConstructServerResponseHeadersPacket(
6946 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6947 GetResponseHeaders("200 OK")));
6948 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:456949 server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:256950 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:456951 ? GetNthClientInitiatedBidirectionalStreamId(0)
6952 : quic::QuicUtils::GetHeadersStreamId(
6953 version_.transport_version));
allada71b2efb2016-09-09 04:57:486954
Victor Vasiliev076657c2019-03-12 02:46:436955 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366956 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336957 ASYNC, ConstructServerDataPacket(
6958 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176959 "Main Resource Data"));
Renjie Tangaadb84b2019-08-31 01:00:236960 mock_quic_data.AddWrite(SYNCHRONOUS,
6961 ConstructClientAckPacket(packet_num++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486962
6963 mock_quic_data.AddRead(ASYNC, 0); // EOF
6964
6965 CreateSession();
6966
6967 TestDelegate delegate;
6968 QuicURLRequestContext quic_url_request_context(std::move(session_),
6969 &socket_factory_);
6970
6971 mock_quic_data.AddSocketDataToFactory(
6972 &quic_url_request_context.socket_factory());
6973 TestNetworkDelegate network_delegate;
6974 quic_url_request_context.set_network_delegate(&network_delegate);
6975
6976 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296977 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6978 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486979 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6980 &ssl_data_);
6981
6982 request->Start();
Wez2a31b222018-06-07 22:07:156983 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486984
6985 EXPECT_LT(0, request->GetTotalSentBytes());
6986 EXPECT_LT(0, request->GetTotalReceivedBytes());
allada71b2efb2016-09-09 04:57:486987 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6988 request->raw_header_size());
Wez0e717112018-06-18 23:09:226989
6990 // Pump the message loop to allow all data to be consumed.
6991 base::RunLoop().RunUntilIdle();
6992
allada71b2efb2016-09-09 04:57:486993 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6994 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6995}
6996
6997TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
Zhongyi Shi1c022d22020-03-20 19:00:166998 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
Ryan Hamilton6c6493102019-12-05 21:36:506999 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:387000 context_.params()->origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:487001 HostPortPair::FromString("mail.example.org:443"));
7002
Ryan Hamiltonabad59e2019-06-06 04:02:597003 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237004 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257005 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237006 mock_quic_data.AddWrite(
7007 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7008 }
Ryan Hamilton0239aac2018-05-19 00:03:137009 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:487010 headers["user-agent"] = "";
7011 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:437012 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337013 SYNCHRONOUS,
7014 ConstructClientRequestHeadersPacket(
7015 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027016 true, true, std::move(headers)));
allada71b2efb2016-09-09 04:57:487017
Fan Yang2330d182019-08-05 14:50:507018 const quic::QuicStreamOffset initial = server_maker_.stream_offset(
7019 GetNthClientInitiatedBidirectionalStreamId(0));
Zhongyi Shi32f2fd02018-04-16 18:23:437020 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027021 ASYNC,
7022 ConstructServerPushPromisePacket(
7023 1, GetNthClientInitiatedBidirectionalStreamId(0),
7024 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7025 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Fan Yang2330d182019-08-05 14:50:507026 quic::QuicStreamOffset push_promise_offset = 0;
Victor Vasiliev7da08172019-10-14 06:04:257027 if (VersionUsesHttp3(version_.transport_version)) {
Fan Yang2330d182019-08-05 14:50:507028 push_promise_offset = server_maker_.stream_offset(
7029 GetNthClientInitiatedBidirectionalStreamId(0)) -
7030 initial;
7031 }
allada71b2efb2016-09-09 04:57:487032
Haoyue Wang9d70d65c2020-05-29 22:45:347033 const bool should_send_priority_packet =
7034 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:347035 !VersionUsesHttp3(version_.transport_version);
7036 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347037 mock_quic_data.AddWrite(
7038 SYNCHRONOUS,
7039 ConstructClientAckAndPriorityPacket(
7040 client_packet_number++, false,
7041 /*largest_received=*/1, /*smallest_received=*/1,
7042 GetNthServerInitiatedUnidirectionalStreamId(0),
7043 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577044 }
7045
Ryan Hamiltone940bd12019-06-30 02:46:457046 const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257047 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457048 ? GetNthClientInitiatedBidirectionalStreamId(0)
7049 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Zhongyi Shi32f2fd02018-04-16 18:23:437050 mock_quic_data.AddRead(
7051 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337052 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027053 GetResponseHeaders("200 OK")));
Ryan Hamiltone940bd12019-06-30 02:46:457054 const quic::QuicStreamOffset final_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257055 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457056 ? GetNthClientInitiatedBidirectionalStreamId(0)
7057 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Ryan Hamilton0d65a8c2019-06-07 00:46:027058 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:457059 final_offset - initial_offset;
allada71b2efb2016-09-09 04:57:487060
Fan Yang32d79502020-06-24 22:36:007061 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347062 mock_quic_data.AddWrite(
7063 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7064 }
allada71b2efb2016-09-09 04:57:487065
ckrasicbf2f59c2017-05-04 23:54:367066 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:437067 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337068 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027069 false, GetResponseHeaders("200 OK")));
Fan Yang32d79502020-06-24 22:36:007070 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347071 mock_quic_data.AddWrite(
7072 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1, 1));
7073 }
Victor Vasiliev076657c2019-03-12 02:46:437074 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:437075 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337076 ASYNC, ConstructServerDataPacket(
7077 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177078 header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:487079
Fan Yang32d79502020-06-24 22:36:007080 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347081 mock_quic_data.AddWrite(
7082 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
7083 }
Victor Vasiliev076657c2019-03-12 02:46:437084 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:367085 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337086 ASYNC, ConstructServerDataPacket(
7087 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177088 header2 + "Main Resource Data"));
Fan Yang32d79502020-06-24 22:36:007089 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347090 mock_quic_data.AddWrite(
7091 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3, 1));
7092 }
allada71b2efb2016-09-09 04:57:487093
Zhongyi Shi32f2fd02018-04-16 18:23:437094 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:487095
7096 CreateSession();
7097
7098 TestDelegate delegate;
7099 QuicURLRequestContext quic_url_request_context(std::move(session_),
7100 &socket_factory_);
7101
7102 mock_quic_data.AddSocketDataToFactory(
7103 &quic_url_request_context.socket_factory());
7104 TestNetworkDelegate network_delegate;
7105 quic_url_request_context.set_network_delegate(&network_delegate);
7106
7107 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:297108 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
7109 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:487110 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
7111 &ssl_data_);
7112
7113 request->Start();
Wez2a31b222018-06-07 22:07:157114 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:487115
7116 EXPECT_LT(0, request->GetTotalSentBytes());
7117 EXPECT_LT(0, request->GetTotalReceivedBytes());
Fan Yang2330d182019-08-05 14:50:507118 EXPECT_EQ(
7119 static_cast<int>(expected_raw_header_response_size + push_promise_offset),
7120 request->raw_header_size());
Wez0e717112018-06-18 23:09:227121
7122 // Pump the message loop to allow all data to be consumed.
7123 base::RunLoop().RunUntilIdle();
7124
allada71b2efb2016-09-09 04:57:487125 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7126 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7127}
7128
Ryan Sleevia9d6aa62019-07-26 13:32:187129TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
7130 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:207131
7132 MockRead http_reads[] = {
7133 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7134 MockRead("hello world"),
7135 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7136 MockRead(ASYNC, OK)};
7137
Ryan Sleevib8d7ea02018-05-07 20:01:017138 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207139 socket_factory_.AddSocketDataProvider(&http_data);
7140 AddCertificate(&ssl_data_);
7141 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7142
Ryan Hamiltonabad59e2019-06-06 04:02:597143 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237144 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257145 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237146 mock_quic_data.AddWrite(SYNCHRONOUS,
7147 ConstructInitialSettingsPacket(packet_num++));
7148 }
Yixin Wang10f477ed2017-11-21 04:20:207149 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237150 SYNCHRONOUS,
7151 ConstructClientRequestHeadersPacket(
7152 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7153 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437154 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337155 ASYNC, ConstructServerResponseHeadersPacket(
7156 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7157 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437158 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:337159 mock_quic_data.AddRead(
7160 ASYNC, ConstructServerDataPacket(
7161 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177162 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:237163 mock_quic_data.AddWrite(SYNCHRONOUS,
7164 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:207165 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7166 mock_quic_data.AddRead(ASYNC, 0); // EOF
7167
7168 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7169
7170 AddHangingNonAlternateProtocolSocketData();
7171 CreateSession();
7172
7173 SendRequestAndExpectHttpResponse("hello world");
7174 SendRequestAndExpectQuicResponse("hello!");
7175}
7176
Ryan Sleevia9d6aa62019-07-26 13:32:187177TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
7178 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:207179
7180 MockRead http_reads[] = {
7181 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7182 MockRead("hello world"),
7183 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7184 MockRead(ASYNC, OK)};
7185
Ryan Sleevib8d7ea02018-05-07 20:01:017186 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207187 socket_factory_.AddSocketDataProvider(&http_data);
7188 AddCertificate(&ssl_data_);
7189 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7190 socket_factory_.AddSocketDataProvider(&http_data);
7191 AddCertificate(&ssl_data_);
7192 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7193
7194 AddHangingNonAlternateProtocolSocketData();
7195 CreateSession();
7196
7197 SendRequestAndExpectHttpResponse("hello world");
7198 SendRequestAndExpectHttpResponse("hello world");
7199}
7200
bnc359ed2a2016-04-29 20:43:457201class QuicNetworkTransactionWithDestinationTest
7202 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:017203 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:057204 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:457205 protected:
7206 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:557207 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:057208 client_headers_include_h2_stream_dependency_(
7209 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:567210 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:457211 destination_type_(GetParam().destination_type),
7212 cert_transparency_verifier_(new MultiLogCTVerifier()),
7213 ssl_config_service_(new SSLConfigServiceDefaults),
Nicolas Arciniegad2013f92020-02-07 23:00:567214 proxy_resolution_service_(
7215 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:117216 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Ryan Hamiltonf9a421f2020-01-31 21:09:527217 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:197218 FLAGS_quic_enable_http3_grease_randomness = false;
Ryan Hamiltonf9a421f2020-01-31 21:09:527219 }
bnc359ed2a2016-04-29 20:43:457220
7221 void SetUp() override {
7222 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557223 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457224
mmenke6ddfbea2017-05-31 21:48:417225 HttpNetworkSession::Params session_params;
7226 session_params.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:387227 context_.params()->allow_remote_alt_svc = true;
7228 context_.params()->supported_versions = supported_versions_;
7229 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:057230 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:417231
7232 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:457233
Victor Vasiliev7752898d2019-11-14 21:30:227234 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
bnc359ed2a2016-04-29 20:43:457235
7236 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277237 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:417238 session_context.quic_crypto_client_stream_factory =
7239 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:457240
Victor Vasiliev7752898d2019-11-14 21:30:227241 session_context.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:417242 session_context.client_socket_factory = &socket_factory_;
7243 session_context.host_resolver = &host_resolver_;
7244 session_context.cert_verifier = &cert_verifier_;
7245 session_context.transport_security_state = &transport_security_state_;
7246 session_context.cert_transparency_verifier =
7247 cert_transparency_verifier_.get();
7248 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
7249 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:457250 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:417251 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:597252 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:417253 session_context.http_auth_handler_factory = auth_handler_factory_.get();
7254 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:457255
mmenke6ddfbea2017-05-31 21:48:417256 session_.reset(new HttpNetworkSession(session_params, session_context));
Matt Menkeb566c392019-09-11 23:22:437257 session_->quic_stream_factory()
7258 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:457259 }
7260
7261 void TearDown() override {
7262 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7263 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557264 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457265 PlatformTest::TearDown();
7266 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557267 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:407268 session_.reset();
bnc359ed2a2016-04-29 20:43:457269 }
7270
zhongyie537a002017-06-27 16:48:217271 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:457272 HostPortPair destination;
7273 switch (destination_type_) {
7274 case SAME_AS_FIRST:
7275 destination = HostPortPair(origin1_, 443);
7276 break;
7277 case SAME_AS_SECOND:
7278 destination = HostPortPair(origin2_, 443);
7279 break;
7280 case DIFFERENT:
7281 destination = HostPortPair(kDifferentHostname, 443);
7282 break;
7283 }
bnc3472afd2016-11-17 15:27:217284 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:457285 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:217286 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:077287 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
7288 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:457289 }
7290
Ryan Hamilton8d9ee76e2018-05-29 23:52:527291 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237292 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527293 quic::QuicStreamId stream_id,
7294 bool should_include_version,
7295 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527296 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137297 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457298 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:137299 spdy::SpdyHeaderBlock headers(
7300 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027301 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457302 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027303 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:457304 }
7305
Ryan Hamilton8d9ee76e2018-05-29 23:52:527306 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237307 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527308 quic::QuicStreamId stream_id,
7309 bool should_include_version,
7310 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587311 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:027312 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:457313 }
7314
Ryan Hamilton8d9ee76e2018-05-29 23:52:527315 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237316 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527317 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527318 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137319 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027320 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
7321 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:457322 }
7323
Ryan Hamilton8d9ee76e2018-05-29 23:52:527324 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237325 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527326 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457327 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:437328 std::string header = "";
Nick Harperc6cb7a612020-02-24 20:03:327329 if (version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:417330 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:577331 auto header_length =
7332 quic::HttpEncoder::SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:437333 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:417334 }
Ryan Hamilton7505eb92019-06-08 00:22:177335 return maker->MakeDataPacket(packet_number, stream_id, false, true,
Renjief49758b2019-01-11 23:32:417336 header + "hello");
bnc359ed2a2016-04-29 20:43:457337 }
7338
Ryan Hamilton8d9ee76e2018-05-29 23:52:527339 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237340 uint64_t packet_number,
7341 uint64_t largest_received,
7342 uint64_t smallest_received,
7343 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:457344 QuicTestPacketMaker* maker) {
7345 return maker->MakeAckPacket(packet_number, largest_received,
Bence Béky7a45d4d2020-05-08 01:59:237346 smallest_received, least_unacked);
bnc359ed2a2016-04-29 20:43:457347 }
7348
Ryan Hamilton8d9ee76e2018-05-29 23:52:527349 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237350 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:377351 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027352 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:377353 }
7354
bnc359ed2a2016-04-29 20:43:457355 void AddRefusedSocketData() {
7356 std::unique_ptr<StaticSocketDataProvider> refused_data(
7357 new StaticSocketDataProvider());
7358 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7359 refused_data->set_connect_data(refused_connect);
7360 socket_factory_.AddSocketDataProvider(refused_data.get());
7361 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7362 }
7363
7364 void AddHangingSocketData() {
7365 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7366 new StaticSocketDataProvider());
7367 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7368 hanging_data->set_connect_data(hanging_connect);
7369 socket_factory_.AddSocketDataProvider(hanging_data.get());
7370 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7371 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7372 }
7373
7374 bool AllDataConsumed() {
7375 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7376 if (!socket_data_ptr->AllReadDataConsumed() ||
7377 !socket_data_ptr->AllWriteDataConsumed()) {
7378 return false;
7379 }
7380 }
7381 return true;
7382 }
7383
7384 void SendRequestAndExpectQuicResponse(const std::string& host) {
7385 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7386 HttpRequestInfo request;
7387 std::string url("https://");
7388 url.append(host);
7389 request.url = GURL(url);
7390 request.load_flags = 0;
7391 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107392 request.traffic_annotation =
7393 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457394 TestCompletionCallback callback;
7395 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017396 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457397
7398 std::string response_data;
robpercival214763f2016-07-01 23:27:017399 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457400 EXPECT_EQ("hello", response_data);
7401
7402 const HttpResponseInfo* response = trans.GetResponseInfo();
7403 ASSERT_TRUE(response != nullptr);
7404 ASSERT_TRUE(response->headers.get() != nullptr);
7405 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7406 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527407 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:087408 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457409 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377410 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457411 }
7412
Fan Yang32c5a112018-12-10 20:06:337413 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567414 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7415 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367416 }
7417
Ryan Hamiltonf9a421f2020-01-31 21:09:527418 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Nick Harper23290b82019-05-02 00:02:567419 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057420 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567421 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457422 DestinationType destination_type_;
7423 std::string origin1_;
7424 std::string origin2_;
Victor Vasiliev7752898d2019-11-14 21:30:227425 MockQuicContext context_;
bnc359ed2a2016-04-29 20:43:457426 std::unique_ptr<HttpNetworkSession> session_;
7427 MockClientSocketFactory socket_factory_;
7428 MockHostResolver host_resolver_;
7429 MockCertVerifier cert_verifier_;
7430 TransportSecurityState transport_security_state_;
7431 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237432 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457433 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077434 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:267435 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457436 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:267437 HttpServerProperties http_server_properties_;
Matt Muellerd9342e3a2019-11-26 01:41:147438 RecordingBoundTestNetLog net_log_;
bnc359ed2a2016-04-29 20:43:457439 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7440 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7441 static_socket_data_provider_vector_;
7442 SSLSocketDataProvider ssl_data_;
7443};
7444
Victor Costane635086f2019-01-27 05:20:307445INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7446 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:577447 ::testing::ValuesIn(GetPoolingTestParams()),
7448 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:457449
7450// A single QUIC request fails because the certificate does not match the origin
7451// hostname, regardless of whether it matches the alternative service hostname.
7452TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7453 if (destination_type_ == DIFFERENT)
7454 return;
7455
7456 GURL url("https://mail.example.com/");
7457 origin1_ = url.host();
7458
7459 // Not used for requests, but this provides a test case where the certificate
7460 // is valid for the hostname of the alternative service.
7461 origin2_ = "mail.example.org";
7462
zhongyie537a002017-06-27 16:48:217463 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457464
7465 scoped_refptr<X509Certificate> cert(
7466 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247467 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7468 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457469
7470 ProofVerifyDetailsChromium verify_details;
7471 verify_details.cert_verify_result.verified_cert = cert;
7472 verify_details.cert_verify_result.is_issued_by_known_root = true;
7473 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7474
Ryan Hamiltonabad59e2019-06-06 04:02:597475 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457476 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7477 mock_quic_data.AddRead(ASYNC, 0);
7478
7479 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7480
7481 AddRefusedSocketData();
7482
7483 HttpRequestInfo request;
7484 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107485 request.traffic_annotation =
7486 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457487
7488 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7489 TestCompletionCallback callback;
7490 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017491 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457492
7493 EXPECT_TRUE(AllDataConsumed());
7494}
7495
7496// First request opens QUIC session to alternative service. Second request
7497// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527498// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457499TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7500 origin1_ = "mail.example.org";
7501 origin2_ = "news.example.org";
7502
zhongyie537a002017-06-27 16:48:217503 SetQuicAlternativeService(origin1_);
7504 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457505
7506 scoped_refptr<X509Certificate> cert(
7507 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247508 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7509 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7510 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457511
7512 ProofVerifyDetailsChromium verify_details;
7513 verify_details.cert_verify_result.verified_cert = cert;
7514 verify_details.cert_verify_result.is_issued_by_known_root = true;
7515 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7516
Yixin Wang079ad542018-01-11 04:06:057517 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227518 version_,
7519 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7520 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057521 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177522 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227523 version_,
7524 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7525 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457526
Ryan Hamiltonabad59e2019-06-06 04:02:597527 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237528 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257529 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237530 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7531 packet_num++, &client_maker));
7532 }
Fan Yang32c5a112018-12-10 20:06:337533 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237534 SYNCHRONOUS,
7535 ConstructClientRequestHeadersPacket(
7536 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7537 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:027538 mock_quic_data.AddRead(
7539 ASYNC,
7540 ConstructServerResponseHeadersPacket(
7541 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437542 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337543 ASYNC,
7544 ConstructServerDataPacket(
7545 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237546 mock_quic_data.AddWrite(
7547 SYNCHRONOUS,
7548 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457549
Yixin Wang079ad542018-01-11 04:06:057550 client_maker.set_hostname(origin2_);
7551 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457552
Zhongyi Shi32f2fd02018-04-16 18:23:437553 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027554 SYNCHRONOUS,
7555 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237556 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027557 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7558 mock_quic_data.AddRead(
7559 ASYNC,
7560 ConstructServerResponseHeadersPacket(
7561 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437562 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337563 ASYNC,
7564 ConstructServerDataPacket(
7565 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237566 mock_quic_data.AddWrite(
7567 SYNCHRONOUS,
7568 ConstructClientAckPacket(packet_num++, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457569 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7570 mock_quic_data.AddRead(ASYNC, 0); // EOF
7571
7572 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7573
7574 AddHangingSocketData();
7575 AddHangingSocketData();
7576
Victor Vasiliev7752898d2019-11-14 21:30:227577 scoped_refptr<TestTaskRunner> quic_task_runner(
7578 new TestTaskRunner(context_.mock_clock()));
Fan Yangc9e00dc2018-10-09 14:17:567579 QuicStreamFactoryPeer::SetAlarmFactory(
7580 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097581 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Victor Vasiliev7752898d2019-11-14 21:30:227582 context_.clock()));
Fan Yangc9e00dc2018-10-09 14:17:567583
bnc359ed2a2016-04-29 20:43:457584 SendRequestAndExpectQuicResponse(origin1_);
7585 SendRequestAndExpectQuicResponse(origin2_);
7586
7587 EXPECT_TRUE(AllDataConsumed());
7588}
7589
7590// First request opens QUIC session to alternative service. Second request does
7591// not pool to it, even though destination matches, because certificate is not
7592// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527593// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457594TEST_P(QuicNetworkTransactionWithDestinationTest,
7595 DoNotPoolIfCertificateInvalid) {
7596 origin1_ = "news.example.org";
7597 origin2_ = "mail.example.com";
7598
zhongyie537a002017-06-27 16:48:217599 SetQuicAlternativeService(origin1_);
7600 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457601
7602 scoped_refptr<X509Certificate> cert1(
7603 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247604 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7605 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7606 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457607
7608 scoped_refptr<X509Certificate> cert2(
7609 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247610 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7611 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457612
7613 ProofVerifyDetailsChromium verify_details1;
7614 verify_details1.cert_verify_result.verified_cert = cert1;
7615 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7616 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7617
7618 ProofVerifyDetailsChromium verify_details2;
7619 verify_details2.cert_verify_result.verified_cert = cert2;
7620 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7621 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7622
Yixin Wang079ad542018-01-11 04:06:057623 QuicTestPacketMaker client_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227624 version_,
7625 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7626 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057627 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177628 QuicTestPacketMaker server_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227629 version_,
7630 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7631 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457632
Ryan Hamiltonabad59e2019-06-06 04:02:597633 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:237634 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257635 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237636 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7637 packet_num++, &client_maker1));
7638 }
Fan Yang32c5a112018-12-10 20:06:337639 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237640 SYNCHRONOUS,
7641 ConstructClientRequestHeadersPacket(
7642 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7643 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437644 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337645 ASYNC,
7646 ConstructServerResponseHeadersPacket(
7647 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437648 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337649 ASYNC,
7650 ConstructServerDataPacket(
7651 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437652 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237653 SYNCHRONOUS,
7654 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457655 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7656 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7657
7658 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7659
Yixin Wang079ad542018-01-11 04:06:057660 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227661 version_,
7662 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7663 context_.clock(), origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057664 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177665 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227666 version_,
7667 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7668 context_.clock(), origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457669
Ryan Hamiltonabad59e2019-06-06 04:02:597670 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:237671 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:257672 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237673 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7674 packet_num2++, &client_maker2));
7675 }
Fan Yang32c5a112018-12-10 20:06:337676 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237677 SYNCHRONOUS,
7678 ConstructClientRequestHeadersPacket(
7679 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7680 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437681 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337682 ASYNC,
7683 ConstructServerResponseHeadersPacket(
7684 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437685 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337686 ASYNC,
7687 ConstructServerDataPacket(
7688 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437689 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237690 SYNCHRONOUS,
7691 ConstructClientAckPacket(packet_num2++, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457692 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7693 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7694
7695 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7696
bnc359ed2a2016-04-29 20:43:457697 SendRequestAndExpectQuicResponse(origin1_);
7698 SendRequestAndExpectQuicResponse(origin2_);
7699
7700 EXPECT_TRUE(AllDataConsumed());
7701}
7702
ckrasicdee37572017-04-06 22:42:277703// crbug.com/705109 - this confirms that matching request with a body
7704// triggers a crash (pre-fix).
7705TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Zhongyi Shi1c022d22020-03-20 19:00:167706 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
Ryan Hamilton6c6493102019-12-05 21:36:507707 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:387708 context_.params()->origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277709 HostPortPair::FromString("mail.example.org:443"));
7710
Ryan Hamiltonabad59e2019-06-06 04:02:597711 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237712 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257713 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237714 mock_quic_data.AddWrite(
7715 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7716 }
Zhongyi Shi32f2fd02018-04-16 18:23:437717 mock_quic_data.AddWrite(
7718 SYNCHRONOUS,
7719 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337720 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027721 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437722 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027723 ASYNC,
7724 ConstructServerPushPromisePacket(
7725 1, GetNthClientInitiatedBidirectionalStreamId(0),
7726 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7727 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:317728
Haoyue Wang9d70d65c2020-05-29 22:45:347729 const bool should_send_priority_packet =
7730 client_headers_include_h2_stream_dependency_ &&
Haoyue Wang9d70d65c2020-05-29 22:45:347731 !VersionUsesHttp3(version_.transport_version);
7732 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347733 mock_quic_data.AddWrite(
7734 SYNCHRONOUS,
7735 ConstructClientAckAndPriorityPacket(
7736 client_packet_number++, false,
7737 /*largest_received=*/1, /*smallest_received=*/1,
7738 GetNthServerInitiatedUnidirectionalStreamId(0),
7739 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577740 }
Zhongyi Shi32f2fd02018-04-16 18:23:437741 mock_quic_data.AddRead(
7742 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337743 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027744 GetResponseHeaders("200 OK")));
Fan Yang32d79502020-06-24 22:36:007745 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347746 mock_quic_data.AddWrite(
7747 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7748 }
Zhongyi Shi32f2fd02018-04-16 18:23:437749 mock_quic_data.AddRead(
7750 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337751 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027752 false, GetResponseHeaders("200 OK")));
Fan Yang32d79502020-06-24 22:36:007753 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347754 mock_quic_data.AddWrite(
7755 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 3, 1, 1));
7756 }
Victor Vasiliev076657c2019-03-12 02:46:437757 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437758 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337759 ASYNC, ConstructServerDataPacket(
7760 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177761 header + "hello!"));
Fan Yang32d79502020-06-24 22:36:007762 if (!should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347763 mock_quic_data.AddWrite(
7764 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
7765 }
Renjief49758b2019-01-11 23:32:417766
Victor Vasiliev076657c2019-03-12 02:46:437767 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437768 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337769 ASYNC, ConstructServerDataPacket(
7770 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177771 header2 + "and hello!"));
Fan Yang32d79502020-06-24 22:36:007772 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347773 mock_quic_data.AddWrite(
7774 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 5, 3, 1));
7775 }
ckrasicdee37572017-04-06 22:42:277776
7777 // Because the matching request has a body, we will see the push
7778 // stream get cancelled, and the matching request go out on the
7779 // wire.
Fan Yang32d79502020-06-24 22:36:007780 if (should_send_priority_packet) {
Haoyue Wang9d70d65c2020-05-29 22:45:347781 mock_quic_data.AddWrite(
7782 SYNCHRONOUS,
7783 ConstructClientRstPacket(client_packet_number++,
7784 GetNthServerInitiatedUnidirectionalStreamId(0),
7785 quic::QUIC_STREAM_CANCELLED));
7786 } else {
7787 mock_quic_data.AddWrite(SYNCHRONOUS,
7788 ConstructClientAckAndRstPacket(
7789 client_packet_number++,
7790 GetNthServerInitiatedUnidirectionalStreamId(0),
7791 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
7792 }
ckrasicdee37572017-04-06 22:42:277793 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437794 std::string header3 = ConstructDataHeader(1);
Nick Harperc6cb7a612020-02-24 20:03:327795 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:417796 mock_quic_data.AddWrite(
7797 SYNCHRONOUS,
7798 ConstructClientRequestHeadersAndDataFramesPacket(
7799 client_packet_number++,
7800 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7801 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027802 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, {kBody}));
Renjief49758b2019-01-11 23:32:417803 } else {
7804 mock_quic_data.AddWrite(
7805 SYNCHRONOUS,
7806 ConstructClientRequestHeadersAndDataFramesPacket(
7807 client_packet_number++,
7808 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7809 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027810 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7811 {header3, kBody}));
Renjief49758b2019-01-11 23:32:417812 }
ckrasicdee37572017-04-06 22:42:277813
7814 // We see the same response as for the earlier pushed and cancelled
7815 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437816 mock_quic_data.AddRead(
7817 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337818 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027819 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:437820 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337821 ASYNC, ConstructServerDataPacket(
7822 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177823 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277824
Yixin Wangb470bc882018-02-15 18:43:577825 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437826 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277827 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7828 mock_quic_data.AddRead(ASYNC, 0); // EOF
7829 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7830
7831 // The non-alternate protocol job needs to hang in order to guarantee that
7832 // the alternate-protocol job will "win".
7833 AddHangingNonAlternateProtocolSocketData();
7834
7835 CreateSession();
7836
7837 // PUSH_PROMISE handling in the http layer gets exercised here.
7838 SendRequestAndExpectQuicResponse("hello!");
7839
7840 request_.url = GURL("https://mail.example.org/pushed.jpg");
7841 ChunkedUploadDataStream upload_data(0);
7842 upload_data.AppendData("1", 1, true);
7843 request_.upload_data_stream = &upload_data;
7844 SendRequestAndExpectQuicResponse("and hello!");
7845}
7846
Bence Béky7538a952018-02-01 16:59:527847// Regression test for https://crbug.com/797825: If pushed headers describe a
7848// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7849// not be called (otherwise a DCHECK fails).
7850TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Zhongyi Shi1c022d22020-03-20 19:00:167851 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
Ryan Hamilton6c6493102019-12-05 21:36:507852 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
7853
Ryan Hamilton0239aac2018-05-19 00:03:137854 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527855 pushed_request_headers[":authority"] = "";
7856 pushed_request_headers[":method"] = "GET";
7857 pushed_request_headers[":path"] = "/";
7858 pushed_request_headers[":scheme"] = "nosuchscheme";
7859
Victor Vasilieva1e66d72019-12-05 17:55:387860 context_.params()->origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:527861 HostPortPair::FromString("mail.example.org:443"));
7862
Ryan Hamiltonabad59e2019-06-06 04:02:597863 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:527864
Renjie Tangaadb84b2019-08-31 01:00:237865 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257866 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237867 mock_quic_data.AddWrite(SYNCHRONOUS,
7868 ConstructInitialSettingsPacket(packet_num++));
7869 }
Bence Béky7538a952018-02-01 16:59:527870 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237871 SYNCHRONOUS,
7872 ConstructClientRequestHeadersPacket(
7873 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7874 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:527875
Fan Yang32c5a112018-12-10 20:06:337876 mock_quic_data.AddRead(
7877 ASYNC, ConstructServerPushPromisePacket(
7878 1, GetNthClientInitiatedBidirectionalStreamId(0),
7879 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027880 std::move(pushed_request_headers), &server_maker_));
Haoyue Wang9d70d65c2020-05-29 22:45:347881 mock_quic_data.AddWrite(
7882 SYNCHRONOUS,
7883 ConstructClientAckAndRstPacket(
7884 packet_num++, GetNthServerInitiatedUnidirectionalStreamId(0),
7885 quic::QUIC_INVALID_PROMISE_URL, 1, 1, 1));
Bence Béky7538a952018-02-01 16:59:527886
Zhongyi Shi32f2fd02018-04-16 18:23:437887 mock_quic_data.AddRead(
7888 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337889 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027890 GetResponseHeaders("200 OK")));
Bence Béky7538a952018-02-01 16:59:527891
Zhongyi Shi32f2fd02018-04-16 18:23:437892 mock_quic_data.AddRead(
7893 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337894 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027895 false, GetResponseHeaders("200 OK")));
Haoyue Wang9d70d65c2020-05-29 22:45:347896 mock_quic_data.AddWrite(SYNCHRONOUS,
7897 ConstructClientAckPacket(packet_num++, 3, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:437898 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437899 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337900 ASYNC, ConstructServerDataPacket(
7901 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177902 header + "hello!"));
Bence Béky7538a952018-02-01 16:59:527903
7904 mock_quic_data.AddRead(ASYNC, 0);
7905 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7906
7907 // The non-alternate protocol job needs to hang in order to guarantee that
7908 // the alternate-protocol job will "win".
7909 AddHangingNonAlternateProtocolSocketData();
7910
7911 CreateSession();
7912
7913 // PUSH_PROMISE handling in the http layer gets exercised here.
7914 SendRequestAndExpectQuicResponse("hello!");
7915
7916 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7917 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7918}
7919
Yixin Wang46a273ec302018-01-23 17:59:567920// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147921TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567922 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147923 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:567924 proxy_resolution_service_ =
7925 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
7926 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567927
Ryan Hamiltonabad59e2019-06-06 04:02:597928 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237929 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257930 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237931 mock_quic_data.AddWrite(SYNCHRONOUS,
7932 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:497933 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:167934 SYNCHRONOUS, client_maker_->MakePriorityPacket(
Renjie Tangee921d12020-02-06 00:41:497935 packet_num++, true,
7936 GetNthClientInitiatedBidirectionalStreamId(0), 0,
7937 ConvertRequestPriorityToQuicPriority(
7938 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:237939 }
Fan Yang32c5a112018-12-10 20:06:337940 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237941 SYNCHRONOUS,
7942 ConstructClientRequestHeadersPacket(
7943 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:497944 false,
7945 VersionUsesHttp3(version_.transport_version)
7946 ? MEDIUM
7947 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:237948 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337949 mock_quic_data.AddRead(
7950 ASYNC, ConstructServerResponseHeadersPacket(
7951 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7952 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567953
7954 const char get_request[] =
7955 "GET / HTTP/1.1\r\n"
7956 "Host: mail.example.org\r\n"
7957 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437958 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harperc6cb7a612020-02-24 20:03:327959 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:417960 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357961 SYNCHRONOUS,
7962 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237963 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Zhongyi Shid1c00fc42019-12-14 06:05:097964 1, 1, 1, false, quiche::QuicheStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417965 } else {
7966 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417967 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:287968 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237969 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:287970 1, 1, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417971 }
7972
Yixin Wang46a273ec302018-01-23 17:59:567973 const char get_response[] =
7974 "HTTP/1.1 200 OK\r\n"
7975 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437976 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437977 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337978 ASYNC, ConstructServerDataPacket(
7979 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177980 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:437981 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337982 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417983 SYNCHRONOUS, ConstructServerDataPacket(
7984 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:177985 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:237986 mock_quic_data.AddWrite(SYNCHRONOUS,
7987 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567988 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7989
Bence Béky6e243aa2019-12-13 19:01:077990 if (VersionUsesHttp3(version_.transport_version)) {
7991 mock_quic_data.AddWrite(
7992 SYNCHRONOUS, ConstructClientDataPacket(
7993 packet_num++, GetQpackDecoderStreamId(), true, false,
7994 StreamCancellationQpackDecoderInstruction(0)));
7995 }
7996
Yixin Wang46a273ec302018-01-23 17:59:567997 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417998 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237999 ConstructClientRstPacket(packet_num++,
8000 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418001 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568002
8003 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8004
8005 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8006
8007 CreateSession();
8008
8009 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:098010 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:568011 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568012 RunTransaction(&trans);
8013 CheckWasHttpResponse(&trans);
8014 CheckResponsePort(&trans, 70);
8015 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568016 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8017
8018 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8019 // proxy socket to disconnect.
8020 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8021
8022 base::RunLoop().RunUntilIdle();
8023 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8024 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8025}
8026
8027// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148028TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:568029 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148030 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568031 proxy_resolution_service_ =
8032 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8033 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568034
Ryan Hamiltonabad59e2019-06-06 04:02:598035 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238036 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258037 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238038 mock_quic_data.AddWrite(SYNCHRONOUS,
8039 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498040 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:168041 SYNCHRONOUS, client_maker_->MakePriorityPacket(
Renjie Tangee921d12020-02-06 00:41:498042 packet_num++, true,
8043 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8044 ConvertRequestPriorityToQuicPriority(
8045 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238046 }
Fan Yang32c5a112018-12-10 20:06:338047 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238048 SYNCHRONOUS,
8049 ConstructClientRequestHeadersPacket(
8050 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498051 false,
8052 VersionUsesHttp3(version_.transport_version)
8053 ? MEDIUM
8054 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238055 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338056 mock_quic_data.AddRead(
8057 ASYNC, ConstructServerResponseHeadersPacket(
8058 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8059 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568060
8061 SpdyTestUtil spdy_util;
8062
Ryan Hamilton0239aac2018-05-19 00:03:138063 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568064 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438065 std::string header = ConstructDataHeader(get_frame.size());
Nick Harperc6cb7a612020-02-24 20:03:328066 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:418067 mock_quic_data.AddWrite(
8068 SYNCHRONOUS,
8069 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238070 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8071 1, 1, 1, false,
Zhongyi Shid1c00fc42019-12-14 06:05:098072 quiche::QuicheStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:418073 } else {
8074 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418075 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288076 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238077 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8078 1, 1, 1, false,
Renjie Tangd5133972019-12-06 00:20:288079 {header + std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418080 }
Ryan Hamilton0239aac2018-05-19 00:03:138081 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568082 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438083 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438084 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178085 ASYNC, ConstructServerDataPacket(
8086 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8087 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568088
Ryan Hamilton0239aac2018-05-19 00:03:138089 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198090 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:438091 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438092 mock_quic_data.AddRead(
8093 SYNCHRONOUS,
8094 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:338095 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438096 header3 + std::string(data_frame.data(), data_frame.size())));
Renjie Tangaadb84b2019-08-31 01:00:238097 mock_quic_data.AddWrite(SYNCHRONOUS,
8098 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568099 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8100
Bence Béky6e243aa2019-12-13 19:01:078101 if (VersionUsesHttp3(version_.transport_version)) {
8102 mock_quic_data.AddWrite(
8103 SYNCHRONOUS, ConstructClientDataPacket(
8104 packet_num++, GetQpackDecoderStreamId(), true, false,
8105 StreamCancellationQpackDecoderInstruction(0)));
8106 }
8107
Yixin Wang46a273ec302018-01-23 17:59:568108 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438109 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238110 ConstructClientRstPacket(packet_num++,
8111 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418112 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568113
8114 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8115
8116 SSLSocketDataProvider ssl_data(ASYNC, OK);
8117 ssl_data.next_proto = kProtoHTTP2;
8118 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8119
8120 CreateSession();
8121
8122 request_.url = GURL("https://mail.example.org/");
8123 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568124 RunTransaction(&trans);
8125 CheckWasSpdyResponse(&trans);
8126 CheckResponsePort(&trans, 70);
8127 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568128 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8129
Wez0e717112018-06-18 23:09:228130 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
8131 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:568132 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8133
8134 base::RunLoop().RunUntilIdle();
8135 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8136 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8137}
8138
8139// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
8140// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:148141TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:568142 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148143 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568144 proxy_resolution_service_ =
8145 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8146 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568147
Ryan Hamiltonabad59e2019-06-06 04:02:598148 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:418149 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:258150 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238151 mock_quic_data.AddWrite(
8152 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
Renjie Tangee921d12020-02-06 00:41:498153 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:168154 SYNCHRONOUS, client_maker_->MakePriorityPacket(
Renjie Tangee921d12020-02-06 00:41:498155 write_packet_index++, true,
8156 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8157 ConvertRequestPriorityToQuicPriority(
8158 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238159 }
Fan Yang32c5a112018-12-10 20:06:338160 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418161 SYNCHRONOUS,
8162 ConstructClientRequestHeadersPacket(
8163 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangee921d12020-02-06 00:41:498164 true, false,
8165 VersionUsesHttp3(version_.transport_version)
8166 ? MEDIUM
8167 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:028168 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338169 mock_quic_data.AddRead(
8170 ASYNC, ConstructServerResponseHeadersPacket(
8171 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8172 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568173
Ryan Hamilton8d9ee76e2018-05-29 23:52:528174 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568175 const char get_request_1[] =
8176 "GET / HTTP/1.1\r\n"
8177 "Host: mail.example.org\r\n"
8178 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438179 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harperc6cb7a612020-02-24 20:03:328180 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:418181 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:178182 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8183 write_packet_index++, false,
8184 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Zhongyi Shid1c00fc42019-12-14 06:05:098185 false, quiche::QuicheStringPiece(get_request_1)));
Renjief49758b2019-01-11 23:32:418186 } else {
8187 mock_quic_data.AddWrite(
Renjie Tangd5133972019-12-06 00:20:288188 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Ryan Hamilton7505eb92019-06-08 00:22:178189 write_packet_index++, false,
8190 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Renjie Tangd5133972019-12-06 00:20:288191 false, {header + std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:418192 }
8193
Yixin Wang46a273ec302018-01-23 17:59:568194 const char get_response_1[] =
8195 "HTTP/1.1 200 OK\r\n"
8196 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438197 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:438198 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438199 ASYNC, ConstructServerDataPacket(
8200 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178201 header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:418202 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:568203
Victor Vasiliev076657c2019-03-12 02:46:438204 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338205 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178206 SYNCHRONOUS, ConstructServerDataPacket(
8207 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
8208 false, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:418209 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:568210
Renjief49758b2019-01-11 23:32:418211 mock_quic_data.AddWrite(
8212 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568213
8214 const char get_request_2[] =
8215 "GET /2 HTTP/1.1\r\n"
8216 "Host: mail.example.org\r\n"
8217 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438218 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harperc6cb7a612020-02-24 20:03:328219 if (version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:418220 mock_quic_data.AddWrite(
8221 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288222 ConstructClientDataPacket(
Renjied172e812019-01-16 05:12:358223 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288224 false, false, {header4 + std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:358225 } else {
8226 mock_quic_data.AddWrite(
8227 SYNCHRONOUS,
Ryan Hamilton7505eb92019-06-08 00:22:178228 ConstructClientDataPacket(
8229 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Zhongyi Shid1c00fc42019-12-14 06:05:098230 false, false, quiche::QuicheStringPiece(get_request_2)));
Renjief49758b2019-01-11 23:32:418231 }
Yixin Wang46a273ec302018-01-23 17:59:568232
8233 const char get_response_2[] =
8234 "HTTP/1.1 200 OK\r\n"
8235 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438236 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:438237 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438238 ASYNC, ConstructServerDataPacket(
8239 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178240 header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:418241 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:568242
Victor Vasiliev076657c2019-03-12 02:46:438243 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528244 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178245 SYNCHRONOUS, ConstructServerDataPacket(
8246 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
8247 false, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:418248 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:568249
Renjief49758b2019-01-11 23:32:418250 mock_quic_data.AddWrite(
8251 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:568252 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8253
Bence Béky6e243aa2019-12-13 19:01:078254 if (VersionUsesHttp3(version_.transport_version)) {
8255 mock_quic_data.AddWrite(
8256 SYNCHRONOUS, ConstructClientDataPacket(
8257 write_packet_index++, GetQpackDecoderStreamId(), true,
8258 false, StreamCancellationQpackDecoderInstruction(0)));
8259 }
8260
Renjief49758b2019-01-11 23:32:418261 mock_quic_data.AddWrite(
8262 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418263 ConstructClientRstPacket(write_packet_index++,
8264 GetNthClientInitiatedBidirectionalStreamId(0),
8265 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568266
8267 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8268
8269 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8270
8271 CreateSession();
8272
8273 request_.url = GURL("https://mail.example.org/");
8274 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568275 RunTransaction(&trans_1);
8276 CheckWasHttpResponse(&trans_1);
8277 CheckResponsePort(&trans_1, 70);
8278 CheckResponseData(&trans_1, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568279 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8280
8281 request_.url = GURL("https://mail.example.org/2");
8282 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568283 RunTransaction(&trans_2);
8284 CheckWasHttpResponse(&trans_2);
8285 CheckResponsePort(&trans_2, 70);
8286 CheckResponseData(&trans_2, "0123456");
Yixin Wang46a273ec302018-01-23 17:59:568287 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8288
8289 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8290 // proxy socket to disconnect.
8291 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8292
8293 base::RunLoop().RunUntilIdle();
8294 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8295 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8296}
8297
8298// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
8299// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
8300// server is reused for the second request.
Bence Békyf6bb6b22020-04-17 20:22:118301TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:568302 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148303 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568304 proxy_resolution_service_ =
8305 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8306 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568307
Ryan Hamiltonabad59e2019-06-06 04:02:598308 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238309 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258310 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238311 mock_quic_data.AddWrite(SYNCHRONOUS,
8312 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498313 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:168314 SYNCHRONOUS, client_maker_->MakePriorityPacket(
Renjie Tangee921d12020-02-06 00:41:498315 packet_num++, true,
8316 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8317 ConvertRequestPriorityToQuicPriority(
8318 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238319 }
Yixin Wang46a273ec302018-01-23 17:59:568320
8321 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:338322 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238323 SYNCHRONOUS,
8324 ConstructClientRequestHeadersPacket(
8325 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498326 false,
8327 VersionUsesHttp3(version_.transport_version)
8328 ? MEDIUM
8329 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238330 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438331 mock_quic_data.AddRead(
8332 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338333 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028334 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568335
8336 // GET request, response, and data over QUIC tunnel for first request
8337 const char get_request[] =
8338 "GET / HTTP/1.1\r\n"
8339 "Host: mail.example.org\r\n"
8340 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438341 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harperc6cb7a612020-02-24 20:03:328342 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:418343 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358344 SYNCHRONOUS,
8345 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238346 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Zhongyi Shid1c00fc42019-12-14 06:05:098347 1, 1, 1, false, quiche::QuicheStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418348 } else {
8349 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418350 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288351 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238352 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288353 1, 1, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418354 }
8355
Yixin Wang46a273ec302018-01-23 17:59:568356 const char get_response[] =
8357 "HTTP/1.1 200 OK\r\n"
8358 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438359 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:568360 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338361 ASYNC, ConstructServerDataPacket(
8362 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178363 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:438364 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338365 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418366 SYNCHRONOUS, ConstructServerDataPacket(
8367 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178368 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238369 mock_quic_data.AddWrite(SYNCHRONOUS,
8370 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568371
8372 // CONNECT request and response for second request
Renjie Tangee921d12020-02-06 00:41:498373 if (VersionUsesHttp3(version_.transport_version)) {
8374 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:168375 SYNCHRONOUS, client_maker_->MakePriorityPacket(
Renjie Tangee921d12020-02-06 00:41:498376 packet_num++, true,
8377 GetNthClientInitiatedBidirectionalStreamId(1), 0,
8378 ConvertRequestPriorityToQuicPriority(
8379 HttpProxyConnectJob::kH2QuicTunnelPriority)));
8380 }
Zhongyi Shi32f2fd02018-04-16 18:23:438381 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238382 SYNCHRONOUS,
8383 ConstructClientRequestHeadersPacket(
8384 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Renjie Tangee921d12020-02-06 00:41:498385 false,
8386 VersionUsesHttp3(version_.transport_version)
8387 ? MEDIUM
8388 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238389 ConnectRequestHeaders("different.example.org:443"),
8390 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438391 mock_quic_data.AddRead(
8392 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338393 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028394 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568395
8396 // GET request, response, and data over QUIC tunnel for second request
8397 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138398 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568399 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438400 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harperc6cb7a612020-02-24 20:03:328401 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:418402 mock_quic_data.AddWrite(
8403 SYNCHRONOUS,
8404 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238405 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8406 4, 4, 1, false,
Zhongyi Shid1c00fc42019-12-14 06:05:098407 quiche::QuicheStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:418408 } else {
8409 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418410 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288411 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238412 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8413 4, 4, 1, false,
Renjie Tangd5133972019-12-06 00:20:288414 {header4 + std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418415 }
Yixin Wang46a273ec302018-01-23 17:59:568416
Ryan Hamilton0239aac2018-05-19 00:03:138417 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568418 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438419 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438420 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178421 ASYNC, ConstructServerDataPacket(
8422 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8423 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568424
Ryan Hamilton0239aac2018-05-19 00:03:138425 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198426 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:438427 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438428 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438429 ASYNC, ConstructServerDataPacket(
8430 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438431 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568432
Renjie Tangaadb84b2019-08-31 01:00:238433 mock_quic_data.AddWrite(SYNCHRONOUS,
8434 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:568435 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8436
Bence Béky6e243aa2019-12-13 19:01:078437 if (VersionUsesHttp3(version_.transport_version)) {
8438 mock_quic_data.AddWrite(
8439 SYNCHRONOUS, ConstructClientDataPacket(
8440 packet_num++, GetQpackDecoderStreamId(), true, false,
8441 StreamCancellationQpackDecoderInstruction(0)));
8442 }
8443
Yixin Wang46a273ec302018-01-23 17:59:568444 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418445 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238446 ConstructClientRstPacket(packet_num++,
8447 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418448 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:078449
8450 if (VersionUsesHttp3(version_.transport_version)) {
8451 mock_quic_data.AddWrite(
8452 SYNCHRONOUS, ConstructClientDataPacket(
8453 packet_num++, GetQpackDecoderStreamId(), true, false,
Bence Békyf6bb6b22020-04-17 20:22:118454 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078455 }
8456
Yixin Wang46a273ec302018-01-23 17:59:568457 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438458 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238459 ConstructClientRstPacket(packet_num++,
8460 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418461 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568462
8463 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8464
8465 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8466
8467 SSLSocketDataProvider ssl_data(ASYNC, OK);
8468 ssl_data.next_proto = kProtoHTTP2;
8469 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8470
8471 CreateSession();
8472
8473 request_.url = GURL("https://mail.example.org/");
8474 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568475 RunTransaction(&trans_1);
8476 CheckWasHttpResponse(&trans_1);
8477 CheckResponsePort(&trans_1, 70);
8478 CheckResponseData(&trans_1, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568479 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8480
8481 request_.url = GURL("https://different.example.org/");
8482 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568483 RunTransaction(&trans_2);
8484 CheckWasSpdyResponse(&trans_2);
8485 CheckResponsePort(&trans_2, 70);
8486 CheckResponseData(&trans_2, "0123456");
Yixin Wang46a273ec302018-01-23 17:59:568487 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8488
8489 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8490 // proxy socket to disconnect.
8491 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8492
8493 base::RunLoop().RunUntilIdle();
8494 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8495 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8496}
8497
8498// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148499TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568500 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148501 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568502 proxy_resolution_service_ =
8503 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8504 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568505
Ryan Hamiltonabad59e2019-06-06 04:02:598506 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238507 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258508 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238509 mock_quic_data.AddWrite(SYNCHRONOUS,
8510 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498511 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:168512 SYNCHRONOUS, client_maker_->MakePriorityPacket(
Renjie Tangee921d12020-02-06 00:41:498513 packet_num++, true,
8514 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8515 ConvertRequestPriorityToQuicPriority(
8516 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238517 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:528518 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238519 SYNCHRONOUS,
8520 ConstructClientRequestHeadersPacket(
8521 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498522 false,
8523 VersionUsesHttp3(version_.transport_version)
8524 ? MEDIUM
8525 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238526 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338527 mock_quic_data.AddRead(
8528 ASYNC, ConstructServerResponseHeadersPacket(
8529 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8530 GetResponseHeaders("500")));
8531 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:238532 mock_quic_data.AddWrite(
8533 SYNCHRONOUS,
8534 ConstructClientAckAndRstPacket(
8535 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8536 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568537
8538 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8539
8540 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8541
8542 CreateSession();
8543
8544 request_.url = GURL("https://mail.example.org/");
8545 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568546 TestCompletionCallback callback;
8547 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8548 EXPECT_EQ(ERR_IO_PENDING, rv);
8549 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
Yixin Wang46a273ec302018-01-23 17:59:568550
8551 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8552 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8553}
8554
8555// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148556TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568557 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148558 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568559 proxy_resolution_service_ =
8560 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8561 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568562
Ryan Hamiltonabad59e2019-06-06 04:02:598563 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238564 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258565 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238566 mock_quic_data.AddWrite(SYNCHRONOUS,
8567 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498568 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:168569 SYNCHRONOUS, client_maker_->MakePriorityPacket(
Renjie Tangee921d12020-02-06 00:41:498570 packet_num++, true,
8571 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8572 ConvertRequestPriorityToQuicPriority(
8573 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238574 }
Fan Yang32c5a112018-12-10 20:06:338575 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238576 SYNCHRONOUS,
8577 ConstructClientRequestHeadersPacket(
8578 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498579 false,
8580 VersionUsesHttp3(version_.transport_version)
8581 ? MEDIUM
8582 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238583 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:568584 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8585
8586 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8587
8588 CreateSession();
8589
8590 request_.url = GURL("https://mail.example.org/");
8591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568592 TestCompletionCallback callback;
8593 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8594 EXPECT_EQ(ERR_IO_PENDING, rv);
8595 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8596
8597 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8598 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8599}
8600
8601// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8602// host. Retries request and succeeds.
Bence Békyf6bb6b22020-04-17 20:22:118603TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568604 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148605 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568606 proxy_resolution_service_ =
8607 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8608 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568609
Ryan Hamiltonabad59e2019-06-06 04:02:598610 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238611 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258612 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238613 mock_quic_data.AddWrite(SYNCHRONOUS,
8614 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498615 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:168616 SYNCHRONOUS, client_maker_->MakePriorityPacket(
Renjie Tangee921d12020-02-06 00:41:498617 packet_num++, true,
8618 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8619 ConvertRequestPriorityToQuicPriority(
8620 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238621 }
Fan Yang32c5a112018-12-10 20:06:338622 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238623 SYNCHRONOUS,
8624 ConstructClientRequestHeadersPacket(
8625 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498626 false,
8627 VersionUsesHttp3(version_.transport_version)
8628 ? MEDIUM
8629 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238630 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438631 mock_quic_data.AddRead(
8632 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338633 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028634 GetResponseHeaders("200 OK")));
Bence Béky6e243aa2019-12-13 19:01:078635 if (VersionUsesHttp3(version_.transport_version)) {
8636 mock_quic_data.AddWrite(
8637 SYNCHRONOUS,
8638 ConstructClientAckAndDataPacket(
8639 packet_num++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
8640 StreamCancellationQpackDecoderInstruction(0)));
8641 mock_quic_data.AddWrite(
8642 SYNCHRONOUS,
8643 ConstructClientRstPacket(packet_num++,
8644 GetNthClientInitiatedBidirectionalStreamId(0),
8645 quic::QUIC_STREAM_CANCELLED));
8646 } else {
8647 mock_quic_data.AddWrite(
8648 SYNCHRONOUS,
8649 ConstructClientAckAndRstPacket(
8650 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8651 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
8652 }
Yixin Wang46a273ec302018-01-23 17:59:568653
Renjie Tangee921d12020-02-06 00:41:498654 if (VersionUsesHttp3(version_.transport_version)) {
8655 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:168656 SYNCHRONOUS, client_maker_->MakePriorityPacket(
Renjie Tangee921d12020-02-06 00:41:498657 packet_num++, true,
8658 GetNthClientInitiatedBidirectionalStreamId(1), 0,
8659 ConvertRequestPriorityToQuicPriority(
8660 HttpProxyConnectJob::kH2QuicTunnelPriority)));
8661 }
8662
Zhongyi Shi32f2fd02018-04-16 18:23:438663 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238664 SYNCHRONOUS,
8665 ConstructClientRequestHeadersPacket(
8666 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Renjie Tangee921d12020-02-06 00:41:498667 false,
8668 VersionUsesHttp3(version_.transport_version)
8669 ? MEDIUM
8670 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238671 ConnectRequestHeaders("mail.example.org:443"),
8672 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438673 mock_quic_data.AddRead(
8674 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338675 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028676 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568677
8678 const char get_request[] =
8679 "GET / HTTP/1.1\r\n"
8680 "Host: mail.example.org\r\n"
8681 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438682 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harperc6cb7a612020-02-24 20:03:328683 if (!version_.HasIetfQuicFrames()) {
Renjief49758b2019-01-11 23:32:418684 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358685 SYNCHRONOUS,
8686 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238687 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Zhongyi Shid1c00fc42019-12-14 06:05:098688 2, 2, 1, false, quiche::QuicheStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418689 } else {
8690 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418691 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288692 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238693 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Renjie Tangd5133972019-12-06 00:20:288694 2, 2, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418695 }
Yixin Wang46a273ec302018-01-23 17:59:568696 const char get_response[] =
8697 "HTTP/1.1 200 OK\r\n"
8698 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438699 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438700 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338701 ASYNC, ConstructServerDataPacket(
8702 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178703 header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528704
Victor Vasiliev076657c2019-03-12 02:46:438705 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338706 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418707 SYNCHRONOUS, ConstructServerDataPacket(
8708 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178709 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238710 mock_quic_data.AddWrite(SYNCHRONOUS,
8711 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568712 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8713
Bence Béky6e243aa2019-12-13 19:01:078714 if (VersionUsesHttp3(version_.transport_version)) {
8715 mock_quic_data.AddWrite(
8716 SYNCHRONOUS, ConstructClientDataPacket(
8717 packet_num++, GetQpackDecoderStreamId(), true, false,
Bence Békyf6bb6b22020-04-17 20:22:118718 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:078719 }
Yixin Wang46a273ec302018-01-23 17:59:568720 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418721 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238722 ConstructClientRstPacket(packet_num++,
8723 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418724 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568725
8726 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8727
8728 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8729 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8730
8731 SSLSocketDataProvider ssl_data(ASYNC, OK);
8732 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8733
8734 CreateSession();
8735
8736 request_.url = GURL("https://mail.example.org/");
8737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568738 TestCompletionCallback callback;
8739 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8740 EXPECT_EQ(ERR_IO_PENDING, rv);
8741 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8742
8743 rv = trans.RestartIgnoringLastError(callback.callback());
8744 EXPECT_EQ(ERR_IO_PENDING, rv);
8745 EXPECT_EQ(OK, callback.WaitForResult());
8746
8747 CheckWasHttpResponse(&trans);
8748 CheckResponsePort(&trans, 70);
8749 CheckResponseData(&trans, "0123456789");
Yixin Wang46a273ec302018-01-23 17:59:568750 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8751
8752 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8753 // proxy socket to disconnect.
8754 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8755
8756 base::RunLoop().RunUntilIdle();
8757 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8758 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8759}
8760
8761// Checks if a request's specified "user-agent" header shows up correctly in the
8762// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148763TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008764 const char kConfiguredUserAgent[] = "Configured User-Agent";
8765 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568766 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148767 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568768 proxy_resolution_service_ =
8769 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8770 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568771
Ryan Hamiltonabad59e2019-06-06 04:02:598772 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238773 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258774 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238775 mock_quic_data.AddWrite(SYNCHRONOUS,
8776 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498777 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:168778 SYNCHRONOUS, client_maker_->MakePriorityPacket(
Renjie Tangee921d12020-02-06 00:41:498779 packet_num++, true,
8780 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8781 ConvertRequestPriorityToQuicPriority(
8782 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238783 }
Yixin Wang46a273ec302018-01-23 17:59:568784
Ryan Hamilton0239aac2018-05-19 00:03:138785 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008786 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338787 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028788 SYNCHRONOUS,
8789 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238790 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498791 false,
8792 VersionUsesHttp3(version_.transport_version)
8793 ? MEDIUM
8794 : HttpProxyConnectJob::kH2QuicTunnelPriority,
8795 std::move(headers), 0));
Yixin Wang46a273ec302018-01-23 17:59:568796 // Return an error, so the transaction stops here (this test isn't interested
8797 // in the rest).
8798 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8799
8800 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8801
Matt Menked732ea42019-03-08 12:05:008802 StaticHttpUserAgentSettings http_user_agent_settings(
8803 std::string() /* accept_language */, kConfiguredUserAgent);
8804 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568805 CreateSession();
8806
8807 request_.url = GURL("https://mail.example.org/");
8808 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008809 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568810 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:568811 TestCompletionCallback callback;
8812 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8813 EXPECT_EQ(ERR_IO_PENDING, rv);
8814 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8815
8816 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8817 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8818}
8819
Yixin Wang00fc44c2018-01-23 21:12:208820// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8821// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148822TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208823 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148824 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568825 proxy_resolution_service_ =
8826 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8827 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208828
8829 const RequestPriority request_priority = MEDIUM;
8830
Ryan Hamiltonabad59e2019-06-06 04:02:598831 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238832 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258833 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238834 mock_quic_data.AddWrite(SYNCHRONOUS,
8835 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498836 mock_quic_data.AddWrite(
Zhongyi Shi1c022d22020-03-20 19:00:168837 SYNCHRONOUS, client_maker_->MakePriorityPacket(
Renjie Tangee921d12020-02-06 00:41:498838 packet_num++, true,
8839 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8840 ConvertRequestPriorityToQuicPriority(
8841 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238842 }
Zhongyi Shi32f2fd02018-04-16 18:23:438843 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238844 SYNCHRONOUS,
8845 ConstructClientRequestHeadersPacket(
8846 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498847 false,
8848 VersionUsesHttp3(version_.transport_version)
8849 ? MEDIUM
8850 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238851 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:208852 // Return an error, so the transaction stops here (this test isn't interested
8853 // in the rest).
8854 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8855
8856 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8857
8858 CreateSession();
8859
8860 request_.url = GURL("https://mail.example.org/");
8861 HttpNetworkTransaction trans(request_priority, session_.get());
8862 TestCompletionCallback callback;
8863 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8864 EXPECT_EQ(ERR_IO_PENDING, rv);
8865 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8866
8867 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8868 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8869}
8870
Matt Menkeedaf3b82019-03-14 21:39:448871// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8872// HTTP/2 stream dependency and weights given the request priority.
8873TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8874 session_params_.enable_quic = true;
8875 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568876 proxy_resolution_service_ =
8877 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8878 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeedaf3b82019-03-14 21:39:448879
8880 const RequestPriority kRequestPriority = MEDIUM;
8881 const RequestPriority kRequestPriority2 = LOWEST;
8882
Ryan Hamiltonabad59e2019-06-06 04:02:598883 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:258884 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238885 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
8886 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8887 } else {
8888 mock_quic_data.AddWrite(
8889 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8890 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
8891 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8892 ConnectRequestHeaders("mail.example.org:443"), 0));
8893 }
Matt Menkeedaf3b82019-03-14 21:39:448894 // This should never be reached.
8895 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8896 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8897
8898 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:598899 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:448900 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8901 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8902
8903 int original_max_sockets_per_group =
8904 ClientSocketPoolManager::max_sockets_per_group(
8905 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8906 ClientSocketPoolManager::set_max_sockets_per_group(
8907 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8908 int original_max_sockets_per_pool =
8909 ClientSocketPoolManager::max_sockets_per_pool(
8910 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8911 ClientSocketPoolManager::set_max_sockets_per_pool(
8912 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8913 CreateSession();
8914
8915 request_.url = GURL("https://mail.example.org/");
8916 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8917 TestCompletionCallback callback;
8918 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8919 EXPECT_EQ(ERR_IO_PENDING, rv);
8920
8921 HttpRequestInfo request2;
8922 request2.url = GURL("https://mail.example.org/some/other/path/");
8923 request2.traffic_annotation =
8924 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8925
8926 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8927 TestCompletionCallback callback2;
8928 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8929 EXPECT_EQ(ERR_IO_PENDING, rv2);
8930
8931 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8932 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8933
8934 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8935
8936 ClientSocketPoolManager::set_max_sockets_per_pool(
8937 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8938 original_max_sockets_per_pool);
8939 ClientSocketPoolManager::set_max_sockets_per_group(
8940 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8941 original_max_sockets_per_group);
8942}
8943
Yixin Wang46a273ec302018-01-23 17:59:568944// Test the request-challenge-retry sequence for basic auth, over a QUIC
8945// connection when setting up a QUIC proxy tunnel.
Bence Békyf6bb6b22020-04-17 20:22:118946TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568947 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8948 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:568949
Yixin Wang46a273ec302018-01-23 17:59:568950 // On the second pass, the body read of the auth challenge is synchronous, so
8951 // IsConnectedAndIdle returns false. The socket should still be drained and
8952 // reused. See http://crbug.com/544255.
8953 for (int i = 0; i < 2; ++i) {
Bence Béky6e243aa2019-12-13 19:01:078954 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:228955 version_,
8956 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8957 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky6e243aa2019-12-13 19:01:078958 client_headers_include_h2_stream_dependency_);
8959 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:228960 version_,
8961 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8962 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Bence Béky6e243aa2019-12-13 19:01:078963 false);
Yixin Wang46a273ec302018-01-23 17:59:568964
8965 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148966 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568967 proxy_resolution_service_ =
Nicolas Arciniegad2013f92020-02-07 23:00:568968 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498969 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568970
Ryan Hamiltonabad59e2019-06-06 04:02:598971 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528972 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568973
Renjie Tangaadb84b2019-08-31 01:00:238974 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258975 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238976 mock_quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:078977 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498978 mock_quic_data.AddWrite(
8979 SYNCHRONOUS, client_maker.MakePriorityPacket(
8980 packet_num++, true,
8981 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8982 ConvertRequestPriorityToQuicPriority(
8983 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238984 }
Yixin Wang46a273ec302018-01-23 17:59:568985
8986 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438987 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:078988 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238989 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8990 false,
Renjie Tangee921d12020-02-06 00:41:498991 VersionUsesHttp3(version_.transport_version)
8992 ? 1
8993 : ConvertRequestPriorityToQuicPriority(
8994 HttpProxyConnectJob::kH2QuicTunnelPriority),
Bence Béky6e243aa2019-12-13 19:01:078995 client_maker.ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028996 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568997
Ryan Hamilton0239aac2018-05-19 00:03:138998 spdy::SpdyHeaderBlock headers =
Bence Béky6e243aa2019-12-13 19:01:078999 server_maker.GetResponseHeaders("407 Proxy Authentication Required");
Yixin Wang46a273ec302018-01-23 17:59:569000 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
9001 headers["content-length"] = "10";
9002 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079003 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:339004 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:029005 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569006
9007 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:439008 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079009 ASYNC, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:339010 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179011 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:569012 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:439013 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079014 SYNCHRONOUS, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:339015 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:179016 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:569017 }
9018 server_data_offset += 10;
9019
Bence Béky7a45d4d2020-05-08 01:59:239020 mock_quic_data.AddWrite(SYNCHRONOUS,
9021 client_maker.MakeAckPacket(packet_num++, 2, 1, 1));
Bence Béky6e243aa2019-12-13 19:01:079022
9023 if (VersionUsesHttp3(version_.transport_version)) {
9024 mock_quic_data.AddWrite(
9025 SYNCHRONOUS,
9026 client_maker.MakeDataPacket(
9027 packet_num++, GetQpackDecoderStreamId(),
9028 /* should_include_version = */ true,
9029 /* fin = */ false, StreamCancellationQpackDecoderInstruction(0)));
9030 }
Yixin Wang46a273ec302018-01-23 17:59:569031
9032 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:339033 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:079034 client_maker.MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:239035 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:419036 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:189037 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:569038
Bence Béky6e243aa2019-12-13 19:01:079039 headers = client_maker.ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:569040 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
Renjie Tangee921d12020-02-06 00:41:499041 if (VersionUsesHttp3(version_.transport_version)) {
9042 mock_quic_data.AddWrite(
9043 SYNCHRONOUS, client_maker.MakePriorityPacket(
9044 packet_num++, true,
9045 GetNthClientInitiatedBidirectionalStreamId(1), 0,
9046 ConvertRequestPriorityToQuicPriority(
9047 HttpProxyConnectJob::kH2QuicTunnelPriority)));
9048 }
Yixin Wang46a273ec302018-01-23 17:59:569049 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:049050 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:079051 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239052 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
9053 false,
Renjie Tangee921d12020-02-06 00:41:499054 VersionUsesHttp3(version_.transport_version)
9055 ? 1
9056 : ConvertRequestPriorityToQuicPriority(
9057 HttpProxyConnectJob::kH2QuicTunnelPriority),
Matt Menke6e879bd2019-03-18 17:26:049058 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:029059 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569060
9061 // Response to wrong password
9062 headers =
Bence Béky6e243aa2019-12-13 19:01:079063 server_maker.GetResponseHeaders("407 Proxy Authentication Required");
Yixin Wang46a273ec302018-01-23 17:59:569064 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
9065 headers["content-length"] = "10";
9066 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079067 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:339068 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:029069 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569070 mock_quic_data.AddRead(SYNCHRONOUS,
9071 ERR_IO_PENDING); // No more data to read
9072
Bence Béky6e243aa2019-12-13 19:01:079073 if (VersionUsesHttp3(version_.transport_version)) {
9074 mock_quic_data.AddWrite(
9075 SYNCHRONOUS,
9076 client_maker.MakeAckAndDataPacket(
9077 packet_num++, false, GetQpackDecoderStreamId(), 3, 3, 1, false,
Bence Békyf6bb6b22020-04-17 20:22:119078 StreamCancellationQpackDecoderInstruction(1, false)));
Bence Béky6e243aa2019-12-13 19:01:079079 mock_quic_data.AddWrite(SYNCHRONOUS,
9080 client_maker.MakeRstPacket(
9081 packet_num++, false,
9082 GetNthClientInitiatedBidirectionalStreamId(1),
9083 quic::QUIC_STREAM_CANCELLED));
9084 } else {
9085 mock_quic_data.AddWrite(SYNCHRONOUS,
9086 client_maker.MakeAckAndRstPacket(
9087 packet_num++, false,
9088 GetNthClientInitiatedBidirectionalStreamId(1),
Bence Béky7a45d4d2020-05-08 01:59:239089 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
Bence Béky6e243aa2019-12-13 19:01:079090 }
Yixin Wang46a273ec302018-01-23 17:59:569091
9092 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9093 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
9094
9095 CreateSession();
9096
9097 request_.url = GURL("https://mail.example.org/");
9098 // Ensure that proxy authentication is attempted even
9099 // when the no authentication data flag is set.
9100 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
9101 {
9102 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
Yixin Wang46a273ec302018-01-23 17:59:569103 RunTransaction(&trans);
9104
9105 const HttpResponseInfo* response = trans.GetResponseInfo();
9106 ASSERT_TRUE(response != nullptr);
9107 ASSERT_TRUE(response->headers.get() != nullptr);
9108 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
9109 response->headers->GetStatusLine());
9110 EXPECT_TRUE(response->headers->IsKeepAlive());
9111 EXPECT_EQ(407, response->headers->response_code());
9112 EXPECT_EQ(10, response->headers->GetContentLength());
9113 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589114 base::Optional<AuthChallengeInfo> auth_challenge =
9115 response->auth_challenge;
9116 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:569117 EXPECT_TRUE(auth_challenge->is_proxy);
9118 EXPECT_EQ("https://proxy.example.org:70",
9119 auth_challenge->challenger.Serialize());
9120 EXPECT_EQ("MyRealm1", auth_challenge->realm);
9121 EXPECT_EQ("basic", auth_challenge->scheme);
9122
9123 TestCompletionCallback callback;
9124 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
9125 callback.callback());
9126 EXPECT_EQ(ERR_IO_PENDING, rv);
9127 EXPECT_EQ(OK, callback.WaitForResult());
9128
9129 response = trans.GetResponseInfo();
9130 ASSERT_TRUE(response != nullptr);
9131 ASSERT_TRUE(response->headers.get() != nullptr);
9132 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
9133 response->headers->GetStatusLine());
9134 EXPECT_TRUE(response->headers->IsKeepAlive());
9135 EXPECT_EQ(407, response->headers->response_code());
9136 EXPECT_EQ(10, response->headers->GetContentLength());
9137 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589138 auth_challenge = response->auth_challenge;
9139 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:569140 EXPECT_TRUE(auth_challenge->is_proxy);
9141 EXPECT_EQ("https://proxy.example.org:70",
9142 auth_challenge->challenger.Serialize());
9143 EXPECT_EQ("MyRealm1", auth_challenge->realm);
9144 EXPECT_EQ("basic", auth_challenge->scheme);
9145 }
9146 // HttpNetworkTransaction is torn down now that it's out of scope, causing
9147 // the QUIC stream to be cleaned up (since the proxy socket cannot be
9148 // reused because it's not connected).
9149 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9150 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9151 }
9152}
9153
Yixin Wang385652a2018-02-16 02:37:239154TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
Zhongyi Shi1c022d22020-03-20 19:00:169155 client_maker_->set_max_allowed_push_id(quic::kMaxQuicStreamId);
Ryan Hamilton6c6493102019-12-05 21:36:509156 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
9157
Yixin Wang385652a2018-02-16 02:37:239158 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
9159 // in HEADERS frames for requests and PRIORITY frames).
David Schinazi84c58bb2020-06-04 20:14:339160 if (!client_headers_include_h2_stream_dependency_) {
Yixin Wang385652a2018-02-16 02:37:239161 return;
9162 }
9163
Victor Vasiliev7da08172019-10-14 06:04:259164 if (quic::VersionUsesHttp3(version_.transport_version)) {
Renjie Tangba21e032019-09-27 21:52:289165 // HTTP/3 currently doesn't support PRIORITY.
Ryan Hamiltone940bd12019-06-30 02:46:459166 return;
9167 }
9168
Victor Vasilieva1e66d72019-12-05 17:55:389169 context_.params()->origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:239170 HostPortPair::FromString("mail.example.org:443"));
9171
Fan Yang32c5a112018-12-10 20:06:339172 const quic::QuicStreamId client_stream_0 =
9173 GetNthClientInitiatedBidirectionalStreamId(0);
9174 const quic::QuicStreamId client_stream_1 =
9175 GetNthClientInitiatedBidirectionalStreamId(1);
9176 const quic::QuicStreamId client_stream_2 =
9177 GetNthClientInitiatedBidirectionalStreamId(2);
9178 const quic::QuicStreamId push_stream_0 =
9179 GetNthServerInitiatedUnidirectionalStreamId(0);
9180 const quic::QuicStreamId push_stream_1 =
9181 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:239182
Ryan Hamiltonabad59e2019-06-06 04:02:599183 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:239184 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259185 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239186 mock_quic_data.AddWrite(SYNCHRONOUS,
9187 ConstructInitialSettingsPacket(packet_num++));
9188 }
Yixin Wang385652a2018-02-16 02:37:239189
9190 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:239191 mock_quic_data.AddWrite(
9192 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
9193 packet_num++, client_stream_0, true, true, HIGHEST,
9194 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:029195 mock_quic_data.AddWrite(
9196 SYNCHRONOUS,
9197 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239198 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:029199 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
9200 mock_quic_data.AddWrite(
9201 SYNCHRONOUS,
9202 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239203 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:029204 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:239205
9206 // Server replies "OK" for the three requests.
Ryan Hamilton0d65a8c2019-06-07 00:46:029207 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9208 1, client_stream_0, false, false,
9209 GetResponseHeaders("200 OK")));
9210 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9211 2, client_stream_1, false, false,
9212 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:239213 mock_quic_data.AddWrite(SYNCHRONOUS,
9214 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton0d65a8c2019-06-07 00:46:029215 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9216 3, client_stream_2, false, false,
9217 GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:239218
9219 // Server sends two push promises associated with |client_stream_0|; client
9220 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
9221 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:029222 mock_quic_data.AddRead(
9223 ASYNC,
9224 ConstructServerPushPromisePacket(
9225 4, client_stream_0, push_stream_0, false,
9226 GetRequestHeaders("GET", "https", "/pushed_0.jpg"), &server_maker_));
Yixin Wang385652a2018-02-16 02:37:239227 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:439228 SYNCHRONOUS,
9229 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:239230 packet_num++, false, 4, 3, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:439231 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:029232 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
9233 mock_quic_data.AddRead(
9234 ASYNC,
9235 ConstructServerPushPromisePacket(
9236 5, client_stream_0, push_stream_1, false,
9237 GetRequestHeaders("GET", "https", "/pushed_1.jpg"), &server_maker_));
Haoyue Wang9d70d65c2020-05-29 22:45:349238 mock_quic_data.AddWrite(
9239 SYNCHRONOUS, ConstructClientAckAndPriorityPacket(
9240 packet_num++, false,
9241 /*largest_received=*/5, /*smallest_received=*/4,
9242 push_stream_1, push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:239243
9244 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:439245 mock_quic_data.AddRead(
9246 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:029247 6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:439248 mock_quic_data.AddRead(
9249 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:029250 7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
Haoyue Wang9d70d65c2020-05-29 22:45:349251 mock_quic_data.AddWrite(SYNCHRONOUS,
9252 ConstructClientAckPacket(packet_num++, 7, 5, 1));
Yixin Wang385652a2018-02-16 02:37:239253
9254 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
9255 // priority updates to match the request's priority. Client sends PRIORITY
9256 // frames to inform server of new HTTP/2 stream dependencies.
Haoyue Wang9d70d65c2020-05-29 22:45:349257 mock_quic_data.AddWrite(
9258 SYNCHRONOUS,
9259 ConstructClientPriorityFramesPacket(
9260 packet_num++, false,
9261 {{push_stream_1, client_stream_2,
9262 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
9263 {push_stream_0, client_stream_0,
9264 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:239265
9266 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:439267 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:439268 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179269 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Renjief49758b2019-01-11 23:32:419270 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:439271 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179272 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Renjief49758b2019-01-11 23:32:419273 header + "hello 1!"));
Renjie Tangaadb84b2019-08-31 01:00:239274 mock_quic_data.AddWrite(SYNCHRONOUS,
9275 ConstructClientAckPacket(packet_num++, 9, 8, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439276 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179277 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Renjief49758b2019-01-11 23:32:419278 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:439279 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:439280 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179281 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true,
Renjief49758b2019-01-11 23:32:419282 header2 + "and hello 0!"));
Renjie Tangaadb84b2019-08-31 01:00:239283 mock_quic_data.AddWrite(SYNCHRONOUS,
9284 ConstructClientAckPacket(packet_num++, 11, 10, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439285 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179286 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Renjief49758b2019-01-11 23:32:419287 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:239288
Yixin Wang385652a2018-02-16 02:37:239289 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9290 mock_quic_data.AddRead(ASYNC, 0); // EOF
9291 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9292
9293 // The non-alternate protocol job needs to hang in order to guarantee that
9294 // the alternate-protocol job will "win".
9295 AddHangingNonAlternateProtocolSocketData();
9296
9297 CreateSession();
9298
9299 request_.url = GURL("https://mail.example.org/0.jpg");
9300 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
9301 TestCompletionCallback callback_0;
9302 EXPECT_EQ(ERR_IO_PENDING,
9303 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
9304 base::RunLoop().RunUntilIdle();
9305
9306 request_.url = GURL("https://mail.example.org/1.jpg");
9307 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
9308 TestCompletionCallback callback_1;
9309 EXPECT_EQ(ERR_IO_PENDING,
9310 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
9311 base::RunLoop().RunUntilIdle();
9312
9313 request_.url = GURL("https://mail.example.org/2.jpg");
9314 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
9315 TestCompletionCallback callback_2;
9316 EXPECT_EQ(ERR_IO_PENDING,
9317 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
9318 base::RunLoop().RunUntilIdle();
9319
9320 // Client makes request that matches resource pushed in |pushed_stream_0|.
9321 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
9322 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
9323 TestCompletionCallback callback_3;
9324 EXPECT_EQ(ERR_IO_PENDING,
9325 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
9326 base::RunLoop().RunUntilIdle();
9327
9328 EXPECT_TRUE(callback_0.have_result());
9329 EXPECT_EQ(OK, callback_0.WaitForResult());
9330 EXPECT_TRUE(callback_1.have_result());
9331 EXPECT_EQ(OK, callback_1.WaitForResult());
9332 EXPECT_TRUE(callback_2.have_result());
9333 EXPECT_EQ(OK, callback_2.WaitForResult());
9334
9335 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
9336 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
9337 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
9338 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
9339
9340 mock_quic_data.Resume();
9341 base::RunLoop().RunUntilIdle();
9342 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9343 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9344}
9345
Matt Menke26e41542019-06-05 01:09:519346// Test that NetworkIsolationKey is respected by QUIC connections, when
9347// kPartitionConnectionsByNetworkIsolationKey is enabled.
9348TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Shivani Sharma8ae506c2019-07-21 21:08:279349 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9350 const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
9351 NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
9352 NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
Matt Menke26e41542019-06-05 01:09:519353
Victor Vasilieva1e66d72019-12-05 17:55:389354 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519355 HostPortPair::FromString("mail.example.org:443"));
9356
9357 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
9358 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
9359 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
9360 // the same way as the HTTP over H2 proxy case.
9361 for (bool use_proxy : {false, true}) {
9362 SCOPED_TRACE(use_proxy);
9363
9364 if (use_proxy) {
9365 proxy_resolution_service_ =
Nicolas Arciniegad2013f92020-02-07 23:00:569366 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Matt Menke26e41542019-06-05 01:09:519367 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
9368 } else {
Nicolas Arciniegad2013f92020-02-07 23:00:569369 proxy_resolution_service_ =
9370 ConfiguredProxyResolutionService::CreateDirect();
Matt Menke26e41542019-06-05 01:09:519371 }
9372
9373 GURL url1;
9374 GURL url2;
9375 GURL url3;
9376 if (use_proxy) {
9377 url1 = GURL("http://mail.example.org/1");
9378 url2 = GURL("http://mail.example.org/2");
9379 url3 = GURL("http://mail.example.org/3");
9380 } else {
9381 url1 = GURL("https://mail.example.org/1");
9382 url2 = GURL("https://mail.example.org/2");
9383 url3 = GURL("https://mail.example.org/3");
9384 }
9385
9386 for (bool partition_connections : {false, true}) {
9387 SCOPED_TRACE(partition_connections);
9388
9389 base::test::ScopedFeatureList feature_list;
9390 if (partition_connections) {
9391 feature_list.InitAndEnableFeature(
9392 features::kPartitionConnectionsByNetworkIsolationKey);
9393 } else {
9394 feature_list.InitAndDisableFeature(
9395 features::kPartitionConnectionsByNetworkIsolationKey);
9396 }
9397
9398 // Reads and writes for the unpartitioned case, where only one socket is
9399 // used.
9400
Victor Vasilieva1e66d72019-12-05 17:55:389401 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519402 HostPortPair::FromString("mail.example.org:443"));
9403
Ryan Hamiltonabad59e2019-06-06 04:02:599404 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:519405 QuicTestPacketMaker client_maker1(
9406 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229407 quic::QuicUtils::CreateRandomConnectionId(
9408 context_.random_generator()),
9409 context_.clock(), kDefaultServerHostName,
9410 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519411 client_headers_include_h2_stream_dependency_);
9412 QuicTestPacketMaker server_maker1(
9413 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229414 quic::QuicUtils::CreateRandomConnectionId(
9415 context_.random_generator()),
9416 context_.clock(), kDefaultServerHostName,
9417 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519418
Renjie Tangaadb84b2019-08-31 01:00:239419 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259420 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239421 unpartitioned_mock_quic_data.AddWrite(
9422 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
9423 }
Matt Menke26e41542019-06-05 01:09:519424
9425 unpartitioned_mock_quic_data.AddWrite(
9426 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029427 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239428 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9429 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029430 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519431 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029432 ASYNC, server_maker1.MakeResponseHeadersPacket(
9433 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9434 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519435 unpartitioned_mock_quic_data.AddRead(
9436 ASYNC, server_maker1.MakeDataPacket(
9437 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179438 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519439 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239440 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke26e41542019-06-05 01:09:519441
9442 unpartitioned_mock_quic_data.AddWrite(
9443 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029444 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239445 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
9446 false, true,
Matt Menke26e41542019-06-05 01:09:519447 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029448 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519449 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029450 ASYNC, server_maker1.MakeResponseHeadersPacket(
9451 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9452 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519453 unpartitioned_mock_quic_data.AddRead(
9454 ASYNC, server_maker1.MakeDataPacket(
9455 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179456 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519457 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239458 SYNCHRONOUS,
9459 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
Matt Menke26e41542019-06-05 01:09:519460
9461 unpartitioned_mock_quic_data.AddWrite(
9462 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029463 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239464 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
9465 false, true,
Matt Menke26e41542019-06-05 01:09:519466 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029467 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519468 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029469 ASYNC, server_maker1.MakeResponseHeadersPacket(
9470 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
9471 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519472 unpartitioned_mock_quic_data.AddRead(
9473 ASYNC, server_maker1.MakeDataPacket(
9474 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Ryan Hamilton7505eb92019-06-08 00:22:179475 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519476 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239477 SYNCHRONOUS,
9478 ConstructClientAckAndConnectionClosePacket(packet_num++, 6, 5, 1));
Matt Menke26e41542019-06-05 01:09:519479
9480 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9481
9482 // Reads and writes for the partitioned case, where two sockets are used.
9483
Ryan Hamiltonabad59e2019-06-06 04:02:599484 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:519485 QuicTestPacketMaker client_maker2(
9486 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229487 quic::QuicUtils::CreateRandomConnectionId(
9488 context_.random_generator()),
9489 context_.clock(), kDefaultServerHostName,
9490 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519491 client_headers_include_h2_stream_dependency_);
9492 QuicTestPacketMaker server_maker2(
9493 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229494 quic::QuicUtils::CreateRandomConnectionId(
9495 context_.random_generator()),
9496 context_.clock(), kDefaultServerHostName,
9497 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519498
Renjie Tangaadb84b2019-08-31 01:00:239499 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259500 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239501 partitioned_mock_quic_data1.AddWrite(
9502 SYNCHRONOUS,
9503 client_maker2.MakeInitialSettingsPacket(packet_num2++));
9504 }
Matt Menke26e41542019-06-05 01:09:519505
9506 partitioned_mock_quic_data1.AddWrite(
9507 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029508 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239509 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
9510 true, true,
Matt Menke26e41542019-06-05 01:09:519511 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029512 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519513 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029514 ASYNC, server_maker2.MakeResponseHeadersPacket(
9515 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9516 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519517 partitioned_mock_quic_data1.AddRead(
9518 ASYNC, server_maker2.MakeDataPacket(
9519 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179520 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519521 partitioned_mock_quic_data1.AddWrite(
Bence Béky7a45d4d2020-05-08 01:59:239522 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 2, 1, 1));
Matt Menke26e41542019-06-05 01:09:519523
9524 partitioned_mock_quic_data1.AddWrite(
9525 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029526 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239527 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
9528 false, true,
Matt Menke26e41542019-06-05 01:09:519529 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029530 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519531 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029532 ASYNC, server_maker2.MakeResponseHeadersPacket(
9533 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9534 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519535 partitioned_mock_quic_data1.AddRead(
9536 ASYNC, server_maker2.MakeDataPacket(
9537 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179538 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519539 partitioned_mock_quic_data1.AddWrite(
Bence Béky7a45d4d2020-05-08 01:59:239540 SYNCHRONOUS, client_maker2.MakeAckPacket(packet_num2++, 4, 3, 1));
Matt Menke26e41542019-06-05 01:09:519541
9542 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9543
Ryan Hamiltonabad59e2019-06-06 04:02:599544 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:519545 QuicTestPacketMaker client_maker3(
9546 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229547 quic::QuicUtils::CreateRandomConnectionId(
9548 context_.random_generator()),
9549 context_.clock(), kDefaultServerHostName,
9550 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519551 client_headers_include_h2_stream_dependency_);
9552 QuicTestPacketMaker server_maker3(
9553 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229554 quic::QuicUtils::CreateRandomConnectionId(
9555 context_.random_generator()),
9556 context_.clock(), kDefaultServerHostName,
9557 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519558
Renjie Tangaadb84b2019-08-31 01:00:239559 int packet_num3 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259560 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239561 partitioned_mock_quic_data2.AddWrite(
9562 SYNCHRONOUS,
9563 client_maker3.MakeInitialSettingsPacket(packet_num3++));
9564 }
Matt Menke26e41542019-06-05 01:09:519565
9566 partitioned_mock_quic_data2.AddWrite(
9567 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029568 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239569 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9570 true, true,
Matt Menke26e41542019-06-05 01:09:519571 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029572 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519573 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029574 ASYNC, server_maker3.MakeResponseHeadersPacket(
9575 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9576 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519577 partitioned_mock_quic_data2.AddRead(
9578 ASYNC, server_maker3.MakeDataPacket(
9579 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179580 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519581 partitioned_mock_quic_data2.AddWrite(
Bence Béky7a45d4d2020-05-08 01:59:239582 SYNCHRONOUS, client_maker3.MakeAckPacket(packet_num3++, 2, 1, 1));
Matt Menke26e41542019-06-05 01:09:519583
9584 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9585
9586 if (partition_connections) {
9587 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9588 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9589 } else {
9590 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9591 }
9592
9593 CreateSession();
9594
9595 TestCompletionCallback callback;
9596 HttpRequestInfo request1;
9597 request1.method = "GET";
9598 request1.url = GURL(url1);
9599 request1.traffic_annotation =
9600 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9601 request1.network_isolation_key = network_isolation_key1;
9602 HttpNetworkTransaction trans1(LOWEST, session_.get());
9603 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9604 EXPECT_THAT(callback.GetResult(rv), IsOk());
9605 std::string response_data1;
9606 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9607 EXPECT_EQ("1", response_data1);
9608
9609 HttpRequestInfo request2;
9610 request2.method = "GET";
9611 request2.url = GURL(url2);
9612 request2.traffic_annotation =
9613 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9614 request2.network_isolation_key = network_isolation_key2;
9615 HttpNetworkTransaction trans2(LOWEST, session_.get());
9616 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9617 EXPECT_THAT(callback.GetResult(rv), IsOk());
9618 std::string response_data2;
9619 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9620 EXPECT_EQ("2", response_data2);
9621
9622 HttpRequestInfo request3;
9623 request3.method = "GET";
9624 request3.url = GURL(url3);
9625 request3.traffic_annotation =
9626 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9627 request3.network_isolation_key = network_isolation_key1;
9628 HttpNetworkTransaction trans3(LOWEST, session_.get());
9629 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9630 EXPECT_THAT(callback.GetResult(rv), IsOk());
9631 std::string response_data3;
9632 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9633 EXPECT_EQ("3", response_data3);
9634
9635 if (partition_connections) {
9636 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9637 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9638 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9639 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9640 } else {
9641 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9642 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9643 }
9644 }
9645 }
9646}
9647
9648// Test that two requests to the same origin over QUIC tunnels use different
9649// QUIC sessions if their NetworkIsolationKeys don't match, and
9650// kPartitionConnectionsByNetworkIsolationKey is enabled.
9651TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9652 base::test::ScopedFeatureList feature_list;
9653 feature_list.InitAndEnableFeature(
9654 features::kPartitionConnectionsByNetworkIsolationKey);
9655
9656 session_params_.enable_quic = true;
9657 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:569658 proxy_resolution_service_ =
9659 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
9660 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menke26e41542019-06-05 01:09:519661
9662 const char kGetRequest[] =
9663 "GET / HTTP/1.1\r\n"
9664 "Host: mail.example.org\r\n"
9665 "Connection: keep-alive\r\n\r\n";
9666 const char kGetResponse[] =
9667 "HTTP/1.1 200 OK\r\n"
9668 "Content-Length: 10\r\n\r\n";
9669
Ryan Hamiltonabad59e2019-06-06 04:02:599670 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9671 std::make_unique<MockQuicData>(version_),
9672 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519673
9674 for (int index : {0, 1}) {
9675 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229676 version_,
9677 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9678 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519679 client_headers_include_h2_stream_dependency_);
9680 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229681 version_,
9682 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9683 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9684 false);
Matt Menke26e41542019-06-05 01:09:519685
Renjie Tangaadb84b2019-08-31 01:00:239686 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259687 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239688 mock_quic_data[index]->AddWrite(
9689 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:499690 mock_quic_data[index]->AddWrite(
9691 SYNCHRONOUS, client_maker.MakePriorityPacket(
9692 packet_num++, true,
9693 GetNthClientInitiatedBidirectionalStreamId(0), 0,
9694 ConvertRequestPriorityToQuicPriority(
9695 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:239696 }
Matt Menke26e41542019-06-05 01:09:519697
Ryan Hamiltonabad59e2019-06-06 04:02:599698 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519699 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029700 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239701 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9702 false,
Renjie Tangee921d12020-02-06 00:41:499703 VersionUsesHttp3(version_.transport_version)
9704 ? 1
9705 : ConvertRequestPriorityToQuicPriority(
9706 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:029707 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:599708 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029709 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:519710 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9711 false, GetResponseHeaders("200 OK"), nullptr));
9712
9713 std::string header = ConstructDataHeader(strlen(kGetRequest));
Nick Harperc6cb7a612020-02-24 20:03:329714 if (!version_.HasIetfQuicFrames()) {
Ryan Hamiltonabad59e2019-06-06 04:02:599715 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239716 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
9717 packet_num++, false,
9718 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
Zhongyi Shid1c00fc42019-12-14 06:05:099719 1, false, quiche::QuicheStringPiece(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:519720 } else {
Ryan Hamiltonabad59e2019-06-06 04:02:599721 mock_quic_data[index]->AddWrite(
Renjie Tangd5133972019-12-06 00:20:289722 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:239723 packet_num++, false,
9724 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
Renjie Tangd5133972019-12-06 00:20:289725 1, false, {header + std::string(kGetRequest)}));
Matt Menke26e41542019-06-05 01:09:519726 }
9727
9728 std::string header2 = ConstructDataHeader(strlen(kGetResponse));
Ryan Hamiltonabad59e2019-06-06 04:02:599729 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519730 ASYNC, server_maker.MakeDataPacket(
9731 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179732 false, header2 + std::string(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599733 mock_quic_data[index]->AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179734 SYNCHRONOUS,
9735 server_maker.MakeDataPacket(
9736 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
9737 ConstructDataHeader(10) + std::string("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599738 mock_quic_data[index]->AddWrite(
Bence Béky7a45d4d2020-05-08 01:59:239739 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2, 1));
Ryan Hamiltonabad59e2019-06-06 04:02:599740 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9741 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:519742
Ryan Hamiltonabad59e2019-06-06 04:02:599743 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:519744 }
9745
9746 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9747 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9748 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9749
9750 CreateSession();
9751
9752 request_.url = GURL("https://mail.example.org/");
9753 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9754 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9755 RunTransaction(&trans);
9756 CheckResponseData(&trans, "0123456789");
9757
9758 HttpRequestInfo request2;
Shivani Sharma8ae506c2019-07-21 21:08:279759 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9760 request_.network_isolation_key = NetworkIsolationKey(kOrigin1, kOrigin1);
Matt Menke26e41542019-06-05 01:09:519761 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9762 RunTransaction(&trans2);
9763 CheckResponseData(&trans2, "0123456789");
9764
Ryan Hamiltonabad59e2019-06-06 04:02:599765 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9766 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9767 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9768 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:519769}
9770
Yoichi Osato4c75c0c2020-06-24 08:03:579771TEST_P(QuicNetworkTransactionTest, AllowHTTP1FalseProhibitsH1) {
9772 MockRead http_reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING),
9773 MockRead(ASYNC, OK)};
9774 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
9775 socket_factory_.AddSocketDataProvider(&http_data);
9776 AddCertificate(&ssl_data_);
9777 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9778
9779 CreateSession();
9780
9781 request_.method = "POST";
9782 UploadDataStreamNotAllowHTTP1 upload_data("");
9783 request_.upload_data_stream = &upload_data;
9784
9785 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9786 TestCompletionCallback callback;
9787 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9788 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9789 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_H2_OR_QUIC_REQUIRED));
9790}
9791
9792// Confirm mock class UploadDataStreamNotAllowHTTP1 can upload content over
9793// QUIC.
9794TEST_P(QuicNetworkTransactionTest, AllowHTTP1MockTest) {
9795 context_.params()->origins_to_force_quic_on.insert(
9796 HostPortPair::FromString("mail.example.org:443"));
9797
9798 MockQuicData mock_quic_data(version_);
9799 int write_packet_index = 1;
9800 if (VersionUsesHttp3(version_.transport_version)) {
9801 mock_quic_data.AddWrite(
9802 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9803 }
9804 const std::string upload_content = "foo";
9805 if (!version_.HasIetfQuicFrames()) {
9806 mock_quic_data.AddWrite(
9807 SYNCHRONOUS,
9808 ConstructClientRequestHeadersAndDataFramesPacket(
9809 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9810 true, true, DEFAULT_PRIORITY,
9811 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
9812 {upload_content}));
9813 } else {
9814 mock_quic_data.AddWrite(
9815 SYNCHRONOUS,
9816 ConstructClientRequestHeadersAndDataFramesPacket(
9817 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9818 true, true, DEFAULT_PRIORITY,
9819 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
9820 {ConstructDataHeader(upload_content.length()), upload_content}));
9821 }
9822 mock_quic_data.AddRead(
9823 ASYNC, ConstructServerResponseHeadersPacket(
9824 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
9825 GetResponseHeaders("200 OK")));
9826
9827 std::string header2 = ConstructDataHeader(6);
9828 mock_quic_data.AddRead(
9829 ASYNC, ConstructServerDataPacket(
9830 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
9831 header2 + "hello!"));
9832
9833 mock_quic_data.AddWrite(
9834 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
9835
9836 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9837 mock_quic_data.AddRead(ASYNC, 0); // EOF
9838 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9839
9840 // The non-alternate protocol job needs to hang in order to guarantee that
9841 // the alternate-protocol job will "win".
9842 AddHangingNonAlternateProtocolSocketData();
9843
9844 CreateSession();
9845 request_.method = "POST";
9846 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9847 request_.upload_data_stream = &upload_data;
9848
9849 SendRequestAndExpectQuicResponse("hello!");
9850}
9851
9852TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadPauseAndResume) {
9853 context_.params()->origins_to_force_quic_on.insert(
9854 HostPortPair::FromString("mail.example.org:443"));
9855
9856 MockQuicData mock_quic_data(version_);
9857 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
9858 int write_packet_index = 1;
9859 mock_quic_data.AddWrite(
9860 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
9861 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
9862 if (VersionUsesHttp3(version_.transport_version)) {
9863 mock_quic_data.AddWrite(
9864 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9865 }
9866 const std::string upload_content = "foo";
9867 if (!version_.HasIetfQuicFrames()) {
9868 mock_quic_data.AddWrite(
9869 SYNCHRONOUS,
9870 ConstructClientRequestHeadersAndDataFramesPacket(
9871 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9872 true, true, DEFAULT_PRIORITY,
9873 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
9874 {upload_content}));
9875 } else {
9876 mock_quic_data.AddWrite(
9877 SYNCHRONOUS,
9878 ConstructClientRequestHeadersAndDataFramesPacket(
9879 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9880 true, true, DEFAULT_PRIORITY,
9881 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
9882 {ConstructDataHeader(upload_content.length()), upload_content}));
9883 }
9884 mock_quic_data.AddRead(
9885 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
9886 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9887 false, GetResponseHeaders("200 OK")));
9888 std::string header2 = ConstructDataHeader(6);
9889 mock_quic_data.AddRead(
9890 SYNCHRONOUS, ConstructServerDataPacket(
9891 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
9892 true, header2 + "hello!"));
9893
9894 mock_quic_data.AddWrite(
9895 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
9896 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9897 mock_quic_data.AddRead(ASYNC, 0); // EOF
9898 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9899 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
9900
9901 CreateSession();
9902
9903 AddQuicAlternateProtocolMapping(
9904 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
9905
9906 // Set up request.
9907 request_.method = "POST";
9908 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
9909 request_.upload_data_stream = &upload_data;
9910
9911 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9912 TestCompletionCallback callback;
9913 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9914 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9915 base::RunLoop().RunUntilIdle();
9916 // Resume QUIC job
9917 crypto_client_stream_factory_.last_stream()
9918 ->NotifySessionOneRttKeyAvailable();
9919 socket_data->Resume();
9920
9921 base::RunLoop().RunUntilIdle();
9922 CheckResponseData(&trans, "hello!");
9923}
9924
9925TEST_P(QuicNetworkTransactionTest, AllowHTTP1UploadFailH1AndResumeQuic) {
9926 // This test confirms failed main job should not bother quic job.
9927 MockRead http_reads[] = {
9928 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
9929 MockRead("1.1 Body"),
9930 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9931 MockRead(ASYNC, OK)};
9932 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
9933 socket_factory_.AddSocketDataProvider(&http_data);
9934 AddCertificate(&ssl_data_);
9935 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9936
9937 MockQuicData mock_quic_data(version_);
9938 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Hanging read
9939 int write_packet_index = 1;
9940 mock_quic_data.AddWrite(
9941 ASYNC, client_maker_->MakeDummyCHLOPacket(write_packet_index++));
9942 client_maker_->SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
9943 if (VersionUsesHttp3(version_.transport_version)) {
9944 mock_quic_data.AddWrite(
9945 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
9946 }
9947 const std::string upload_content = "foo";
9948 if (!version_.HasIetfQuicFrames()) {
9949 mock_quic_data.AddWrite(
9950 SYNCHRONOUS,
9951 ConstructClientRequestHeadersAndDataFramesPacket(
9952 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9953 true, true, DEFAULT_PRIORITY,
9954 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
9955 {upload_content}));
9956 } else {
9957 mock_quic_data.AddWrite(
9958 SYNCHRONOUS,
9959 ConstructClientRequestHeadersAndDataFramesPacket(
9960 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
9961 true, true, DEFAULT_PRIORITY,
9962 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
9963 {ConstructDataHeader(upload_content.length()), upload_content}));
9964 }
9965 mock_quic_data.AddRead(
9966 SYNCHRONOUS, ConstructServerResponseHeadersPacket(
9967 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9968 false, GetResponseHeaders("200 OK")));
9969 std::string header = ConstructDataHeader(6);
9970 mock_quic_data.AddRead(
9971 SYNCHRONOUS, ConstructServerDataPacket(
9972 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
9973 true, header + "hello!"));
9974 mock_quic_data.AddWrite(
9975 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
9976 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9977 mock_quic_data.AddRead(ASYNC, 0); // EOF
9978 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9979 SequencedSocketData* socket_data = mock_quic_data.GetSequencedSocketData();
9980
9981 // This packet won't be read because AllowHTTP1:false doesn't allow H/1
9982 // connection.
9983 MockRead http_reads2[] = {MockRead("HTTP/1.1 200 OK\r\n")};
9984 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
9985 socket_factory_.AddSocketDataProvider(&http_data2);
9986 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9987
9988 CreateSession();
9989
9990 // Send the first request via TCP and set up alternative service (QUIC) for
9991 // the origin.
9992 SendRequestAndExpectHttpResponse("1.1 Body");
9993
9994 // Settings to resume main H/1 job quickly while pausing quic job.
9995 AddQuicAlternateProtocolMapping(
9996 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
9997 ServerNetworkStats stats1;
9998 stats1.srtt = base::TimeDelta::FromMicroseconds(10);
9999 http_server_properties_->SetServerNetworkStats(
10000 url::SchemeHostPort(request_.url), NetworkIsolationKey(), stats1);
10001
10002 // Set up request.
10003 request_.method = "POST";
10004 UploadDataStreamNotAllowHTTP1 upload_data(upload_content);
10005 request_.upload_data_stream = &upload_data;
10006
10007 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
10008 TestCompletionCallback callback;
10009 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
10010 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10011 // Confirm TCP job was resumed.
10012 // We can not check its failure because HttpStreamFactory::JobController.
10013 // main_job_net_error is not exposed.
10014 while (socket_factory_.mock_data().next_index() < 3u)
10015 base::RunLoop().RunUntilIdle();
10016 // Resume QUIC job.
10017 crypto_client_stream_factory_.last_stream()
10018 ->NotifySessionOneRttKeyAvailable();
10019 socket_data->Resume();
10020 base::RunLoop().RunUntilIdle();
10021 CheckResponseData(&trans, "hello!");
10022}
10023
10024// TODO(yoichio): Add the TCP job reuse case. See crrev.com/c/2174099.
10025
[email protected]61a527782013-02-21 03:58:0010026} // namespace test
10027} // namespace net