blob: 3430795f188a9ea8b7c3375c4e79f708e61d5b21 [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"
[email protected]b1c988b2013-06-13 06:48:1141#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0042#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5143#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4644#include "net/log/test_net_log_util.h"
Nicolas Arciniegad2013f92020-02-07 23:00:5645#include "net/proxy_resolution/configured_proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4046#include "net/proxy_resolution/proxy_config_service_fixed.h"
47#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0848#include "net/quic/crypto/proof_verifier_chromium.h"
49#include "net/quic/mock_crypto_client_stream_factory.h"
Victor Vasiliev7752898d2019-11-14 21:30:2250#include "net/quic/mock_quic_context.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0851#include "net/quic/mock_quic_data.h"
52#include "net/quic/quic_chromium_alarm_factory.h"
53#include "net/quic/quic_http_stream.h"
54#include "net/quic/quic_http_utils.h"
55#include "net/quic/quic_stream_factory_peer.h"
56#include "net/quic/quic_test_packet_maker.h"
57#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0058#include "net/socket/client_socket_factory.h"
59#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2160#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2861#include "net/socket/socket_performance_watcher.h"
62#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0063#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5864#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5765#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2966#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0167#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4368#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4069#include "net/test/test_with_task_environment.h"
Zhongyi Shid1c00fc42019-12-14 06:05:0970#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
71#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5172#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
73#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
74#include "net/third_party/quiche/src/quic/core/quic_framer.h"
75#include "net/third_party/quiche/src/quic/core/quic_utils.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5176#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
77#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
78#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
79#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
80#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
81#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1482#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
83#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2984#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0085#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4886#include "net/url_request/url_request.h"
87#include "net/url_request/url_request_job_factory_impl.h"
88#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0189#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0090#include "testing/gtest/include/gtest/gtest.h"
91#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4692#include "url/gurl.h"
Matt Menke3233d8f22019-08-20 21:01:4993#include "url/origin.h"
[email protected]61a527782013-02-21 03:58:0094
Reilly Grant89a7e512018-01-20 01:57:1695using ::testing::ElementsAre;
96using ::testing::Key;
97
bnc508835902015-05-12 20:10:2998namespace net {
99namespace test {
[email protected]61a527782013-02-21 03:58:00100
101namespace {
102
bnc359ed2a2016-04-29 20:43:45103enum DestinationType {
104 // In pooling tests with two requests for different origins to the same
105 // destination, the destination should be
106 SAME_AS_FIRST, // the same as the first origin,
107 SAME_AS_SECOND, // the same as the second origin, or
108 DIFFERENT, // different from both.
109};
110
rchf114d982015-10-21 01:34:56111static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52112 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12113static const char kQuicAlternativeServiceWithProbabilityHeader[] =
114 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56115static const char kQuicAlternativeServiceDifferentPortHeader[] =
116 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20117
rch9ae5b3b2016-02-11 00:36:29118const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45119const char kDifferentHostname[] = "different.example.com";
120
David Schinazi09e9a6012019-10-03 17:37:57121struct TestParams {
122 quic::ParsedQuicVersion version;
123 bool client_headers_include_h2_stream_dependency;
124};
125
126// Used by ::testing::PrintToStringParamName().
127std::string PrintToString(const TestParams& p) {
Zhongyi Shid1c00fc42019-12-14 06:05:09128 return quiche::QuicheStrCat(
David Schinazi09e9a6012019-10-03 17:37:57129 ParsedQuicVersionToString(p.version), "_",
130 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
131 "Dependency");
132}
133
bnc359ed2a2016-04-29 20:43:45134// Run QuicNetworkTransactionWithDestinationTest instances with all value
135// combinations of version and destination_type.
136struct PoolingTestParams {
Nick Harper23290b82019-05-02 00:02:56137 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45138 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05139 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45140};
141
David Schinazi09e9a6012019-10-03 17:37:57142// Used by ::testing::PrintToStringParamName().
143std::string PrintToString(const PoolingTestParams& p) {
144 const char* destination_string = "";
145 switch (p.destination_type) {
146 case SAME_AS_FIRST:
147 destination_string = "SAME_AS_FIRST";
148 break;
149 case SAME_AS_SECOND:
150 destination_string = "SAME_AS_SECOND";
151 break;
152 case DIFFERENT:
153 destination_string = "DIFFERENT";
154 break;
155 }
Zhongyi Shid1c00fc42019-12-14 06:05:09156 return quiche::QuicheStrCat(
David Schinazi09e9a6012019-10-03 17:37:57157 ParsedQuicVersionToString(p.version), "_", destination_string, "_",
158 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
159 "Dependency");
160}
161
Bence Békyb89104962020-01-24 00:05:17162std::string GenerateQuicAltSvcHeader() {
163 std::string altsvc_header = "Alt-Svc: ";
164 std::string version_string;
165 for (const auto& version : quic::AllSupportedVersions()) {
166 if (version.handshake_protocol == quic::PROTOCOL_TLS1_3) {
167 altsvc_header.append(quic::AlpnForVersion(version));
168 altsvc_header.append("=\":443\", ");
169 } else {
170 if (!version_string.empty()) {
171 version_string.append(",");
172 }
173 version_string.append(base::NumberToString(version.transport_version));
174 }
zhongyie537a002017-06-27 16:48:21175 }
Bence Békyb89104962020-01-24 00:05:17176 altsvc_header.append("quic=\":443\"; v=\"");
177 altsvc_header.append(version_string);
178 altsvc_header.append("\"\r\n");
179
180 return altsvc_header;
zhongyie537a002017-06-27 16:48:21181}
182
David Schinazi09e9a6012019-10-03 17:37:57183std::vector<TestParams> GetTestParams() {
184 std::vector<TestParams> params;
185 quic::ParsedQuicVersionVector all_supported_versions =
186 quic::AllSupportedVersions();
187 for (const quic::ParsedQuicVersion version : all_supported_versions) {
Renjie Tang3d8a6ddd2019-11-20 00:18:43188 params.push_back(TestParams{version, false});
189 params.push_back(TestParams{version, true});
David Schinazi09e9a6012019-10-03 17:37:57190 }
191 return params;
192}
193
bnc359ed2a2016-04-29 20:43:45194std::vector<PoolingTestParams> GetPoolingTestParams() {
195 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56196 quic::ParsedQuicVersionVector all_supported_versions =
Ryan Hamilton93424eb82019-08-23 04:28:40197 quic::AllSupportedVersions();
Nick Harper23290b82019-05-02 00:02:56198 for (const quic::ParsedQuicVersion version : all_supported_versions) {
Renjie Tang3d8a6ddd2019-11-20 00:18:43199 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
200 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
201 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
202 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
203 params.push_back(PoolingTestParams{version, DIFFERENT, false});
204 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45205 }
206 return params;
207}
bncb07c05532015-05-14 19:07:20208
[email protected]61a527782013-02-21 03:58:00209} // namespace
210
ryansturm49a8cb12016-06-15 16:51:09211class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12212 public:
ryansturm49a8cb12016-06-15 16:51:09213 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12214
ryansturm49a8cb12016-06-15 16:51:09215 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12216
ryansturm49a8cb12016-06-15 16:51:09217 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
218 HttpRequestHeaders* request_headers) {
219 if (!proxy_info.is_http() && !proxy_info.is_https() &&
220 !proxy_info.is_quic()) {
221 return;
222 }
223 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12224 }
225
226 private:
ryansturm49a8cb12016-06-15 16:51:09227 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12228};
229
tbansal0f56a39a2016-04-07 22:03:38230class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40231 public:
tbansal180587c2017-02-16 15:13:23232 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
233 bool* rtt_notification_received)
234 : should_notify_updated_rtt_(should_notify_updated_rtt),
235 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38236 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40237
tbansal180587c2017-02-16 15:13:23238 bool ShouldNotifyUpdatedRTT() const override {
239 return *should_notify_updated_rtt_;
240 }
tbansalfdf5665b2015-09-21 22:46:40241
tbansal0f56a39a2016-04-07 22:03:38242 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
243 *rtt_notification_received_ = true;
244 }
245
246 void OnConnectionChanged() override {}
247
248 private:
tbansal180587c2017-02-16 15:13:23249 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38250 bool* rtt_notification_received_;
251
252 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
253};
254
255class TestSocketPerformanceWatcherFactory
256 : public SocketPerformanceWatcherFactory {
257 public:
258 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23259 : watcher_count_(0u),
260 should_notify_updated_rtt_(true),
261 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38262 ~TestSocketPerformanceWatcherFactory() override {}
263
264 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42265 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41266 const Protocol protocol,
267 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51268 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38269 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51270 }
271 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42272 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23273 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
274 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40275 }
276
tbansalc8a94ea2015-11-02 23:58:51277 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40278
tbansalc8a94ea2015-11-02 23:58:51279 bool rtt_notification_received() const { return rtt_notification_received_; }
280
tbansal180587c2017-02-16 15:13:23281 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
282 should_notify_updated_rtt_ = should_notify_updated_rtt;
283 }
284
tbansalc8a94ea2015-11-02 23:58:51285 private:
tbansal0f56a39a2016-04-07 22:03:38286 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23287 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51288 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38289
290 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51291};
292
Ryan Hamilton8d9ee76e2018-05-29 23:52:52293class QuicNetworkTransactionTest
294 : public PlatformTest,
David Schinazi09e9a6012019-10-03 17:37:57295 public ::testing::WithParamInterface<TestParams>,
Gabriel Charette694c3c332019-08-19 14:53:05296 public WithTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00297 protected:
[email protected]1c04f9522013-02-21 20:32:43298 QuicNetworkTransactionTest()
David Schinazi09e9a6012019-10-03 17:37:57299 : version_(GetParam().version),
300 client_headers_include_h2_stream_dependency_(
301 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:56302 supported_versions_(quic::test::SupportedVersions(version_)),
Victor Vasiliev7752898d2019-11-14 21:30:22303 client_maker_(version_,
304 quic::QuicUtils::CreateRandomConnectionId(
305 context_.random_generator()),
306 context_.clock(),
307 kDefaultServerHostName,
308 quic::Perspective::IS_CLIENT,
309 client_headers_include_h2_stream_dependency_),
310 server_maker_(version_,
311 quic::QuicUtils::CreateRandomConnectionId(
312 context_.random_generator()),
313 context_.clock(),
314 kDefaultServerHostName,
315 quic::Perspective::IS_SERVER,
316 false),
317 quic_task_runner_(new TestTaskRunner(context_.mock_clock())),
rtenneti052774e2015-11-24 21:00:12318 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43319 ssl_config_service_(new SSLConfigServiceDefaults),
Nicolas Arciniegad2013f92020-02-07 23:00:56320 proxy_resolution_service_(
321 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11322 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke3233d8f22019-08-20 21:01:49323 http_server_properties_(std::make_unique<HttpServerProperties>()),
rchf114d982015-10-21 01:34:56324 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:19325 FLAGS_quic_enable_http3_grease_randomness = false;
[email protected]aa9b14d2013-05-10 23:45:19326 request_.method = "GET";
rchf114d982015-10-21 01:34:56327 std::string url("https://");
bncb07c05532015-05-14 19:07:20328 url.append(kDefaultServerHostName);
329 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19330 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10331 request_.traffic_annotation =
332 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Victor Vasiliev7752898d2019-11-14 21:30:22333 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56334
335 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29336 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56337 verify_details_.cert_verify_result.verified_cert = cert;
338 verify_details_.cert_verify_result.is_issued_by_known_root = true;
339 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43340 }
[email protected]61a527782013-02-21 03:58:00341
dcheng67be2b1f2014-10-27 21:47:29342 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00343 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55344 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00345 }
346
dcheng67be2b1f2014-10-27 21:47:29347 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00348 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
349 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55350 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00351 PlatformTest::TearDown();
352 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55353 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40354 session_.reset();
[email protected]61a527782013-02-21 03:58:00355 }
356
Ryan Hamilton8d9ee76e2018-05-29 23:52:52357 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23358 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03359 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52360 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30361 }
362
Ryan Hamilton8d9ee76e2018-05-29 23:52:52363 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23364 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03365 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52366 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58367 }
368
Ryan Hamilton8d9ee76e2018-05-29 23:52:52369 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23370 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52371 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20372 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58373 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20374 }
375
Ryan Hamilton8d9ee76e2018-05-29 23:52:52376 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23377 uint64_t packet_number,
378 uint64_t largest_received,
379 uint64_t smallest_received,
380 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37381 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49382 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37383 }
384
Ryan Hamilton8d9ee76e2018-05-29 23:52:52385 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23386 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52387 quic::QuicStreamId stream_id,
388 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23389 uint64_t largest_received,
390 uint64_t smallest_received,
391 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58392 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49393 num, false, stream_id, error_code, largest_received, smallest_received,
394 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20395 }
396
Ryan Hamilton8d9ee76e2018-05-29 23:52:52397 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23398 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52399 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41400 quic::QuicRstStreamErrorCode error_code) {
Yixin Wang46a273ec302018-01-23 17:59:56401 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18402 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56403 }
404
Ryan Hamilton8d9ee76e2018-05-29 23:52:52405 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23406 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
407 uint64_t largest_received,
408 uint64_t smallest_received,
409 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58410 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49411 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20412 }
[email protected]61a527782013-02-21 03:58:00413
Ryan Hamilton8d9ee76e2018-05-29 23:52:52414 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58415 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23416 uint64_t num,
Fan Yangac867502019-01-28 21:10:23417 uint64_t largest_received,
418 uint64_t smallest_received,
419 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52420 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29421 const std::string& quic_error_details,
422 uint64_t frame_type) {
alyssar2adf3ac2016-05-03 17:12:58423 return client_maker_.MakeAckAndConnectionClosePacket(
Bence Békyde6290f2019-12-19 15:21:53424 num, false, largest_received, smallest_received, least_unacked,
425 quic_error, quic_error_details, frame_type);
zhongyica364fbb2015-12-12 03:39:12426 }
427
Ryan Hamilton8d9ee76e2018-05-29 23:52:52428 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23429 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12430 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52431 quic::QuicStreamId stream_id,
432 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58433 return server_maker_.MakeRstPacket(num, include_version, stream_id,
434 error_code);
zhongyica364fbb2015-12-12 03:39:12435 }
436
Ryan Hamilton8d9ee76e2018-05-29 23:52:52437 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02438 uint64_t packet_number) {
439 return client_maker_.MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37440 }
441
Ryan Hamilton8d9ee76e2018-05-29 23:52:52442 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23443 uint64_t packet_number,
444 uint64_t largest_received,
445 uint64_t smallest_received,
446 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37447 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49448 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37449 }
450
Ryan Hamilton8d9ee76e2018-05-29 23:52:52451 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23452 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57453 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52454 quic::QuicStreamId id,
455 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02456 RequestPriority request_priority) {
Yixin Wangb470bc882018-02-15 18:43:57457 return client_maker_.MakePriorityPacket(
458 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02459 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wang385652a2018-02-16 02:37:23460 }
461
Ryan Hamilton8d9ee76e2018-05-29 23:52:52462 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) {
Yixin Wange7ecc472018-03-06 19:00:25471 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
zhongyi32569c62016-01-08 02:54:30476 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13477 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
478 const std::string& scheme,
479 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58480 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30481 }
482
483 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13484 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
485 const std::string& scheme,
486 const std::string& path,
487 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50488 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00489 }
490
Ryan Hamilton0239aac2018-05-19 00:03:13491 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56492 return client_maker_.ConnectRequestHeaders(host_port);
493 }
494
Ryan Hamilton0239aac2018-05-19 00:03:13495 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58496 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00497 }
498
zhongyi32569c62016-01-08 02:54:30499 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13500 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
501 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58502 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30503 }
504
Ryan Hamilton8d9ee76e2018-05-29 23:52:52505 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23506 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52507 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05508 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00509 bool fin,
Zhongyi Shid1c00fc42019-12-14 06:05:09510 quiche::QuicheStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17511 return server_maker_.MakeDataPacket(packet_number, stream_id,
512 should_include_version, fin, data);
[email protected]61a527782013-02-21 03:58:00513 }
514
Ryan Hamilton8d9ee76e2018-05-29 23:52:52515 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23516 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52517 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36518 bool should_include_version,
519 bool fin,
Zhongyi Shid1c00fc42019-12-14 06:05:09520 quiche::QuicheStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17521 return client_maker_.MakeDataPacket(packet_number, stream_id,
522 should_include_version, fin, data);
ckrasicda193a82016-07-09 00:39:36523 }
524
Ryan Hamilton8d9ee76e2018-05-29 23:52:52525 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23526 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56527 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52528 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23529 uint64_t largest_received,
530 uint64_t smallest_received,
531 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56532 bool fin,
Zhongyi Shid1c00fc42019-12-14 06:05:09533 quiche::QuicheStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56534 return client_maker_.MakeAckAndDataPacket(
535 packet_number, include_version, stream_id, largest_received,
Ryan Hamilton7505eb92019-06-08 00:22:17536 smallest_received, least_unacked, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56537 }
538
Ryan Hamilton8d9ee76e2018-05-29 23:52:52539 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23540 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52541 quic::QuicStreamId stream_id,
542 bool should_include_version,
543 bool fin,
544 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56545 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
546 should_include_version, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02547 std::move(headers), 0);
Yixin Wang46a273ec302018-01-23 17:59:56548 }
549
Ryan Hamilton8d9ee76e2018-05-29 23:52:52550 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23551 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52552 quic::QuicStreamId stream_id,
553 bool should_include_version,
554 bool fin,
555 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02556 quic::QuicStreamId parent_stream_id) {
Yixin Wang46a273ec302018-01-23 17:59:56557 return ConstructClientRequestHeadersPacket(
558 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:02559 std::move(headers), parent_stream_id);
zhongyi32569c62016-01-08 02:54:30560 }
561
Ryan Hamilton8d9ee76e2018-05-29 23:52:52562 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23563 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52564 quic::QuicStreamId stream_id,
565 bool should_include_version,
566 bool fin,
567 RequestPriority request_priority,
568 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02569 quic::QuicStreamId parent_stream_id) {
Ryan Hamilton0239aac2018-05-19 00:03:13570 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56571 ConvertRequestPriorityToQuicPriority(request_priority);
Ryan Hamilton0d65a8c2019-06-07 00:46:02572 return client_maker_.MakeRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56573 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02574 std::move(headers), parent_stream_id, nullptr);
[email protected]61a527782013-02-21 03:58:00575 }
576
Ryan Hamilton8d9ee76e2018-05-29 23:52:52577 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25578 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23579 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52580 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25581 bool should_include_version,
582 bool fin,
583 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13584 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52585 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25586 size_t* spdy_headers_frame_length,
587 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13588 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25589 ConvertRequestPriorityToQuicPriority(request_priority);
590 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
591 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02592 std::move(headers), parent_stream_id, spdy_headers_frame_length,
Yixin Wange7ecc472018-03-06 19:00:25593 data_writes);
594 }
595
Ryan Hamilton8d9ee76e2018-05-29 23:52:52596 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23597 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52598 quic::QuicStreamId stream_id,
599 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13600 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13601 spdy::SpdyHeaderBlock headers,
ckrasic769733c2016-06-30 00:42:13602 QuicTestPacketMaker* maker) {
603 return maker->MakePushPromisePacket(
604 packet_number, stream_id, promised_stream_id, should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02605 false, std::move(headers), nullptr);
ckrasic769733c2016-06-30 00:42:13606 }
607
Ryan Hamilton8d9ee76e2018-05-29 23:52:52608 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23609 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52610 quic::QuicStreamId stream_id,
611 bool should_include_version,
612 bool fin,
613 spdy::SpdyHeaderBlock headers) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02614 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
615 should_include_version, fin,
616 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30617 }
618
Victor Vasiliev076657c2019-03-12 02:46:43619 std::string ConstructDataHeader(size_t body_len) {
Nick Harper23290b82019-05-02 00:02:56620 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:41621 return "";
622 }
Renjief49758b2019-01-11 23:32:41623 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:57624 auto header_length =
625 quic::HttpEncoder::SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43626 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41627 }
628
Nick Harper23290b82019-05-02 00:02:56629 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41630 session_params_.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:38631 context_.params()->supported_versions = supported_versions;
Victor Vasilieva1e66d72019-12-05 17:55:38632 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:05633 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00634
Victor Vasiliev7752898d2019-11-14 21:30:22635 session_context_.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:41636 session_context_.client_socket_factory = &socket_factory_;
637 session_context_.quic_crypto_client_stream_factory =
638 &crypto_client_stream_factory_;
639 session_context_.host_resolver = &host_resolver_;
640 session_context_.cert_verifier = &cert_verifier_;
641 session_context_.transport_security_state = &transport_security_state_;
642 session_context_.cert_transparency_verifier =
643 cert_transparency_verifier_.get();
644 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
645 session_context_.socket_performance_watcher_factory =
646 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59647 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41648 session_context_.ssl_config_service = ssl_config_service_.get();
649 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49650 session_context_.http_server_properties = http_server_properties_.get();
mmenke6ddfbea2017-05-31 21:48:41651 session_context_.net_log = net_log_.bound().net_log();
652
653 session_.reset(new HttpNetworkSession(session_params_, session_context_));
Matt Menkeb566c392019-09-11 23:22:43654 session_->quic_stream_factory()
655 ->set_is_quic_known_to_work_on_current_network(true);
Yixin Wang46a273ec302018-01-23 17:59:56656 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
657 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00658 }
659
zhongyi86838d52017-06-30 01:19:44660 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21661
David Schinazif832cb82019-11-08 22:25:27662 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
663 const std::string& status_line) {
[email protected]aa9b14d2013-05-10 23:45:19664 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42665 ASSERT_TRUE(response != nullptr);
666 ASSERT_TRUE(response->headers.get() != nullptr);
David Schinazif832cb82019-11-08 22:25:27667 EXPECT_EQ(status_line, response->headers->GetStatusLine());
[email protected]aa9b14d2013-05-10 23:45:19668 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52669 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:08670 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19671 response->connection_info);
672 }
673
David Schinazif832cb82019-11-08 22:25:27674 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
675 CheckWasQuicResponse(trans, "HTTP/1.1 200 OK");
676 }
677
bnc691fda62016-08-12 00:43:16678 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41679 const HttpResponseInfo* response = trans->GetResponseInfo();
680 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37681 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41682 }
683
bnc691fda62016-08-12 00:43:16684 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19685 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42686 ASSERT_TRUE(response != nullptr);
687 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19688 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
689 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52690 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52691 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19692 response->connection_info);
693 }
694
Yixin Wang46a273ec302018-01-23 17:59:56695 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
696 const HttpResponseInfo* response = trans->GetResponseInfo();
697 ASSERT_TRUE(response != nullptr);
698 ASSERT_TRUE(response->headers.get() != nullptr);
699 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
700 EXPECT_TRUE(response->was_fetched_via_spdy);
701 EXPECT_TRUE(response->was_alpn_negotiated);
702 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
703 response->connection_info);
704 }
705
bnc691fda62016-08-12 00:43:16706 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19707 const std::string& expected) {
708 std::string response_data;
bnc691fda62016-08-12 00:43:16709 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19710 EXPECT_EQ(expected, response_data);
711 }
712
bnc691fda62016-08-12 00:43:16713 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19714 TestCompletionCallback callback;
715 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
717 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19718 }
719
720 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16721 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
722 RunTransaction(&trans);
723 CheckWasHttpResponse(&trans);
724 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19725 }
726
tbansalc3308d72016-08-27 10:25:04727 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
728 bool used_proxy,
729 uint16_t port) {
730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
731 HeadersHandler headers_handler;
732 trans.SetBeforeHeadersSentCallback(
733 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
734 base::Unretained(&headers_handler)));
735 RunTransaction(&trans);
736 CheckWasHttpResponse(&trans);
737 CheckResponsePort(&trans, port);
738 CheckResponseData(&trans, expected);
739 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47740 if (used_proxy) {
741 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
742 } else {
743 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
744 }
tbansalc3308d72016-08-27 10:25:04745 }
David Schinazif832cb82019-11-08 22:25:27746 void SendRequestAndExpectQuicResponse(const std::string& expected,
747 const std::string& status_line) {
748 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443,
749 status_line);
750 }
tbansalc3308d72016-08-27 10:25:04751
[email protected]aa9b14d2013-05-10 23:45:19752 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56753 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12754 }
755
bnc62a44f022015-04-02 15:59:41756 void SendRequestAndExpectQuicResponseFromProxyOnPort(
757 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46758 uint16_t port) {
bnc62a44f022015-04-02 15:59:41759 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19760 }
761
762 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05763 MockCryptoClientStream::HandshakeMode handshake_mode,
764 const NetworkIsolationKey& network_isolation_key =
765 NetworkIsolationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19766 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46767 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21768 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12769 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49770 http_server_properties_->SetQuicAlternativeService(
Matt Menkeb32ba5122019-09-10 19:17:05771 server, network_isolation_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07772 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19773 }
774
rchbe69cb902016-02-11 01:10:48775 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27776 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48777 const HostPortPair& alternative) {
778 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46779 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21780 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48781 alternative.port());
782 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49783 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07784 server, NetworkIsolationKey(), alternative_service, expiration,
785 supported_versions_);
rchbe69cb902016-02-11 01:10:48786 }
787
Matt Menkeb32ba5122019-09-10 19:17:05788 void ExpectBrokenAlternateProtocolMapping(
789 const NetworkIsolationKey& network_isolation_key =
790 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46791 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34792 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49793 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05794 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34795 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49796 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05797 alternative_service_info_vector[0].alternative_service(),
798 network_isolation_key));
[email protected]aa9b14d2013-05-10 23:45:19799 }
800
Matt Menkeb32ba5122019-09-10 19:17:05801 void ExpectQuicAlternateProtocolMapping(
802 const NetworkIsolationKey& network_isolation_key =
803 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46804 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34805 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49806 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05807 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34808 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54809 EXPECT_EQ(
810 kProtoQUIC,
811 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49812 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05813 alternative_service_info_vector[0].alternative_service(),
814 network_isolation_key));
[email protected]4d590c9c2014-05-02 05:14:33815 }
816
[email protected]aa9b14d2013-05-10 23:45:19817 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42818 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30819 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30820 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30821 hanging_data->set_connect_data(hanging_connect);
822 hanging_data_.push_back(std::move(hanging_data));
823 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56824 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19825 }
826
Zhongyi Shia6b68d112018-09-24 07:49:03827 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Victor Vasilieva1e66d72019-12-05 17:55:38828 context_.params()->migrate_sessions_on_network_change_v2 = true;
829 context_.params()->migrate_sessions_early_v2 = true;
830 context_.params()->retry_on_alternate_network_before_handshake = true;
Zhongyi Shia6b68d112018-09-24 07:49:03831 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
832 MockNetworkChangeNotifier* mock_ncn =
833 scoped_mock_change_notifier_->mock_network_change_notifier();
834 mock_ncn->ForceNetworkHandlesSupported();
835 mock_ncn->SetConnectedNetworksList(
836 {kDefaultNetworkForTests, kNewNetworkForTests});
837 }
838
tbansalc3308d72016-08-27 10:25:04839 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
840 // alternative proxy. Verifies that if the alternative proxy job returns
841 // |error_code|, the request is fetched successfully by the main job.
842 void TestAlternativeProxy(int error_code) {
843 // Use a non-cryptographic scheme for the request URL since this request
844 // will be fetched via proxy with QUIC as the alternative service.
845 request_.url = GURL("http://example.org/");
846 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27847 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04848 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27849 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04850 };
851
Ryan Sleevib8d7ea02018-05-07 20:01:01852 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04853 socket_factory_.AddSocketDataProvider(&quic_data);
854
855 // Main job succeeds and the alternative job fails.
856 // Add data for two requests that will be read by the main job.
857 MockRead http_reads_1[] = {
858 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
859 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
860 MockRead(ASYNC, OK)};
861
862 MockRead http_reads_2[] = {
863 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
864 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
865 MockRead(ASYNC, OK)};
866
Ryan Sleevib8d7ea02018-05-07 20:01:01867 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
868 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04869 socket_factory_.AddSocketDataProvider(&http_data_1);
870 socket_factory_.AddSocketDataProvider(&http_data_2);
871 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
872 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
873
874 TestProxyDelegate test_proxy_delegate;
875 // Proxy URL is different from the request URL.
876 test_proxy_delegate.set_alternative_proxy_server(
877 ProxyServer::FromPacString("QUIC myproxy.org:443"));
878
Lily Houghton8c2f97d2018-01-22 05:06:59879 proxy_resolution_service_ =
Nicolas Arciniegad2013f92020-02-07 23:00:56880 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49881 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52882 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04883
884 CreateSession();
885 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
886
887 // The first request should be fetched via the HTTPS proxy.
888 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
889
Reilly Grant89a7e512018-01-20 01:57:16890 // Since the main job succeeded only the alternative proxy server should be
891 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59892 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16893 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04894
895 // Verify that the second request completes successfully, and the
896 // alternative proxy server job is not started.
897 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
898 }
899
Matt Menkeb32ba5122019-09-10 19:17:05900 // Adds a new socket data provider for an HTTP request, and runs a request,
901 // expecting it to be used.
902 void AddHttpDataAndRunRequest() {
903 MockWrite http_writes[] = {
904 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
905 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
906 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
907
908 MockRead http_reads[] = {
909 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
910 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
911 MockRead(SYNCHRONOUS, 5, "http used"),
912 // Connection closed.
913 MockRead(SYNCHRONOUS, OK, 6)};
914 SequencedSocketData http_data(http_reads, http_writes);
915 socket_factory_.AddSocketDataProvider(&http_data);
916 SSLSocketDataProvider ssl_data(ASYNC, OK);
917 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
918 SendRequestAndExpectHttpResponse("http used");
919 EXPECT_TRUE(http_data.AllWriteDataConsumed());
920 EXPECT_TRUE(http_data.AllReadDataConsumed());
921 }
922
923 // Adds a new socket data provider for a QUIC request, and runs a request,
924 // expecting it to be used. The new QUIC session is not closed.
925 void AddQuicDataAndRunRequest() {
926 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22927 version_,
928 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
929 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menkeb32ba5122019-09-10 19:17:05930 client_headers_include_h2_stream_dependency_);
931 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22932 version_,
933 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
934 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
935 false);
Matt Menkeb32ba5122019-09-10 19:17:05936 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56937 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05938 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:25939 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:56940 quic_data.AddWrite(
941 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_number++));
942 }
Matt Menkeb32ba5122019-09-10 19:17:05943 quic_data.AddWrite(
944 SYNCHRONOUS,
945 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56946 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
947 true, true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Matt Menkeb32ba5122019-09-10 19:17:05948 GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
949 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
950 quic_data.AddRead(
951 ASYNC, server_maker.MakeResponseHeadersPacket(
952 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
953 false, server_maker.GetResponseHeaders("200 OK"), nullptr));
954 std::string header = ConstructDataHeader(9);
955 quic_data.AddRead(
956 ASYNC, server_maker.MakeDataPacket(
957 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
958 true, header + "quic used"));
959 // Don't care about the final ack.
960 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
961 // No more data to read.
962 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
963 quic_data.AddSocketDataToFactory(&socket_factory_);
964 SendRequestAndExpectQuicResponse("quic used");
965
966 EXPECT_TRUE(quic_data.AllReadDataConsumed());
967 }
968
Bence Béky6e243aa2019-12-13 19:01:07969 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56970 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
971 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36972 }
973
Bence Béky6e243aa2019-12-13 19:01:07974 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56975 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
976 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36977 }
978
Bence Béky6e243aa2019-12-13 19:01:07979 quic::QuicStreamId GetQpackDecoderStreamId() const {
980 return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
981 version_.transport_version, 1);
982 }
983
984 std::string StreamCancellationQpackDecoderInstruction(int n) const {
985 const quic::QuicStreamId cancelled_stream_id =
986 GetNthClientInitiatedBidirectionalStreamId(n);
987 EXPECT_LT(cancelled_stream_id, 63u);
988
989 const unsigned char opcode = 0x40;
990 return {opcode | static_cast<unsigned char>(cancelled_stream_id)};
991 }
992
Bence Béky230ac612017-08-30 19:17:08993 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49994 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08995 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49996 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08997 }
998
Nick Harper23290b82019-05-02 00:02:56999 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:051000 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:561001 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:011002 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Victor Vasiliev7752898d2019-11-14 21:30:221003 MockQuicContext context_;
alyssar2adf3ac2016-05-03 17:12:581004 QuicTestPacketMaker client_maker_;
1005 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:091006 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:421007 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:001008 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:561009 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:051010 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:431011 MockHostResolver host_resolver_;
1012 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:111013 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:421014 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:231015 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:381016 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:071017 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniegad2013f92020-02-07 23:00:561018 std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:421019 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:491020 std::unique_ptr<HttpServerProperties> http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:411021 HttpNetworkSession::Params session_params_;
1022 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:191023 HttpRequestInfo request_;
Matt Muellerd9342e3a2019-11-26 01:41:141024 RecordingBoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:421025 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:561026 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:031027 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:121028
1029 private:
1030 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1031 const std::string& expected,
bnc62a44f022015-04-02 15:59:411032 bool used_proxy,
David Schinazif832cb82019-11-08 22:25:271033 uint16_t port,
1034 const std::string& status_line) {
bnc691fda62016-08-12 00:43:161035 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:091036 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:161037 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091038 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
1039 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:161040 RunTransaction(&trans);
David Schinazif832cb82019-11-08 22:25:271041 CheckWasQuicResponse(&trans, status_line);
bnc691fda62016-08-12 00:43:161042 CheckResponsePort(&trans, port);
1043 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:091044 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:471045 if (used_proxy) {
1046 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
1047 } else {
1048 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1049 }
tbansal7cec3812015-02-05 21:25:121050 }
David Schinazif832cb82019-11-08 22:25:271051
1052 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1053 const std::string& expected,
1054 bool used_proxy,
1055 uint16_t port) {
1056 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
1057 "HTTP/1.1 200 OK");
1058 }
[email protected]61a527782013-02-21 03:58:001059};
1060
David Schinazi09e9a6012019-10-03 17:37:571061INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1062 QuicNetworkTransactionTest,
1063 ::testing::ValuesIn(GetTestParams()),
1064 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201065
Shivani Sharma8ae506c2019-07-21 21:08:271066// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
1067// kAppendInitiatingFrameOriginToNetworkIsolationKey.
1068
Ryan Hamiltona64a5bcf2017-11-30 07:35:281069TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:381070 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281071 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381072 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281073 HostPortPair::FromString("mail.example.org:443"));
1074 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271075 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281076
Ryan Hamiltonabad59e2019-06-06 04:02:591077 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251078 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231079 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281080 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1081 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1082 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1083
1084 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1085
1086 CreateSession();
1087
1088 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1089 TestCompletionCallback callback;
1090 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1091 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1092 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1093
1094 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1095 -ERR_INTERNET_DISCONNECTED, 1);
1096 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1097 -ERR_INTERNET_DISCONNECTED, 1);
1098}
1099
1100TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Victor Vasilieva1e66d72019-12-05 17:55:381101 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281102 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381103 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281104 HostPortPair::FromString("mail.example.org:443"));
1105 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271106 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281107
Ryan Hamiltonabad59e2019-06-06 04:02:591108 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251109 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231110 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281111 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1112 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1113 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1114
1115 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1116
1117 CreateSession();
1118
1119 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1120 TestCompletionCallback callback;
1121 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1122 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1123 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1124
1125 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1126 -ERR_INTERNET_DISCONNECTED, 1);
1127 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1128 -ERR_INTERNET_DISCONNECTED, 1);
1129}
1130
tbansal180587c2017-02-16 15:13:231131TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381132 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231133 HostPortPair::FromString("mail.example.org:443"));
1134
Ryan Hamiltonabad59e2019-06-06 04:02:591135 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231136 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251137 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231138 mock_quic_data.AddWrite(SYNCHRONOUS,
1139 ConstructInitialSettingsPacket(packet_num++));
1140 }
rch5cb522462017-04-25 20:18:361141 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231142 SYNCHRONOUS,
1143 ConstructClientRequestHeadersPacket(
1144 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1145 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431146 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331147 ASYNC, ConstructServerResponseHeadersPacket(
1148 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1149 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431150 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331151 mock_quic_data.AddRead(
1152 ASYNC, ConstructServerDataPacket(
1153 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171154 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231155 mock_quic_data.AddWrite(SYNCHRONOUS,
1156 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231157 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1158
1159 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1160
1161 CreateSession();
1162 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1163
1164 EXPECT_FALSE(
1165 test_socket_performance_watcher_factory_.rtt_notification_received());
1166 SendRequestAndExpectQuicResponse("hello!");
1167 EXPECT_TRUE(
1168 test_socket_performance_watcher_factory_.rtt_notification_received());
1169}
1170
1171TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381172 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231173 HostPortPair::FromString("mail.example.org:443"));
1174
Ryan Hamiltonabad59e2019-06-06 04:02:591175 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231176 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251177 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231178 mock_quic_data.AddWrite(SYNCHRONOUS,
1179 ConstructInitialSettingsPacket(packet_num++));
1180 }
rch5cb522462017-04-25 20:18:361181 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231182 SYNCHRONOUS,
1183 ConstructClientRequestHeadersPacket(
1184 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1185 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431186 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331187 ASYNC, ConstructServerResponseHeadersPacket(
1188 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1189 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431190 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331191 mock_quic_data.AddRead(
1192 ASYNC, ConstructServerDataPacket(
1193 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171194 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231195 mock_quic_data.AddWrite(SYNCHRONOUS,
1196 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231197 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1198
1199 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1200
1201 CreateSession();
1202 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1203
1204 EXPECT_FALSE(
1205 test_socket_performance_watcher_factory_.rtt_notification_received());
1206 SendRequestAndExpectQuicResponse("hello!");
1207 EXPECT_FALSE(
1208 test_socket_performance_watcher_factory_.rtt_notification_received());
1209}
1210
[email protected]1e960032013-12-20 19:00:201211TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:381212 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571213 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471214
Ryan Hamiltonabad59e2019-06-06 04:02:591215 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231216 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251217 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231218 mock_quic_data.AddWrite(SYNCHRONOUS,
1219 ConstructInitialSettingsPacket(packet_num++));
1220 }
rch5cb522462017-04-25 20:18:361221 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231222 SYNCHRONOUS,
1223 ConstructClientRequestHeadersPacket(
1224 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1225 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431226 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331227 ASYNC, ConstructServerResponseHeadersPacket(
1228 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1229 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431230 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331231 mock_quic_data.AddRead(
1232 ASYNC, ConstructServerDataPacket(
1233 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171234 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231235 mock_quic_data.AddWrite(SYNCHRONOUS,
1236 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591237 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471238
rcha5399e02015-04-21 19:32:041239 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471240
[email protected]4dca587c2013-03-07 16:54:471241 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471242
[email protected]aa9b14d2013-05-10 23:45:191243 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471244
[email protected]98b20ce2013-05-10 05:55:261245 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:541246 auto entries = net_log_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261247 EXPECT_LT(0u, entries.size());
1248
1249 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291250 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001251 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1252 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261253 EXPECT_LT(0, pos);
1254
rchfd527212015-08-25 00:41:261255 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291256 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261257 entries, 0,
mikecirone8b85c432016-09-08 19:11:001258 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1259 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261260 EXPECT_LT(0, pos);
1261
Eric Roman79cc7552019-07-19 02:17:541262 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261263
rchfd527212015-08-25 00:41:261264 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1265 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001266 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1267 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261268 EXPECT_LT(0, pos);
1269
[email protected]98b20ce2013-05-10 05:55:261270 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291271 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001272 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1273 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261274 EXPECT_LT(0, pos);
1275
Eric Roman79cc7552019-07-19 02:17:541276 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Victor Vasiliev7da08172019-10-14 06:04:251277 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451278 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1279 static_cast<quic::QuicStreamId>(log_stream_id));
1280 } else {
1281 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1282 static_cast<quic::QuicStreamId>(log_stream_id));
1283 }
[email protected]4dca587c2013-03-07 16:54:471284}
1285
Bence Békyb6300042020-01-28 21:18:201286// Regression test for https://crbug.com/1043531.
1287TEST_P(QuicNetworkTransactionTest, ResetOnEmptyResponseHeaders) {
1288 if (!quic::VersionUsesHttp3(version_.transport_version)) {
1289 return;
1290 }
1291
1292 context_.params()->origins_to_force_quic_on.insert(
1293 HostPortPair::FromString("mail.example.org:443"));
1294
1295 MockQuicData mock_quic_data(version_);
1296 int write_packet_num = 1;
1297 mock_quic_data.AddWrite(SYNCHRONOUS,
1298 ConstructInitialSettingsPacket(write_packet_num++));
1299 mock_quic_data.AddWrite(
1300 SYNCHRONOUS,
1301 ConstructClientRequestHeadersPacket(
1302 write_packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1303 true, true, GetRequestHeaders("GET", "https", "/")));
1304
1305 const quic::QuicStreamId request_stream_id =
1306 GetNthClientInitiatedBidirectionalStreamId(0);
1307 spdy::SpdyHeaderBlock empty_response_headers;
1308 const std::string response_data = server_maker_.QpackEncodeHeaders(
1309 request_stream_id, std::move(empty_response_headers), nullptr);
1310 uint64_t read_packet_num = 1;
1311 mock_quic_data.AddRead(
1312 ASYNC, ConstructServerDataPacket(read_packet_num++, request_stream_id,
1313 false, false, response_data));
1314 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1315
1316 mock_quic_data.AddWrite(
1317 ASYNC,
1318 ConstructClientAckAndDataPacket(
1319 write_packet_num++, true, GetQpackDecoderStreamId(), 1, 1, 1, false,
1320 StreamCancellationQpackDecoderInstruction(request_stream_id)));
1321
1322 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1323
1324 CreateSession();
1325
1326 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1327 TestCompletionCallback callback;
1328 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1330 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_INVALID_RESPONSE));
1331}
1332
rchbd089ab2017-05-26 23:05:041333TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381334 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041335 HostPortPair::FromString("mail.example.org:443"));
1336
Ryan Hamiltonabad59e2019-06-06 04:02:591337 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231338 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251339 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231340 mock_quic_data.AddWrite(SYNCHRONOUS,
1341 ConstructInitialSettingsPacket(packet_num++));
1342 }
rchbd089ab2017-05-26 23:05:041343 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231344 SYNCHRONOUS,
1345 ConstructClientRequestHeadersPacket(
1346 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1347 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0239aac2018-05-19 00:03:131348 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041349 response_headers["key1"] = std::string(30000, 'A');
1350 response_headers["key2"] = std::string(30000, 'A');
1351 response_headers["key3"] = std::string(30000, 'A');
1352 response_headers["key4"] = std::string(30000, 'A');
1353 response_headers["key5"] = std::string(30000, 'A');
1354 response_headers["key6"] = std::string(30000, 'A');
1355 response_headers["key7"] = std::string(30000, 'A');
1356 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451357 quic::QuicStreamId stream_id;
1358 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251359 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451360 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281361 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451362 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451363 } else {
1364 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1365 spdy::SpdyHeadersIR headers_frame(
1366 GetNthClientInitiatedBidirectionalStreamId(0),
1367 std::move(response_headers));
1368 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1369 spdy::SpdySerializedFrame spdy_frame =
1370 response_framer.SerializeFrame(headers_frame);
1371 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1372 }
rchbd089ab2017-05-26 23:05:041373
Fan Yangac867502019-01-28 21:10:231374 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041375 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451376 for (size_t offset = 0; offset < response_data.length();
1377 offset += chunk_size) {
1378 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431379 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451380 ASYNC, ConstructServerDataPacket(
1381 packet_number++, stream_id, false, false,
1382 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041383 }
1384
Victor Vasiliev076657c2019-03-12 02:46:431385 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041386 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331387 ASYNC, ConstructServerDataPacket(
1388 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171389 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041390 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431391 mock_quic_data.AddWrite(ASYNC,
Renjie Tangaadb84b2019-08-31 01:00:231392 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1393 mock_quic_data.AddWrite(
1394 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041395
1396 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1397
1398 CreateSession();
1399
1400 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421401 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1402 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041403}
1404
1405TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381406 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1407 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041408 HostPortPair::FromString("mail.example.org:443"));
1409
Ryan Hamiltonabad59e2019-06-06 04:02:591410 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231411 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251412 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231413 mock_quic_data.AddWrite(SYNCHRONOUS,
1414 ConstructInitialSettingsPacket(packet_num++));
1415 }
rchbd089ab2017-05-26 23:05:041416 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231417 SYNCHRONOUS,
1418 ConstructClientRequestHeadersPacket(
1419 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1420 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451421
Ryan Hamilton0239aac2018-05-19 00:03:131422 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041423 response_headers["key1"] = std::string(30000, 'A');
1424 response_headers["key2"] = std::string(30000, 'A');
1425 response_headers["key3"] = std::string(30000, 'A');
1426 response_headers["key4"] = std::string(30000, 'A');
1427 response_headers["key5"] = std::string(30000, 'A');
1428 response_headers["key6"] = std::string(30000, 'A');
1429 response_headers["key7"] = std::string(30000, 'A');
1430 response_headers["key8"] = std::string(30000, 'A');
1431 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451432
1433 quic::QuicStreamId stream_id;
1434 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251435 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451436 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281437 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451438 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451439 } else {
1440 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1441 spdy::SpdyHeadersIR headers_frame(
1442 GetNthClientInitiatedBidirectionalStreamId(0),
1443 std::move(response_headers));
1444 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1445 spdy::SpdySerializedFrame spdy_frame =
1446 response_framer.SerializeFrame(headers_frame);
1447 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1448 }
rchbd089ab2017-05-26 23:05:041449
Fan Yangac867502019-01-28 21:10:231450 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041451 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451452 for (size_t offset = 0; offset < response_data.length();
1453 offset += chunk_size) {
1454 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431455 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451456 ASYNC, ConstructServerDataPacket(
1457 packet_number++, stream_id, false, false,
1458 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041459 }
1460
Victor Vasiliev076657c2019-03-12 02:46:431461 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411462
rchbd089ab2017-05-26 23:05:041463 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331464 ASYNC, ConstructServerDataPacket(
1465 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171466 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041467 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:231468 mock_quic_data.AddWrite(ASYNC,
1469 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431470 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331471 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231472 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:331473 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041474
1475 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1476
1477 CreateSession();
1478
1479 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1480 TestCompletionCallback callback;
1481 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1482 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1483 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1484}
1485
rcha2bd44b2016-07-02 00:42:551486TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Victor Vasilieva1e66d72019-12-05 17:55:381487 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551488
Ryan Hamilton9835e662018-08-02 05:36:271489 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551490
Ryan Hamiltonabad59e2019-06-06 04:02:591491 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231492 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251493 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231494 mock_quic_data.AddWrite(SYNCHRONOUS,
1495 ConstructInitialSettingsPacket(packet_num++));
1496 }
rch5cb522462017-04-25 20:18:361497 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231498 SYNCHRONOUS,
1499 ConstructClientRequestHeadersPacket(
1500 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1501 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431502 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331503 ASYNC, ConstructServerResponseHeadersPacket(
1504 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1505 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431506 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331507 mock_quic_data.AddRead(
1508 ASYNC, ConstructServerDataPacket(
1509 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171510 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231511 mock_quic_data.AddWrite(SYNCHRONOUS,
1512 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551513 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1514
1515 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1516
1517 CreateSession();
1518
1519 SendRequestAndExpectQuicResponse("hello!");
1520 EXPECT_TRUE(
1521 test_socket_performance_watcher_factory_.rtt_notification_received());
1522}
1523
David Schinazif832cb82019-11-08 22:25:271524// Regression test for https://crbug.com/695225
1525TEST_P(QuicNetworkTransactionTest, 408Response) {
Victor Vasilieva1e66d72019-12-05 17:55:381526 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
David Schinazif832cb82019-11-08 22:25:271527
1528 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1529
1530 MockQuicData mock_quic_data(version_);
1531 int packet_num = 1;
1532 if (VersionUsesHttp3(version_.transport_version)) {
1533 mock_quic_data.AddWrite(SYNCHRONOUS,
1534 ConstructInitialSettingsPacket(packet_num++));
1535 }
1536 mock_quic_data.AddWrite(
1537 SYNCHRONOUS,
1538 ConstructClientRequestHeadersPacket(
1539 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1540 true, GetRequestHeaders("GET", "https", "/")));
1541 mock_quic_data.AddRead(
1542 ASYNC, ConstructServerResponseHeadersPacket(
1543 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1544 GetResponseHeaders("408 Request Timeout")));
1545 std::string header = ConstructDataHeader(6);
1546 mock_quic_data.AddRead(
1547 ASYNC, ConstructServerDataPacket(
1548 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1549 header + "hello!"));
1550 mock_quic_data.AddWrite(SYNCHRONOUS,
1551 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1552 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1553
1554 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1555
1556 CreateSession();
1557
1558 SendRequestAndExpectQuicResponse("hello!", "HTTP/1.1 408 Request Timeout");
1559}
1560
[email protected]cf3e3cd62014-02-05 16:16:161561TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411562 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561563 proxy_resolution_service_ =
1564 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
1565 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161566
Ryan Hamiltonabad59e2019-06-06 04:02:591567 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231568 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251569 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231570 mock_quic_data.AddWrite(SYNCHRONOUS,
1571 ConstructInitialSettingsPacket(packet_num++));
1572 }
rch5cb522462017-04-25 20:18:361573 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231574 SYNCHRONOUS,
1575 ConstructClientRequestHeadersPacket(
1576 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1577 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431578 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331579 ASYNC, ConstructServerResponseHeadersPacket(
1580 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1581 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431582 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331583 mock_quic_data.AddRead(
1584 ASYNC, ConstructServerDataPacket(
1585 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171586 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231587 mock_quic_data.AddWrite(SYNCHRONOUS,
1588 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501589 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591590 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161591
rcha5399e02015-04-21 19:32:041592 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161593
tbansal0f56a39a2016-04-07 22:03:381594 EXPECT_FALSE(
1595 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161596 // There is no need to set up an alternate protocol job, because
1597 // no attempt will be made to speak to the proxy over TCP.
1598
rch9ae5b3b2016-02-11 00:36:291599 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161600 CreateSession();
1601
bnc62a44f022015-04-02 15:59:411602 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381603 EXPECT_TRUE(
1604 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161605}
1606
bnc313ba9c2015-06-11 15:42:311607// Regression test for https://crbug.com/492458. Test that for an HTTP
1608// connection through a QUIC proxy, the certificate exhibited by the proxy is
1609// checked against the proxy hostname, not the origin hostname.
1610TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291611 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311612 const std::string proxy_host = "www.example.org";
1613
mmenke6ddfbea2017-05-31 21:48:411614 session_params_.enable_quic = true;
Nicolas Arciniegad2013f92020-02-07 23:00:561615 proxy_resolution_service_ =
1616 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
1617 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311618
alyssar2adf3ac2016-05-03 17:12:581619 client_maker_.set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591620 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231621 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251622 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231623 mock_quic_data.AddWrite(SYNCHRONOUS,
1624 ConstructInitialSettingsPacket(packet_num++));
1625 }
rch5cb522462017-04-25 20:18:361626 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231627 SYNCHRONOUS,
1628 ConstructClientRequestHeadersPacket(
1629 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1630 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431631 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331632 ASYNC, ConstructServerResponseHeadersPacket(
1633 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1634 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431635 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331636 mock_quic_data.AddRead(
1637 ASYNC, ConstructServerDataPacket(
1638 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171639 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231640 mock_quic_data.AddWrite(SYNCHRONOUS,
1641 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501642 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591643 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311644 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1645
1646 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291647 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311648 ASSERT_TRUE(cert.get());
1649 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241650 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1651 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311652 ProofVerifyDetailsChromium verify_details;
1653 verify_details.cert_verify_result.verified_cert = cert;
1654 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561655 ProofVerifyDetailsChromium verify_details2;
1656 verify_details2.cert_verify_result.verified_cert = cert;
1657 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311658
1659 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091660 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321661 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271662 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311663 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1664}
1665
rchbe69cb902016-02-11 01:10:481666TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Victor Vasilieva1e66d72019-12-05 17:55:381667 context_.params()->allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481668 HostPortPair origin("www.example.org", 443);
1669 HostPortPair alternative("mail.example.org", 443);
1670
1671 base::FilePath certs_dir = GetTestCertsDirectory();
1672 scoped_refptr<X509Certificate> cert(
1673 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1674 ASSERT_TRUE(cert.get());
1675 // TODO(rch): the connection should be "to" the origin, so if the cert is
1676 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241677 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1678 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481679 ProofVerifyDetailsChromium verify_details;
1680 verify_details.cert_verify_result.verified_cert = cert;
1681 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1682
alyssar2adf3ac2016-05-03 17:12:581683 client_maker_.set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591684 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021685
Renjie Tangaadb84b2019-08-31 01:00:231686 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251687 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231688 mock_quic_data.AddWrite(SYNCHRONOUS,
1689 ConstructInitialSettingsPacket(packet_num++));
1690 }
rch5cb522462017-04-25 20:18:361691 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231692 SYNCHRONOUS,
1693 ConstructClientRequestHeadersPacket(
1694 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1695 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431696 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331697 ASYNC, ConstructServerResponseHeadersPacket(
1698 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1699 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431700 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331701 mock_quic_data.AddRead(
1702 ASYNC, ConstructServerDataPacket(
1703 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171704 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231705 mock_quic_data.AddWrite(SYNCHRONOUS,
1706 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481707 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1708 mock_quic_data.AddRead(ASYNC, 0);
1709 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1710
1711 request_.url = GURL("https://" + origin.host());
1712 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271713 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091714 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321715 CreateSession();
rchbe69cb902016-02-11 01:10:481716
1717 SendRequestAndExpectQuicResponse("hello!");
1718}
1719
zhongyief3f4ce52017-07-05 23:53:281720TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:561721 quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
Bence Békyb89104962020-01-24 00:05:171722 // Add support for another QUIC version besides |version_|. Also find an
zhongyief3f4ce52017-07-05 23:53:281723 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561724 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281725 if (version == version_)
1726 continue;
1727 if (supported_versions_.size() != 2) {
1728 supported_versions_.push_back(version);
1729 continue;
1730 }
1731 unsupported_version = version;
1732 break;
1733 }
Bence Békyb89104962020-01-24 00:05:171734 ASSERT_EQ(2u, supported_versions_.size());
1735 ASSERT_NE(quic::UnsupportedQuicVersion(), unsupported_version);
zhongyief3f4ce52017-07-05 23:53:281736
1737 // Set up alternative service to use QUIC with a version that is not
1738 // supported.
1739 url::SchemeHostPort server(request_.url);
1740 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1741 443);
1742 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491743 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071744 server, NetworkIsolationKey(), alternative_service, expiration,
1745 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281746
1747 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491748 http_server_properties_->GetAlternativeServiceInfos(
1749 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281750 EXPECT_EQ(1u, alt_svc_info_vector.size());
1751 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1752 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1753 EXPECT_EQ(unsupported_version,
1754 alt_svc_info_vector[0].advertised_versions()[0]);
1755
1756 // First request should still be sent via TCP as the QUIC version advertised
1757 // in the stored AlternativeService is not supported by the client. However,
1758 // the response from the server will advertise new Alt-Svc with supported
1759 // versions.
Bence Békyb89104962020-01-24 00:05:171760 std::string altsvc_header = GenerateQuicAltSvcHeader();
zhongyief3f4ce52017-07-05 23:53:281761 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:171762 MockRead("HTTP/1.1 200 OK\r\n"),
1763 MockRead(altsvc_header.c_str()),
1764 MockRead("\r\n"),
zhongyief3f4ce52017-07-05 23:53:281765 MockRead("hello world"),
1766 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1767 MockRead(ASYNC, OK)};
1768
Ryan Sleevib8d7ea02018-05-07 20:01:011769 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281770 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081771 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281772 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1773
1774 // Second request should be sent via QUIC as a new list of verions supported
1775 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591776 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231777 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251778 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231779 mock_quic_data.AddWrite(SYNCHRONOUS,
1780 ConstructInitialSettingsPacket(packet_num++));
1781 }
zhongyief3f4ce52017-07-05 23:53:281782 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231783 SYNCHRONOUS,
1784 ConstructClientRequestHeadersPacket(
1785 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1786 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431787 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331788 ASYNC, ConstructServerResponseHeadersPacket(
1789 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1790 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431791 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331792 mock_quic_data.AddRead(
1793 ASYNC, ConstructServerDataPacket(
1794 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171795 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231796 mock_quic_data.AddWrite(SYNCHRONOUS,
1797 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281798 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1799 mock_quic_data.AddRead(ASYNC, 0); // EOF
1800
1801 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1802
1803 AddHangingNonAlternateProtocolSocketData();
1804
1805 CreateSession(supported_versions_);
1806
1807 SendRequestAndExpectHttpResponse("hello world");
1808 SendRequestAndExpectQuicResponse("hello!");
1809
1810 // Check alternative service list is updated with new versions.
1811 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491812 session_->http_server_properties()->GetAlternativeServiceInfos(
1813 server, NetworkIsolationKey());
Bence Békyb89104962020-01-24 00:05:171814 // All PROTOCOL_QUIC_CRYPTO versions are sent in a single Alt-Svc entry,
1815 // therefore they aer accumulated in a single AlternativeServiceInfo, whereas
1816 // each PROTOCOL_TLS1_3 version has its own Alt-Svc entry and
1817 // AlternativeServiceInfo entry. Flatten to compare.
1818 quic::ParsedQuicVersionVector alt_svc_negotiated_versions;
1819 for (const auto& alt_svc_info : alt_svc_info_vector) {
1820 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
1821 for (const auto& version : alt_svc_info.advertised_versions()) {
1822 alt_svc_negotiated_versions.push_back(version);
1823 }
1824 }
1825
1826 ASSERT_EQ(supported_versions_.size(), alt_svc_negotiated_versions.size());
1827 auto version_compare = [](const quic::ParsedQuicVersion& a,
1828 const quic::ParsedQuicVersion& b) {
1829 return std::tie(a.transport_version, a.handshake_protocol) <
1830 std::tie(b.transport_version, b.handshake_protocol);
1831 };
1832 std::sort(supported_versions_.begin(), supported_versions_.end(),
1833 version_compare);
1834 std::sort(alt_svc_negotiated_versions.begin(),
1835 alt_svc_negotiated_versions.end(), version_compare);
1836 EXPECT_TRUE(std::equal(supported_versions_.begin(), supported_versions_.end(),
1837 alt_svc_negotiated_versions.begin()));
zhongyief3f4ce52017-07-05 23:53:281838}
1839
bncaccd4962017-04-06 21:00:261840// Regression test for https://crbug.com/546991.
1841// The server might not be able to serve a request on an alternative connection,
1842// and might send a 421 Misdirected Request response status to indicate this.
1843// HttpNetworkTransaction should reset the request and retry without using
1844// alternative services.
1845TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1846 // Set up alternative service to use QUIC.
1847 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1848 // that overrides |enable_alternative_services|.
1849 url::SchemeHostPort server(request_.url);
1850 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1851 443);
1852 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491853 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071854 server, NetworkIsolationKey(), alternative_service, expiration,
1855 supported_versions_);
bncaccd4962017-04-06 21:00:261856
davidbena4449722017-05-05 23:30:531857 // First try: The alternative job uses QUIC and reports an HTTP 421
1858 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1859 // paused at Connect(), so it will never exit the socket pool. This ensures
1860 // that the alternate job always wins the race and keeps whether the
1861 // |http_data| exits the socket pool before the main job is aborted
1862 // deterministic. The first main job gets aborted without the socket pool ever
1863 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591864 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231865 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251866 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231867 mock_quic_data.AddWrite(SYNCHRONOUS,
1868 ConstructInitialSettingsPacket(packet_num++));
1869 }
rch5cb522462017-04-25 20:18:361870 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231871 SYNCHRONOUS,
1872 ConstructClientRequestHeadersPacket(
1873 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1874 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331875 mock_quic_data.AddRead(
1876 ASYNC, ConstructServerResponseHeadersPacket(
1877 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021878 GetResponseHeaders("421")));
bncaccd4962017-04-06 21:00:261879 mock_quic_data.AddRead(ASYNC, OK);
1880 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1881
davidbena4449722017-05-05 23:30:531882 // Second try: The main job uses TCP, and there is no alternate job. Once the
1883 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1884 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261885 // Note that if there was an alternative QUIC Job created for the second try,
1886 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1887 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531888 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1889 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1890 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1891 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1892 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1893 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011894 reads, writes);
bncaccd4962017-04-06 21:00:261895 socket_factory_.AddSocketDataProvider(&http_data);
1896 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1897
bncaccd4962017-04-06 21:00:261898 CreateSession();
1899 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531900
1901 // Run until |mock_quic_data| has failed and |http_data| has paused.
1902 TestCompletionCallback callback;
1903 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1905 base::RunLoop().RunUntilIdle();
1906
1907 // |mock_quic_data| must have run to completion.
1908 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1909 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1910
1911 // Now that the QUIC data has been consumed, unblock |http_data|.
1912 http_data.socket()->OnConnectComplete(MockConnect());
1913
1914 // The retry logic must hide the 421 status. The transaction succeeds on
1915 // |http_data|.
1916 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261917 CheckWasHttpResponse(&trans);
1918 CheckResponsePort(&trans, 443);
1919 CheckResponseData(&trans, "hello!");
1920}
1921
[email protected]1e960032013-12-20 19:00:201922TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Victor Vasilieva1e66d72019-12-05 17:55:381923 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571924 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301925
Ryan Hamiltonabad59e2019-06-06 04:02:591926 MockQuicData mock_quic_data1(version_);
Victor Vasiliev7da08172019-10-14 06:04:251927 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231928 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401929 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Ryan Hamilton0d65a8c2019-06-07 00:46:021930 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591931 MockQuicData mock_quic_data2(version_);
Victor Vasiliev7da08172019-10-14 06:04:251932 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231933 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301934 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401935 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431936 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401937
1938 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1939 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301940
1941 CreateSession();
1942
tbansal0f56a39a2016-04-07 22:03:381943 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401944 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161945 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401946 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161947 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011948 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1949 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381950 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531951
1952 NetErrorDetails details;
1953 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521954 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401955 }
[email protected]cebe3282013-05-22 23:49:301956}
1957
tbansalc8a94ea2015-11-02 23:58:511958TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1959 // Attempt to "force" quic on 443, which will not be honored.
Victor Vasilieva1e66d72019-12-05 17:55:381960 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571961 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511962
1963 MockRead http_reads[] = {
1964 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1965 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1966 MockRead(ASYNC, OK)};
1967
Ryan Sleevib8d7ea02018-05-07 20:01:011968 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511969 socket_factory_.AddSocketDataProvider(&data);
1970 SSLSocketDataProvider ssl(ASYNC, OK);
1971 socket_factory_.AddSSLSocketDataProvider(&ssl);
1972
1973 CreateSession();
1974
1975 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381976 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511977}
1978
bncc958faa2015-07-31 18:14:521979TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521980 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561981 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1982 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521983 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1984 MockRead(ASYNC, OK)};
1985
Ryan Sleevib8d7ea02018-05-07 20:01:011986 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521987 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081988 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561989 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521990
Ryan Hamiltonabad59e2019-06-06 04:02:591991 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231992 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251993 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231994 mock_quic_data.AddWrite(SYNCHRONOUS,
1995 ConstructInitialSettingsPacket(packet_num++));
1996 }
rch5cb522462017-04-25 20:18:361997 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231998 SYNCHRONOUS,
1999 ConstructClientRequestHeadersPacket(
2000 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2001 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432002 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332003 ASYNC, ConstructServerResponseHeadersPacket(
2004 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2005 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432006 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332007 mock_quic_data.AddRead(
2008 ASYNC, ConstructServerDataPacket(
2009 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172010 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232011 mock_quic_data.AddWrite(SYNCHRONOUS,
2012 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:522013 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592014 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:522015
2016 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2017
rtennetib8e80fb2016-05-16 00:12:092018 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322019 CreateSession();
bncc958faa2015-07-31 18:14:522020
2021 SendRequestAndExpectHttpResponse("hello world");
2022 SendRequestAndExpectQuicResponse("hello!");
2023}
2024
Ryan Hamilton64f21d52019-08-31 07:10:512025TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
2026 std::string alt_svc_header =
2027 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
2028 MockRead http_reads[] = {
2029 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
2030 MockRead("hello world"),
2031 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2032 MockRead(ASYNC, OK)};
2033
2034 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2035 socket_factory_.AddSocketDataProvider(&http_data);
2036 AddCertificate(&ssl_data_);
2037 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2038
2039 MockQuicData mock_quic_data(version_);
2040 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252041 if (VersionUsesHttp3(version_.transport_version)) {
Ryan Hamilton64f21d52019-08-31 07:10:512042 mock_quic_data.AddWrite(SYNCHRONOUS,
2043 ConstructInitialSettingsPacket(packet_num++));
2044 }
2045 mock_quic_data.AddWrite(
2046 SYNCHRONOUS,
2047 ConstructClientRequestHeadersPacket(
2048 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2049 true, GetRequestHeaders("GET", "https", "/")));
2050 mock_quic_data.AddRead(
2051 ASYNC, ConstructServerResponseHeadersPacket(
2052 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2053 GetResponseHeaders("200 OK")));
2054 std::string header = ConstructDataHeader(6);
2055 mock_quic_data.AddRead(
2056 ASYNC, ConstructServerDataPacket(
2057 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2058 header + "hello!"));
2059 mock_quic_data.AddWrite(SYNCHRONOUS,
2060 ConstructClientAckPacket(packet_num++, 2, 1, 1));
2061 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2062 mock_quic_data.AddRead(ASYNC, 0); // EOF
2063
2064 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2065
2066 AddHangingNonAlternateProtocolSocketData();
2067 CreateSession();
2068
2069 SendRequestAndExpectHttpResponse("hello world");
2070 SendRequestAndExpectQuicResponse("hello!");
2071}
2072
Matt Menke3233d8f22019-08-20 21:01:492073// Much like above, but makes sure NetworkIsolationKey is respected.
2074TEST_P(QuicNetworkTransactionTest,
2075 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
2076 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:052077 feature_list.InitWithFeatures(
2078 // enabled_features
2079 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2080 features::kPartitionConnectionsByNetworkIsolationKey},
2081 // disabled_features
2082 {});
Matt Menke3233d8f22019-08-20 21:01:492083 // Since HttpServerProperties caches the feature value, have to create a new
2084 // one.
2085 http_server_properties_ = std::make_unique<HttpServerProperties>();
2086
2087 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2088 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2089 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2090 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2091
2092 MockRead http_reads[] = {
2093 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
2094 MockRead("hello world"),
2095 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2096 MockRead(ASYNC, OK)};
2097
2098 AddCertificate(&ssl_data_);
2099
2100 // Request with empty NetworkIsolationKey.
2101 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2102 socket_factory_.AddSocketDataProvider(&http_data1);
2103 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2104
2105 // First request with kNetworkIsolationKey1.
2106 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2107 socket_factory_.AddSocketDataProvider(&http_data2);
2108 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2109
2110 // Request with kNetworkIsolationKey2.
2111 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2112 socket_factory_.AddSocketDataProvider(&http_data3);
2113 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2114
2115 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2116 // alternative service infrmation has been received in this context before.
2117 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232118 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252119 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232120 mock_quic_data.AddWrite(SYNCHRONOUS,
2121 ConstructInitialSettingsPacket(packet_num++));
2122 }
Matt Menke3233d8f22019-08-20 21:01:492123 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232124 SYNCHRONOUS,
2125 ConstructClientRequestHeadersPacket(
2126 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2127 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492128 mock_quic_data.AddRead(
2129 ASYNC, ConstructServerResponseHeadersPacket(
2130 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2131 GetResponseHeaders("200 OK")));
2132 std::string header = ConstructDataHeader(6);
2133 mock_quic_data.AddRead(
2134 ASYNC, ConstructServerDataPacket(
2135 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2136 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232137 mock_quic_data.AddWrite(SYNCHRONOUS,
2138 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke3233d8f22019-08-20 21:01:492139 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2140 mock_quic_data.AddRead(ASYNC, 0); // EOF
2141
2142 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2143
2144 AddHangingNonAlternateProtocolSocketData();
2145 CreateSession();
2146
2147 // This is first so that the test fails if alternative service info is
2148 // written with the right NetworkIsolationKey, but always queried with an
2149 // empty one.
2150 request_.network_isolation_key = NetworkIsolationKey();
2151 SendRequestAndExpectHttpResponse("hello world");
2152 request_.network_isolation_key = kNetworkIsolationKey1;
2153 SendRequestAndExpectHttpResponse("hello world");
2154 request_.network_isolation_key = kNetworkIsolationKey2;
2155 SendRequestAndExpectHttpResponse("hello world");
2156
2157 // Only use QUIC when using a NetworkIsolationKey which has been used when
2158 // alternative service information was received.
2159 request_.network_isolation_key = kNetworkIsolationKey1;
2160 SendRequestAndExpectQuicResponse("hello!");
2161}
2162
zhongyia00ca012017-07-06 23:36:392163TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
2164 // Both server advertises and client supports two QUIC versions.
2165 // Only |version_| is advertised and supported.
2166 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2167 // PacketMakers are using |version_|.
2168
2169 // Add support for another QUIC version besides |version_| on the client side.
2170 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:562171 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
2172 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392173 if (version == version_)
2174 continue;
2175 if (supported_versions_.size() != 2) {
2176 supported_versions_.push_back(version);
2177 continue;
2178 }
2179 advertised_version_2 = version;
2180 break;
2181 }
Bence Békyb89104962020-01-24 00:05:172182 ASSERT_EQ(2u, supported_versions_.size());
2183 ASSERT_NE(quic::UnsupportedQuicVersion(), advertised_version_2);
zhongyia00ca012017-07-06 23:36:392184
Bence Békyb89104962020-01-24 00:05:172185 std::string QuicAltSvcWithVersionHeader =
2186 base::StringPrintf("Alt-Svc: %s=\":443\", %s=\":443\"\r\n\r\n",
2187 quic::AlpnForVersion(advertised_version_2).c_str(),
2188 quic::AlpnForVersion(version_).c_str());
zhongyia00ca012017-07-06 23:36:392189
2190 MockRead http_reads[] = {
2191 MockRead("HTTP/1.1 200 OK\r\n"),
2192 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2193 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2194 MockRead(ASYNC, OK)};
2195
Ryan Sleevib8d7ea02018-05-07 20:01:012196 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392197 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082198 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392199 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2200
Ryan Hamiltonabad59e2019-06-06 04:02:592201 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232202 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252203 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232204 mock_quic_data.AddWrite(SYNCHRONOUS,
2205 ConstructInitialSettingsPacket(packet_num++));
2206 }
zhongyia00ca012017-07-06 23:36:392207 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232208 SYNCHRONOUS,
2209 ConstructClientRequestHeadersPacket(
2210 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2211 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432212 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332213 ASYNC, ConstructServerResponseHeadersPacket(
2214 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2215 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432216 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332217 mock_quic_data.AddRead(
2218 ASYNC, ConstructServerDataPacket(
2219 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172220 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232221 mock_quic_data.AddWrite(SYNCHRONOUS,
2222 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392223 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2224 mock_quic_data.AddRead(ASYNC, 0); // EOF
2225
2226 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2227
2228 AddHangingNonAlternateProtocolSocketData();
2229 CreateSession(supported_versions_);
2230
2231 SendRequestAndExpectHttpResponse("hello world");
2232 SendRequestAndExpectQuicResponse("hello!");
2233}
2234
2235TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
Bence Békyb89104962020-01-24 00:05:172236 if (version_.handshake_protocol != quic::PROTOCOL_QUIC_CRYPTO) {
2237 // Only QUIC_CRYPTO versions can be encoded with Google-style AltSvc.
2238 // Currently client preference is not observed with IETF-style AltSvc.
2239 // TODO(https://crbug.com/1044691): Fix that and add test.
2240 return;
2241 }
2242
zhongyia00ca012017-07-06 23:36:392243 // Client and server mutually support more than one QUIC_VERSION.
2244 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
2245 // which is verified as the PacketMakers are using |version_|.
2246
Nick Harper23290b82019-05-02 00:02:562247 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
2248 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392249 if (version == version_)
2250 continue;
2251 common_version_2 = version;
2252 break;
2253 }
Bence Békyb89104962020-01-24 00:05:172254 ASSERT_NE(quic::UnsupportedQuicVersion(), common_version_2);
zhongyia00ca012017-07-06 23:36:392255
2256 supported_versions_.push_back(
2257 common_version_2); // Supported but unpreferred.
2258
2259 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:562260 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2261 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392262
2263 MockRead http_reads[] = {
2264 MockRead("HTTP/1.1 200 OK\r\n"),
2265 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2266 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2267 MockRead(ASYNC, OK)};
2268
Ryan Sleevib8d7ea02018-05-07 20:01:012269 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392270 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082271 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392272 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2273
Ryan Hamiltonabad59e2019-06-06 04:02:592274 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232275 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252276 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232277 mock_quic_data.AddWrite(SYNCHRONOUS,
2278 ConstructInitialSettingsPacket(packet_num++));
2279 }
zhongyia00ca012017-07-06 23:36:392280 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232281 SYNCHRONOUS,
2282 ConstructClientRequestHeadersPacket(
2283 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2284 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432285 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332286 ASYNC, ConstructServerResponseHeadersPacket(
2287 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2288 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432289 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332290 mock_quic_data.AddRead(
2291 ASYNC, ConstructServerDataPacket(
2292 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172293 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232294 mock_quic_data.AddWrite(SYNCHRONOUS,
2295 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392296 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2297 mock_quic_data.AddRead(ASYNC, 0); // EOF
2298
2299 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2300
2301 AddHangingNonAlternateProtocolSocketData();
2302 CreateSession(supported_versions_);
2303
2304 SendRequestAndExpectHttpResponse("hello world");
2305 SendRequestAndExpectQuicResponse("hello!");
2306}
2307
rchf47265dc2016-03-21 21:33:122308TEST_P(QuicNetworkTransactionTest,
2309 UseAlternativeServiceWithProbabilityForQuic) {
2310 MockRead http_reads[] = {
2311 MockRead("HTTP/1.1 200 OK\r\n"),
2312 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
2313 MockRead("hello world"),
2314 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2315 MockRead(ASYNC, OK)};
2316
Ryan Sleevib8d7ea02018-05-07 20:01:012317 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:122318 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082319 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:122320 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2321
Ryan Hamiltonabad59e2019-06-06 04:02:592322 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232323 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252324 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232325 mock_quic_data.AddWrite(SYNCHRONOUS,
2326 ConstructInitialSettingsPacket(packet_num++));
2327 }
rch5cb522462017-04-25 20:18:362328 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232329 SYNCHRONOUS,
2330 ConstructClientRequestHeadersPacket(
2331 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2332 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432333 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332334 ASYNC, ConstructServerResponseHeadersPacket(
2335 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2336 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432337 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332338 mock_quic_data.AddRead(
2339 ASYNC, ConstructServerDataPacket(
2340 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172341 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232342 mock_quic_data.AddWrite(SYNCHRONOUS,
2343 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchf47265dc2016-03-21 21:33:122344 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2345 mock_quic_data.AddRead(ASYNC, 0); // EOF
2346
2347 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2348
rtennetib8e80fb2016-05-16 00:12:092349 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:122350 CreateSession();
2351
2352 SendRequestAndExpectHttpResponse("hello world");
2353 SendRequestAndExpectQuicResponse("hello!");
2354}
2355
zhongyi3d4a55e72016-04-22 20:36:462356TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2357 MockRead http_reads[] = {
2358 MockRead("HTTP/1.1 200 OK\r\n"),
2359 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2360 MockRead("hello world"),
2361 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2362 MockRead(ASYNC, OK)};
2363
Ryan Sleevib8d7ea02018-05-07 20:01:012364 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462365 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082366 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462367 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2368
2369 CreateSession();
bncb26024382016-06-29 02:39:452370 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462371 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452372 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462373 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402374 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462375 session_->http_server_properties();
2376 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2377 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2378 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462379 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492380 2u, http_server_properties
2381 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2382 .size());
bncb26024382016-06-29 02:39:452383 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492384 http_server_properties
2385 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2386 .empty());
zhongyi3d4a55e72016-04-22 20:36:462387}
2388
2389TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2390 MockRead http_reads[] = {
2391 MockRead("HTTP/1.1 200 OK\r\n"),
2392 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2393 MockRead("hello world"),
2394 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2395 MockRead(ASYNC, OK)};
2396
Ryan Sleevib8d7ea02018-05-07 20:01:012397 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082398 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462399
2400 socket_factory_.AddSocketDataProvider(&http_data);
2401 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2402 socket_factory_.AddSocketDataProvider(&http_data);
2403 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2404
2405 CreateSession();
2406
2407 // Send https request and set alternative services if response header
2408 // advertises alternative service for mail.example.org.
2409 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402410 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462411 session_->http_server_properties();
2412
2413 const url::SchemeHostPort https_server(request_.url);
2414 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342415 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492416 2u, http_server_properties
2417 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2418 .size());
zhongyi3d4a55e72016-04-22 20:36:462419
2420 // Send http request to the same origin but with diffrent scheme, should not
2421 // use QUIC.
2422 request_.url = GURL("http://mail.example.org:443");
2423 SendRequestAndExpectHttpResponse("hello world");
2424}
2425
zhongyie537a002017-06-27 16:48:212426TEST_P(QuicNetworkTransactionTest,
2427 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442428 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562429 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Bence Békyb89104962020-01-24 00:05:172430 if (version != version_) {
2431 supported_versions_.push_back(version);
2432 break;
2433 }
zhongyi86838d52017-06-30 01:19:442434 }
2435
Bence Békyb89104962020-01-24 00:05:172436 std::string altsvc_header = GenerateQuicAltSvcHeader();
zhongyie537a002017-06-27 16:48:212437 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:172438 MockRead("HTTP/1.1 200 OK\r\n"),
2439 MockRead(altsvc_header.c_str()),
2440 MockRead("\r\n"),
zhongyie537a002017-06-27 16:48:212441 MockRead("hello world"),
2442 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2443 MockRead(ASYNC, OK)};
2444
Ryan Sleevib8d7ea02018-05-07 20:01:012445 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212446 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082447 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212448 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2449
Ryan Hamiltonabad59e2019-06-06 04:02:592450 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232451 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252452 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232453 mock_quic_data.AddWrite(SYNCHRONOUS,
2454 ConstructInitialSettingsPacket(packet_num++));
2455 }
zhongyie537a002017-06-27 16:48:212456 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232457 SYNCHRONOUS,
2458 ConstructClientRequestHeadersPacket(
2459 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2460 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432461 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332462 ASYNC, ConstructServerResponseHeadersPacket(
2463 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2464 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432465 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332466 mock_quic_data.AddRead(
2467 ASYNC, ConstructServerDataPacket(
2468 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172469 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232470 mock_quic_data.AddWrite(SYNCHRONOUS,
2471 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212472 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2473 mock_quic_data.AddRead(ASYNC, 0); // EOF
2474
2475 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2476
2477 AddHangingNonAlternateProtocolSocketData();
2478
zhongyi86838d52017-06-30 01:19:442479 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212480
2481 SendRequestAndExpectHttpResponse("hello world");
2482 SendRequestAndExpectQuicResponse("hello!");
2483
Bence Békyb89104962020-01-24 00:05:172484 // Alt-Svc header contains all possible versions, so alternative services
2485 // should contain all of |supported_versions_|.
zhongyie537a002017-06-27 16:48:212486 const url::SchemeHostPort https_server(request_.url);
2487 const AlternativeServiceInfoVector alt_svc_info_vector =
2488 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492489 https_server, NetworkIsolationKey());
Bence Békyb89104962020-01-24 00:05:172490 // However, all PROTOCOL_QUIC_CRYPTO versions are sent in a single Alt-Svc
2491 // entry, therefore they aer accumulated in a single AlternativeServiceInfo,
2492 // whereas each PROTOCOL_TLS1_3 version has its own Alt-Svc entry and
2493 // AlternativeServiceInfo entry. Flatten to compare.
2494 quic::ParsedQuicVersionVector alt_svc_negotiated_versions;
2495 for (const auto& alt_svc_info : alt_svc_info_vector) {
2496 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
2497 for (const auto& version : alt_svc_info.advertised_versions()) {
2498 alt_svc_negotiated_versions.push_back(version);
2499 }
2500 }
2501
2502 ASSERT_EQ(supported_versions_.size(), alt_svc_negotiated_versions.size());
2503 auto version_compare = [](const quic::ParsedQuicVersion& a,
2504 const quic::ParsedQuicVersion& b) {
2505 return std::tie(a.transport_version, a.handshake_protocol) <
2506 std::tie(b.transport_version, b.handshake_protocol);
2507 };
2508 std::sort(supported_versions_.begin(), supported_versions_.end(),
2509 version_compare);
2510 std::sort(alt_svc_negotiated_versions.begin(),
2511 alt_svc_negotiated_versions.end(), version_compare);
2512 EXPECT_TRUE(std::equal(supported_versions_.begin(), supported_versions_.end(),
2513 alt_svc_negotiated_versions.begin()));
zhongyie537a002017-06-27 16:48:212514}
2515
danzh3134c2562016-08-12 14:07:522516TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562517 std::string altsvc_header = base::StringPrintf(
Bence Békyb89104962020-01-24 00:05:172518 "Alt-Svc: %s=\":443\"\r\n\r\n", quic::AlpnForVersion(version_).c_str());
bnc8be55ebb2015-10-30 14:12:072519 MockRead http_reads[] = {
2520 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2521 MockRead("hello world"),
2522 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2523 MockRead(ASYNC, OK)};
2524
Ryan Sleevib8d7ea02018-05-07 20:01:012525 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072526 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082527 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072528 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2529
Ryan Hamiltonabad59e2019-06-06 04:02:592530 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232531 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252532 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232533 mock_quic_data.AddWrite(SYNCHRONOUS,
2534 ConstructInitialSettingsPacket(packet_num++));
2535 }
rch5cb522462017-04-25 20:18:362536 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232537 SYNCHRONOUS,
2538 ConstructClientRequestHeadersPacket(
2539 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2540 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432541 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332542 ASYNC, ConstructServerResponseHeadersPacket(
2543 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2544 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432545 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332546 mock_quic_data.AddRead(
2547 ASYNC, ConstructServerDataPacket(
2548 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172549 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232550 mock_quic_data.AddWrite(SYNCHRONOUS,
2551 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072552 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592553 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072554
2555 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2556
rtennetib8e80fb2016-05-16 00:12:092557 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322558 CreateSession();
bnc8be55ebb2015-10-30 14:12:072559
2560 SendRequestAndExpectHttpResponse("hello world");
2561 SendRequestAndExpectQuicResponse("hello!");
2562}
2563
zhongyi6b5a3892016-03-12 04:46:202564TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562565 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjie Tangba21e032019-09-27 21:52:282566 // GoAway is not available under version 99
Frank Kastenholz6e4c5382018-06-21 23:00:092567 return;
2568 }
Ryan Hamiltonabad59e2019-06-06 04:02:592569 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232570 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252571 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232572 mock_quic_data.AddWrite(SYNCHRONOUS,
2573 ConstructInitialSettingsPacket(packet_num++));
2574 }
rch5cb522462017-04-25 20:18:362575 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232576 SYNCHRONOUS,
2577 ConstructClientRequestHeadersPacket(
2578 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2579 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332580 mock_quic_data.AddRead(
2581 ASYNC, ConstructServerResponseHeadersPacket(
2582 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2583 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202584 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522585 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432586 mock_quic_data.AddRead(SYNCHRONOUS,
2587 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522588 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432589 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232590 mock_quic_data.AddWrite(SYNCHRONOUS,
2591 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432592 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332593 mock_quic_data.AddRead(
2594 SYNCHRONOUS, ConstructServerDataPacket(
2595 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:172596 true, header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232597 mock_quic_data.AddWrite(
2598 SYNCHRONOUS,
2599 ConstructClientAckAndRstPacket(
2600 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2601 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202602 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2603 mock_quic_data.AddRead(ASYNC, 0); // EOF
2604
2605 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2606
2607 // The non-alternate protocol job needs to hang in order to guarantee that
2608 // the alternate-protocol job will "win".
2609 AddHangingNonAlternateProtocolSocketData();
2610
2611 // In order for a new QUIC session to be established via alternate-protocol
2612 // without racing an HTTP connection, we need the host resolution to happen
2613 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2614 // connection to the the server, in this test we require confirmation
2615 // before encrypting so the HTTP job will still start.
2616 host_resolver_.set_synchronous_mode(true);
2617 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2618 "");
zhongyi6b5a3892016-03-12 04:46:202619
2620 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432621 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2622 false);
Ryan Hamilton9835e662018-08-02 05:36:272623 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202624
bnc691fda62016-08-12 00:43:162625 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202626 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362627 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012628 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202629
Fan Yang3673cc72020-02-07 14:49:282630 crypto_client_stream_factory_.last_stream()
2631 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:012632 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202633
2634 // Check whether this transaction is correctly marked as received a go-away
2635 // because of migrating port.
2636 NetErrorDetails details;
2637 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162638 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202639 EXPECT_TRUE(details.quic_port_migration_detected);
2640}
2641
Zhongyi Shia6b68d112018-09-24 07:49:032642// This test verifies that a new QUIC connection will be attempted on the
2643// alternate network if the original QUIC connection fails with idle timeout
2644// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2645// alternate network as well, QUIC is marked as broken and the brokenness will
2646// not expire when default network changes.
2647TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432648 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2649 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2650 return;
2651 }
Zhongyi Shia6b68d112018-09-24 07:49:032652 SetUpTestForRetryConnectionOnAlternateNetwork();
2653
Michael Warres167db3e2019-03-01 21:38:032654 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032655
2656 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592657 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032658 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2659 int packet_num = 1;
2660 quic_data.AddWrite(SYNCHRONOUS,
2661 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2662 // Retranmit the handshake messages.
2663 quic_data.AddWrite(SYNCHRONOUS,
2664 client_maker_.MakeDummyCHLOPacket(packet_num++));
2665 quic_data.AddWrite(SYNCHRONOUS,
2666 client_maker_.MakeDummyCHLOPacket(packet_num++));
2667 quic_data.AddWrite(SYNCHRONOUS,
2668 client_maker_.MakeDummyCHLOPacket(packet_num++));
2669 quic_data.AddWrite(SYNCHRONOUS,
2670 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032671 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2672 quic_data.AddWrite(SYNCHRONOUS,
2673 client_maker_.MakeConnectionClosePacket(
2674 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522675 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:032676 quic_data.AddSocketDataToFactory(&socket_factory_);
2677
2678 // Add successful TCP data so that TCP job will succeed.
2679 MockWrite http_writes[] = {
2680 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2681 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2682 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2683
2684 MockRead http_reads[] = {
2685 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2686 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2687 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2688 SequencedSocketData http_data(http_reads, http_writes);
2689 socket_factory_.AddSocketDataProvider(&http_data);
2690 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2691
2692 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592693 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032694 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2695 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2696 quic_data2.AddSocketDataToFactory(&socket_factory_);
2697
2698 // Resolve the host resolution synchronously.
2699 host_resolver_.set_synchronous_mode(true);
2700 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2701 "");
Zhongyi Shia6b68d112018-09-24 07:49:032702
2703 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432704 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2705 false);
Zhongyi Shia6b68d112018-09-24 07:49:032706 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032707 QuicStreamFactoryPeer::SetAlarmFactory(
2708 session_->quic_stream_factory(),
2709 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222710 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032711 // Add alternate protocol mapping to race QUIC and TCP.
2712 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2713 // peer.
2714 AddQuicAlternateProtocolMapping(
2715 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2716
2717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2718 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362719 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2721
2722 // Pump the message loop to get the request started.
2723 // Request will be served with TCP job.
2724 base::RunLoop().RunUntilIdle();
2725 EXPECT_THAT(callback.WaitForResult(), IsOk());
2726 CheckResponseData(&trans, "TCP succeeds");
2727
Zhongyi Shia6b68d112018-09-24 07:49:032728 // Fast forward to idle timeout the original connection. A new connection will
2729 // be kicked off on the alternate network.
2730 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2731 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2732 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2733
2734 // Run the message loop to execute posted tasks, which will report job status.
2735 base::RunLoop().RunUntilIdle();
2736
2737 // Verify that QUIC is marked as broken.
2738 ExpectBrokenAlternateProtocolMapping();
2739
2740 // Deliver a message to notify the new network becomes default, the brokenness
2741 // will not expire as QUIC is broken on both networks.
2742 scoped_mock_change_notifier_->mock_network_change_notifier()
2743 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2744 ExpectBrokenAlternateProtocolMapping();
2745
2746 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2747 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2748}
2749
2750// This test verifies that a new QUIC connection will be attempted on the
2751// alternate network if the original QUIC connection fails with idle timeout
2752// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2753// alternate network, QUIC is marked as broken. The brokenness will expire when
2754// the default network changes.
2755TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432756 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2757 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2758 return;
2759 }
2760
Zhongyi Shia6b68d112018-09-24 07:49:032761 SetUpTestForRetryConnectionOnAlternateNetwork();
2762
Michael Warres167db3e2019-03-01 21:38:032763 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032764
2765 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592766 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032767 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2768 int packet_num = 1;
2769 quic_data.AddWrite(SYNCHRONOUS,
2770 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2771 // Retranmit the handshake messages.
2772 quic_data.AddWrite(SYNCHRONOUS,
2773 client_maker_.MakeDummyCHLOPacket(packet_num++));
2774 quic_data.AddWrite(SYNCHRONOUS,
2775 client_maker_.MakeDummyCHLOPacket(packet_num++));
2776 quic_data.AddWrite(SYNCHRONOUS,
2777 client_maker_.MakeDummyCHLOPacket(packet_num++));
2778 quic_data.AddWrite(SYNCHRONOUS,
2779 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032780 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2781 quic_data.AddWrite(SYNCHRONOUS,
2782 client_maker_.MakeConnectionClosePacket(
2783 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522784 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:032785 quic_data.AddSocketDataToFactory(&socket_factory_);
2786
2787 // Add successful TCP data so that TCP job will succeed.
2788 MockWrite http_writes[] = {
2789 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2790 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2791 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2792
2793 MockRead http_reads[] = {
2794 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2795 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2796 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2797 SequencedSocketData http_data(http_reads, http_writes);
2798 socket_factory_.AddSocketDataProvider(&http_data);
2799 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2800
2801 // Quic connection will be retried on the alternate network after the initial
2802 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592803 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032804 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2805 quic_data2.AddWrite(SYNCHRONOUS,
2806 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2807
2808 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252809 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232810 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032811 quic_data2.AddSocketDataToFactory(&socket_factory_);
2812
2813 // Resolve the host resolution synchronously.
2814 host_resolver_.set_synchronous_mode(true);
2815 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2816 "");
Zhongyi Shia6b68d112018-09-24 07:49:032817
2818 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432819 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2820 false);
Zhongyi Shia6b68d112018-09-24 07:49:032821 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032822 QuicStreamFactoryPeer::SetAlarmFactory(
2823 session_->quic_stream_factory(),
2824 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222825 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032826 // Add alternate protocol mapping to race QUIC and TCP.
2827 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2828 // peer.
2829 AddQuicAlternateProtocolMapping(
2830 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2831
2832 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2833 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362834 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032835 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2836
2837 // Pump the message loop to get the request started.
2838 // Request will be served with TCP job.
2839 base::RunLoop().RunUntilIdle();
2840 EXPECT_THAT(callback.WaitForResult(), IsOk());
2841 CheckResponseData(&trans, "TCP succeeds");
2842
Zhongyi Shia6b68d112018-09-24 07:49:032843 // Fast forward to idle timeout the original connection. A new connection will
2844 // be kicked off on the alternate network.
2845 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2846 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2847 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2848
2849 // The second connection hasn't finish handshake, verify that QUIC is not
2850 // marked as broken.
2851 ExpectQuicAlternateProtocolMapping();
2852 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:282853 crypto_client_stream_factory_.last_stream()
2854 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia6b68d112018-09-24 07:49:032855 // Run message loop to execute posted tasks, which will notify JoController
2856 // about the orphaned job status.
2857 base::RunLoop().RunUntilIdle();
2858
2859 // Verify that QUIC is marked as broken.
2860 ExpectBrokenAlternateProtocolMapping();
2861
2862 // Deliver a message to notify the new network becomes default, the previous
2863 // brokenness will be clear as the brokenness is bond with old default
2864 // network.
2865 scoped_mock_change_notifier_->mock_network_change_notifier()
2866 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2867 ExpectQuicAlternateProtocolMapping();
2868
2869 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2870 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2871}
2872
Matt Menkeb32ba5122019-09-10 19:17:052873// Much like above test, but verifies NetworkIsolationKeys are respected.
2874TEST_P(QuicNetworkTransactionTest,
2875 RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432876 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2877 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2878 return;
2879 }
2880
Matt Menkeb32ba5122019-09-10 19:17:052881 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2882 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2883 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2884 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2885
2886 base::test::ScopedFeatureList feature_list;
2887 feature_list.InitWithFeatures(
2888 // enabled_features
2889 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2890 // Need to partition connections by NetworkIsolationKey for
2891 // QuicSessionAliasKey to include NetworkIsolationKeys.
2892 features::kPartitionConnectionsByNetworkIsolationKey},
2893 // disabled_features
2894 {});
2895 // Since HttpServerProperties caches the feature value, have to create a new
2896 // one.
2897 http_server_properties_ = std::make_unique<HttpServerProperties>();
2898
2899 SetUpTestForRetryConnectionOnAlternateNetwork();
2900
2901 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
2902
2903 // The request will initially go out over QUIC.
2904 MockQuicData quic_data(version_);
2905 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2906 int packet_num = 1;
2907 quic_data.AddWrite(SYNCHRONOUS,
2908 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2909 // Retranmit the handshake messages.
2910 quic_data.AddWrite(SYNCHRONOUS,
2911 client_maker_.MakeDummyCHLOPacket(packet_num++));
2912 quic_data.AddWrite(SYNCHRONOUS,
2913 client_maker_.MakeDummyCHLOPacket(packet_num++));
2914 quic_data.AddWrite(SYNCHRONOUS,
2915 client_maker_.MakeDummyCHLOPacket(packet_num++));
2916 quic_data.AddWrite(SYNCHRONOUS,
2917 client_maker_.MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052918 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2919 quic_data.AddWrite(SYNCHRONOUS,
2920 client_maker_.MakeConnectionClosePacket(
2921 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:522922 "No recent network activity after 4s. Timeout:4s"));
Matt Menkeb32ba5122019-09-10 19:17:052923 quic_data.AddSocketDataToFactory(&socket_factory_);
2924
2925 // Add successful TCP data so that TCP job will succeed.
2926 MockWrite http_writes[] = {
2927 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2928 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2929 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2930
2931 MockRead http_reads[] = {
2932 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2933 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2934 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2935 SequencedSocketData http_data(http_reads, http_writes);
2936 socket_factory_.AddSocketDataProvider(&http_data);
2937 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2938
2939 // Quic connection will be retried on the alternate network after the initial
2940 // one fails on the default network.
2941 MockQuicData quic_data2(version_);
2942 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2943 quic_data2.AddWrite(SYNCHRONOUS,
2944 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2945
2946 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252947 if (VersionUsesHttp3(version_.transport_version))
Matt Menkeb32ba5122019-09-10 19:17:052948 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
2949 quic_data2.AddSocketDataToFactory(&socket_factory_);
2950
2951 // Resolve the host resolution synchronously.
2952 host_resolver_.set_synchronous_mode(true);
2953 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2954 "");
2955
2956 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432957 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2958 false);
Matt Menkeb32ba5122019-09-10 19:17:052959 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2960 QuicStreamFactoryPeer::SetAlarmFactory(
2961 session_->quic_stream_factory(),
2962 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222963 context_.clock()));
Matt Menkeb32ba5122019-09-10 19:17:052964 // Add alternate protocol mapping to race QUIC and TCP.
2965 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2966 // peer.
2967 AddQuicAlternateProtocolMapping(
2968 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
2969 AddQuicAlternateProtocolMapping(
2970 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
2971
2972 request_.network_isolation_key = kNetworkIsolationKey1;
2973 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2974 TestCompletionCallback callback;
2975 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2977
2978 // Pump the message loop to get the request started.
2979 // Request will be served with TCP job.
2980 base::RunLoop().RunUntilIdle();
2981 EXPECT_THAT(callback.WaitForResult(), IsOk());
2982 CheckResponseData(&trans, "TCP succeeds");
2983
2984 // Fast forward to idle timeout the original connection. A new connection will
2985 // be kicked off on the alternate network.
2986 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2987 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2988 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2989
2990 // The second connection hasn't finish handshake, verify that QUIC is not
2991 // marked as broken.
2992 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2993 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2994 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:282995 crypto_client_stream_factory_.last_stream()
2996 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:052997 // Run message loop to execute posted tasks, which will notify JoController
2998 // about the orphaned job status.
2999 base::RunLoop().RunUntilIdle();
3000
3001 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
3002 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3003 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3004
3005 // Deliver a message to notify the new network becomes default, the previous
3006 // brokenness will be clear as the brokenness is bond with old default
3007 // network.
3008 scoped_mock_change_notifier_->mock_network_change_notifier()
3009 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3010 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
3011 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3012
3013 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3014 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3015}
3016
Zhongyi Shia6b68d112018-09-24 07:49:033017// This test verifies that a new QUIC connection will be attempted on the
3018// alternate network if the original QUIC connection fails with idle timeout
3019// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
3020// alternative network succeeds, QUIC is not marked as broken.
3021TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433022 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3023 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3024 return;
3025 }
3026
Zhongyi Shia6b68d112018-09-24 07:49:033027 SetUpTestForRetryConnectionOnAlternateNetwork();
3028
Michael Warres167db3e2019-03-01 21:38:033029 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:033030
3031 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593032 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:033033 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
3034 int packet_num = 1;
3035 quic_data.AddWrite(SYNCHRONOUS,
3036 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
3037 // Retranmit the handshake messages.
3038 quic_data.AddWrite(SYNCHRONOUS,
3039 client_maker_.MakeDummyCHLOPacket(packet_num++));
3040 quic_data.AddWrite(SYNCHRONOUS,
3041 client_maker_.MakeDummyCHLOPacket(packet_num++));
3042 quic_data.AddWrite(SYNCHRONOUS,
3043 client_maker_.MakeDummyCHLOPacket(packet_num++));
3044 quic_data.AddWrite(SYNCHRONOUS,
3045 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033046 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
3047 quic_data.AddWrite(SYNCHRONOUS,
3048 client_maker_.MakeConnectionClosePacket(
3049 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523050 "No recent network activity after 4s. Timeout:4s"));
Zhongyi Shia6b68d112018-09-24 07:49:033051 quic_data.AddSocketDataToFactory(&socket_factory_);
3052
3053 // Add hanging TCP data so that TCP job will never succeeded.
3054 AddHangingNonAlternateProtocolSocketData();
3055
3056 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:593057 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:233058 packet_num = 1;
Zhongyi Shia6b68d112018-09-24 07:49:033059 quic_data2.AddWrite(SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:233060 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:033061
Victor Vasiliev076657c2019-03-12 02:46:433062 const std::string body = "hello!";
3063 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:413064
Zhongyi Shia6b68d112018-09-24 07:49:033065 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253066 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233067 quic_data2.AddWrite(SYNCHRONOUS,
3068 ConstructInitialSettingsPacket(packet_num++));
3069 }
Zhongyi Shia6b68d112018-09-24 07:49:033070 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233071 SYNCHRONOUS,
3072 ConstructClientRequestHeadersPacket(
3073 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3074 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:033075 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333076 ASYNC, ConstructServerResponseHeadersPacket(
3077 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
3078 GetResponseHeaders("200 OK")));
3079 quic_data2.AddRead(
3080 ASYNC, ConstructServerDataPacket(
3081 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173082 header + body));
Renjie Tangaadb84b2019-08-31 01:00:233083 quic_data2.AddWrite(SYNCHRONOUS,
3084 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia6b68d112018-09-24 07:49:033085 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
3086 quic_data2.AddSocketDataToFactory(&socket_factory_);
3087
3088 // Resolve the host resolution synchronously.
3089 host_resolver_.set_synchronous_mode(true);
3090 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3091 "");
Zhongyi Shia6b68d112018-09-24 07:49:033092
3093 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433094 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3095 false);
Zhongyi Shia6b68d112018-09-24 07:49:033096 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:033097 QuicStreamFactoryPeer::SetAlarmFactory(
3098 session_->quic_stream_factory(),
3099 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223100 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:033101 // Add alternate protocol mapping to race QUIC and TCP.
3102 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3103 // peer.
3104 AddQuicAlternateProtocolMapping(
3105 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3106
3107 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3108 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363109 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:033110 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3111
3112 // Pump the message loop to get the request started.
3113 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:033114
3115 // Fast forward to idle timeout the original connection. A new connection will
3116 // be kicked off on the alternate network.
3117 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3118 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3119 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3120
3121 // Verify that QUIC is not marked as broken.
3122 ExpectQuicAlternateProtocolMapping();
3123 // Explicitly confirm the handshake on the second connection.
Fan Yang3673cc72020-02-07 14:49:283124 crypto_client_stream_factory_.last_stream()
3125 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia6b68d112018-09-24 07:49:033126
3127 // Read the response.
3128 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:413129 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:033130 // Verify that QUIC is not marked as broken.
3131 ExpectQuicAlternateProtocolMapping();
3132
3133 // Deliver a message to notify the new network becomes default.
3134 scoped_mock_change_notifier_->mock_network_change_notifier()
3135 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3136 ExpectQuicAlternateProtocolMapping();
3137 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3138 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3139}
3140
rch9ecde09b2017-04-08 00:18:233141// Verify that if a QUIC connection times out, the QuicHttpStream will
3142// return QUIC_PROTOCOL_ERROR.
3143TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433144 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3145 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3146 return;
3147 }
3148
Victor Vasilieva1e66d72019-12-05 17:55:383149 context_.params()->retry_without_alt_svc_on_quic_errors = false;
3150 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:233151
3152 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593153 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133154 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233155 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3156
Ryan Hamiltone940bd12019-06-30 02:46:453157 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033158 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493159 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253160 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493161 quic_data.AddWrite(SYNCHRONOUS,
3162 ConstructInitialSettingsPacket(packet_num++));
3163 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023164 quic_data.AddWrite(
3165 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453166 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493167 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3168 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453169
3170 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233171
Victor Vasiliev7da08172019-10-14 06:04:253172 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493173 // TLP 1
3174 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3175 1, packet_num++, true));
3176 // TLP 2
3177 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3178 2, packet_num++, true));
3179 // RTO 1
3180 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3181 1, packet_num++, true));
3182 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3183 2, packet_num++, true));
3184 // RTO 2
3185 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3186 1, packet_num++, true));
3187 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3188 2, packet_num++, true));
3189 // RTO 3
3190 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3191 1, packet_num++, true));
3192 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3193 2, packet_num++, true));
Ryan Hamilton3cc2c152019-07-09 19:36:013194
Findit2403b85d2019-11-19 05:06:373195 quic_data.AddWrite(SYNCHRONOUS,
3196 client_maker_.MakeConnectionClosePacket(
3197 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523198 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493199 } else {
3200 // Settings were sent in the request packet so there is only 1 packet to
3201 // retransmit.
3202 // TLP 1
3203 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3204 1, packet_num++, true));
3205 // TLP 2
3206 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3207 1, packet_num++, true));
3208 // RTO 1
3209 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3210 1, packet_num++, true));
3211 // RTO 2
3212 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3213 1, packet_num++, true));
3214 // RTO 3
3215 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3216 1, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373217
Nick Harper057264a82019-09-12 23:33:493218 quic_data.AddWrite(SYNCHRONOUS,
3219 client_maker_.MakeConnectionClosePacket(
3220 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523221 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493222 }
Fan Yang928f1632017-12-14 18:55:223223
rch9ecde09b2017-04-08 00:18:233224 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3225 quic_data.AddRead(ASYNC, OK);
3226 quic_data.AddSocketDataToFactory(&socket_factory_);
3227
3228 // In order for a new QUIC session to be established via alternate-protocol
3229 // without racing an HTTP connection, we need the host resolution to happen
3230 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3231 // connection to the the server, in this test we require confirmation
3232 // before encrypting so the HTTP job will still start.
3233 host_resolver_.set_synchronous_mode(true);
3234 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3235 "");
rch9ecde09b2017-04-08 00:18:233236
3237 CreateSession();
3238 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233239 QuicStreamFactoryPeer::SetAlarmFactory(
3240 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193241 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223242 context_.clock()));
rch9ecde09b2017-04-08 00:18:233243
Ryan Hamilton9835e662018-08-02 05:36:273244 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233245
3246 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3247 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363248 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3250
3251 // Pump the message loop to get the request started.
3252 base::RunLoop().RunUntilIdle();
3253 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283254 crypto_client_stream_factory_.last_stream()
3255 ->NotifySessionOneRttKeyAvailable();
rch9ecde09b2017-04-08 00:18:233256
3257 // Run the QUIC session to completion.
3258 quic_task_runner_->RunUntilIdle();
3259
3260 ExpectQuicAlternateProtocolMapping();
3261 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3262 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3263}
3264
3265// Verify that if a QUIC connection RTOs, the QuicHttpStream will
3266// return QUIC_PROTOCOL_ERROR.
3267TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433268 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3269 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3270 return;
3271 }
3272
Victor Vasilieva1e66d72019-12-05 17:55:383273 context_.params()->retry_without_alt_svc_on_quic_errors = false;
3274 context_.params()->connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233275
3276 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593277 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133278 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233279 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3280
Ryan Hamiltone940bd12019-06-30 02:46:453281 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033282 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493283 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:253284 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493285 quic_data.AddWrite(
3286 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3287 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023288 quic_data.AddWrite(
3289 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453290 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493291 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3292 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453293
3294 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253295 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493296 // TLP 1
3297 quic_data.AddWrite(SYNCHRONOUS,
3298 client_maker_.MakeRetransmissionPacket(1, 3, true));
3299 // TLP 2
3300 quic_data.AddWrite(SYNCHRONOUS,
3301 client_maker_.MakeRetransmissionPacket(2, 4, true));
3302 // RTO 1
3303 quic_data.AddWrite(SYNCHRONOUS,
3304 client_maker_.MakeRetransmissionPacket(1, 5, true));
3305 quic_data.AddWrite(SYNCHRONOUS,
3306 client_maker_.MakeRetransmissionPacket(2, 6, true));
3307 // RTO 2
3308 quic_data.AddWrite(SYNCHRONOUS,
3309 client_maker_.MakeRetransmissionPacket(1, 7, true));
3310 quic_data.AddWrite(SYNCHRONOUS,
3311 client_maker_.MakeRetransmissionPacket(2, 8, true));
3312 // RTO 3
3313 quic_data.AddWrite(SYNCHRONOUS,
3314 client_maker_.MakeRetransmissionPacket(1, 9, true));
3315 quic_data.AddWrite(SYNCHRONOUS,
3316 client_maker_.MakeRetransmissionPacket(2, 10, true));
3317 // RTO 4
3318 quic_data.AddWrite(SYNCHRONOUS,
3319 client_maker_.MakeRetransmissionPacket(1, 11, true));
3320 quic_data.AddWrite(SYNCHRONOUS,
3321 client_maker_.MakeRetransmissionPacket(2, 12, true));
3322 // RTO 5
3323 quic_data.AddWrite(SYNCHRONOUS,
3324 client_maker_.MakeConnectionClosePacket(
3325 13, true, quic::QUIC_TOO_MANY_RTOS,
3326 "5 consecutive retransmission timeouts"));
3327 } else {
3328 // TLP 1
3329 quic_data.AddWrite(SYNCHRONOUS,
3330 client_maker_.MakeRetransmissionPacket(1, 2, true));
3331 // TLP 2
3332 quic_data.AddWrite(SYNCHRONOUS,
3333 client_maker_.MakeRetransmissionPacket(1, 3, true));
3334 // RTO 1
3335 quic_data.AddWrite(SYNCHRONOUS,
3336 client_maker_.MakeRetransmissionPacket(1, 4, true));
3337 // RTO 2
3338 quic_data.AddWrite(SYNCHRONOUS,
3339 client_maker_.MakeRetransmissionPacket(1, 5, true));
3340 // RTO 3
3341 quic_data.AddWrite(SYNCHRONOUS,
3342 client_maker_.MakeRetransmissionPacket(1, 6, true));
3343 // RTO 4
3344 quic_data.AddWrite(SYNCHRONOUS,
3345 client_maker_.MakeRetransmissionPacket(1, 7, true));
3346 // RTO 5
3347 quic_data.AddWrite(SYNCHRONOUS,
3348 client_maker_.MakeConnectionClosePacket(
3349 8, true, quic::QUIC_TOO_MANY_RTOS,
3350 "5 consecutive retransmission timeouts"));
3351 }
rch9ecde09b2017-04-08 00:18:233352
3353 quic_data.AddRead(ASYNC, OK);
3354 quic_data.AddSocketDataToFactory(&socket_factory_);
3355
3356 // In order for a new QUIC session to be established via alternate-protocol
3357 // without racing an HTTP connection, we need the host resolution to happen
3358 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3359 // connection to the the server, in this test we require confirmation
3360 // before encrypting so the HTTP job will still start.
3361 host_resolver_.set_synchronous_mode(true);
3362 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3363 "");
rch9ecde09b2017-04-08 00:18:233364
3365 CreateSession();
3366 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233367 QuicStreamFactoryPeer::SetAlarmFactory(
3368 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193369 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223370 context_.clock()));
rch9ecde09b2017-04-08 00:18:233371
Ryan Hamilton9835e662018-08-02 05:36:273372 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233373
3374 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3375 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363376 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233377 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3378
3379 // Pump the message loop to get the request started.
3380 base::RunLoop().RunUntilIdle();
3381 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283382 crypto_client_stream_factory_.last_stream()
3383 ->NotifySessionOneRttKeyAvailable();
rch9ecde09b2017-04-08 00:18:233384
3385 // Run the QUIC session to completion.
3386 quic_task_runner_->RunUntilIdle();
3387
3388 ExpectQuicAlternateProtocolMapping();
3389 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3390 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3391}
3392
3393// Verify that if a QUIC connection RTOs, while there are no active streams
3394// QUIC will not be marked as broken.
3395TEST_P(QuicNetworkTransactionTest,
3396 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433397 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3398 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3399 return;
3400 }
3401
Victor Vasilieva1e66d72019-12-05 17:55:383402 context_.params()->connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233403
3404 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593405 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133406 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233407 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3408
Ryan Hamiltone940bd12019-06-30 02:46:453409 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033410 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493411 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:253412 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493413 quic_data.AddWrite(
3414 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3415 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023416 quic_data.AddWrite(
3417 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453418 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493419 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3420 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453421
3422 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233423
Victor Vasiliev7da08172019-10-14 06:04:253424 if (!VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493425 quic_data.AddWrite(SYNCHRONOUS,
3426 client_maker_.MakeRstPacket(
3427 packet_number++, true,
3428 GetNthClientInitiatedBidirectionalStreamId(0),
3429 quic::QUIC_STREAM_CANCELLED));
3430 // TLP 1
Bence Béky6e243aa2019-12-13 19:01:073431 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3432 1, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493433 // TLP 2
Bence Béky6e243aa2019-12-13 19:01:073434 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3435 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493436 // RTO 1
Bence Béky6e243aa2019-12-13 19:01:073437 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3438 1, packet_number++, true));
3439 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3440 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493441 // RTO 2
Bence Béky6e243aa2019-12-13 19:01:073442 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3443 1, packet_number++, true));
3444 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3445 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493446 // RTO 3
Bence Béky6e243aa2019-12-13 19:01:073447 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3448 1, packet_number++, true));
3449 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3450 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493451 // RTO 4
Bence Béky6e243aa2019-12-13 19:01:073452 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3453 1, packet_number++, true));
3454 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3455 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493456 // RTO 5
3457 quic_data.AddWrite(SYNCHRONOUS,
3458 client_maker_.MakeConnectionClosePacket(
Bence Béky6e243aa2019-12-13 19:01:073459 packet_number++, true, quic::QUIC_TOO_MANY_RTOS,
Nick Harper057264a82019-09-12 23:33:493460 "5 consecutive retransmission timeouts"));
Renjie Tang33f43ce2019-09-23 22:11:423461 } else {
3462 quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:073463 SYNCHRONOUS, ConstructClientDataPacket(
3464 packet_number++, GetQpackDecoderStreamId(), true,
3465 false, StreamCancellationQpackDecoderInstruction(0)));
3466 quic_data.AddWrite(SYNCHRONOUS,
3467 client_maker_.MakeRstPacket(
3468 packet_number++, true,
3469 GetNthClientInitiatedBidirectionalStreamId(0),
3470 quic::QUIC_STREAM_CANCELLED));
Renjie Tang33f43ce2019-09-23 22:11:423471 client_maker_.RemoveSavedStreamFrames(
3472 GetNthClientInitiatedBidirectionalStreamId(0));
Bence Béky6e243aa2019-12-13 19:01:073473
Bence Béky6e243aa2019-12-13 19:01:073474 // TLP 1
3475 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3476 1, packet_number++, true));
3477 // TLP 2
3478 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3479 2, packet_number++, true));
3480 // RTO 1
3481 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3482 3, packet_number++, true));
3483 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3484 4, packet_number++, true));
3485 // RTO 2
3486 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3487 1, packet_number++, true));
3488 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3489 2, packet_number++, true));
3490 // RTO 3
3491 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3492 3, packet_number++, true));
3493 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3494 4, packet_number++, true));
3495 // RTO 4
3496 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3497 1, packet_number++, true));
3498 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3499 2, packet_number++, true));
3500 // RTO 5
3501 quic_data.AddWrite(SYNCHRONOUS,
3502 client_maker_.MakeConnectionClosePacket(
3503 packet_number++, true, quic::QUIC_TOO_MANY_RTOS,
3504 "5 consecutive retransmission timeouts"));
Nick Harper057264a82019-09-12 23:33:493505 }
rch9ecde09b2017-04-08 00:18:233506
3507 quic_data.AddRead(ASYNC, OK);
3508 quic_data.AddSocketDataToFactory(&socket_factory_);
3509
3510 // In order for a new QUIC session to be established via alternate-protocol
3511 // without racing an HTTP connection, we need the host resolution to happen
3512 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3513 // connection to the the server, in this test we require confirmation
3514 // before encrypting so the HTTP job will still start.
3515 host_resolver_.set_synchronous_mode(true);
3516 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3517 "");
rch9ecde09b2017-04-08 00:18:233518
3519 CreateSession();
3520 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233521 QuicStreamFactoryPeer::SetAlarmFactory(
3522 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193523 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223524 context_.clock()));
rch9ecde09b2017-04-08 00:18:233525
Ryan Hamilton9835e662018-08-02 05:36:273526 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233527
Jeremy Roman0579ed62017-08-29 15:56:193528 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233529 session_.get());
3530 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363531 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233532 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3533
3534 // Pump the message loop to get the request started.
3535 base::RunLoop().RunUntilIdle();
3536 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283537 crypto_client_stream_factory_.last_stream()
3538 ->NotifySessionOneRttKeyAvailable();
rch9ecde09b2017-04-08 00:18:233539
3540 // Now cancel the request.
3541 trans.reset();
3542
3543 // Run the QUIC session to completion.
3544 quic_task_runner_->RunUntilIdle();
3545
3546 ExpectQuicAlternateProtocolMapping();
3547
3548 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3549}
3550
rch2f2991c2017-04-13 19:28:173551// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3552// the request fails with QUIC_PROTOCOL_ERROR.
3553TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433554 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3555 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3556 return;
3557 }
3558
Victor Vasilieva1e66d72019-12-05 17:55:383559 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173560 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593561 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033562 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493563 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253564 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493565 quic_data.AddWrite(SYNCHRONOUS,
3566 ConstructInitialSettingsPacket(packet_num++));
3567 }
3568 quic_data.AddWrite(
3569 SYNCHRONOUS,
3570 ConstructClientRequestHeadersPacket(
3571 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3572 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023573 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553574 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173575 // Peer sending data from an non-existing stream causes this end to raise
3576 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333577 quic_data.AddRead(
3578 ASYNC, ConstructServerRstPacket(
3579 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3580 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173581 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:373582 quic_data.AddWrite(SYNCHRONOUS,
3583 ConstructClientAckAndConnectionClosePacket(
Bence Békyde6290f2019-12-19 15:21:533584 packet_num++, 1, 1, 1, quic::QUIC_INVALID_STREAM_ID,
3585 quic_error_details, quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173586 quic_data.AddSocketDataToFactory(&socket_factory_);
3587
3588 // In order for a new QUIC session to be established via alternate-protocol
3589 // without racing an HTTP connection, we need the host resolution to happen
3590 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3591 // connection to the the server, in this test we require confirmation
3592 // before encrypting so the HTTP job will still start.
3593 host_resolver_.set_synchronous_mode(true);
3594 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3595 "");
rch2f2991c2017-04-13 19:28:173596
3597 CreateSession();
3598
Ryan Hamilton9835e662018-08-02 05:36:273599 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173600
3601 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3602 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363603 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173604 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3605
3606 // Pump the message loop to get the request started.
3607 base::RunLoop().RunUntilIdle();
3608 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283609 crypto_client_stream_factory_.last_stream()
3610 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:173611
3612 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553613 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173614
3615 // Run the QUIC session to completion.
3616 base::RunLoop().RunUntilIdle();
3617 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3618 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3619
3620 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3621 ExpectQuicAlternateProtocolMapping();
3622 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3623}
3624
rch2f2991c2017-04-13 19:28:173625// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3626// connection times out, then QUIC will be marked as broken and the request
3627// retried over TCP.
3628TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433629 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3630 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3631 return;
3632 }
3633
Victor Vasilieva1e66d72019-12-05 17:55:383634 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173635
3636 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593637 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133638 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173639 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3640
Ryan Hamiltone940bd12019-06-30 02:46:453641 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033642 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493643 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253644 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493645 quic_data.AddWrite(SYNCHRONOUS,
3646 client_maker_.MakeInitialSettingsPacket(packet_num++));
3647 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023648 quic_data.AddWrite(
3649 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453650 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493651 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3652 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453653
3654 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253655 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493656 // TLP 1
3657 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3658 1, packet_num++, true));
3659 // TLP 2
3660 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3661 2, packet_num++, true));
3662 // RTO 1
3663 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3664 1, packet_num++, true));
3665 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3666 2, packet_num++, true));
3667 // RTO 2
3668 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3669 1, packet_num++, true));
3670 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3671 2, packet_num++, true));
3672 // RTO 3
3673 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3674 1, packet_num++, true));
3675 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3676 2, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373677
3678 quic_data.AddWrite(SYNCHRONOUS,
3679 client_maker_.MakeConnectionClosePacket(
3680 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523681 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493682 } else {
3683 // TLP 1
3684 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3685 1, packet_num++, true));
3686 // TLP 2
3687 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3688 1, packet_num++, true));
3689 // RTO 1
3690 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3691 1, packet_num++, true));
3692 // RTO 2
3693 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3694 1, packet_num++, true));
3695 // RTO 3
3696 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3697 1, packet_num++, true));
3698
3699 quic_data.AddWrite(SYNCHRONOUS,
3700 client_maker_.MakeConnectionClosePacket(
3701 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Ryan Hamiltonf9a421f2020-01-31 21:09:523702 "No recent network activity after 4s. Timeout:4s"));
Nick Harper057264a82019-09-12 23:33:493703 }
Fan Yang928f1632017-12-14 18:55:223704
rch2f2991c2017-04-13 19:28:173705 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3706 quic_data.AddRead(ASYNC, OK);
3707 quic_data.AddSocketDataToFactory(&socket_factory_);
3708
3709 // After that fails, it will be resent via TCP.
3710 MockWrite http_writes[] = {
3711 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3712 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3713 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3714
3715 MockRead http_reads[] = {
3716 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3717 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3718 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013719 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173720 socket_factory_.AddSocketDataProvider(&http_data);
3721 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3722
3723 // In order for a new QUIC session to be established via alternate-protocol
3724 // without racing an HTTP connection, we need the host resolution to happen
3725 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3726 // connection to the the server, in this test we require confirmation
3727 // before encrypting so the HTTP job will still start.
3728 host_resolver_.set_synchronous_mode(true);
3729 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3730 "");
rch2f2991c2017-04-13 19:28:173731
3732 CreateSession();
3733 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173734 QuicStreamFactoryPeer::SetAlarmFactory(
3735 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193736 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223737 context_.clock()));
rch2f2991c2017-04-13 19:28:173738
Ryan Hamilton9835e662018-08-02 05:36:273739 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173740
3741 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3742 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363743 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173744 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3745
3746 // Pump the message loop to get the request started.
3747 base::RunLoop().RunUntilIdle();
3748 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283749 crypto_client_stream_factory_.last_stream()
3750 ->NotifySessionOneRttKeyAvailable();
rch2f2991c2017-04-13 19:28:173751
3752 // Run the QUIC session to completion.
3753 quic_task_runner_->RunUntilIdle();
3754 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3755
3756 ExpectQuicAlternateProtocolMapping();
3757
3758 // Let the transaction proceed which will result in QUIC being marked
3759 // as broken and the request falling back to TCP.
3760 EXPECT_THAT(callback.WaitForResult(), IsOk());
3761
3762 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3763 ASSERT_FALSE(http_data.AllReadDataConsumed());
3764
3765 // Read the response body over TCP.
3766 CheckResponseData(&trans, "hello world");
3767 ExpectBrokenAlternateProtocolMapping();
3768 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3769 ASSERT_TRUE(http_data.AllReadDataConsumed());
3770}
3771
rch2f2991c2017-04-13 19:28:173772// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3773// protocol error occurs after the handshake is confirmed, the request
3774// retried over TCP and the QUIC will be marked as broken.
3775TEST_P(QuicNetworkTransactionTest,
3776 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433777 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3778 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3779 return;
3780 }
3781
Victor Vasilieva1e66d72019-12-05 17:55:383782 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173783
3784 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593785 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033786 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493787 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253788 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493789 quic_data.AddWrite(SYNCHRONOUS,
3790 ConstructInitialSettingsPacket(packet_num++));
3791 }
3792 quic_data.AddWrite(
3793 SYNCHRONOUS,
3794 ConstructClientRequestHeadersPacket(
3795 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3796 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023797 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553798 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3799
rch2f2991c2017-04-13 19:28:173800 // Peer sending data from an non-existing stream causes this end to raise
3801 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333802 quic_data.AddRead(
3803 ASYNC, ConstructServerRstPacket(
3804 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3805 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173806 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:373807 quic_data.AddWrite(SYNCHRONOUS,
3808 ConstructClientAckAndConnectionClosePacket(
Bence Békyde6290f2019-12-19 15:21:533809 packet_num++, 1, 1, 1, quic::QUIC_INVALID_STREAM_ID,
3810 quic_error_details, quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173811 quic_data.AddSocketDataToFactory(&socket_factory_);
3812
3813 // After that fails, it will be resent via TCP.
3814 MockWrite http_writes[] = {
3815 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3816 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3817 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3818
3819 MockRead http_reads[] = {
3820 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3821 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3822 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013823 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173824 socket_factory_.AddSocketDataProvider(&http_data);
3825 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3826
3827 // In order for a new QUIC session to be established via alternate-protocol
3828 // without racing an HTTP connection, we need the host resolution to happen
3829 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3830 // connection to the the server, in this test we require confirmation
3831 // before encrypting so the HTTP job will still start.
3832 host_resolver_.set_synchronous_mode(true);
3833 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3834 "");
rch2f2991c2017-04-13 19:28:173835
3836 CreateSession();
3837
Ryan Hamilton9835e662018-08-02 05:36:273838 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173839
3840 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3841 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363842 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173843 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3844
3845 // Pump the message loop to get the request started.
3846 base::RunLoop().RunUntilIdle();
3847 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283848 crypto_client_stream_factory_.last_stream()
3849 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:553850 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173851
3852 // Run the QUIC session to completion.
3853 base::RunLoop().RunUntilIdle();
3854 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3855
3856 ExpectQuicAlternateProtocolMapping();
3857
3858 // Let the transaction proceed which will result in QUIC being marked
3859 // as broken and the request falling back to TCP.
3860 EXPECT_THAT(callback.WaitForResult(), IsOk());
3861
3862 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3863 ASSERT_FALSE(http_data.AllReadDataConsumed());
3864
3865 // Read the response body over TCP.
3866 CheckResponseData(&trans, "hello world");
3867 ExpectBrokenAlternateProtocolMapping();
3868 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3869 ASSERT_TRUE(http_data.AllReadDataConsumed());
3870}
3871
Matt Menkeb32ba5122019-09-10 19:17:053872// Much like above test, but verifies that NetworkIsolationKey is respected.
3873TEST_P(QuicNetworkTransactionTest,
3874 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433875 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3876 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3877 return;
3878 }
3879
Matt Menkeb32ba5122019-09-10 19:17:053880 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
3881 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
3882 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
3883 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
3884
3885 base::test::ScopedFeatureList feature_list;
3886 feature_list.InitWithFeatures(
3887 // enabled_features
3888 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3889 features::kPartitionConnectionsByNetworkIsolationKey},
3890 // disabled_features
3891 {});
3892 // Since HttpServerProperties caches the feature value, have to create a new
3893 // one.
3894 http_server_properties_ = std::make_unique<HttpServerProperties>();
3895
Victor Vasilieva1e66d72019-12-05 17:55:383896 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
Matt Menkeb32ba5122019-09-10 19:17:053897
3898 // The request will initially go out over QUIC.
3899 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:563900 uint64_t packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:053901 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:253902 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:563903 quic_data.AddWrite(SYNCHRONOUS,
3904 ConstructInitialSettingsPacket(packet_number++));
3905 }
3906 quic_data.AddWrite(
3907 SYNCHRONOUS,
3908 ConstructClientRequestHeadersPacket(
3909 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3910 true, GetRequestHeaders("GET", "https", "/")));
Matt Menkeb32ba5122019-09-10 19:17:053911 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:053912 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3913
3914 // Peer sending data from an non-existing stream causes this end to raise
3915 // error and close connection.
3916 quic_data.AddRead(
3917 ASYNC, ConstructServerRstPacket(
3918 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3919 quic::QUIC_STREAM_LAST_ERROR));
3920 std::string quic_error_details = "Data for nonexistent stream";
Bence Békyde6290f2019-12-19 15:21:533921 quic_data.AddWrite(SYNCHRONOUS,
3922 ConstructClientAckAndConnectionClosePacket(
3923 packet_number++, 1, 1, 1, quic::QUIC_INVALID_STREAM_ID,
3924 quic_error_details, quic::IETF_RST_STREAM));
Matt Menkeb32ba5122019-09-10 19:17:053925 quic_data.AddSocketDataToFactory(&socket_factory_);
3926
3927 // After that fails, it will be resent via TCP.
3928 MockWrite http_writes[] = {
3929 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3930 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3931 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3932
3933 MockRead http_reads[] = {
3934 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3935 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3936 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3937 SequencedSocketData http_data(http_reads, http_writes);
3938 socket_factory_.AddSocketDataProvider(&http_data);
3939 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3940
3941 // In order for a new QUIC session to be established via alternate-protocol
3942 // without racing an HTTP connection, we need the host resolution to happen
3943 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3944 // connection to the the server, in this test we require confirmation
3945 // before encrypting so the HTTP job will still start.
3946 host_resolver_.set_synchronous_mode(true);
3947 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3948 "");
3949
3950 CreateSession();
3951
3952 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3953 kNetworkIsolationKey1);
3954 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3955 kNetworkIsolationKey2);
3956
3957 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3958 TestCompletionCallback callback;
3959 request_.network_isolation_key = kNetworkIsolationKey1;
3960 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3961 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3962
3963 // Pump the message loop to get the request started.
3964 base::RunLoop().RunUntilIdle();
3965 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:283966 crypto_client_stream_factory_.last_stream()
3967 ->NotifySessionOneRttKeyAvailable();
Matt Menkeb32ba5122019-09-10 19:17:053968 quic_data.Resume();
3969
3970 // Run the QUIC session to completion.
3971 base::RunLoop().RunUntilIdle();
3972 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3973
3974 // Let the transaction proceed which will result in QUIC being marked
3975 // as broken and the request falling back to TCP.
3976 EXPECT_THAT(callback.WaitForResult(), IsOk());
3977 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3978 ASSERT_FALSE(http_data.AllReadDataConsumed());
3979
3980 // Read the response body over TCP.
3981 CheckResponseData(&trans, "hello world");
3982 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3983 ASSERT_TRUE(http_data.AllReadDataConsumed());
3984
3985 // The alternative service shouldhave been marked as broken under
3986 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3987 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3988 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3989
3990 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3991 AddHttpDataAndRunRequest();
3992 // Requests using other NetworkIsolationKeys can still use QUIC.
3993 request_.network_isolation_key = kNetworkIsolationKey2;
3994 AddQuicDataAndRunRequest();
3995
3996 // The last two requests should not have changed the alternative service
3997 // mappings.
3998 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3999 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
4000}
4001
rch30943ee2017-06-12 21:28:444002// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4003// request is reset from, then QUIC will be marked as broken and the request
4004// retried over TCP.
4005TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
Renjie Tang3d8a6ddd2019-11-20 00:18:434006 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
4007 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
4008 return;
4009 }
4010
rch30943ee2017-06-12 21:28:444011 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:594012 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:134013 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:444014 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
4015
Michael Warres167db3e2019-03-01 21:38:034016 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494017 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254018 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:494019 quic_data.AddWrite(SYNCHRONOUS,
4020 ConstructInitialSettingsPacket(packet_num++));
4021 }
Ryan Hamilton0d65a8c2019-06-07 00:46:024022 quic_data.AddWrite(
4023 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:454024 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:494025 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4026 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:454027
4028 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:554029 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:444030
Fan Yang32c5a112018-12-10 20:06:334031 quic_data.AddRead(ASYNC,
4032 ConstructServerRstPacket(
4033 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
4034 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444035
Bence Béky6e243aa2019-12-13 19:01:074036 if (VersionUsesHttp3(version_.transport_version)) {
4037 quic_data.AddWrite(SYNCHRONOUS,
4038 ConstructClientDataPacket(
4039 packet_num++, GetQpackDecoderStreamId(), true, false,
4040 StreamCancellationQpackDecoderInstruction(0)));
4041 }
4042
rch30943ee2017-06-12 21:28:444043 quic_data.AddRead(ASYNC, OK);
4044 quic_data.AddSocketDataToFactory(&socket_factory_);
4045
4046 // After that fails, it will be resent via TCP.
4047 MockWrite http_writes[] = {
4048 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4049 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
4050 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4051
4052 MockRead http_reads[] = {
4053 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4054 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4055 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014056 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444057 socket_factory_.AddSocketDataProvider(&http_data);
4058 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4059
4060 // In order for a new QUIC session to be established via alternate-protocol
4061 // without racing an HTTP connection, we need the host resolution to happen
4062 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4063 // connection to the the server, in this test we require confirmation
4064 // before encrypting so the HTTP job will still start.
4065 host_resolver_.set_synchronous_mode(true);
4066 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4067 "");
rch30943ee2017-06-12 21:28:444068
4069 CreateSession();
4070
Ryan Hamilton9835e662018-08-02 05:36:274071 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:444072
4073 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4074 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364075 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:444076 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4077
4078 // Pump the message loop to get the request started.
4079 base::RunLoop().RunUntilIdle();
4080 // Explicitly confirm the handshake.
Fan Yang3673cc72020-02-07 14:49:284081 crypto_client_stream_factory_.last_stream()
4082 ->NotifySessionOneRttKeyAvailable();
Ryan Hamiltonb01f886f2019-07-10 02:25:554083 quic_data.Resume();
rch30943ee2017-06-12 21:28:444084
4085 // Run the QUIC session to completion.
4086 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4087
4088 ExpectQuicAlternateProtocolMapping();
4089
4090 // Let the transaction proceed which will result in QUIC being marked
4091 // as broken and the request falling back to TCP.
4092 EXPECT_THAT(callback.WaitForResult(), IsOk());
4093
4094 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4095 ASSERT_FALSE(http_data.AllReadDataConsumed());
4096
4097 // Read the response body over TCP.
4098 CheckResponseData(&trans, "hello world");
4099 ExpectBrokenAlternateProtocolMapping();
4100 ASSERT_TRUE(http_data.AllWriteDataConsumed());
4101 ASSERT_TRUE(http_data.AllReadDataConsumed());
4102}
4103
Ryan Hamilton6c2a2a82017-12-15 02:06:284104// Verify that when an origin has two alt-svc advertisements, one local and one
4105// remote, that when the local is broken the request will go over QUIC via
4106// the remote Alt-Svc.
4107// This is a regression test for crbug/825646.
4108TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:384109 context_.params()->allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:284110
4111 GURL origin1 = request_.url; // mail.example.org
4112 GURL origin2("https://www.example.org/");
4113 ASSERT_NE(origin1.host(), origin2.host());
4114
4115 scoped_refptr<X509Certificate> cert(
4116 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244117 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4118 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:284119
4120 ProofVerifyDetailsChromium verify_details;
4121 verify_details.cert_verify_result.verified_cert = cert;
4122 verify_details.cert_verify_result.is_issued_by_known_root = true;
4123 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4124
Ryan Hamiltonabad59e2019-06-06 04:02:594125 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234126 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254127 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234128 mock_quic_data.AddWrite(SYNCHRONOUS,
4129 ConstructInitialSettingsPacket(packet_num++));
4130 }
Ryan Hamilton6c2a2a82017-12-15 02:06:284131 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234132 SYNCHRONOUS,
4133 ConstructClientRequestHeadersPacket(
4134 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4135 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434136 mock_quic_data.AddRead(
4137 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334138 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024139 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434140 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434141 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334142 ASYNC, ConstructServerDataPacket(
4143 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174144 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234145 mock_quic_data.AddWrite(SYNCHRONOUS,
4146 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284147 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4148 mock_quic_data.AddRead(ASYNC, 0); // EOF
4149
4150 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:594151 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:284152 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4153 AddHangingNonAlternateProtocolSocketData();
4154
4155 CreateSession();
4156
4157 // Set up alternative service for |origin1|.
4158 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4159 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4160 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4161 AlternativeServiceInfoVector alternative_services;
4162 alternative_services.push_back(
4163 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4164 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384165 context_.params()->supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:284166 alternative_services.push_back(
4167 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4168 remote_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384169 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494170 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4171 NetworkIsolationKey(),
4172 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:284173
Matt Menkeb32ba5122019-09-10 19:17:054174 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4175 NetworkIsolationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:284176
4177 SendRequestAndExpectQuicResponse("hello!");
4178}
4179
Ryan Hamilton899c2e082019-11-14 01:22:024180// Verify that when multiple alternatives are broken,
4181// ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
4182// This is a regression test for crbug/1024613.
4183TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
4184 base::HistogramTester histogram_tester;
4185
4186 MockRead http_reads[] = {
4187 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4188 MockRead("hello world"),
4189 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4190 MockRead(ASYNC, OK)};
4191
4192 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4193 socket_factory_.AddSocketDataProvider(&http_data);
4194 AddCertificate(&ssl_data_);
4195 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4196
4197 GURL origin1 = request_.url; // mail.example.org
4198
4199 scoped_refptr<X509Certificate> cert(
4200 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
4201 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
4202
4203 ProofVerifyDetailsChromium verify_details;
4204 verify_details.cert_verify_result.verified_cert = cert;
4205 verify_details.cert_verify_result.is_issued_by_known_root = true;
4206 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4207
4208 CreateSession();
4209
4210 // Set up alternative service for |origin1|.
4211 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4212 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4213 AlternativeServiceInfoVector alternative_services;
4214 alternative_services.push_back(
4215 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4216 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384217 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024218 alternative_services.push_back(
4219 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4220 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384221 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024222 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4223 NetworkIsolationKey(),
4224 alternative_services);
4225
4226 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4227 NetworkIsolationKey());
4228
4229 SendRequestAndExpectHttpResponse("hello world");
4230
4231 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
4232 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
4233}
4234
rch30943ee2017-06-12 21:28:444235// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4236// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:054237// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:444238// connection instead of going back to the broken QUIC connection.
4239// This is a regression tests for crbug/731303.
4240TEST_P(QuicNetworkTransactionTest,
4241 ResetPooledAfterHandshakeConfirmedThenBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:384242 context_.params()->allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444243
4244 GURL origin1 = request_.url;
4245 GURL origin2("https://www.example.org/");
4246 ASSERT_NE(origin1.host(), origin2.host());
4247
Ryan Hamiltonabad59e2019-06-06 04:02:594248 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:444249
4250 scoped_refptr<X509Certificate> cert(
4251 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244252 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4253 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444254
4255 ProofVerifyDetailsChromium verify_details;
4256 verify_details.cert_verify_result.verified_cert = cert;
4257 verify_details.cert_verify_result.is_issued_by_known_root = true;
4258 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4259
Renjie Tangaadb84b2019-08-31 01:00:234260 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254261 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234262 mock_quic_data.AddWrite(SYNCHRONOUS,
4263 ConstructInitialSettingsPacket(packet_num++));
4264 }
rch30943ee2017-06-12 21:28:444265 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434266 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234267 SYNCHRONOUS,
4268 ConstructClientRequestHeadersPacket(
4269 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4270 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434271 mock_quic_data.AddRead(
4272 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334273 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024274 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434275 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434276 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334277 ASYNC, ConstructServerDataPacket(
4278 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174279 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234280 mock_quic_data.AddWrite(SYNCHRONOUS,
4281 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rch30943ee2017-06-12 21:28:444282
4283 // Second request will go over the pooled QUIC connection, but will be
4284 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054285 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224286 version_,
4287 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4288 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054289 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174290 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224291 version_,
4292 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4293 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434294 mock_quic_data.AddWrite(
4295 SYNCHRONOUS,
4296 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234297 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4298 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024299 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334300 mock_quic_data.AddRead(
4301 ASYNC, ConstructServerRstPacket(
4302 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4303 quic::QUIC_HEADERS_TOO_LARGE));
Bence Béky6e243aa2019-12-13 19:01:074304
4305 if (VersionUsesHttp3(version_.transport_version)) {
4306 mock_quic_data.AddWrite(
4307 SYNCHRONOUS, ConstructClientDataPacket(
4308 packet_num++, GetQpackDecoderStreamId(), true, false,
4309 StreamCancellationQpackDecoderInstruction(1)));
4310 }
4311
rch30943ee2017-06-12 21:28:444312 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4313 mock_quic_data.AddRead(ASYNC, 0); // EOF
4314
4315 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4316
4317 // After that fails, it will be resent via TCP.
4318 MockWrite http_writes[] = {
4319 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4320 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4321 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4322
4323 MockRead http_reads[] = {
4324 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4325 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4326 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014327 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444328 socket_factory_.AddSocketDataProvider(&http_data);
4329 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4330
Ryan Hamilton6c2a2a82017-12-15 02:06:284331 // Then the next request to the second origin will be sent over TCP.
4332 socket_factory_.AddSocketDataProvider(&http_data);
4333 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444334
4335 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564336 QuicStreamFactoryPeer::SetAlarmFactory(
4337 session_->quic_stream_factory(),
4338 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224339 context_.clock()));
rch30943ee2017-06-12 21:28:444340
4341 // Set up alternative service for |origin1|.
4342 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244343 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494344 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074345 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4346 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:444347
4348 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244349 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494350 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074351 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4352 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344353
rch30943ee2017-06-12 21:28:444354 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524355 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444356 SendRequestAndExpectQuicResponse("hello!");
4357
4358 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524359 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:054360 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:444361 request_.url = origin2;
4362 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:054363 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
4364 alternative1, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244365 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:054366 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
4367 alternative2, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244368 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444369
Matt Menkeb32ba5122019-09-10 19:17:054370 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:444371 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284372 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444373}
4374
bnc8be55ebb2015-10-30 14:12:074375TEST_P(QuicNetworkTransactionTest,
4376 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564377 std::string altsvc_header =
4378 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4379 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074380 MockRead http_reads[] = {
4381 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4382 MockRead("hello world"),
4383 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4384 MockRead(ASYNC, OK)};
4385
Ryan Sleevib8d7ea02018-05-07 20:01:014386 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074387 socket_factory_.AddSocketDataProvider(&http_data);
4388 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4389 socket_factory_.AddSocketDataProvider(&http_data);
4390 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4391
rch3f4b8452016-02-23 16:59:324392 CreateSession();
bnc8be55ebb2015-10-30 14:12:074393
4394 SendRequestAndExpectHttpResponse("hello world");
4395 SendRequestAndExpectHttpResponse("hello world");
4396}
4397
Xida Chen9bfe0b62018-04-24 19:52:214398// When multiple alternative services are advertised, HttpStreamFactory should
4399// select the alternative service which uses existing QUIC session if available.
4400// If no existing QUIC session can be used, use the first alternative service
4401// from the list.
zhongyi32569c62016-01-08 02:54:304402TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:384403 context_.params()->allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524404 MockRead http_reads[] = {
4405 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294406 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524407 MockRead("hello world"),
4408 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4409 MockRead(ASYNC, OK)};
4410
Ryan Sleevib8d7ea02018-05-07 20:01:014411 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524412 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084413 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564414 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524415
zhongyi32569c62016-01-08 02:54:304416 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294417 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304418 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594419 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234420 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254421 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234422 mock_quic_data.AddWrite(SYNCHRONOUS,
4423 ConstructInitialSettingsPacket(packet_num++));
4424 }
rch5cb522462017-04-25 20:18:364425 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234426 SYNCHRONOUS,
4427 ConstructClientRequestHeadersPacket(
4428 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4429 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304430
4431 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294432 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4433 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434434 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024435 ASYNC, ConstructServerResponseHeadersPacket(
4436 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4437 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434438 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434439 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334440 ASYNC, ConstructServerDataPacket(
4441 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174442 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234443 mock_quic_data.AddWrite(SYNCHRONOUS,
4444 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304445
4446 // Second QUIC request data.
4447 // Connection pooling, using existing session, no need to include version
4448 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584449 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234450 SYNCHRONOUS,
4451 ConstructClientRequestHeadersPacket(
4452 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4453 true, GetRequestHeaders("GET", "https", "/"),
4454 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434455 mock_quic_data.AddRead(
4456 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334457 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024458 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434459 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334460 ASYNC, ConstructServerDataPacket(
4461 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174462 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434463 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234464 SYNCHRONOUS,
4465 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bncc958faa2015-07-31 18:14:524466 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594467 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524468
4469 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4470
rtennetib8e80fb2016-05-16 00:12:094471 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324472 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564473 QuicStreamFactoryPeer::SetAlarmFactory(
4474 session_->quic_stream_factory(),
4475 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224476 context_.clock()));
bncc958faa2015-07-31 18:14:524477
4478 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304479
bnc359ed2a2016-04-29 20:43:454480 SendRequestAndExpectQuicResponse("hello!");
4481 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304482}
4483
tbansal6490783c2016-09-20 17:55:274484// Check that an existing QUIC connection to an alternative proxy server is
4485// used.
4486TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4487 base::HistogramTester histogram_tester;
4488
tbansal6490783c2016-09-20 17:55:274489 // First QUIC request data.
4490 // Open a session to foo.example.org:443 using the first entry of the
4491 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594492 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234493 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254494 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234495 mock_quic_data.AddWrite(SYNCHRONOUS,
4496 ConstructInitialSettingsPacket(packet_num++));
4497 }
rch5cb522462017-04-25 20:18:364498 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234499 SYNCHRONOUS,
4500 ConstructClientRequestHeadersPacket(
4501 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4502 true, GetRequestHeaders("GET", "http", "/")));
tbansal6490783c2016-09-20 17:55:274503
4504 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434505 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024506 ASYNC, ConstructServerResponseHeadersPacket(
4507 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4508 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434509 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434510 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334511 ASYNC, ConstructServerDataPacket(
4512 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174513 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234514 mock_quic_data.AddWrite(SYNCHRONOUS,
4515 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274516
4517 // Second QUIC request data.
4518 // Connection pooling, using existing session, no need to include version
4519 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274520 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234521 SYNCHRONOUS,
4522 ConstructClientRequestHeadersPacket(
4523 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4524 true, GetRequestHeaders("GET", "http", "/"),
4525 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434526 mock_quic_data.AddRead(
4527 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334528 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024529 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434530 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334531 ASYNC, ConstructServerDataPacket(
4532 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174533 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434534 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234535 SYNCHRONOUS,
4536 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274537 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4538 mock_quic_data.AddRead(ASYNC, 0); // EOF
4539
4540 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4541
4542 AddHangingNonAlternateProtocolSocketData();
4543
4544 TestProxyDelegate test_proxy_delegate;
4545
Nicolas Arciniegad2013f92020-02-07 23:00:564546 proxy_resolution_service_ =
4547 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
4548 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274549
4550 test_proxy_delegate.set_alternative_proxy_server(
4551 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524552 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274553
4554 request_.url = GURL("http://mail.example.org/");
4555
4556 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564557 QuicStreamFactoryPeer::SetAlarmFactory(
4558 session_->quic_stream_factory(),
4559 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224560 context_.clock()));
tbansal6490783c2016-09-20 17:55:274561
4562 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4563 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4564 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4565 1);
4566
4567 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4568 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4569 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4570 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4571 1);
4572}
4573
Ryan Hamilton8d9ee76e2018-05-29 23:52:524574// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454575// even if alternative service destination is different.
4576TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Victor Vasilieva1e66d72019-12-05 17:55:384577 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594578 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454579
Renjie Tangaadb84b2019-08-31 01:00:234580 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254581 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234582 mock_quic_data.AddWrite(SYNCHRONOUS,
4583 ConstructInitialSettingsPacket(packet_num++));
4584 }
bnc359ed2a2016-04-29 20:43:454585 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434586 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234587 SYNCHRONOUS,
4588 ConstructClientRequestHeadersPacket(
4589 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4590 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434591 mock_quic_data.AddRead(
4592 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334593 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024594 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434595 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434596 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334597 ASYNC, ConstructServerDataPacket(
4598 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174599 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234600 mock_quic_data.AddWrite(SYNCHRONOUS,
4601 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304602
bnc359ed2a2016-04-29 20:43:454603 // Second request.
alyssar2adf3ac2016-05-03 17:12:584604 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234605 SYNCHRONOUS,
4606 ConstructClientRequestHeadersPacket(
4607 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4608 true, GetRequestHeaders("GET", "https", "/"),
4609 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434610 mock_quic_data.AddRead(
4611 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334612 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024613 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434614 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334615 ASYNC, ConstructServerDataPacket(
4616 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174617 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434618 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234619 SYNCHRONOUS,
4620 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304621 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4622 mock_quic_data.AddRead(ASYNC, 0); // EOF
4623
4624 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454625
4626 AddHangingNonAlternateProtocolSocketData();
4627 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304628
rch3f4b8452016-02-23 16:59:324629 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564630 QuicStreamFactoryPeer::SetAlarmFactory(
4631 session_->quic_stream_factory(),
4632 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224633 context_.clock()));
zhongyi32569c62016-01-08 02:54:304634
bnc359ed2a2016-04-29 20:43:454635 const char destination1[] = "first.example.com";
4636 const char destination2[] = "second.example.com";
4637
4638 // Set up alternative service entry to destination1.
4639 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214640 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454641 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494642 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074643 server, NetworkIsolationKey(), alternative_service, expiration,
4644 supported_versions_);
bnc359ed2a2016-04-29 20:43:454645 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524646 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454647 SendRequestAndExpectQuicResponse("hello!");
4648
4649 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214650 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494651 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074652 server, NetworkIsolationKey(), alternative_service, expiration,
4653 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524654 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454655 // even though alternative service destination is different.
4656 SendRequestAndExpectQuicResponse("hello!");
4657}
4658
4659// Pool to existing session with matching destination and matching certificate
4660// even if origin is different, and even if the alternative service with
4661// matching destination is not the first one on the list.
4662TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Victor Vasilieva1e66d72019-12-05 17:55:384663 context_.params()->allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454664 GURL origin1 = request_.url;
4665 GURL origin2("https://www.example.org/");
4666 ASSERT_NE(origin1.host(), origin2.host());
4667
Ryan Hamiltonabad59e2019-06-06 04:02:594668 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454669
Renjie Tangaadb84b2019-08-31 01:00:234670 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254671 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234672 mock_quic_data.AddWrite(SYNCHRONOUS,
4673 ConstructInitialSettingsPacket(packet_num++));
4674 }
bnc359ed2a2016-04-29 20:43:454675 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434676 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234677 SYNCHRONOUS,
4678 ConstructClientRequestHeadersPacket(
4679 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4680 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434681 mock_quic_data.AddRead(
4682 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334683 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024684 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434685 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434686 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334687 ASYNC, ConstructServerDataPacket(
4688 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174689 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234690 mock_quic_data.AddWrite(SYNCHRONOUS,
4691 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454692
4693 // Second request.
Yixin Wang079ad542018-01-11 04:06:054694 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224695 version_,
4696 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4697 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054698 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174699 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224700 version_,
4701 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4702 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584703 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434704 SYNCHRONOUS,
4705 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234706 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4707 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024708 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434709 mock_quic_data.AddRead(
4710 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334711 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024712 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434713 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334714 ASYNC, ConstructServerDataPacket(
4715 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174716 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434717 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234718 SYNCHRONOUS,
4719 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454720 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4721 mock_quic_data.AddRead(ASYNC, 0); // EOF
4722
4723 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4724
4725 AddHangingNonAlternateProtocolSocketData();
4726 AddHangingNonAlternateProtocolSocketData();
4727
4728 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564729 QuicStreamFactoryPeer::SetAlarmFactory(
4730 session_->quic_stream_factory(),
4731 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224732 context_.clock()));
bnc359ed2a2016-04-29 20:43:454733
4734 const char destination1[] = "first.example.com";
4735 const char destination2[] = "second.example.com";
4736
4737 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214738 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454739 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494740 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074741 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4742 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454743
4744 // Set up multiple alternative service entries for |origin2|,
4745 // the first one with a different destination as for |origin1|,
4746 // the second one with the same. The second one should be used,
4747 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214748 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454749 AlternativeServiceInfoVector alternative_services;
4750 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214751 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4752 alternative_service2, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384753 context_.params()->supported_versions));
bnc359ed2a2016-04-29 20:43:454754 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214755 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4756 alternative_service1, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384757 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494758 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4759 NetworkIsolationKey(),
4760 alternative_services);
bnc359ed2a2016-04-29 20:43:454761 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524762 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454763 SendRequestAndExpectQuicResponse("hello!");
4764
4765 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524766 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454767 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584768
bnc359ed2a2016-04-29 20:43:454769 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304770}
4771
4772// Multiple origins have listed the same alternative services. When there's a
4773// existing QUIC session opened by a request to other origin,
4774// if the cert is valid, should select this QUIC session to make the request
4775// if this is also the first existing QUIC session.
4776TEST_P(QuicNetworkTransactionTest,
4777 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Victor Vasilieva1e66d72019-12-05 17:55:384778 context_.params()->allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294779 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304780
rch9ae5b3b2016-02-11 00:36:294781 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304782 MockRead http_reads[] = {
4783 MockRead("HTTP/1.1 200 OK\r\n"),
4784 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294785 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304786 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4787 MockRead(ASYNC, OK)};
4788
Ryan Sleevib8d7ea02018-05-07 20:01:014789 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304790 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084791 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304792 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4793
4794 // HTTP data for request to mail.example.org.
4795 MockRead http_reads2[] = {
4796 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294797 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304798 MockRead("hello world from mail.example.org"),
4799 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4800 MockRead(ASYNC, OK)};
4801
Ryan Sleevib8d7ea02018-05-07 20:01:014802 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304803 socket_factory_.AddSocketDataProvider(&http_data2);
4804 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4805
Yixin Wang079ad542018-01-11 04:06:054806 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:224807 version_,
4808 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4809 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054810 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584811 server_maker_.set_hostname("www.example.org");
4812 client_maker_.set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594813 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234814 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254815 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234816 mock_quic_data.AddWrite(SYNCHRONOUS,
4817 ConstructInitialSettingsPacket(packet_num++));
4818 }
zhongyi32569c62016-01-08 02:54:304819 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584820 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234821 SYNCHRONOUS,
4822 ConstructClientRequestHeadersPacket(
4823 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4824 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434825
4826 mock_quic_data.AddRead(
4827 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334828 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024829 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434830 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334831 mock_quic_data.AddRead(
4832 ASYNC, ConstructServerDataPacket(
4833 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174834 header + "hello from mail QUIC!"));
Renjie Tangaadb84b2019-08-31 01:00:234835 mock_quic_data.AddWrite(SYNCHRONOUS,
4836 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434837 // Second QUIC request data.
4838 mock_quic_data.AddWrite(
4839 SYNCHRONOUS,
4840 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234841 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4842 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024843 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434844 mock_quic_data.AddRead(
4845 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334846 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024847 GetResponseHeaders("200 OK")));
Fan Yang32c5a112018-12-10 20:06:334848 mock_quic_data.AddRead(
4849 ASYNC, ConstructServerDataPacket(
4850 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174851 header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434852 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234853 SYNCHRONOUS,
4854 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304855 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4856 mock_quic_data.AddRead(ASYNC, 0); // EOF
4857
4858 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304859
rtennetib8e80fb2016-05-16 00:12:094860 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324861 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564862 QuicStreamFactoryPeer::SetAlarmFactory(
4863 session_->quic_stream_factory(),
4864 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224865 context_.clock()));
zhongyi32569c62016-01-08 02:54:304866
4867 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294868 request_.url = GURL("https://www.example.org/");
4869 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304870 request_.url = GURL("https://mail.example.org/");
4871 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4872
rch9ae5b3b2016-02-11 00:36:294873 // Open a QUIC session to mail.example.org:443 when making request
4874 // to mail.example.org.
4875 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454876 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304877
rch9ae5b3b2016-02-11 00:36:294878 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304879 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454880 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524881}
4882
4883TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524884 MockRead http_reads[] = {
4885 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564886 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524887 MockRead("hello world"),
4888 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4889 MockRead(ASYNC, OK)};
4890
Ryan Sleevib8d7ea02018-05-07 20:01:014891 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524892 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084893 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564894 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524895
rtennetib8e80fb2016-05-16 00:12:094896 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324897 CreateSession();
bncc958faa2015-07-31 18:14:524898
4899 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454900
4901 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344902 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494903 http_server_properties_->GetAlternativeServiceInfos(
4904 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344905 ASSERT_EQ(1u, alternative_service_info_vector.size());
4906 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544907 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344908 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4909 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4910 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524911}
4912
4913TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524914 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564915 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4916 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524917 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4918 MockRead(ASYNC, OK)};
4919
Ryan Sleevib8d7ea02018-05-07 20:01:014920 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524921 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084922 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564923 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524924
Ryan Hamiltonabad59e2019-06-06 04:02:594925 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234926 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254927 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234928 mock_quic_data.AddWrite(SYNCHRONOUS,
4929 ConstructInitialSettingsPacket(packet_num++));
4930 }
rch5cb522462017-04-25 20:18:364931 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234932 SYNCHRONOUS,
4933 ConstructClientRequestHeadersPacket(
4934 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4935 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434936 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334937 ASYNC, ConstructServerResponseHeadersPacket(
4938 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4939 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434940 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334941 mock_quic_data.AddRead(
4942 ASYNC, ConstructServerDataPacket(
4943 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174944 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234945 mock_quic_data.AddWrite(SYNCHRONOUS,
4946 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524947 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4948 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524949
4950 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4951
rtennetib8e80fb2016-05-16 00:12:094952 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324953 CreateSession();
bncc958faa2015-07-31 18:14:524954
bnc3472afd2016-11-17 15:27:214955 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524956 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494957 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054958 alternative_service, NetworkIsolationKey());
Matt Menke3233d8f22019-08-20 21:01:494959 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054960 alternative_service, NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524961
4962 SendRequestAndExpectHttpResponse("hello world");
4963 SendRequestAndExpectQuicResponse("hello!");
4964
mmenkee24011922015-12-17 22:12:594965 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524966
Matt Menke3233d8f22019-08-20 21:01:494967 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054968 alternative_service, NetworkIsolationKey()));
Matt Menke19475f72019-08-21 18:57:444969 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4970 url::SchemeHostPort("https", request_.url.host(), 443),
4971 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524972}
4973
Matt Menkeb32ba5122019-09-10 19:17:054974TEST_P(QuicNetworkTransactionTest,
4975 ConfirmAlternativeServiceWithNetworkIsolationKey) {
4976 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
4977 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
4978 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
4979 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
4980
4981 base::test::ScopedFeatureList feature_list;
4982 feature_list.InitWithFeatures(
4983 // enabled_features
4984 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4985 features::kPartitionConnectionsByNetworkIsolationKey},
4986 // disabled_features
4987 {});
4988 // Since HttpServerProperties caches the feature value, have to create a new
4989 // one.
4990 http_server_properties_ = std::make_unique<HttpServerProperties>();
4991
4992 MockRead http_reads[] = {
4993 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4994 MockRead("hello world"),
4995 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4996 MockRead(ASYNC, OK)};
4997
4998 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4999 socket_factory_.AddSocketDataProvider(&http_data);
5000 AddCertificate(&ssl_data_);
5001 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5002
5003 MockQuicData mock_quic_data(version_);
5004 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255005 if (VersionUsesHttp3(version_.transport_version)) {
Matt Menkeb32ba5122019-09-10 19:17:055006 mock_quic_data.AddWrite(SYNCHRONOUS,
5007 ConstructInitialSettingsPacket(packet_num++));
5008 }
5009 mock_quic_data.AddWrite(
5010 SYNCHRONOUS,
5011 ConstructClientRequestHeadersPacket(
5012 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5013 true, GetRequestHeaders("GET", "https", "/")));
5014 mock_quic_data.AddRead(
5015 ASYNC, ConstructServerResponseHeadersPacket(
5016 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5017 GetResponseHeaders("200 OK")));
5018 std::string header = ConstructDataHeader(6);
5019 mock_quic_data.AddRead(
5020 ASYNC, ConstructServerDataPacket(
5021 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
5022 header + "hello!"));
5023 mock_quic_data.AddWrite(SYNCHRONOUS,
5024 ConstructClientAckPacket(packet_num++, 2, 1, 1));
5025 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5026 mock_quic_data.AddRead(ASYNC, 0); // EOF
5027
5028 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5029
5030 CreateSession();
5031
5032 AlternativeService alternative_service(kProtoQUIC,
5033 HostPortPair::FromURL(request_.url));
5034 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
5035 alternative_service, kNetworkIsolationKey1);
5036 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
5037 alternative_service, kNetworkIsolationKey2);
5038 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5039 alternative_service, kNetworkIsolationKey1));
5040 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5041 alternative_service, kNetworkIsolationKey2));
5042
5043 request_.network_isolation_key = kNetworkIsolationKey1;
5044 SendRequestAndExpectHttpResponse("hello world");
5045 SendRequestAndExpectQuicResponse("hello!");
5046
5047 mock_quic_data.Resume();
5048
5049 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5050 alternative_service, kNetworkIsolationKey1));
5051 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
5052 url::SchemeHostPort("https", request_.url.host(), 443),
5053 kNetworkIsolationKey1));
5054 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5055 alternative_service, kNetworkIsolationKey2));
5056 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5057 url::SchemeHostPort("https", request_.url.host(), 443),
5058 kNetworkIsolationKey2));
5059}
5060
bncc958faa2015-07-31 18:14:525061TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:525062 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565063 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5064 MockRead("hello world"),
bncc958faa2015-07-31 18:14:525065 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5066 MockRead(ASYNC, OK)};
5067
Ryan Sleevib8d7ea02018-05-07 20:01:015068 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:525069 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565070 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:525071
Ryan Hamiltonabad59e2019-06-06 04:02:595072 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235073 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255074 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235075 mock_quic_data.AddWrite(SYNCHRONOUS,
5076 ConstructInitialSettingsPacket(packet_num++));
5077 }
rch5cb522462017-04-25 20:18:365078 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235079 SYNCHRONOUS,
5080 ConstructClientRequestHeadersPacket(
5081 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5082 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435083 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335084 ASYNC, ConstructServerResponseHeadersPacket(
5085 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5086 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435087 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335088 mock_quic_data.AddRead(
5089 ASYNC, ConstructServerDataPacket(
5090 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175091 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235092 mock_quic_data.AddWrite(SYNCHRONOUS,
5093 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:525094 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
5095
5096 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5097
5098 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325099 CreateSession();
bncc958faa2015-07-31 18:14:525100
5101 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
5102 SendRequestAndExpectHttpResponse("hello world");
5103}
5104
tbansalc3308d72016-08-27 10:25:045105// Tests that the connection to an HTTPS proxy is raced with an available
5106// alternative proxy server.
5107TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:275108 base::HistogramTester histogram_tester;
Nicolas Arciniegad2013f92020-02-07 23:00:565109 proxy_resolution_service_ =
5110 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
5111 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045112
Ryan Hamiltonabad59e2019-06-06 04:02:595113 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235114 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255115 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235116 mock_quic_data.AddWrite(SYNCHRONOUS,
5117 ConstructInitialSettingsPacket(packet_num++));
5118 }
rch5cb522462017-04-25 20:18:365119 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235120 SYNCHRONOUS,
5121 ConstructClientRequestHeadersPacket(
5122 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5123 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435124 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335125 ASYNC, ConstructServerResponseHeadersPacket(
5126 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5127 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435128 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335129 mock_quic_data.AddRead(
5130 ASYNC, ConstructServerDataPacket(
5131 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175132 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235133 mock_quic_data.AddWrite(SYNCHRONOUS,
5134 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:045135 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5136 mock_quic_data.AddRead(ASYNC, 0); // EOF
5137
5138 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5139
5140 // There is no need to set up main job, because no attempt will be made to
5141 // speak to the proxy over TCP.
5142 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:045143 TestProxyDelegate test_proxy_delegate;
5144 const HostPortPair host_port_pair("mail.example.org", 443);
5145
5146 test_proxy_delegate.set_alternative_proxy_server(
5147 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525148 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045149 CreateSession();
5150 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5151
5152 // The main job needs to hang in order to guarantee that the alternative
5153 // proxy server job will "win".
5154 AddHangingNonAlternateProtocolSocketData();
5155
5156 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
5157
5158 // Verify that the alternative proxy server is not marked as broken.
5159 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5160
5161 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595162 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275163
5164 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5165 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5166 1);
tbansalc3308d72016-08-27 10:25:045167}
5168
bnc1c196c6e2016-05-28 13:51:485169TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:305170 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:275171 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:305172
5173 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:565174 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:295175 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565176 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:305177
5178 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565179 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485180 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565181 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:305182
Ryan Sleevib8d7ea02018-05-07 20:01:015183 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:505184 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:085185 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:505186 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:305187
5188 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:455189 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:305190 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:455191 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:305192 };
Ryan Sleevib8d7ea02018-05-07 20:01:015193 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:505194 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:305195
5196 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:015197 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:505198 socket_factory_.AddSocketDataProvider(&http_data2);
5199 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:305200
bnc912a04b2016-04-20 14:19:505201 CreateSession();
[email protected]dda75ab2013-06-22 22:43:305202
5203 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:305204 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:175205 ASSERT_TRUE(http_data.AllReadDataConsumed());
5206 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305207
5208 // Now run the second request in which the QUIC socket hangs,
5209 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:305210 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:455211 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:305212
rch37de576c2015-05-17 20:28:175213 ASSERT_TRUE(http_data2.AllReadDataConsumed());
5214 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:455215 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305216}
5217
[email protected]1e960032013-12-20 19:00:205218TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435219 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5220 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5221 return;
5222 }
5223
Ryan Hamiltonabad59e2019-06-06 04:02:595224 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035225 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495226 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255227 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495228 mock_quic_data.AddWrite(SYNCHRONOUS,
5229 ConstructInitialSettingsPacket(packet_num++));
5230 }
Zhongyi Shi32f2fd02018-04-16 18:23:435231 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495232 SYNCHRONOUS,
5233 ConstructClientRequestHeadersPacket(
5234 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5235 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435236 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335237 ASYNC, ConstructServerResponseHeadersPacket(
5238 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5239 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435240 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335241 mock_quic_data.AddRead(
5242 ASYNC, ConstructServerDataPacket(
5243 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175244 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495245 mock_quic_data.AddWrite(SYNCHRONOUS,
5246 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505247 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595248 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:485249
rcha5399e02015-04-21 19:32:045250 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:485251
rtennetib8e80fb2016-05-16 00:12:095252 // The non-alternate protocol job needs to hang in order to guarantee that
5253 // the alternate-protocol job will "win".
5254 AddHangingNonAlternateProtocolSocketData();
5255
rch3f4b8452016-02-23 16:59:325256 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275257 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:195258 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:305259
Matt Menke19475f72019-08-21 18:57:445260 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5261 url::SchemeHostPort("https", request_.url.host(), 443),
5262 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:485263}
5264
[email protected]1e960032013-12-20 19:00:205265TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435266 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5267 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5268 return;
5269 }
5270
Ryan Hamiltonabad59e2019-06-06 04:02:595271 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035272 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495273 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255274 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495275 mock_quic_data.AddWrite(
5276 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5277 }
Fan Yang32c5a112018-12-10 20:06:335278 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495279 SYNCHRONOUS,
5280 ConstructClientRequestHeadersPacket(
5281 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5282 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435283 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335284 ASYNC, ConstructServerResponseHeadersPacket(
5285 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5286 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435287 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335288 mock_quic_data.AddRead(
5289 ASYNC, ConstructServerDataPacket(
5290 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175291 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495292 mock_quic_data.AddWrite(SYNCHRONOUS,
5293 ConstructClientAckPacket(packet_number++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505294 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595295 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:045296 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275297
5298 // In order for a new QUIC session to be established via alternate-protocol
5299 // without racing an HTTP connection, we need the host resolution to happen
5300 // synchronously.
5301 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295302 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565303 "");
[email protected]3a120a6b2013-06-25 01:08:275304
rtennetib8e80fb2016-05-16 00:12:095305 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325306 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275307 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:275308 SendRequestAndExpectQuicResponse("hello!");
5309}
5310
[email protected]0fc924b2014-03-31 04:34:155311TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Nicolas Arciniegad2013f92020-02-07 23:00:565312 proxy_resolution_service_ =
5313 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
5314 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155315
5316 // Since we are using a proxy, the QUIC job will not succeed.
5317 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295318 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5319 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565320 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155321
5322 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565323 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485324 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565325 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155326
Ryan Sleevib8d7ea02018-05-07 20:01:015327 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155328 socket_factory_.AddSocketDataProvider(&http_data);
5329
5330 // In order for a new QUIC session to be established via alternate-protocol
5331 // without racing an HTTP connection, we need the host resolution to happen
5332 // synchronously.
5333 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295334 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565335 "");
[email protected]0fc924b2014-03-31 04:34:155336
rch9ae5b3b2016-02-11 00:36:295337 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325338 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275339 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155340 SendRequestAndExpectHttpResponse("hello world");
5341}
5342
[email protected]1e960032013-12-20 19:00:205343TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435344 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5345 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5346 return;
5347 }
5348
Ryan Hamiltonabad59e2019-06-06 04:02:595349 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235350 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495351 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255352 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235353 mock_quic_data.AddWrite(SYNCHRONOUS,
5354 ConstructInitialSettingsPacket(packet_num++));
5355 }
Nick Harper057264a82019-09-12 23:33:495356 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365357 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235358 SYNCHRONOUS,
5359 ConstructClientRequestHeadersPacket(
5360 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5361 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435362 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335363 ASYNC, ConstructServerResponseHeadersPacket(
5364 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5365 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435366 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335367 mock_quic_data.AddRead(
5368 ASYNC, ConstructServerDataPacket(
5369 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175370 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235371 mock_quic_data.AddWrite(SYNCHRONOUS,
5372 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595373 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045374 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125375
rtennetib8e80fb2016-05-16 00:12:095376 // The non-alternate protocol job needs to hang in order to guarantee that
5377 // the alternate-protocol job will "win".
5378 AddHangingNonAlternateProtocolSocketData();
5379
[email protected]11c05872013-08-20 02:04:125380 // In order for a new QUIC session to be established via alternate-protocol
5381 // without racing an HTTP connection, we need the host resolution to happen
5382 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5383 // connection to the the server, in this test we require confirmation
5384 // before encrypting so the HTTP job will still start.
5385 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295386 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565387 "");
[email protected]11c05872013-08-20 02:04:125388
rch3f4b8452016-02-23 16:59:325389 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435390 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5391 false);
Ryan Hamilton9835e662018-08-02 05:36:275392 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125393
bnc691fda62016-08-12 00:43:165394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125395 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365396 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125398
Fan Yang3673cc72020-02-07 14:49:285399 crypto_client_stream_factory_.last_stream()
5400 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015401 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505402
bnc691fda62016-08-12 00:43:165403 CheckWasQuicResponse(&trans);
5404 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125405}
5406
Steven Valdez58097ec32018-07-16 18:29:045407TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435408 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5409 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5410 return;
5411 }
5412
Ryan Hamilton3cc2c152019-07-09 19:36:015413 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595414 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035415 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255416 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495417 mock_quic_data.AddWrite(
5418 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5419 }
Steven Valdez58097ec32018-07-16 18:29:045420 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015421 SYNCHRONOUS,
5422 ConstructClientRequestHeadersPacket(
5423 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5424 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335425 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025426 ASYNC, ConstructServerResponseHeadersPacket(
5427 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5428 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075429 if (VersionUsesHttp3(version_.transport_version)) {
5430 mock_quic_data.AddWrite(
5431 SYNCHRONOUS,
5432 ConstructClientAckAndDataPacket(
5433 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
5434 StreamCancellationQpackDecoderInstruction(0)));
5435 mock_quic_data.AddWrite(SYNCHRONOUS,
5436 client_maker_.MakeRstPacket(
5437 packet_number++, false,
5438 GetNthClientInitiatedBidirectionalStreamId(0),
5439 quic::QUIC_STREAM_CANCELLED));
5440 } else {
5441 mock_quic_data.AddWrite(
5442 SYNCHRONOUS,
5443 ConstructClientAckAndRstPacket(
5444 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5445 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
5446 }
Steven Valdez58097ec32018-07-16 18:29:045447
5448 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5449
Steven Valdez58097ec32018-07-16 18:29:045450 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015451 SYNCHRONOUS,
5452 ConstructClientRequestHeadersPacket(
5453 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5454 true, GetRequestHeaders("GET", "https", "/"),
5455 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045456 mock_quic_data.AddRead(
5457 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335458 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025459 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435460 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045461 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335462 ASYNC, ConstructServerDataPacket(
5463 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175464 header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045465 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015466 SYNCHRONOUS,
5467 ConstructClientAckAndConnectionClosePacket(packet_number++, 3, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045468 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5469 mock_quic_data.AddRead(ASYNC, 0); // EOF
5470
5471 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5472
5473 // In order for a new QUIC session to be established via alternate-protocol
5474 // without racing an HTTP connection, we need the host resolution to happen
5475 // synchronously.
5476 host_resolver_.set_synchronous_mode(true);
5477 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5478 "");
Steven Valdez58097ec32018-07-16 18:29:045479
5480 AddHangingNonAlternateProtocolSocketData();
5481 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275482 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565483 QuicStreamFactoryPeer::SetAlarmFactory(
5484 session_->quic_stream_factory(),
5485 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225486 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045487
5488 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5489 TestCompletionCallback callback;
5490 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5492
5493 // Confirm the handshake after the 425 Too Early.
5494 base::RunLoop().RunUntilIdle();
5495
5496 // The handshake hasn't been confirmed yet, so the retry should not have
5497 // succeeded.
5498 EXPECT_FALSE(callback.have_result());
5499
Fan Yang3673cc72020-02-07 14:49:285500 crypto_client_stream_factory_.last_stream()
5501 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:045502
5503 EXPECT_THAT(callback.WaitForResult(), IsOk());
5504 CheckWasQuicResponse(&trans);
5505 CheckResponseData(&trans, "hello!");
5506}
5507
5508TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435509 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5510 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5511 return;
5512 }
5513
Ryan Hamilton3cc2c152019-07-09 19:36:015514 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595515 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035516 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255517 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495518 mock_quic_data.AddWrite(
5519 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5520 }
Steven Valdez58097ec32018-07-16 18:29:045521 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015522 SYNCHRONOUS,
5523 ConstructClientRequestHeadersPacket(
5524 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5525 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335526 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025527 ASYNC, ConstructServerResponseHeadersPacket(
5528 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5529 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075530 if (VersionUsesHttp3(version_.transport_version)) {
5531 mock_quic_data.AddWrite(
5532 SYNCHRONOUS,
5533 ConstructClientAckAndDataPacket(
5534 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
5535 StreamCancellationQpackDecoderInstruction(0)));
5536 mock_quic_data.AddWrite(SYNCHRONOUS,
5537 client_maker_.MakeRstPacket(
5538 packet_number++, false,
5539 GetNthClientInitiatedBidirectionalStreamId(0),
5540 quic::QUIC_STREAM_CANCELLED));
5541 } else {
5542 mock_quic_data.AddWrite(
5543 SYNCHRONOUS,
5544 ConstructClientAckAndRstPacket(
5545 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5546 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
5547 }
Steven Valdez58097ec32018-07-16 18:29:045548
5549 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5550
Steven Valdez58097ec32018-07-16 18:29:045551 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015552 SYNCHRONOUS,
5553 ConstructClientRequestHeadersPacket(
5554 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5555 true, GetRequestHeaders("GET", "https", "/"),
5556 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335557 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025558 ASYNC, ConstructServerResponseHeadersPacket(
5559 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5560 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075561 if (VersionUsesHttp3(version_.transport_version)) {
5562 mock_quic_data.AddWrite(
5563 SYNCHRONOUS,
5564 ConstructClientAckAndDataPacket(
5565 packet_number++, false, GetQpackDecoderStreamId(), 2, 1, 1, false,
5566 StreamCancellationQpackDecoderInstruction(1)));
5567 mock_quic_data.AddWrite(SYNCHRONOUS,
5568 client_maker_.MakeRstPacket(
5569 packet_number++, false,
5570 GetNthClientInitiatedBidirectionalStreamId(1),
5571 quic::QUIC_STREAM_CANCELLED));
5572 } else {
5573 mock_quic_data.AddWrite(
5574 SYNCHRONOUS,
5575 ConstructClientAckAndRstPacket(
5576 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
5577 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
5578 }
Steven Valdez58097ec32018-07-16 18:29:045579 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5580 mock_quic_data.AddRead(ASYNC, 0); // EOF
5581
5582 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5583
5584 // In order for a new QUIC session to be established via alternate-protocol
5585 // without racing an HTTP connection, we need the host resolution to happen
5586 // synchronously.
5587 host_resolver_.set_synchronous_mode(true);
5588 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5589 "");
Steven Valdez58097ec32018-07-16 18:29:045590
5591 AddHangingNonAlternateProtocolSocketData();
5592 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275593 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565594 QuicStreamFactoryPeer::SetAlarmFactory(
5595 session_->quic_stream_factory(),
5596 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225597 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045598
5599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5600 TestCompletionCallback callback;
5601 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5602 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5603
5604 // Confirm the handshake after the 425 Too Early.
5605 base::RunLoop().RunUntilIdle();
5606
5607 // The handshake hasn't been confirmed yet, so the retry should not have
5608 // succeeded.
5609 EXPECT_FALSE(callback.have_result());
5610
Fan Yang3673cc72020-02-07 14:49:285611 crypto_client_stream_factory_.last_stream()
5612 ->NotifySessionOneRttKeyAvailable();
Steven Valdez58097ec32018-07-16 18:29:045613
5614 EXPECT_THAT(callback.WaitForResult(), IsOk());
5615 const HttpResponseInfo* response = trans.GetResponseInfo();
5616 ASSERT_TRUE(response != nullptr);
5617 ASSERT_TRUE(response->headers.get() != nullptr);
5618 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5619 EXPECT_TRUE(response->was_fetched_via_spdy);
5620 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085621 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5622 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045623}
5624
zhongyica364fbb2015-12-12 03:39:125625TEST_P(QuicNetworkTransactionTest,
5626 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435627 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5628 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5629 return;
5630 }
5631
Victor Vasilieva1e66d72019-12-05 17:55:385632 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595633 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235634 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495635 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255636 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235637 mock_quic_data.AddWrite(SYNCHRONOUS,
5638 ConstructInitialSettingsPacket(packet_num++));
5639 }
Nick Harper057264a82019-09-12 23:33:495640 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365641 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235642 SYNCHRONOUS,
5643 ConstructClientRequestHeadersPacket(
5644 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5645 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125646 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525647 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435648 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125649 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5650
5651 // The non-alternate protocol job needs to hang in order to guarantee that
5652 // the alternate-protocol job will "win".
5653 AddHangingNonAlternateProtocolSocketData();
5654
5655 // In order for a new QUIC session to be established via alternate-protocol
5656 // without racing an HTTP connection, we need the host resolution to happen
5657 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5658 // connection to the the server, in this test we require confirmation
5659 // before encrypting so the HTTP job will still start.
5660 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295661 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125662 "");
zhongyica364fbb2015-12-12 03:39:125663
rch3f4b8452016-02-23 16:59:325664 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435665 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5666 false);
Ryan Hamilton9835e662018-08-02 05:36:275667 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125668
bnc691fda62016-08-12 00:43:165669 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125670 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365671 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125673
Fan Yang3673cc72020-02-07 14:49:285674 crypto_client_stream_factory_.last_stream()
5675 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015676 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125677
5678 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525679 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125680
bnc691fda62016-08-12 00:43:165681 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125682 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525683 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5684 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125685}
5686
5687TEST_P(QuicNetworkTransactionTest,
5688 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435689 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5690 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5691 return;
5692 }
5693
Victor Vasilieva1e66d72019-12-05 17:55:385694 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595695 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235696 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495697 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255698 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235699 mock_quic_data.AddWrite(SYNCHRONOUS,
5700 ConstructInitialSettingsPacket(packet_num++));
5701 }
Nick Harper057264a82019-09-12 23:33:495702 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365703 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235704 SYNCHRONOUS,
5705 ConstructClientRequestHeadersPacket(
5706 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5707 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215708 // Peer sending data from an non-existing stream causes this end to raise
5709 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335710 mock_quic_data.AddRead(
5711 ASYNC, ConstructServerRstPacket(
5712 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5713 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215714 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:375715 mock_quic_data.AddWrite(
5716 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
Bence Békyde6290f2019-12-19 15:21:535717 packet_num++, 1, 1, 1, quic::QUIC_INVALID_STREAM_ID,
5718 quic_error_details, quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125719 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5720
5721 // The non-alternate protocol job needs to hang in order to guarantee that
5722 // the alternate-protocol job will "win".
5723 AddHangingNonAlternateProtocolSocketData();
5724
5725 // In order for a new QUIC session to be established via alternate-protocol
5726 // without racing an HTTP connection, we need the host resolution to happen
5727 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5728 // connection to the the server, in this test we require confirmation
5729 // before encrypting so the HTTP job will still start.
5730 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295731 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125732 "");
zhongyica364fbb2015-12-12 03:39:125733
rch3f4b8452016-02-23 16:59:325734 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435735 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5736 false);
Ryan Hamilton9835e662018-08-02 05:36:275737 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125738
bnc691fda62016-08-12 00:43:165739 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125740 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365741 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125743
Fan Yang3673cc72020-02-07 14:49:285744 crypto_client_stream_factory_.last_stream()
5745 ->NotifySessionOneRttKeyAvailable();
robpercival214763f2016-07-01 23:27:015746 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125747 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525748 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125749
bnc691fda62016-08-12 00:43:165750 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525751 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125752}
5753
Nick Harper057264a82019-09-12 23:33:495754TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435755 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5756 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5757 return;
5758 }
5759
Ryan Hamiltonabad59e2019-06-06 04:02:595760 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235761 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495762 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255763 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235764 mock_quic_data.AddWrite(SYNCHRONOUS,
5765 ConstructInitialSettingsPacket(packet_num++));
5766 }
Nick Harper057264a82019-09-12 23:33:495767 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365768 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235769 SYNCHRONOUS,
5770 ConstructClientRequestHeadersPacket(
5771 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5772 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485773 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335774 mock_quic_data.AddRead(
5775 ASYNC, ConstructServerResponseHeadersPacket(
5776 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5777 GetResponseHeaders("200 OK")));
5778 mock_quic_data.AddRead(
5779 ASYNC, ConstructServerRstPacket(
5780 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5781 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075782
5783 if (VersionUsesHttp3(version_.transport_version)) {
5784 mock_quic_data.AddWrite(
5785 SYNCHRONOUS,
5786 ConstructClientAckAndDataPacket(
5787 packet_num++, false, GetQpackDecoderStreamId(), 2, 1, 1, false,
5788 StreamCancellationQpackDecoderInstruction(0)));
5789 } else {
5790 mock_quic_data.AddWrite(SYNCHRONOUS,
5791 ConstructClientAckPacket(packet_num++, 2, 1, 1));
5792 }
rchcd5f1c62016-06-23 02:43:485793 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5794 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5795
5796 // The non-alternate protocol job needs to hang in order to guarantee that
5797 // the alternate-protocol job will "win".
5798 AddHangingNonAlternateProtocolSocketData();
5799
5800 // In order for a new QUIC session to be established via alternate-protocol
5801 // without racing an HTTP connection, we need the host resolution to happen
5802 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5803 // connection to the the server, in this test we require confirmation
5804 // before encrypting so the HTTP job will still start.
5805 host_resolver_.set_synchronous_mode(true);
5806 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5807 "");
rchcd5f1c62016-06-23 02:43:485808
5809 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435810 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5811 false);
Ryan Hamilton9835e662018-08-02 05:36:275812 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485813
bnc691fda62016-08-12 00:43:165814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485815 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365816 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485818
Fan Yang3673cc72020-02-07 14:49:285819 crypto_client_stream_factory_.last_stream()
5820 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:485821 // Read the headers.
robpercival214763f2016-07-01 23:27:015822 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485823
bnc691fda62016-08-12 00:43:165824 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485825 ASSERT_TRUE(response != nullptr);
5826 ASSERT_TRUE(response->headers.get() != nullptr);
5827 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5828 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525829 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085830 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5831 response->connection_info);
rchcd5f1c62016-06-23 02:43:485832
5833 std::string response_data;
bnc691fda62016-08-12 00:43:165834 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485835}
5836
Nick Harper057264a82019-09-12 23:33:495837TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435838 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5839 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5840 return;
5841 }
5842
Victor Vasilieva1e66d72019-12-05 17:55:385843 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595844 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235845 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495846 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255847 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235848 mock_quic_data.AddWrite(SYNCHRONOUS,
5849 ConstructInitialSettingsPacket(packet_num++));
5850 }
Nick Harper057264a82019-09-12 23:33:495851 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365852 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235853 SYNCHRONOUS,
5854 ConstructClientRequestHeadersPacket(
5855 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5856 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335857 mock_quic_data.AddRead(
5858 ASYNC, ConstructServerRstPacket(
5859 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5860 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075861
5862 if (VersionUsesHttp3(version_.transport_version)) {
5863 mock_quic_data.AddWrite(
5864 SYNCHRONOUS, ConstructClientDataPacket(
5865 packet_num++, GetQpackDecoderStreamId(), true, false,
5866 StreamCancellationQpackDecoderInstruction(0)));
5867 }
5868
rchcd5f1c62016-06-23 02:43:485869 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5870 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5871
5872 // The non-alternate protocol job needs to hang in order to guarantee that
5873 // the alternate-protocol job will "win".
5874 AddHangingNonAlternateProtocolSocketData();
5875
5876 // In order for a new QUIC session to be established via alternate-protocol
5877 // without racing an HTTP connection, we need the host resolution to happen
5878 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5879 // connection to the the server, in this test we require confirmation
5880 // before encrypting so the HTTP job will still start.
5881 host_resolver_.set_synchronous_mode(true);
5882 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5883 "");
rchcd5f1c62016-06-23 02:43:485884
5885 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435886 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5887 false);
Ryan Hamilton9835e662018-08-02 05:36:275888 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485889
bnc691fda62016-08-12 00:43:165890 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485891 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365892 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485894
Fan Yang3673cc72020-02-07 14:49:285895 crypto_client_stream_factory_.last_stream()
5896 ->NotifySessionOneRttKeyAvailable();
rchcd5f1c62016-06-23 02:43:485897 // Read the headers.
robpercival214763f2016-07-01 23:27:015898 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485899}
5900
[email protected]1e960032013-12-20 19:00:205901TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305902 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525903 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585904 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305905 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505906 MockRead(ASYNC, close->data(), close->length()),
5907 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5908 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305909 };
Ryan Sleevib8d7ea02018-05-07 20:01:015910 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305911 socket_factory_.AddSocketDataProvider(&quic_data);
5912
5913 // Main job which will succeed even though the alternate job fails.
5914 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025915 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5916 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5917 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305918
Ryan Sleevib8d7ea02018-05-07 20:01:015919 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305920 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565921 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305922
rch3f4b8452016-02-23 16:59:325923 CreateSession();
David Schinazic8281052019-01-24 06:14:175924 AddQuicAlternateProtocolMapping(
5925 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195926 SendRequestAndExpectHttpResponse("hello from http");
5927 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305928}
5929
Matt Menkeb32ba5122019-09-10 19:17:055930TEST_P(QuicNetworkTransactionTest,
5931 BrokenAlternateProtocolWithNetworkIsolationKey) {
5932 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5933 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5934 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5935 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5936
5937 base::test::ScopedFeatureList feature_list;
5938 feature_list.InitWithFeatures(
5939 // enabled_features
5940 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5941 features::kPartitionConnectionsByNetworkIsolationKey},
5942 // disabled_features
5943 {});
5944 // Since HttpServerProperties caches the feature value, have to create a new
5945 // one.
5946 http_server_properties_ = std::make_unique<HttpServerProperties>();
5947
5948 // Alternate-protocol job
5949 std::unique_ptr<quic::QuicEncryptedPacket> close(
5950 ConstructServerConnectionClosePacket(1));
5951 MockRead quic_reads[] = {
5952 MockRead(ASYNC, close->data(), close->length()),
5953 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5954 MockRead(ASYNC, OK), // EOF
5955 };
5956 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5957 socket_factory_.AddSocketDataProvider(&quic_data);
5958
5959 // Main job which will succeed even though the alternate job fails.
5960 MockRead http_reads[] = {
5961 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5962 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5963 MockRead(ASYNC, OK)};
5964
5965 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5966 socket_factory_.AddSocketDataProvider(&http_data);
5967 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5968
5969 CreateSession();
5970 AddQuicAlternateProtocolMapping(
5971 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5972 AddQuicAlternateProtocolMapping(
5973 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5974 request_.network_isolation_key = kNetworkIsolationKey1;
5975 SendRequestAndExpectHttpResponse("hello from http");
5976
5977 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5978 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5979}
5980
[email protected]1e960032013-12-20 19:00:205981TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595982 // Alternate-protocol job
5983 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025984 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595985 };
Ryan Sleevib8d7ea02018-05-07 20:01:015986 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595987 socket_factory_.AddSocketDataProvider(&quic_data);
5988
5989 // Main job which will succeed even though the alternate job fails.
5990 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025991 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5992 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5993 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595994
Ryan Sleevib8d7ea02018-05-07 20:01:015995 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595996 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565997 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595998
rch3f4b8452016-02-23 16:59:325999 CreateSession();
[email protected]d03a66d2013-05-06 12:55:596000
Ryan Hamilton9835e662018-08-02 05:36:276001 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:196002 SendRequestAndExpectHttpResponse("hello from http");
6003 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:596004}
6005
[email protected]00c159f2014-05-21 22:38:166006TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:536007 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:166008 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:026009 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:166010 };
Ryan Sleevib8d7ea02018-05-07 20:01:016011 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:166012 socket_factory_.AddSocketDataProvider(&quic_data);
6013
[email protected]eb71ab62014-05-23 07:57:536014 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:166015 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026016 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:166017 };
6018
Ryan Sleevib8d7ea02018-05-07 20:01:016019 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:166020 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
6021 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566022 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:166023
rtennetib8e80fb2016-05-16 00:12:096024 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326025 CreateSession();
[email protected]00c159f2014-05-21 22:38:166026
Ryan Hamilton9835e662018-08-02 05:36:276027 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:166028 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:166029 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166030 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016031 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6032 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:166033 ExpectQuicAlternateProtocolMapping();
6034}
6035
Zhongyi Shia0cef1082017-08-25 01:49:506036TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436037 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6038 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6039 return;
6040 }
6041
Zhongyi Shia0cef1082017-08-25 01:49:506042 // Tests that TCP job is delayed and QUIC job does not require confirmation
6043 // if QUIC was recently supported on the same IP on start.
6044
6045 // Set QUIC support on the last IP address, which is same with the local IP
6046 // address. Require confirmation mode will be turned off immediately when
6047 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:436048 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
6049 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:506050
Ryan Hamiltonabad59e2019-06-06 04:02:596051 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:036052 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:496053 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:256054 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:496055 mock_quic_data.AddWrite(SYNCHRONOUS,
6056 ConstructInitialSettingsPacket(packet_number++));
6057 }
Zhongyi Shi32f2fd02018-04-16 18:23:436058 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:496059 SYNCHRONOUS,
6060 ConstructClientRequestHeadersPacket(
6061 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6062 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436063 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336064 ASYNC, ConstructServerResponseHeadersPacket(
6065 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6066 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436067 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336068 mock_quic_data.AddRead(
6069 ASYNC, ConstructServerDataPacket(
6070 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176071 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:496072 mock_quic_data.AddWrite(SYNCHRONOUS,
6073 ConstructClientAckPacket(packet_number++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:506074 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6075 mock_quic_data.AddRead(ASYNC, 0); // EOF
6076
6077 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6078 // No HTTP data is mocked as TCP job never starts in this case.
6079
6080 CreateSession();
6081 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:436082 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6083 false);
Zhongyi Shia0cef1082017-08-25 01:49:506084
Ryan Hamilton9835e662018-08-02 05:36:276085 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:506086
6087 // Stall host resolution so that QUIC job will not succeed synchronously.
6088 // Socket will not be configured immediately and QUIC support is not sorted
6089 // out, TCP job will still be delayed as server properties indicates QUIC
6090 // support on last IP address.
6091 host_resolver_.set_synchronous_mode(false);
6092
6093 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6094 TestCompletionCallback callback;
6095 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
6096 IsError(ERR_IO_PENDING));
6097 // Complete host resolution in next message loop so that QUIC job could
6098 // proceed.
6099 base::RunLoop().RunUntilIdle();
6100 EXPECT_THAT(callback.WaitForResult(), IsOk());
6101
6102 CheckWasQuicResponse(&trans);
6103 CheckResponseData(&trans, "hello!");
6104}
6105
6106TEST_P(QuicNetworkTransactionTest,
6107 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436108 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6109 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6110 return;
6111 }
6112
Zhongyi Shia0cef1082017-08-25 01:49:506113 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
6114 // was recently supported on a different IP address on start.
6115
6116 // Set QUIC support on the last IP address, which is different with the local
6117 // IP address. Require confirmation mode will remain when local IP address is
6118 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:436119 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
6120 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:506121
Ryan Hamiltonabad59e2019-06-06 04:02:596122 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236123 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:496124 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:256125 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236126 mock_quic_data.AddWrite(SYNCHRONOUS,
6127 ConstructInitialSettingsPacket(packet_num++));
6128 }
Nick Harper057264a82019-09-12 23:33:496129 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:506130 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236131 SYNCHRONOUS,
6132 ConstructClientRequestHeadersPacket(
6133 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6134 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436135 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336136 ASYNC, ConstructServerResponseHeadersPacket(
6137 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6138 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436139 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336140 mock_quic_data.AddRead(
6141 ASYNC, ConstructServerDataPacket(
6142 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176143 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236144 mock_quic_data.AddWrite(SYNCHRONOUS,
6145 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:506146 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6147 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6148 // No HTTP data is mocked as TCP job will be delayed and never starts.
6149
6150 CreateSession();
Matt Menkeb566c392019-09-11 23:22:436151 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6152 false);
Ryan Hamilton9835e662018-08-02 05:36:276153 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:506154
6155 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
6156 // Socket will not be configured immediately and QUIC support is not sorted
6157 // out, TCP job will still be delayed as server properties indicates QUIC
6158 // support on last IP address.
6159 host_resolver_.set_synchronous_mode(false);
6160
6161 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6162 TestCompletionCallback callback;
6163 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
6164 IsError(ERR_IO_PENDING));
6165
6166 // Complete host resolution in next message loop so that QUIC job could
6167 // proceed.
6168 base::RunLoop().RunUntilIdle();
6169 // Explicitly confirm the handshake so that QUIC job could succeed.
Fan Yang3673cc72020-02-07 14:49:286170 crypto_client_stream_factory_.last_stream()
6171 ->NotifySessionOneRttKeyAvailable();
Zhongyi Shia0cef1082017-08-25 01:49:506172 EXPECT_THAT(callback.WaitForResult(), IsOk());
6173
6174 CheckWasQuicResponse(&trans);
6175 CheckResponseData(&trans, "hello!");
6176}
6177
Ryan Hamilton75f197262017-08-17 14:00:076178TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
6179 // Test that NetErrorDetails is correctly populated, even if the
6180 // handshake has not yet been confirmed and no stream has been created.
6181
6182 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:596183 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:076184 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
6185 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
6186 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6187
6188 // Main job will also fail.
6189 MockRead http_reads[] = {
6190 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
6191 };
6192
Ryan Sleevib8d7ea02018-05-07 20:01:016193 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:076194 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
6195 socket_factory_.AddSocketDataProvider(&http_data);
6196 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6197
6198 AddHangingNonAlternateProtocolSocketData();
6199 CreateSession();
6200 // Require handshake confirmation to ensure that no QUIC streams are
6201 // created, and to ensure that the TCP job does not wait for the QUIC
6202 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:436203 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6204 false);
Ryan Hamilton75f197262017-08-17 14:00:076205
Ryan Hamilton9835e662018-08-02 05:36:276206 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:076207 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6208 TestCompletionCallback callback;
6209 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6210 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6211 // Allow the TCP job to fail.
6212 base::RunLoop().RunUntilIdle();
6213 // Now let the QUIC job fail.
6214 mock_quic_data.Resume();
6215 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6216 ExpectQuicAlternateProtocolMapping();
6217 NetErrorDetails details;
6218 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526219 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:076220}
6221
[email protected]1e960032013-12-20 19:00:206222TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:456223 // Alternate-protocol job
6224 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:026225 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:456226 };
Ryan Sleevib8d7ea02018-05-07 20:01:016227 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:456228 socket_factory_.AddSocketDataProvider(&quic_data);
6229
[email protected]c92c1b52014-05-31 04:16:066230 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:016231 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:066232 socket_factory_.AddSocketDataProvider(&quic_data2);
6233
[email protected]4d283b32013-10-17 12:57:276234 // Final job that will proceed when the QUIC job fails.
6235 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026236 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6237 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6238 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:276239
Ryan Sleevib8d7ea02018-05-07 20:01:016240 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:276241 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566242 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:276243
rch3f4b8452016-02-23 16:59:326244 CreateSession();
[email protected]77c6c162013-08-17 02:57:456245
Ryan Hamilton9835e662018-08-02 05:36:276246 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:456247
[email protected]4d283b32013-10-17 12:57:276248 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:456249
6250 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:276251
rch37de576c2015-05-17 20:28:176252 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6253 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:456254}
6255
Matt Menkeb32ba5122019-09-10 19:17:056256TEST_P(QuicNetworkTransactionTest,
6257 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436258 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6259 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6260 return;
6261 }
6262
Matt Menkeb32ba5122019-09-10 19:17:056263 base::test::ScopedFeatureList feature_list;
6264 feature_list.InitWithFeatures(
6265 // enabled_features
6266 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
6267 features::kPartitionConnectionsByNetworkIsolationKey},
6268 // disabled_features
6269 {});
6270 // Since HttpServerProperties caches the feature value, have to create a new
6271 // one.
6272 http_server_properties_ = std::make_unique<HttpServerProperties>();
6273
6274 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
6275 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
6276 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
6277 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
6278
6279 // Alternate-protocol job
6280 MockRead quic_reads[] = {
6281 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
6282 };
6283 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
6284 socket_factory_.AddSocketDataProvider(&quic_data);
6285
6286 // Second Alternate-protocol job which will race with the TCP job.
6287 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
6288 socket_factory_.AddSocketDataProvider(&quic_data2);
6289
6290 // Final job that will proceed when the QUIC job fails.
6291 MockRead http_reads[] = {
6292 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6293 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6294 MockRead(ASYNC, OK)};
6295
6296 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
6297 socket_factory_.AddSocketDataProvider(&http_data);
6298 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6299
6300 CreateSession();
6301
6302 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6303 kNetworkIsolationKey1);
6304 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6305 kNetworkIsolationKey2);
6306
6307 request_.network_isolation_key = kNetworkIsolationKey1;
6308 SendRequestAndExpectHttpResponse("hello from http");
6309 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6310 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
6311
6312 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6313 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6314
6315 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
6316 AddHttpDataAndRunRequest();
6317 // Requests using other NetworkIsolationKeys can still use QUIC.
6318 request_.network_isolation_key = kNetworkIsolationKey2;
6319 AddQuicDataAndRunRequest();
6320
6321 // The last two requests should not have changed the alternative service
6322 // mappings.
6323 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6324 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6325}
6326
[email protected]93b31772014-06-19 08:03:356327TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:036328 // Alternate-protocol job
6329 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:596330 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:036331 };
Ryan Sleevib8d7ea02018-05-07 20:01:016332 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036333 socket_factory_.AddSocketDataProvider(&quic_data);
6334
6335 // Main job that will proceed when the QUIC job fails.
6336 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026337 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6338 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6339 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:036340
Ryan Sleevib8d7ea02018-05-07 20:01:016341 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036342 socket_factory_.AddSocketDataProvider(&http_data);
6343
rtennetib8e80fb2016-05-16 00:12:096344 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326345 CreateSession();
[email protected]65768442014-06-06 23:37:036346
Ryan Hamilton9835e662018-08-02 05:36:276347 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:036348
6349 SendRequestAndExpectHttpResponse("hello from http");
6350}
6351
[email protected]eb71ab62014-05-23 07:57:536352TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:336353 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:016354 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:496355 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:336356 socket_factory_.AddSocketDataProvider(&quic_data);
6357
6358 // Main job which will succeed even though the alternate job fails.
6359 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026360 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6361 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6362 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:336363
Ryan Sleevib8d7ea02018-05-07 20:01:016364 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:336365 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566366 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:336367
rch3f4b8452016-02-23 16:59:326368 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276369 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:336370 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:536371
6372 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:336373}
6374
[email protected]4fee9672014-01-08 14:47:156375TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltonabad59e2019-06-06 04:02:596376 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:176377 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
6378 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:046379 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:156380
6381 // When the QUIC connection fails, we will try the request again over HTTP.
6382 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:486383 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:566384 MockRead("hello world"),
6385 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6386 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:156387
Ryan Sleevib8d7ea02018-05-07 20:01:016388 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:156389 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566390 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:156391
6392 // In order for a new QUIC session to be established via alternate-protocol
6393 // without racing an HTTP connection, we need the host resolution to happen
6394 // synchronously.
6395 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:296396 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:566397 "");
[email protected]4fee9672014-01-08 14:47:156398
rch3f4b8452016-02-23 16:59:326399 CreateSession();
David Schinazic8281052019-01-24 06:14:176400 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
6401 AddQuicAlternateProtocolMapping(
6402 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:156403 SendRequestAndExpectHttpResponse("hello world");
6404}
6405
tbansalc3308d72016-08-27 10:25:046406// For an alternative proxy that supports QUIC, test that the request is
6407// successfully fetched by the main job when the alternate proxy job encounters
6408// an error.
6409TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
6410 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
6411}
6412TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
6413 TestAlternativeProxy(ERR_CONNECTION_FAILED);
6414}
6415TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
6416 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
6417}
6418TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
6419 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
6420}
6421TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
6422 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
6423}
6424TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
6425 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
6426}
6427TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
6428 TestAlternativeProxy(ERR_IO_PENDING);
6429}
6430TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
6431 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
6432}
6433
6434TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltonabad59e2019-06-06 04:02:596435 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:176436 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
6437 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:336438 mock_quic_data.AddWrite(
6439 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6440 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
6441 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436442 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:046443 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6444
6445 // When the QUIC connection fails, we will try the request again over HTTP.
6446 MockRead http_reads[] = {
6447 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6448 MockRead("hello world"),
6449 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6450 MockRead(ASYNC, OK)};
6451
Ryan Sleevib8d7ea02018-05-07 20:01:016452 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:046453 socket_factory_.AddSocketDataProvider(&http_data);
6454 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6455
6456 TestProxyDelegate test_proxy_delegate;
6457 const HostPortPair host_port_pair("myproxy.org", 443);
6458 test_proxy_delegate.set_alternative_proxy_server(
6459 ProxyServer::FromPacString("QUIC myproxy.org:443"));
6460 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6461
Nicolas Arciniegad2013f92020-02-07 23:00:566462 proxy_resolution_service_ =
6463 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
6464 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526465 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046466 request_.url = GURL("http://mail.example.org/");
6467
6468 // In order for a new QUIC session to be established via alternate-protocol
6469 // without racing an HTTP connection, we need the host resolution to happen
6470 // synchronously.
6471 host_resolver_.set_synchronous_mode(true);
6472 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:046473
6474 CreateSession();
David Schinazic8281052019-01-24 06:14:176475 crypto_client_stream_factory_.set_handshake_mode(
6476 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:046477 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596478 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166479 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046480}
6481
bnc508835902015-05-12 20:10:296482TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:586483 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386484 EXPECT_FALSE(
6485 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:596486 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236487 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256488 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236489 mock_quic_data.AddWrite(SYNCHRONOUS,
6490 ConstructInitialSettingsPacket(packet_num++));
6491 }
rch5cb522462017-04-25 20:18:366492 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236493 SYNCHRONOUS,
6494 ConstructClientRequestHeadersPacket(
6495 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6496 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436497 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336498 ASYNC, ConstructServerResponseHeadersPacket(
6499 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6500 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436501 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336502 mock_quic_data.AddRead(
6503 ASYNC, ConstructServerDataPacket(
6504 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176505 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236506 mock_quic_data.AddWrite(SYNCHRONOUS,
6507 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:506508 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296509 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6510
bncb07c05532015-05-14 19:07:206511 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096512 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326513 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276514 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296515 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386516 EXPECT_TRUE(
6517 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296518}
6519
zhongyi363c91c2017-03-23 23:16:086520// TODO(zhongyi): disabled this broken test as it was not testing the correct
6521// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
6522TEST_P(QuicNetworkTransactionTest,
6523 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:276524 base::HistogramTester histogram_tester;
Nicolas Arciniegad2013f92020-02-07 23:00:566525 proxy_resolution_service_ =
6526 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
6527 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:046528
6529 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:046530
6531 test_proxy_delegate.set_alternative_proxy_server(
6532 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:526533 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046534
6535 request_.url = GURL("http://mail.example.org/");
6536
6537 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6538 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016539 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:046540 socket_factory_.AddSocketDataProvider(&socket_data);
6541
6542 // The non-alternate protocol job needs to hang in order to guarantee that
6543 // the alternate-protocol job will "win".
6544 AddHangingNonAlternateProtocolSocketData();
6545
6546 CreateSession();
6547 request_.method = "POST";
6548 ChunkedUploadDataStream upload_data(0);
6549 upload_data.AppendData("1", 1, true);
6550
6551 request_.upload_data_stream = &upload_data;
6552
6553 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6554 TestCompletionCallback callback;
6555 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6556 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6557 EXPECT_NE(OK, callback.WaitForResult());
6558
6559 // Verify that the alternative proxy server is not marked as broken.
6560 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6561
6562 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596563 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276564
6565 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6566 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6567 1);
tbansalc3308d72016-08-27 10:25:046568}
6569
rtenneti56977812016-01-15 19:26:566570TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Victor Vasilieva1e66d72019-12-05 17:55:386571 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576572 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566573
Renjie Tangaadb84b2019-08-31 01:00:236574 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:256575 if (!VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236576 mock_quic_data.AddRead(SYNCHRONOUS, OK);
6577 else
6578 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6579 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6580 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6581
6582 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6583 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
6584 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:016585 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:236586 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:566587
rtennetib8e80fb2016-05-16 00:12:096588 // The non-alternate protocol job needs to hang in order to guarantee that
6589 // the alternate-protocol job will "win".
6590 AddHangingNonAlternateProtocolSocketData();
6591
rtenneti56977812016-01-15 19:26:566592 CreateSession();
6593 request_.method = "POST";
6594 ChunkedUploadDataStream upload_data(0);
6595 upload_data.AppendData("1", 1, true);
6596
6597 request_.upload_data_stream = &upload_data;
6598
bnc691fda62016-08-12 00:43:166599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566600 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166601 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016602 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566603 EXPECT_NE(OK, callback.WaitForResult());
6604}
6605
rche11300ef2016-09-02 01:44:286606TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Victor Vasilieva1e66d72019-12-05 17:55:386607 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286608 ScopedMockNetworkChangeNotifier network_change_notifier;
6609 MockNetworkChangeNotifier* mock_ncn =
6610 network_change_notifier.mock_network_change_notifier();
6611 mock_ncn->ForceNetworkHandlesSupported();
6612 mock_ncn->SetConnectedNetworksList(
6613 {kDefaultNetworkForTests, kNewNetworkForTests});
6614
Victor Vasilieva1e66d72019-12-05 17:55:386615 context_.params()->origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286616 HostPortPair::FromString("mail.example.org:443"));
Victor Vasilieva1e66d72019-12-05 17:55:386617 context_.params()->migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286618
Ryan Hamiltonabad59e2019-06-06 04:02:596619 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286620 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236621 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256622 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236623 socket_data.AddWrite(SYNCHRONOUS,
6624 ConstructInitialSettingsPacket(packet_num++));
6625 }
Fan Yang32c5a112018-12-10 20:06:336626 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236627 SYNCHRONOUS,
6628 ConstructClientRequestHeadersPacket(
6629 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6630 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:286631 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6632 socket_data.AddSocketDataToFactory(&socket_factory_);
6633
Ryan Hamiltonabad59e2019-06-06 04:02:596634 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286635 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6636 socket_data2.AddSocketDataToFactory(&socket_factory_);
6637
6638 // The non-alternate protocol job needs to hang in order to guarantee that
6639 // the alternate-protocol job will "win".
6640 AddHangingNonAlternateProtocolSocketData();
6641
6642 CreateSession();
6643 request_.method = "POST";
6644 ChunkedUploadDataStream upload_data(0);
6645
6646 request_.upload_data_stream = &upload_data;
6647
rdsmith1d343be52016-10-21 20:37:506648 std::unique_ptr<HttpNetworkTransaction> trans(
6649 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286650 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506651 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6653
6654 base::RunLoop().RunUntilIdle();
6655 upload_data.AppendData("1", 1, true);
6656 base::RunLoop().RunUntilIdle();
6657
6658 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506659 trans.reset();
rche11300ef2016-09-02 01:44:286660 session_.reset();
6661}
6662
Ryan Hamilton4b3574532017-10-30 20:17:256663TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386664 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256665 HostPortPair::FromString("mail.example.org:443"));
6666
Ryan Hamiltonabad59e2019-06-06 04:02:596667 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236668 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256669 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236670 socket_data.AddWrite(SYNCHRONOUS,
6671 ConstructInitialSettingsPacket(packet_num++));
6672 }
Ryan Hamilton4b3574532017-10-30 20:17:256673 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336674 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236675 SYNCHRONOUS,
6676 ConstructClientRequestHeadersPacket(
6677 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6678 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436679 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336680 ASYNC, ConstructServerResponseHeadersPacket(
6681 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6682 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436683 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336684 socket_data.AddRead(
6685 ASYNC, ConstructServerDataPacket(
6686 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176687 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236688 socket_data.AddWrite(SYNCHRONOUS,
6689 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256690 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tang3d8a6ddd2019-11-20 00:18:436691 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6692 // TLS1.3 supports multiple packet number space, so the ack is no longer
6693 // sent.
6694 socket_data.AddWrite(
6695 SYNCHRONOUS,
6696 client_maker_.MakeConnectionClosePacket(
6697 packet_num++, false, quic::QUIC_CONNECTION_CANCELLED, "net error"));
6698 } else {
Bence Békyde6290f2019-12-19 15:21:536699 socket_data.AddWrite(SYNCHRONOUS,
6700 client_maker_.MakeAckAndConnectionClosePacket(
6701 packet_num++, false, 2, 1, 1,
6702 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Renjie Tang3d8a6ddd2019-11-20 00:18:436703 }
Ryan Hamilton4b3574532017-10-30 20:17:256704
6705 socket_data.AddSocketDataToFactory(&socket_factory_);
6706
6707 CreateSession();
6708
6709 SendRequestAndExpectQuicResponse("hello!");
6710 session_.reset();
6711}
6712
6713TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386714 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256715 HostPortPair::FromString("mail.example.org:443"));
6716
Ryan Hamiltonabad59e2019-06-06 04:02:596717 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236718 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256719 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236720 socket_data.AddWrite(SYNCHRONOUS,
6721 ConstructInitialSettingsPacket(packet_num++));
6722 }
Ryan Hamilton4b3574532017-10-30 20:17:256723 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336724 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236725 SYNCHRONOUS,
6726 ConstructClientRequestHeadersPacket(
6727 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6728 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436729 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336730 ASYNC, ConstructServerResponseHeadersPacket(
6731 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6732 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436733 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336734 socket_data.AddRead(
6735 ASYNC, ConstructServerDataPacket(
6736 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176737 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236738 socket_data.AddWrite(SYNCHRONOUS,
6739 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256740 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tang3d8a6ddd2019-11-20 00:18:436741 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6742 // TLS1.3 supports multiple packet number space, so the ack is no longer
6743 // sent.
6744 socket_data.AddWrite(
6745 SYNCHRONOUS,
6746 client_maker_.MakeConnectionClosePacket(
6747 packet_num++, false, quic::QUIC_CONNECTION_CANCELLED, "net error"));
6748 } else {
Bence Békyde6290f2019-12-19 15:21:536749 socket_data.AddWrite(SYNCHRONOUS,
6750 client_maker_.MakeAckAndConnectionClosePacket(
6751 packet_num++, false, 2, 1, 1,
6752 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Renjie Tang3d8a6ddd2019-11-20 00:18:436753 }
Ryan Hamilton4b3574532017-10-30 20:17:256754
6755 socket_data.AddSocketDataToFactory(&socket_factory_);
6756
6757 CreateSession();
6758
6759 SendRequestAndExpectQuicResponse("hello!");
6760 session_.reset();
6761}
6762
Ryan Hamilton9edcf1a2017-11-22 05:55:176763TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386764 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6765 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256766 HostPortPair::FromString("mail.example.org:443"));
6767
Ryan Hamiltonabad59e2019-06-06 04:02:596768 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256769 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256770 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236771 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176772 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256773 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6774 }
6775 socket_data.AddSocketDataToFactory(&socket_factory_);
6776
6777 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176778 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176779 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6780 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256781
Victor Vasiliev7752898d2019-11-14 21:30:226782 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256783 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6784 TestCompletionCallback callback;
6785 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6786 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176787 while (!callback.have_result()) {
6788 base::RunLoop().RunUntilIdle();
6789 quic_task_runner_->RunUntilIdle();
6790 }
6791 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256792 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176793 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6794 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6795 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226796 EXPECT_TRUE(context_.clock()->Now() - start >
6797 quic::QuicTime::Delta::FromSeconds(4));
6798 EXPECT_TRUE(context_.clock()->Now() - start <
6799 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256800}
6801
Ryan Hamilton9edcf1a2017-11-22 05:55:176802TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386803 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6804 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256805 HostPortPair::FromString("mail.example.org:443"));
6806
Ryan Hamiltonabad59e2019-06-06 04:02:596807 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256808 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256809 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236810 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176811 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256812 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6813 }
6814 socket_data.AddSocketDataToFactory(&socket_factory_);
6815
6816 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176817 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176818 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6819 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256820
Victor Vasiliev7752898d2019-11-14 21:30:226821 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256822 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6823 TestCompletionCallback callback;
6824 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176826 while (!callback.have_result()) {
6827 base::RunLoop().RunUntilIdle();
6828 quic_task_runner_->RunUntilIdle();
6829 }
6830 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256831 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176832 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6833 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6834 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226835 EXPECT_TRUE(context_.clock()->Now() - start >
6836 quic::QuicTime::Delta::FromSeconds(4));
6837 EXPECT_TRUE(context_.clock()->Now() - start <
6838 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256839}
6840
Cherie Shi7596de632018-02-22 07:28:186841TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Victor Vasilieva1e66d72019-12-05 17:55:386842 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6843 context_.params()->origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186844 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436845 const std::string error_details =
Zhongyi Shid1c00fc42019-12-14 06:05:096846 quiche::QuicheStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6847 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186848
Ryan Hamiltonabad59e2019-06-06 04:02:596849 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186850 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236851 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256852 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236853 socket_data.AddWrite(SYNCHRONOUS,
6854 ConstructInitialSettingsPacket(packet_num++));
6855 }
Cherie Shi7596de632018-02-22 07:28:186856 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6857 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526858 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236859 SYNCHRONOUS,
6860 client_maker_.MakeConnectionClosePacket(
6861 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186862 socket_data.AddSocketDataToFactory(&socket_factory_);
6863
6864 CreateSession();
6865
6866 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6867 TestCompletionCallback callback;
6868 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6869 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6870 base::RunLoop().RunUntilIdle();
6871 ASSERT_TRUE(callback.have_result());
6872 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6873 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6874 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6875}
6876
ckrasic769733c2016-06-30 00:42:136877// Adds coverage to catch regression such as https://crbug.com/622043
6878TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Ryan Hamilton6c6493102019-12-05 21:36:506879 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
6880 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:386881 context_.params()->origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136882 HostPortPair::FromString("mail.example.org:443"));
6883
Ryan Hamiltonabad59e2019-06-06 04:02:596884 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236885 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:256886 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236887 mock_quic_data.AddWrite(
6888 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6889 }
Zhongyi Shi32f2fd02018-04-16 18:23:436890 mock_quic_data.AddWrite(
6891 SYNCHRONOUS,
6892 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336893 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026894 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436895 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026896 ASYNC,
6897 ConstructServerPushPromisePacket(
6898 1, GetNthClientInitiatedBidirectionalStreamId(0),
6899 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6900 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316901 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:426902 version_.transport_version >= quic::QUIC_VERSION_43 &&
Ian Swett25d3c3b32020-01-14 17:51:296903 !VersionUsesHttp3(version_.transport_version))) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026904 mock_quic_data.AddWrite(
6905 SYNCHRONOUS,
6906 ConstructClientPriorityPacket(
6907 client_packet_number++, false,
6908 GetNthServerInitiatedUnidirectionalStreamId(0),
6909 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576910 }
Zhongyi Shi32f2fd02018-04-16 18:23:436911 mock_quic_data.AddRead(
6912 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336913 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026914 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:576915 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436916 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6917 mock_quic_data.AddRead(
6918 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336919 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026920 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436921 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436922 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336923 ASYNC, ConstructServerDataPacket(
6924 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176925 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576926 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436927 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436928 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436929 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336930 ASYNC, ConstructServerDataPacket(
6931 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176932 header2 + "and hello!"));
Renjie Tangee921d12020-02-06 00:41:496933 if (!VersionUsesHttp3(version_.transport_version)) {
6934 mock_quic_data.AddWrite(SYNCHRONOUS,
6935 ConstructClientAckAndRstPacket(
6936 client_packet_number++,
6937 GetNthServerInitiatedUnidirectionalStreamId(0),
6938 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
6939 } else {
6940 mock_quic_data.AddWrite(
6941 SYNCHRONOUS, client_maker_.MakeAckAndPriorityUpdatePacket(
6942 client_packet_number++, true, 5, 5, 1, 3,
6943 GetNthServerInitiatedUnidirectionalStreamId(0)));
6944 }
ckrasic769733c2016-06-30 00:42:136945 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6946 mock_quic_data.AddRead(ASYNC, 0); // EOF
6947 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6948
6949 // The non-alternate protocol job needs to hang in order to guarantee that
6950 // the alternate-protocol job will "win".
6951 AddHangingNonAlternateProtocolSocketData();
6952
6953 CreateSession();
6954
6955 // PUSH_PROMISE handling in the http layer gets exercised here.
6956 SendRequestAndExpectQuicResponse("hello!");
6957
6958 request_.url = GURL("https://mail.example.org/pushed.jpg");
6959 SendRequestAndExpectQuicResponse("and hello!");
6960
6961 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:546962 auto entries = net_log_.GetEntries();
ckrasic769733c2016-06-30 00:42:136963 EXPECT_LT(0u, entries.size());
6964
6965 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6966 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006967 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6968 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136969 EXPECT_LT(0, pos);
6970}
6971
rch56ec40a2017-06-23 14:48:446972// Regression test for http://crbug.com/719461 in which a promised stream
6973// is closed before the pushed headers arrive, but after the connection
6974// is closed and before the callbacks are executed.
6975TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamilton6c6493102019-12-05 21:36:506976 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
6977 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:386978 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6979 context_.params()->origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446980 HostPortPair::FromString("mail.example.org:443"));
6981
Ryan Hamiltonabad59e2019-06-06 04:02:596982 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236983 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446984 // Initial SETTINGS frame.
Victor Vasiliev7da08172019-10-14 06:04:256985 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236986 mock_quic_data.AddWrite(
6987 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6988 }
rch56ec40a2017-06-23 14:48:446989 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436990 mock_quic_data.AddWrite(
6991 SYNCHRONOUS,
6992 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336993 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026994 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446995 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436996 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026997 ASYNC,
6998 ConstructServerPushPromisePacket(
6999 1, GetNthClientInitiatedBidirectionalStreamId(0),
7000 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7001 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:317002 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:427003 version_.transport_version >= quic::QUIC_VERSION_43 &&
Ian Swett25d3c3b32020-01-14 17:51:297004 !VersionUsesHttp3(version_.transport_version))) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027005 mock_quic_data.AddWrite(
7006 SYNCHRONOUS,
7007 ConstructClientPriorityPacket(
7008 client_packet_number++, false,
7009 GetNthServerInitiatedUnidirectionalStreamId(0),
7010 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577011 }
rch56ec40a2017-06-23 14:48:447012 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:437013 mock_quic_data.AddRead(
7014 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337015 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027016 GetResponseHeaders("200 OK")));
rch56ec40a2017-06-23 14:48:447017 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:577018 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437019 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:447020 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:437021 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437022 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337023 ASYNC, ConstructServerDataPacket(
7024 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177025 header + "hello!"));
rch56ec40a2017-06-23 14:48:447026 // Write error for the third request.
7027 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
7028 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7029 mock_quic_data.AddRead(ASYNC, 0); // EOF
7030 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7031
7032 CreateSession();
7033
7034 // Send a request which triggers a push promise from the server.
7035 SendRequestAndExpectQuicResponse("hello!");
7036
7037 // Start a push transaction that will be cancelled after the connection
7038 // is closed, but before the callback is executed.
7039 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:197040 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:447041 session_.get());
7042 TestCompletionCallback callback2;
7043 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
7044 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7045 base::RunLoop().RunUntilIdle();
7046
7047 // Cause the connection to close on a write error.
7048 HttpRequestInfo request3;
7049 request3.method = "GET";
7050 request3.url = GURL("https://mail.example.org/");
7051 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107052 request3.traffic_annotation =
7053 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:447054 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
7055 TestCompletionCallback callback3;
7056 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
7057 IsError(ERR_IO_PENDING));
7058
7059 base::RunLoop().RunUntilIdle();
7060
7061 // When |trans2| is destroyed, the underlying stream will be closed.
7062 EXPECT_FALSE(callback2.have_result());
7063 trans2 = nullptr;
7064
7065 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
7066}
7067
ckrasicda193a82016-07-09 00:39:367068TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Victor Vasilieva1e66d72019-12-05 17:55:387069 context_.params()->origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:367070 HostPortPair::FromString("mail.example.org:443"));
7071
Ryan Hamiltonabad59e2019-06-06 04:02:597072 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:367073
Renjief49758b2019-01-11 23:32:417074 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:257075 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237076 mock_quic_data.AddWrite(
7077 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7078 }
ckrasicda193a82016-07-09 00:39:367079
Victor Vasiliev076657c2019-03-12 02:46:437080 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567081 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417082 mock_quic_data.AddWrite(
7083 SYNCHRONOUS,
7084 ConstructClientRequestHeadersAndDataFramesPacket(
7085 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7086 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:027087 GetRequestHeaders("POST", "https", "/"), 0, nullptr, {"1"}));
Renjief49758b2019-01-11 23:32:417088 } else {
7089 mock_quic_data.AddWrite(
7090 SYNCHRONOUS,
7091 ConstructClientRequestHeadersAndDataFramesPacket(
7092 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7093 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:027094 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
Renjief49758b2019-01-11 23:32:417095 {header, "1"}));
7096 }
ckrasicda193a82016-07-09 00:39:367097
Zhongyi Shi32f2fd02018-04-16 18:23:437098 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337099 ASYNC, ConstructServerResponseHeadersPacket(
7100 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7101 GetResponseHeaders("200 OK")));
7102
Victor Vasiliev076657c2019-03-12 02:46:437103 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:337104 mock_quic_data.AddRead(
7105 ASYNC, ConstructServerDataPacket(
7106 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177107 header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:367108
Renjief49758b2019-01-11 23:32:417109 mock_quic_data.AddWrite(
7110 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:367111
7112 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7113 mock_quic_data.AddRead(ASYNC, 0); // EOF
7114 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7115
7116 // The non-alternate protocol job needs to hang in order to guarantee that
7117 // the alternate-protocol job will "win".
7118 AddHangingNonAlternateProtocolSocketData();
7119
7120 CreateSession();
7121 request_.method = "POST";
7122 ChunkedUploadDataStream upload_data(0);
7123 upload_data.AppendData("1", 1, true);
7124
7125 request_.upload_data_stream = &upload_data;
7126
7127 SendRequestAndExpectQuicResponse("hello!");
7128}
7129
allada71b2efb2016-09-09 04:57:487130class QuicURLRequestContext : public URLRequestContext {
7131 public:
7132 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
7133 MockClientSocketFactory* socket_factory)
7134 : storage_(this) {
7135 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:077136 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:047137 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:487138 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:047139 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:597140 storage_.set_proxy_resolution_service(
Nicolas Arciniegad2013f92020-02-07 23:00:567141 ConfiguredProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:077142 storage_.set_ssl_config_service(
7143 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:487144 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:117145 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:487146 storage_.set_http_server_properties(
Matt Menke609160742019-08-02 18:47:267147 std::make_unique<HttpServerProperties>());
Bence Béky8f9d7d3952017-10-09 19:58:047148 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:487149 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:047150 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
7151 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
7152 false));
allada71b2efb2016-09-09 04:57:487153 }
7154
7155 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
7156
7157 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
7158
7159 private:
7160 MockClientSocketFactory* socket_factory_;
7161 URLRequestContextStorage storage_;
7162};
7163
7164TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
Victor Vasilieva1e66d72019-12-05 17:55:387165 context_.params()->origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:487166 HostPortPair::FromString("mail.example.org:443"));
7167
Ryan Hamiltonabad59e2019-06-06 04:02:597168 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237169 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257170 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237171 mock_quic_data.AddWrite(SYNCHRONOUS,
7172 ConstructInitialSettingsPacket(packet_num++));
7173 }
Ryan Hamilton0239aac2018-05-19 00:03:137174 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:487175 headers["user-agent"] = "";
7176 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:337177 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237178 SYNCHRONOUS,
7179 ConstructClientRequestHeadersPacket(
7180 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7181 true, std::move(headers)));
allada71b2efb2016-09-09 04:57:487182
Fan Yang32c5a112018-12-10 20:06:337183 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027184 ASYNC, ConstructServerResponseHeadersPacket(
7185 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7186 GetResponseHeaders("200 OK")));
7187 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:457188 server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257189 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457190 ? GetNthClientInitiatedBidirectionalStreamId(0)
7191 : quic::QuicUtils::GetHeadersStreamId(
7192 version_.transport_version));
allada71b2efb2016-09-09 04:57:487193
Victor Vasiliev076657c2019-03-12 02:46:437194 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:367195 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337196 ASYNC, ConstructServerDataPacket(
7197 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177198 "Main Resource Data"));
Renjie Tangaadb84b2019-08-31 01:00:237199 mock_quic_data.AddWrite(SYNCHRONOUS,
7200 ConstructClientAckPacket(packet_num++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:487201
7202 mock_quic_data.AddRead(ASYNC, 0); // EOF
7203
7204 CreateSession();
7205
7206 TestDelegate delegate;
7207 QuicURLRequestContext quic_url_request_context(std::move(session_),
7208 &socket_factory_);
7209
7210 mock_quic_data.AddSocketDataToFactory(
7211 &quic_url_request_context.socket_factory());
7212 TestNetworkDelegate network_delegate;
7213 quic_url_request_context.set_network_delegate(&network_delegate);
7214
7215 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:297216 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
7217 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:487218 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
7219 &ssl_data_);
7220
7221 request->Start();
Wez2a31b222018-06-07 22:07:157222 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:487223
7224 EXPECT_LT(0, request->GetTotalSentBytes());
7225 EXPECT_LT(0, request->GetTotalReceivedBytes());
allada71b2efb2016-09-09 04:57:487226 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
7227 request->raw_header_size());
Wez0e717112018-06-18 23:09:227228
7229 // Pump the message loop to allow all data to be consumed.
7230 base::RunLoop().RunUntilIdle();
7231
allada71b2efb2016-09-09 04:57:487232 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7233 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7234}
7235
7236TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
Ryan Hamilton6c6493102019-12-05 21:36:507237 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
7238 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:387239 context_.params()->origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:487240 HostPortPair::FromString("mail.example.org:443"));
7241
Ryan Hamiltonabad59e2019-06-06 04:02:597242 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237243 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257244 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237245 mock_quic_data.AddWrite(
7246 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7247 }
Ryan Hamilton0239aac2018-05-19 00:03:137248 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:487249 headers["user-agent"] = "";
7250 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:437251 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337252 SYNCHRONOUS,
7253 ConstructClientRequestHeadersPacket(
7254 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027255 true, true, std::move(headers)));
allada71b2efb2016-09-09 04:57:487256
Fan Yang2330d182019-08-05 14:50:507257 const quic::QuicStreamOffset initial = server_maker_.stream_offset(
7258 GetNthClientInitiatedBidirectionalStreamId(0));
Zhongyi Shi32f2fd02018-04-16 18:23:437259 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027260 ASYNC,
7261 ConstructServerPushPromisePacket(
7262 1, GetNthClientInitiatedBidirectionalStreamId(0),
7263 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7264 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Fan Yang2330d182019-08-05 14:50:507265 quic::QuicStreamOffset push_promise_offset = 0;
Victor Vasiliev7da08172019-10-14 06:04:257266 if (VersionUsesHttp3(version_.transport_version)) {
Fan Yang2330d182019-08-05 14:50:507267 push_promise_offset = server_maker_.stream_offset(
7268 GetNthClientInitiatedBidirectionalStreamId(0)) -
7269 initial;
7270 }
allada71b2efb2016-09-09 04:57:487271
Renjie Tang703fea92019-07-23 21:08:317272 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:427273 version_.transport_version >= quic::QUIC_VERSION_43 &&
Ian Swett25d3c3b32020-01-14 17:51:297274 !VersionUsesHttp3(version_.transport_version))) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027275 mock_quic_data.AddWrite(
7276 SYNCHRONOUS,
7277 ConstructClientPriorityPacket(
7278 client_packet_number++, false,
7279 GetNthServerInitiatedUnidirectionalStreamId(0),
7280 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577281 }
7282
Ryan Hamiltone940bd12019-06-30 02:46:457283 const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257284 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457285 ? GetNthClientInitiatedBidirectionalStreamId(0)
7286 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Zhongyi Shi32f2fd02018-04-16 18:23:437287 mock_quic_data.AddRead(
7288 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337289 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027290 GetResponseHeaders("200 OK")));
Ryan Hamiltone940bd12019-06-30 02:46:457291 const quic::QuicStreamOffset final_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257292 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457293 ? GetNthClientInitiatedBidirectionalStreamId(0)
7294 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Ryan Hamilton0d65a8c2019-06-07 00:46:027295 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:457296 final_offset - initial_offset;
allada71b2efb2016-09-09 04:57:487297
Yixin Wangb470bc882018-02-15 18:43:577298 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437299 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:487300
ckrasicbf2f59c2017-05-04 23:54:367301 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:437302 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337303 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027304 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437305 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:437306 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337307 ASYNC, ConstructServerDataPacket(
7308 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177309 header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:487310
Yixin Wangb470bc882018-02-15 18:43:577311 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437312 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:437313 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:367314 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337315 ASYNC, ConstructServerDataPacket(
7316 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177317 header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:487318
Zhongyi Shi32f2fd02018-04-16 18:23:437319 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:487320
7321 CreateSession();
7322
7323 TestDelegate delegate;
7324 QuicURLRequestContext quic_url_request_context(std::move(session_),
7325 &socket_factory_);
7326
7327 mock_quic_data.AddSocketDataToFactory(
7328 &quic_url_request_context.socket_factory());
7329 TestNetworkDelegate network_delegate;
7330 quic_url_request_context.set_network_delegate(&network_delegate);
7331
7332 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:297333 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
7334 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:487335 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
7336 &ssl_data_);
7337
7338 request->Start();
Wez2a31b222018-06-07 22:07:157339 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:487340
7341 EXPECT_LT(0, request->GetTotalSentBytes());
7342 EXPECT_LT(0, request->GetTotalReceivedBytes());
Fan Yang2330d182019-08-05 14:50:507343 EXPECT_EQ(
7344 static_cast<int>(expected_raw_header_response_size + push_promise_offset),
7345 request->raw_header_size());
Wez0e717112018-06-18 23:09:227346
7347 // Pump the message loop to allow all data to be consumed.
7348 base::RunLoop().RunUntilIdle();
7349
allada71b2efb2016-09-09 04:57:487350 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7351 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7352}
7353
Ryan Sleevia9d6aa62019-07-26 13:32:187354TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
7355 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:207356
7357 MockRead http_reads[] = {
7358 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7359 MockRead("hello world"),
7360 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7361 MockRead(ASYNC, OK)};
7362
Ryan Sleevib8d7ea02018-05-07 20:01:017363 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207364 socket_factory_.AddSocketDataProvider(&http_data);
7365 AddCertificate(&ssl_data_);
7366 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7367
Ryan Hamiltonabad59e2019-06-06 04:02:597368 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237369 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257370 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237371 mock_quic_data.AddWrite(SYNCHRONOUS,
7372 ConstructInitialSettingsPacket(packet_num++));
7373 }
Yixin Wang10f477ed2017-11-21 04:20:207374 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237375 SYNCHRONOUS,
7376 ConstructClientRequestHeadersPacket(
7377 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7378 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437379 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337380 ASYNC, ConstructServerResponseHeadersPacket(
7381 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7382 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437383 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:337384 mock_quic_data.AddRead(
7385 ASYNC, ConstructServerDataPacket(
7386 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177387 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:237388 mock_quic_data.AddWrite(SYNCHRONOUS,
7389 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:207390 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7391 mock_quic_data.AddRead(ASYNC, 0); // EOF
7392
7393 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7394
7395 AddHangingNonAlternateProtocolSocketData();
7396 CreateSession();
7397
7398 SendRequestAndExpectHttpResponse("hello world");
7399 SendRequestAndExpectQuicResponse("hello!");
7400}
7401
Ryan Sleevia9d6aa62019-07-26 13:32:187402TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
7403 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:207404
7405 MockRead http_reads[] = {
7406 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7407 MockRead("hello world"),
7408 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7409 MockRead(ASYNC, OK)};
7410
Ryan Sleevib8d7ea02018-05-07 20:01:017411 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207412 socket_factory_.AddSocketDataProvider(&http_data);
7413 AddCertificate(&ssl_data_);
7414 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7415 socket_factory_.AddSocketDataProvider(&http_data);
7416 AddCertificate(&ssl_data_);
7417 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7418
7419 AddHangingNonAlternateProtocolSocketData();
7420 CreateSession();
7421
7422 SendRequestAndExpectHttpResponse("hello world");
7423 SendRequestAndExpectHttpResponse("hello world");
7424}
7425
bnc359ed2a2016-04-29 20:43:457426class QuicNetworkTransactionWithDestinationTest
7427 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:017428 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:057429 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:457430 protected:
7431 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:557432 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:057433 client_headers_include_h2_stream_dependency_(
7434 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:567435 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:457436 destination_type_(GetParam().destination_type),
7437 cert_transparency_verifier_(new MultiLogCTVerifier()),
7438 ssl_config_service_(new SSLConfigServiceDefaults),
Nicolas Arciniegad2013f92020-02-07 23:00:567439 proxy_resolution_service_(
7440 ConfiguredProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:117441 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Ryan Hamiltonf9a421f2020-01-31 21:09:527442 ssl_data_(ASYNC, OK) {
Renjie Tang98b4d512020-02-08 01:24:197443 FLAGS_quic_enable_http3_grease_randomness = false;
Ryan Hamiltonf9a421f2020-01-31 21:09:527444 }
bnc359ed2a2016-04-29 20:43:457445
7446 void SetUp() override {
7447 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557448 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457449
mmenke6ddfbea2017-05-31 21:48:417450 HttpNetworkSession::Params session_params;
7451 session_params.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:387452 context_.params()->allow_remote_alt_svc = true;
7453 context_.params()->supported_versions = supported_versions_;
7454 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:057455 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:417456
7457 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:457458
Victor Vasiliev7752898d2019-11-14 21:30:227459 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
bnc359ed2a2016-04-29 20:43:457460
7461 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277462 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:417463 session_context.quic_crypto_client_stream_factory =
7464 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:457465
Victor Vasiliev7752898d2019-11-14 21:30:227466 session_context.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:417467 session_context.client_socket_factory = &socket_factory_;
7468 session_context.host_resolver = &host_resolver_;
7469 session_context.cert_verifier = &cert_verifier_;
7470 session_context.transport_security_state = &transport_security_state_;
7471 session_context.cert_transparency_verifier =
7472 cert_transparency_verifier_.get();
7473 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
7474 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:457475 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:417476 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:597477 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:417478 session_context.http_auth_handler_factory = auth_handler_factory_.get();
7479 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:457480
mmenke6ddfbea2017-05-31 21:48:417481 session_.reset(new HttpNetworkSession(session_params, session_context));
Matt Menkeb566c392019-09-11 23:22:437482 session_->quic_stream_factory()
7483 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:457484 }
7485
7486 void TearDown() override {
7487 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7488 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557489 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457490 PlatformTest::TearDown();
7491 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557492 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:407493 session_.reset();
bnc359ed2a2016-04-29 20:43:457494 }
7495
zhongyie537a002017-06-27 16:48:217496 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:457497 HostPortPair destination;
7498 switch (destination_type_) {
7499 case SAME_AS_FIRST:
7500 destination = HostPortPair(origin1_, 443);
7501 break;
7502 case SAME_AS_SECOND:
7503 destination = HostPortPair(origin2_, 443);
7504 break;
7505 case DIFFERENT:
7506 destination = HostPortPair(kDifferentHostname, 443);
7507 break;
7508 }
bnc3472afd2016-11-17 15:27:217509 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:457510 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:217511 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:077512 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
7513 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:457514 }
7515
Ryan Hamilton8d9ee76e2018-05-29 23:52:527516 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237517 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527518 quic::QuicStreamId stream_id,
7519 bool should_include_version,
7520 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527521 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137522 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457523 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:137524 spdy::SpdyHeaderBlock headers(
7525 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027526 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457527 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027528 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:457529 }
7530
Ryan Hamilton8d9ee76e2018-05-29 23:52:527531 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237532 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527533 quic::QuicStreamId stream_id,
7534 bool should_include_version,
7535 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587536 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:027537 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:457538 }
7539
Ryan Hamilton8d9ee76e2018-05-29 23:52:527540 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237541 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527542 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527543 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137544 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027545 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
7546 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:457547 }
7548
Ryan Hamilton8d9ee76e2018-05-29 23:52:527549 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237550 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527551 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457552 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:437553 std::string header = "";
Nick Harper23290b82019-05-02 00:02:567554 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417555 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:577556 auto header_length =
7557 quic::HttpEncoder::SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:437558 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:417559 }
Ryan Hamilton7505eb92019-06-08 00:22:177560 return maker->MakeDataPacket(packet_number, stream_id, false, true,
Renjief49758b2019-01-11 23:32:417561 header + "hello");
bnc359ed2a2016-04-29 20:43:457562 }
7563
Ryan Hamilton8d9ee76e2018-05-29 23:52:527564 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237565 uint64_t packet_number,
7566 uint64_t largest_received,
7567 uint64_t smallest_received,
7568 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:457569 QuicTestPacketMaker* maker) {
7570 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:497571 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:457572 }
7573
Ryan Hamilton8d9ee76e2018-05-29 23:52:527574 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237575 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:377576 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027577 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:377578 }
7579
bnc359ed2a2016-04-29 20:43:457580 void AddRefusedSocketData() {
7581 std::unique_ptr<StaticSocketDataProvider> refused_data(
7582 new StaticSocketDataProvider());
7583 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7584 refused_data->set_connect_data(refused_connect);
7585 socket_factory_.AddSocketDataProvider(refused_data.get());
7586 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7587 }
7588
7589 void AddHangingSocketData() {
7590 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7591 new StaticSocketDataProvider());
7592 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7593 hanging_data->set_connect_data(hanging_connect);
7594 socket_factory_.AddSocketDataProvider(hanging_data.get());
7595 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7596 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7597 }
7598
7599 bool AllDataConsumed() {
7600 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7601 if (!socket_data_ptr->AllReadDataConsumed() ||
7602 !socket_data_ptr->AllWriteDataConsumed()) {
7603 return false;
7604 }
7605 }
7606 return true;
7607 }
7608
7609 void SendRequestAndExpectQuicResponse(const std::string& host) {
7610 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7611 HttpRequestInfo request;
7612 std::string url("https://");
7613 url.append(host);
7614 request.url = GURL(url);
7615 request.load_flags = 0;
7616 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107617 request.traffic_annotation =
7618 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457619 TestCompletionCallback callback;
7620 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017621 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457622
7623 std::string response_data;
robpercival214763f2016-07-01 23:27:017624 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457625 EXPECT_EQ("hello", response_data);
7626
7627 const HttpResponseInfo* response = trans.GetResponseInfo();
7628 ASSERT_TRUE(response != nullptr);
7629 ASSERT_TRUE(response->headers.get() != nullptr);
7630 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7631 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527632 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:087633 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457634 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377635 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457636 }
7637
Fan Yang32c5a112018-12-10 20:06:337638 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567639 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7640 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367641 }
7642
Ryan Hamiltonf9a421f2020-01-31 21:09:527643 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Nick Harper23290b82019-05-02 00:02:567644 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057645 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567646 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457647 DestinationType destination_type_;
7648 std::string origin1_;
7649 std::string origin2_;
Victor Vasiliev7752898d2019-11-14 21:30:227650 MockQuicContext context_;
bnc359ed2a2016-04-29 20:43:457651 std::unique_ptr<HttpNetworkSession> session_;
7652 MockClientSocketFactory socket_factory_;
7653 MockHostResolver host_resolver_;
7654 MockCertVerifier cert_verifier_;
7655 TransportSecurityState transport_security_state_;
7656 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237657 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457658 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077659 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Nicolas Arciniegad2013f92020-02-07 23:00:567660 std::unique_ptr<ConfiguredProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457661 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:267662 HttpServerProperties http_server_properties_;
Matt Muellerd9342e3a2019-11-26 01:41:147663 RecordingBoundTestNetLog net_log_;
bnc359ed2a2016-04-29 20:43:457664 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7665 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7666 static_socket_data_provider_vector_;
7667 SSLSocketDataProvider ssl_data_;
7668};
7669
Victor Costane635086f2019-01-27 05:20:307670INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7671 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:577672 ::testing::ValuesIn(GetPoolingTestParams()),
7673 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:457674
7675// A single QUIC request fails because the certificate does not match the origin
7676// hostname, regardless of whether it matches the alternative service hostname.
7677TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7678 if (destination_type_ == DIFFERENT)
7679 return;
7680
7681 GURL url("https://mail.example.com/");
7682 origin1_ = url.host();
7683
7684 // Not used for requests, but this provides a test case where the certificate
7685 // is valid for the hostname of the alternative service.
7686 origin2_ = "mail.example.org";
7687
zhongyie537a002017-06-27 16:48:217688 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457689
7690 scoped_refptr<X509Certificate> cert(
7691 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247692 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7693 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457694
7695 ProofVerifyDetailsChromium verify_details;
7696 verify_details.cert_verify_result.verified_cert = cert;
7697 verify_details.cert_verify_result.is_issued_by_known_root = true;
7698 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7699
Ryan Hamiltonabad59e2019-06-06 04:02:597700 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457701 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7702 mock_quic_data.AddRead(ASYNC, 0);
7703
7704 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7705
7706 AddRefusedSocketData();
7707
7708 HttpRequestInfo request;
7709 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107710 request.traffic_annotation =
7711 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457712
7713 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7714 TestCompletionCallback callback;
7715 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017716 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457717
7718 EXPECT_TRUE(AllDataConsumed());
7719}
7720
7721// First request opens QUIC session to alternative service. Second request
7722// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527723// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457724TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7725 origin1_ = "mail.example.org";
7726 origin2_ = "news.example.org";
7727
zhongyie537a002017-06-27 16:48:217728 SetQuicAlternativeService(origin1_);
7729 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457730
7731 scoped_refptr<X509Certificate> cert(
7732 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247733 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7734 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7735 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457736
7737 ProofVerifyDetailsChromium verify_details;
7738 verify_details.cert_verify_result.verified_cert = cert;
7739 verify_details.cert_verify_result.is_issued_by_known_root = true;
7740 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7741
Yixin Wang079ad542018-01-11 04:06:057742 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227743 version_,
7744 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7745 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057746 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177747 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227748 version_,
7749 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7750 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457751
Ryan Hamiltonabad59e2019-06-06 04:02:597752 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237753 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257754 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237755 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7756 packet_num++, &client_maker));
7757 }
Fan Yang32c5a112018-12-10 20:06:337758 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237759 SYNCHRONOUS,
7760 ConstructClientRequestHeadersPacket(
7761 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7762 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:027763 mock_quic_data.AddRead(
7764 ASYNC,
7765 ConstructServerResponseHeadersPacket(
7766 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437767 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337768 ASYNC,
7769 ConstructServerDataPacket(
7770 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237771 mock_quic_data.AddWrite(
7772 SYNCHRONOUS,
7773 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457774
Yixin Wang079ad542018-01-11 04:06:057775 client_maker.set_hostname(origin2_);
7776 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457777
Zhongyi Shi32f2fd02018-04-16 18:23:437778 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027779 SYNCHRONOUS,
7780 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237781 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027782 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7783 mock_quic_data.AddRead(
7784 ASYNC,
7785 ConstructServerResponseHeadersPacket(
7786 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437787 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337788 ASYNC,
7789 ConstructServerDataPacket(
7790 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237791 mock_quic_data.AddWrite(
7792 SYNCHRONOUS,
7793 ConstructClientAckPacket(packet_num++, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457794 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7795 mock_quic_data.AddRead(ASYNC, 0); // EOF
7796
7797 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7798
7799 AddHangingSocketData();
7800 AddHangingSocketData();
7801
Victor Vasiliev7752898d2019-11-14 21:30:227802 scoped_refptr<TestTaskRunner> quic_task_runner(
7803 new TestTaskRunner(context_.mock_clock()));
Fan Yangc9e00dc2018-10-09 14:17:567804 QuicStreamFactoryPeer::SetAlarmFactory(
7805 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097806 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Victor Vasiliev7752898d2019-11-14 21:30:227807 context_.clock()));
Fan Yangc9e00dc2018-10-09 14:17:567808
bnc359ed2a2016-04-29 20:43:457809 SendRequestAndExpectQuicResponse(origin1_);
7810 SendRequestAndExpectQuicResponse(origin2_);
7811
7812 EXPECT_TRUE(AllDataConsumed());
7813}
7814
7815// First request opens QUIC session to alternative service. Second request does
7816// not pool to it, even though destination matches, because certificate is not
7817// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527818// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457819TEST_P(QuicNetworkTransactionWithDestinationTest,
7820 DoNotPoolIfCertificateInvalid) {
7821 origin1_ = "news.example.org";
7822 origin2_ = "mail.example.com";
7823
zhongyie537a002017-06-27 16:48:217824 SetQuicAlternativeService(origin1_);
7825 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457826
7827 scoped_refptr<X509Certificate> cert1(
7828 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247829 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7830 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7831 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457832
7833 scoped_refptr<X509Certificate> cert2(
7834 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247835 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7836 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457837
7838 ProofVerifyDetailsChromium verify_details1;
7839 verify_details1.cert_verify_result.verified_cert = cert1;
7840 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7841 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7842
7843 ProofVerifyDetailsChromium verify_details2;
7844 verify_details2.cert_verify_result.verified_cert = cert2;
7845 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7846 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7847
Yixin Wang079ad542018-01-11 04:06:057848 QuicTestPacketMaker client_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227849 version_,
7850 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7851 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057852 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177853 QuicTestPacketMaker server_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227854 version_,
7855 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7856 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457857
Ryan Hamiltonabad59e2019-06-06 04:02:597858 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:237859 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257860 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237861 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7862 packet_num++, &client_maker1));
7863 }
Fan Yang32c5a112018-12-10 20:06:337864 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237865 SYNCHRONOUS,
7866 ConstructClientRequestHeadersPacket(
7867 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7868 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437869 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337870 ASYNC,
7871 ConstructServerResponseHeadersPacket(
7872 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437873 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337874 ASYNC,
7875 ConstructServerDataPacket(
7876 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437877 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237878 SYNCHRONOUS,
7879 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457880 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7881 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7882
7883 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7884
Yixin Wang079ad542018-01-11 04:06:057885 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227886 version_,
7887 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7888 context_.clock(), origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057889 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177890 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227891 version_,
7892 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7893 context_.clock(), origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457894
Ryan Hamiltonabad59e2019-06-06 04:02:597895 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:237896 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:257897 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237898 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7899 packet_num2++, &client_maker2));
7900 }
Fan Yang32c5a112018-12-10 20:06:337901 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237902 SYNCHRONOUS,
7903 ConstructClientRequestHeadersPacket(
7904 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7905 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437906 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337907 ASYNC,
7908 ConstructServerResponseHeadersPacket(
7909 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437910 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337911 ASYNC,
7912 ConstructServerDataPacket(
7913 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437914 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237915 SYNCHRONOUS,
7916 ConstructClientAckPacket(packet_num2++, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457917 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7918 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7919
7920 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7921
bnc359ed2a2016-04-29 20:43:457922 SendRequestAndExpectQuicResponse(origin1_);
7923 SendRequestAndExpectQuicResponse(origin2_);
7924
7925 EXPECT_TRUE(AllDataConsumed());
7926}
7927
ckrasicdee37572017-04-06 22:42:277928// crbug.com/705109 - this confirms that matching request with a body
7929// triggers a crash (pre-fix).
7930TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Ryan Hamilton6c6493102019-12-05 21:36:507931 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
7932 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:387933 context_.params()->origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277934 HostPortPair::FromString("mail.example.org:443"));
7935
Ryan Hamiltonabad59e2019-06-06 04:02:597936 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237937 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257938 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237939 mock_quic_data.AddWrite(
7940 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7941 }
Zhongyi Shi32f2fd02018-04-16 18:23:437942 mock_quic_data.AddWrite(
7943 SYNCHRONOUS,
7944 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337945 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027946 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437947 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027948 ASYNC,
7949 ConstructServerPushPromisePacket(
7950 1, GetNthClientInitiatedBidirectionalStreamId(0),
7951 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7952 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:317953
7954 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:427955 version_.transport_version >= quic::QUIC_VERSION_43 &&
Ian Swett25d3c3b32020-01-14 17:51:297956 !VersionUsesHttp3(version_.transport_version))) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027957 mock_quic_data.AddWrite(
7958 SYNCHRONOUS,
7959 ConstructClientPriorityPacket(
7960 client_packet_number++, false,
7961 GetNthServerInitiatedUnidirectionalStreamId(0),
7962 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577963 }
Zhongyi Shi32f2fd02018-04-16 18:23:437964 mock_quic_data.AddRead(
7965 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337966 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027967 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:577968 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437969 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7970 mock_quic_data.AddRead(
7971 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337972 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027973 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437974 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437975 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337976 ASYNC, ConstructServerDataPacket(
7977 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177978 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577979 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437980 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417981
Victor Vasiliev076657c2019-03-12 02:46:437982 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437983 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337984 ASYNC, ConstructServerDataPacket(
7985 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177986 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277987
7988 // Because the matching request has a body, we will see the push
7989 // stream get cancelled, and the matching request go out on the
7990 // wire.
Fan Yang32c5a112018-12-10 20:06:337991 mock_quic_data.AddWrite(SYNCHRONOUS,
7992 ConstructClientAckAndRstPacket(
7993 client_packet_number++,
7994 GetNthServerInitiatedUnidirectionalStreamId(0),
7995 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277996 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437997 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567998 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417999 mock_quic_data.AddWrite(
8000 SYNCHRONOUS,
8001 ConstructClientRequestHeadersAndDataFramesPacket(
8002 client_packet_number++,
8003 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
8004 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:028005 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, {kBody}));
Renjief49758b2019-01-11 23:32:418006 } else {
8007 mock_quic_data.AddWrite(
8008 SYNCHRONOUS,
8009 ConstructClientRequestHeadersAndDataFramesPacket(
8010 client_packet_number++,
8011 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
8012 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:028013 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
8014 {header3, kBody}));
Renjief49758b2019-01-11 23:32:418015 }
ckrasicdee37572017-04-06 22:42:278016
8017 // We see the same response as for the earlier pushed and cancelled
8018 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438019 mock_quic_data.AddRead(
8020 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338021 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028022 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:438023 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338024 ASYNC, ConstructServerDataPacket(
8025 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:178026 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:278027
Yixin Wangb470bc882018-02-15 18:43:578028 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438029 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:278030 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8031 mock_quic_data.AddRead(ASYNC, 0); // EOF
8032 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8033
8034 // The non-alternate protocol job needs to hang in order to guarantee that
8035 // the alternate-protocol job will "win".
8036 AddHangingNonAlternateProtocolSocketData();
8037
8038 CreateSession();
8039
8040 // PUSH_PROMISE handling in the http layer gets exercised here.
8041 SendRequestAndExpectQuicResponse("hello!");
8042
8043 request_.url = GURL("https://mail.example.org/pushed.jpg");
8044 ChunkedUploadDataStream upload_data(0);
8045 upload_data.AppendData("1", 1, true);
8046 request_.upload_data_stream = &upload_data;
8047 SendRequestAndExpectQuicResponse("and hello!");
8048}
8049
Bence Béky7538a952018-02-01 16:59:528050// Regression test for https://crbug.com/797825: If pushed headers describe a
8051// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
8052// not be called (otherwise a DCHECK fails).
8053TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton6c6493102019-12-05 21:36:508054 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
8055 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
8056
Ryan Hamilton0239aac2018-05-19 00:03:138057 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:528058 pushed_request_headers[":authority"] = "";
8059 pushed_request_headers[":method"] = "GET";
8060 pushed_request_headers[":path"] = "/";
8061 pushed_request_headers[":scheme"] = "nosuchscheme";
8062
Victor Vasilieva1e66d72019-12-05 17:55:388063 context_.params()->origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:528064 HostPortPair::FromString("mail.example.org:443"));
8065
Ryan Hamiltonabad59e2019-06-06 04:02:598066 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:528067
Renjie Tangaadb84b2019-08-31 01:00:238068 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258069 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238070 mock_quic_data.AddWrite(SYNCHRONOUS,
8071 ConstructInitialSettingsPacket(packet_num++));
8072 }
Bence Béky7538a952018-02-01 16:59:528073 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238074 SYNCHRONOUS,
8075 ConstructClientRequestHeadersPacket(
8076 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8077 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:528078
Fan Yang32c5a112018-12-10 20:06:338079 mock_quic_data.AddRead(
8080 ASYNC, ConstructServerPushPromisePacket(
8081 1, GetNthClientInitiatedBidirectionalStreamId(0),
8082 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028083 std::move(pushed_request_headers), &server_maker_));
Renjie Tangaadb84b2019-08-31 01:00:238084 mock_quic_data.AddWrite(
8085 SYNCHRONOUS,
8086 ConstructClientRstPacket(packet_num++,
8087 GetNthServerInitiatedUnidirectionalStreamId(0),
8088 quic::QUIC_INVALID_PROMISE_URL));
Bence Béky7538a952018-02-01 16:59:528089
Zhongyi Shi32f2fd02018-04-16 18:23:438090 mock_quic_data.AddRead(
8091 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338092 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028093 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238094 mock_quic_data.AddWrite(SYNCHRONOUS,
8095 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:528096
Zhongyi Shi32f2fd02018-04-16 18:23:438097 mock_quic_data.AddRead(
8098 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338099 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028100 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:438101 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:438102 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338103 ASYNC, ConstructServerDataPacket(
8104 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:178105 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:238106 mock_quic_data.AddWrite(SYNCHRONOUS,
8107 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:528108
8109 mock_quic_data.AddRead(ASYNC, 0);
8110 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8111
8112 // The non-alternate protocol job needs to hang in order to guarantee that
8113 // the alternate-protocol job will "win".
8114 AddHangingNonAlternateProtocolSocketData();
8115
8116 CreateSession();
8117
8118 // PUSH_PROMISE handling in the http layer gets exercised here.
8119 SendRequestAndExpectQuicResponse("hello!");
8120
8121 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8122 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8123}
8124
Yixin Wang46a273ec302018-01-23 17:59:568125// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148126TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:568127 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148128 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568129 proxy_resolution_service_ =
8130 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8131 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568132
Ryan Hamiltonabad59e2019-06-06 04:02:598133 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238134 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258135 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238136 mock_quic_data.AddWrite(SYNCHRONOUS,
8137 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498138 mock_quic_data.AddWrite(
8139 SYNCHRONOUS, client_maker_.MakePriorityPacket(
8140 packet_num++, true,
8141 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8142 ConvertRequestPriorityToQuicPriority(
8143 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238144 }
Fan Yang32c5a112018-12-10 20:06:338145 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238146 SYNCHRONOUS,
8147 ConstructClientRequestHeadersPacket(
8148 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498149 false,
8150 VersionUsesHttp3(version_.transport_version)
8151 ? MEDIUM
8152 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238153 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338154 mock_quic_data.AddRead(
8155 ASYNC, ConstructServerResponseHeadersPacket(
8156 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8157 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568158
8159 const char get_request[] =
8160 "GET / HTTP/1.1\r\n"
8161 "Host: mail.example.org\r\n"
8162 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438163 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568164 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418165 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358166 SYNCHRONOUS,
8167 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238168 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Zhongyi Shid1c00fc42019-12-14 06:05:098169 1, 1, 1, false, quiche::QuicheStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418170 } else {
8171 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418172 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288173 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238174 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288175 1, 1, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418176 }
8177
Yixin Wang46a273ec302018-01-23 17:59:568178 const char get_response[] =
8179 "HTTP/1.1 200 OK\r\n"
8180 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438181 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438182 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338183 ASYNC, ConstructServerDataPacket(
8184 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178185 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:438186 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338187 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418188 SYNCHRONOUS, ConstructServerDataPacket(
8189 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178190 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238191 mock_quic_data.AddWrite(SYNCHRONOUS,
8192 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568193 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8194
Bence Béky6e243aa2019-12-13 19:01:078195 if (VersionUsesHttp3(version_.transport_version)) {
8196 mock_quic_data.AddWrite(
8197 SYNCHRONOUS, ConstructClientDataPacket(
8198 packet_num++, GetQpackDecoderStreamId(), true, false,
8199 StreamCancellationQpackDecoderInstruction(0)));
8200 }
8201
Yixin Wang46a273ec302018-01-23 17:59:568202 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418203 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238204 ConstructClientRstPacket(packet_num++,
8205 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418206 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568207
8208 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8209
8210 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8211
8212 CreateSession();
8213
8214 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:098215 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:568216 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8217 HeadersHandler headers_handler;
8218 trans.SetBeforeHeadersSentCallback(
8219 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8220 base::Unretained(&headers_handler)));
8221 RunTransaction(&trans);
8222 CheckWasHttpResponse(&trans);
8223 CheckResponsePort(&trans, 70);
8224 CheckResponseData(&trans, "0123456789");
8225 EXPECT_TRUE(headers_handler.was_proxied());
8226 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8227
8228 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8229 // proxy socket to disconnect.
8230 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8231
8232 base::RunLoop().RunUntilIdle();
8233 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8234 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8235}
8236
8237// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148238TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:568239 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148240 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568241 proxy_resolution_service_ =
8242 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8243 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568244
Ryan Hamiltonabad59e2019-06-06 04:02:598245 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238246 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258247 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238248 mock_quic_data.AddWrite(SYNCHRONOUS,
8249 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498250 mock_quic_data.AddWrite(
8251 SYNCHRONOUS, client_maker_.MakePriorityPacket(
8252 packet_num++, true,
8253 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8254 ConvertRequestPriorityToQuicPriority(
8255 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238256 }
Fan Yang32c5a112018-12-10 20:06:338257 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238258 SYNCHRONOUS,
8259 ConstructClientRequestHeadersPacket(
8260 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498261 false,
8262 VersionUsesHttp3(version_.transport_version)
8263 ? MEDIUM
8264 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238265 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338266 mock_quic_data.AddRead(
8267 ASYNC, ConstructServerResponseHeadersPacket(
8268 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8269 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568270
8271 SpdyTestUtil spdy_util;
8272
Ryan Hamilton0239aac2018-05-19 00:03:138273 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568274 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438275 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:568276 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418277 mock_quic_data.AddWrite(
8278 SYNCHRONOUS,
8279 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238280 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8281 1, 1, 1, false,
Zhongyi Shid1c00fc42019-12-14 06:05:098282 quiche::QuicheStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:418283 } else {
8284 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418285 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288286 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238287 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8288 1, 1, 1, false,
Renjie Tangd5133972019-12-06 00:20:288289 {header + std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418290 }
Ryan Hamilton0239aac2018-05-19 00:03:138291 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568292 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438293 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438294 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178295 ASYNC, ConstructServerDataPacket(
8296 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8297 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568298
Ryan Hamilton0239aac2018-05-19 00:03:138299 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198300 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:438301 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438302 mock_quic_data.AddRead(
8303 SYNCHRONOUS,
8304 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:338305 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438306 header3 + std::string(data_frame.data(), data_frame.size())));
Renjie Tangaadb84b2019-08-31 01:00:238307 mock_quic_data.AddWrite(SYNCHRONOUS,
8308 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568309 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8310
Bence Béky6e243aa2019-12-13 19:01:078311 if (VersionUsesHttp3(version_.transport_version)) {
8312 mock_quic_data.AddWrite(
8313 SYNCHRONOUS, ConstructClientDataPacket(
8314 packet_num++, GetQpackDecoderStreamId(), true, false,
8315 StreamCancellationQpackDecoderInstruction(0)));
8316 }
8317
Yixin Wang46a273ec302018-01-23 17:59:568318 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438319 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238320 ConstructClientRstPacket(packet_num++,
8321 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418322 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568323
8324 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8325
8326 SSLSocketDataProvider ssl_data(ASYNC, OK);
8327 ssl_data.next_proto = kProtoHTTP2;
8328 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8329
8330 CreateSession();
8331
8332 request_.url = GURL("https://mail.example.org/");
8333 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8334 HeadersHandler headers_handler;
8335 trans.SetBeforeHeadersSentCallback(
8336 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8337 base::Unretained(&headers_handler)));
8338 RunTransaction(&trans);
8339 CheckWasSpdyResponse(&trans);
8340 CheckResponsePort(&trans, 70);
8341 CheckResponseData(&trans, "0123456789");
8342 EXPECT_TRUE(headers_handler.was_proxied());
8343 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8344
Wez0e717112018-06-18 23:09:228345 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
8346 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:568347 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8348
8349 base::RunLoop().RunUntilIdle();
8350 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8351 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8352}
8353
8354// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
8355// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:148356TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:568357 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148358 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568359 proxy_resolution_service_ =
8360 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8361 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568362
Ryan Hamiltonabad59e2019-06-06 04:02:598363 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:418364 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:258365 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238366 mock_quic_data.AddWrite(
8367 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
Renjie Tangee921d12020-02-06 00:41:498368 mock_quic_data.AddWrite(
8369 SYNCHRONOUS, client_maker_.MakePriorityPacket(
8370 write_packet_index++, true,
8371 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8372 ConvertRequestPriorityToQuicPriority(
8373 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238374 }
Fan Yang32c5a112018-12-10 20:06:338375 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418376 SYNCHRONOUS,
8377 ConstructClientRequestHeadersPacket(
8378 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangee921d12020-02-06 00:41:498379 true, false,
8380 VersionUsesHttp3(version_.transport_version)
8381 ? MEDIUM
8382 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:028383 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338384 mock_quic_data.AddRead(
8385 ASYNC, ConstructServerResponseHeadersPacket(
8386 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8387 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568388
Ryan Hamilton8d9ee76e2018-05-29 23:52:528389 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568390 const char get_request_1[] =
8391 "GET / HTTP/1.1\r\n"
8392 "Host: mail.example.org\r\n"
8393 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438394 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:568395 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418396 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:178397 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8398 write_packet_index++, false,
8399 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Zhongyi Shid1c00fc42019-12-14 06:05:098400 false, quiche::QuicheStringPiece(get_request_1)));
Renjief49758b2019-01-11 23:32:418401 } else {
8402 mock_quic_data.AddWrite(
Renjie Tangd5133972019-12-06 00:20:288403 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Ryan Hamilton7505eb92019-06-08 00:22:178404 write_packet_index++, false,
8405 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Renjie Tangd5133972019-12-06 00:20:288406 false, {header + std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:418407 }
8408
Yixin Wang46a273ec302018-01-23 17:59:568409 const char get_response_1[] =
8410 "HTTP/1.1 200 OK\r\n"
8411 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438412 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:438413 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438414 ASYNC, ConstructServerDataPacket(
8415 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178416 header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:418417 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:568418
Victor Vasiliev076657c2019-03-12 02:46:438419 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338420 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178421 SYNCHRONOUS, ConstructServerDataPacket(
8422 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
8423 false, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:418424 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:568425
Renjief49758b2019-01-11 23:32:418426 mock_quic_data.AddWrite(
8427 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568428
8429 const char get_request_2[] =
8430 "GET /2 HTTP/1.1\r\n"
8431 "Host: mail.example.org\r\n"
8432 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438433 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:568434 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418435 mock_quic_data.AddWrite(
8436 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288437 ConstructClientDataPacket(
Renjied172e812019-01-16 05:12:358438 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288439 false, false, {header4 + std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:358440 } else {
8441 mock_quic_data.AddWrite(
8442 SYNCHRONOUS,
Ryan Hamilton7505eb92019-06-08 00:22:178443 ConstructClientDataPacket(
8444 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Zhongyi Shid1c00fc42019-12-14 06:05:098445 false, false, quiche::QuicheStringPiece(get_request_2)));
Renjief49758b2019-01-11 23:32:418446 }
Yixin Wang46a273ec302018-01-23 17:59:568447
8448 const char get_response_2[] =
8449 "HTTP/1.1 200 OK\r\n"
8450 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438451 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:438452 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438453 ASYNC, ConstructServerDataPacket(
8454 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178455 header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:418456 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:568457
Victor Vasiliev076657c2019-03-12 02:46:438458 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528459 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178460 SYNCHRONOUS, ConstructServerDataPacket(
8461 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
8462 false, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:418463 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:568464
Renjief49758b2019-01-11 23:32:418465 mock_quic_data.AddWrite(
8466 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:568467 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8468
Bence Béky6e243aa2019-12-13 19:01:078469 if (VersionUsesHttp3(version_.transport_version)) {
8470 mock_quic_data.AddWrite(
8471 SYNCHRONOUS, ConstructClientDataPacket(
8472 write_packet_index++, GetQpackDecoderStreamId(), true,
8473 false, StreamCancellationQpackDecoderInstruction(0)));
8474 }
8475
Renjief49758b2019-01-11 23:32:418476 mock_quic_data.AddWrite(
8477 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418478 ConstructClientRstPacket(write_packet_index++,
8479 GetNthClientInitiatedBidirectionalStreamId(0),
8480 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568481
8482 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8483
8484 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8485
8486 CreateSession();
8487
8488 request_.url = GURL("https://mail.example.org/");
8489 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8490 HeadersHandler headers_handler_1;
8491 trans_1.SetBeforeHeadersSentCallback(
8492 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8493 base::Unretained(&headers_handler_1)));
8494 RunTransaction(&trans_1);
8495 CheckWasHttpResponse(&trans_1);
8496 CheckResponsePort(&trans_1, 70);
8497 CheckResponseData(&trans_1, "0123456789");
8498 EXPECT_TRUE(headers_handler_1.was_proxied());
8499 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8500
8501 request_.url = GURL("https://mail.example.org/2");
8502 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8503 HeadersHandler headers_handler_2;
8504 trans_2.SetBeforeHeadersSentCallback(
8505 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8506 base::Unretained(&headers_handler_2)));
8507 RunTransaction(&trans_2);
8508 CheckWasHttpResponse(&trans_2);
8509 CheckResponsePort(&trans_2, 70);
8510 CheckResponseData(&trans_2, "0123456");
8511 EXPECT_TRUE(headers_handler_2.was_proxied());
8512 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8513
8514 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8515 // proxy socket to disconnect.
8516 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8517
8518 base::RunLoop().RunUntilIdle();
8519 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8520 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8521}
8522
8523// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
8524// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
8525// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:148526TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:568527 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148528 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568529 proxy_resolution_service_ =
8530 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8531 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568532
Ryan Hamiltonabad59e2019-06-06 04:02:598533 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238534 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258535 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238536 mock_quic_data.AddWrite(SYNCHRONOUS,
8537 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498538 mock_quic_data.AddWrite(
8539 SYNCHRONOUS, client_maker_.MakePriorityPacket(
8540 packet_num++, true,
8541 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8542 ConvertRequestPriorityToQuicPriority(
8543 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238544 }
Yixin Wang46a273ec302018-01-23 17:59:568545
8546 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:338547 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238548 SYNCHRONOUS,
8549 ConstructClientRequestHeadersPacket(
8550 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498551 false,
8552 VersionUsesHttp3(version_.transport_version)
8553 ? MEDIUM
8554 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238555 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438556 mock_quic_data.AddRead(
8557 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338558 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028559 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568560
8561 // GET request, response, and data over QUIC tunnel for first request
8562 const char get_request[] =
8563 "GET / HTTP/1.1\r\n"
8564 "Host: mail.example.org\r\n"
8565 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438566 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568567 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418568 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358569 SYNCHRONOUS,
8570 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238571 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Zhongyi Shid1c00fc42019-12-14 06:05:098572 1, 1, 1, false, quiche::QuicheStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418573 } else {
8574 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418575 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288576 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238577 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288578 1, 1, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418579 }
8580
Yixin Wang46a273ec302018-01-23 17:59:568581 const char get_response[] =
8582 "HTTP/1.1 200 OK\r\n"
8583 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438584 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:568585 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338586 ASYNC, ConstructServerDataPacket(
8587 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178588 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:438589 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338590 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418591 SYNCHRONOUS, ConstructServerDataPacket(
8592 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178593 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238594 mock_quic_data.AddWrite(SYNCHRONOUS,
8595 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568596
8597 // CONNECT request and response for second request
Renjie Tangee921d12020-02-06 00:41:498598 if (VersionUsesHttp3(version_.transport_version)) {
8599 mock_quic_data.AddWrite(
8600 SYNCHRONOUS, client_maker_.MakePriorityPacket(
8601 packet_num++, true,
8602 GetNthClientInitiatedBidirectionalStreamId(1), 0,
8603 ConvertRequestPriorityToQuicPriority(
8604 HttpProxyConnectJob::kH2QuicTunnelPriority)));
8605 }
Zhongyi Shi32f2fd02018-04-16 18:23:438606 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238607 SYNCHRONOUS,
8608 ConstructClientRequestHeadersPacket(
8609 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Renjie Tangee921d12020-02-06 00:41:498610 false,
8611 VersionUsesHttp3(version_.transport_version)
8612 ? MEDIUM
8613 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238614 ConnectRequestHeaders("different.example.org:443"),
8615 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438616 mock_quic_data.AddRead(
8617 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338618 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028619 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568620
8621 // GET request, response, and data over QUIC tunnel for second request
8622 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138623 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568624 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438625 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:568626 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418627 mock_quic_data.AddWrite(
8628 SYNCHRONOUS,
8629 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238630 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8631 4, 4, 1, false,
Zhongyi Shid1c00fc42019-12-14 06:05:098632 quiche::QuicheStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:418633 } else {
8634 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418635 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288636 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238637 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8638 4, 4, 1, false,
Renjie Tangd5133972019-12-06 00:20:288639 {header4 + std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418640 }
Yixin Wang46a273ec302018-01-23 17:59:568641
Ryan Hamilton0239aac2018-05-19 00:03:138642 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568643 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438644 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438645 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178646 ASYNC, ConstructServerDataPacket(
8647 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8648 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568649
Ryan Hamilton0239aac2018-05-19 00:03:138650 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198651 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:438652 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438653 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438654 ASYNC, ConstructServerDataPacket(
8655 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438656 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568657
Renjie Tangaadb84b2019-08-31 01:00:238658 mock_quic_data.AddWrite(SYNCHRONOUS,
8659 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:568660 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8661
Bence Béky6e243aa2019-12-13 19:01:078662 if (VersionUsesHttp3(version_.transport_version)) {
8663 mock_quic_data.AddWrite(
8664 SYNCHRONOUS, ConstructClientDataPacket(
8665 packet_num++, GetQpackDecoderStreamId(), true, false,
8666 StreamCancellationQpackDecoderInstruction(0)));
8667 }
8668
Yixin Wang46a273ec302018-01-23 17:59:568669 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418670 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238671 ConstructClientRstPacket(packet_num++,
8672 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418673 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:078674
8675 if (VersionUsesHttp3(version_.transport_version)) {
8676 mock_quic_data.AddWrite(
8677 SYNCHRONOUS, ConstructClientDataPacket(
8678 packet_num++, GetQpackDecoderStreamId(), true, false,
8679 StreamCancellationQpackDecoderInstruction(1)));
8680 }
8681
Yixin Wang46a273ec302018-01-23 17:59:568682 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438683 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238684 ConstructClientRstPacket(packet_num++,
8685 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418686 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568687
8688 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8689
8690 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8691
8692 SSLSocketDataProvider ssl_data(ASYNC, OK);
8693 ssl_data.next_proto = kProtoHTTP2;
8694 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8695
8696 CreateSession();
8697
8698 request_.url = GURL("https://mail.example.org/");
8699 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8700 HeadersHandler headers_handler_1;
8701 trans_1.SetBeforeHeadersSentCallback(
8702 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8703 base::Unretained(&headers_handler_1)));
8704 RunTransaction(&trans_1);
8705 CheckWasHttpResponse(&trans_1);
8706 CheckResponsePort(&trans_1, 70);
8707 CheckResponseData(&trans_1, "0123456789");
8708 EXPECT_TRUE(headers_handler_1.was_proxied());
8709 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8710
8711 request_.url = GURL("https://different.example.org/");
8712 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8713 HeadersHandler headers_handler_2;
8714 trans_2.SetBeforeHeadersSentCallback(
8715 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8716 base::Unretained(&headers_handler_2)));
8717 RunTransaction(&trans_2);
8718 CheckWasSpdyResponse(&trans_2);
8719 CheckResponsePort(&trans_2, 70);
8720 CheckResponseData(&trans_2, "0123456");
8721 EXPECT_TRUE(headers_handler_2.was_proxied());
8722 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8723
8724 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8725 // proxy socket to disconnect.
8726 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8727
8728 base::RunLoop().RunUntilIdle();
8729 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8730 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8731}
8732
8733// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148734TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568735 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148736 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568737 proxy_resolution_service_ =
8738 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8739 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568740
Ryan Hamiltonabad59e2019-06-06 04:02:598741 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238742 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258743 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238744 mock_quic_data.AddWrite(SYNCHRONOUS,
8745 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498746 mock_quic_data.AddWrite(
8747 SYNCHRONOUS, client_maker_.MakePriorityPacket(
8748 packet_num++, true,
8749 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8750 ConvertRequestPriorityToQuicPriority(
8751 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238752 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:528753 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238754 SYNCHRONOUS,
8755 ConstructClientRequestHeadersPacket(
8756 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498757 false,
8758 VersionUsesHttp3(version_.transport_version)
8759 ? MEDIUM
8760 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238761 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338762 mock_quic_data.AddRead(
8763 ASYNC, ConstructServerResponseHeadersPacket(
8764 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8765 GetResponseHeaders("500")));
8766 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:238767 mock_quic_data.AddWrite(
8768 SYNCHRONOUS,
8769 ConstructClientAckAndRstPacket(
8770 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8771 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568772
8773 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8774
8775 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8776
8777 CreateSession();
8778
8779 request_.url = GURL("https://mail.example.org/");
8780 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8781 HeadersHandler headers_handler;
8782 trans.SetBeforeHeadersSentCallback(
8783 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8784 base::Unretained(&headers_handler)));
8785 TestCompletionCallback callback;
8786 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8787 EXPECT_EQ(ERR_IO_PENDING, rv);
8788 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8789 EXPECT_EQ(false, headers_handler.was_proxied());
8790
8791 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8792 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8793}
8794
8795// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148796TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568797 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148798 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568799 proxy_resolution_service_ =
8800 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8801 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568802
Ryan Hamiltonabad59e2019-06-06 04:02:598803 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238804 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258805 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238806 mock_quic_data.AddWrite(SYNCHRONOUS,
8807 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498808 mock_quic_data.AddWrite(
8809 SYNCHRONOUS, client_maker_.MakePriorityPacket(
8810 packet_num++, true,
8811 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8812 ConvertRequestPriorityToQuicPriority(
8813 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238814 }
Fan Yang32c5a112018-12-10 20:06:338815 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238816 SYNCHRONOUS,
8817 ConstructClientRequestHeadersPacket(
8818 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498819 false,
8820 VersionUsesHttp3(version_.transport_version)
8821 ? MEDIUM
8822 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238823 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:568824 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8825
8826 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8827
8828 CreateSession();
8829
8830 request_.url = GURL("https://mail.example.org/");
8831 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8832 HeadersHandler headers_handler;
8833 trans.SetBeforeHeadersSentCallback(
8834 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8835 base::Unretained(&headers_handler)));
8836 TestCompletionCallback callback;
8837 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8838 EXPECT_EQ(ERR_IO_PENDING, rv);
8839 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8840
8841 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8842 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8843}
8844
8845// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8846// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148847TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568848 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148849 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:568850 proxy_resolution_service_ =
8851 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
8852 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568853
Ryan Hamiltonabad59e2019-06-06 04:02:598854 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238855 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258856 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238857 mock_quic_data.AddWrite(SYNCHRONOUS,
8858 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:498859 mock_quic_data.AddWrite(
8860 SYNCHRONOUS, client_maker_.MakePriorityPacket(
8861 packet_num++, true,
8862 GetNthClientInitiatedBidirectionalStreamId(0), 0,
8863 ConvertRequestPriorityToQuicPriority(
8864 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:238865 }
Fan Yang32c5a112018-12-10 20:06:338866 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238867 SYNCHRONOUS,
8868 ConstructClientRequestHeadersPacket(
8869 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:498870 false,
8871 VersionUsesHttp3(version_.transport_version)
8872 ? MEDIUM
8873 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238874 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438875 mock_quic_data.AddRead(
8876 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338877 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028878 GetResponseHeaders("200 OK")));
Bence Béky6e243aa2019-12-13 19:01:078879 if (VersionUsesHttp3(version_.transport_version)) {
8880 mock_quic_data.AddWrite(
8881 SYNCHRONOUS,
8882 ConstructClientAckAndDataPacket(
8883 packet_num++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
8884 StreamCancellationQpackDecoderInstruction(0)));
8885 mock_quic_data.AddWrite(
8886 SYNCHRONOUS,
8887 ConstructClientRstPacket(packet_num++,
8888 GetNthClientInitiatedBidirectionalStreamId(0),
8889 quic::QUIC_STREAM_CANCELLED));
8890 } else {
8891 mock_quic_data.AddWrite(
8892 SYNCHRONOUS,
8893 ConstructClientAckAndRstPacket(
8894 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8895 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
8896 }
Yixin Wang46a273ec302018-01-23 17:59:568897
Renjie Tangee921d12020-02-06 00:41:498898 if (VersionUsesHttp3(version_.transport_version)) {
8899 mock_quic_data.AddWrite(
8900 SYNCHRONOUS, client_maker_.MakePriorityPacket(
8901 packet_num++, true,
8902 GetNthClientInitiatedBidirectionalStreamId(1), 0,
8903 ConvertRequestPriorityToQuicPriority(
8904 HttpProxyConnectJob::kH2QuicTunnelPriority)));
8905 }
8906
Zhongyi Shi32f2fd02018-04-16 18:23:438907 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238908 SYNCHRONOUS,
8909 ConstructClientRequestHeadersPacket(
8910 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Renjie Tangee921d12020-02-06 00:41:498911 false,
8912 VersionUsesHttp3(version_.transport_version)
8913 ? MEDIUM
8914 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:238915 ConnectRequestHeaders("mail.example.org:443"),
8916 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438917 mock_quic_data.AddRead(
8918 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338919 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028920 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568921
8922 const char get_request[] =
8923 "GET / HTTP/1.1\r\n"
8924 "Host: mail.example.org\r\n"
8925 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438926 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568927 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418928 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358929 SYNCHRONOUS,
8930 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238931 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Zhongyi Shid1c00fc42019-12-14 06:05:098932 2, 2, 1, false, quiche::QuicheStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418933 } else {
8934 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418935 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288936 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238937 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Renjie Tangd5133972019-12-06 00:20:288938 2, 2, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418939 }
Yixin Wang46a273ec302018-01-23 17:59:568940 const char get_response[] =
8941 "HTTP/1.1 200 OK\r\n"
8942 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438943 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438944 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338945 ASYNC, ConstructServerDataPacket(
8946 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178947 header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528948
Victor Vasiliev076657c2019-03-12 02:46:438949 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338950 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418951 SYNCHRONOUS, ConstructServerDataPacket(
8952 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178953 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238954 mock_quic_data.AddWrite(SYNCHRONOUS,
8955 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568956 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8957
Bence Béky6e243aa2019-12-13 19:01:078958 if (VersionUsesHttp3(version_.transport_version)) {
8959 mock_quic_data.AddWrite(
8960 SYNCHRONOUS, ConstructClientDataPacket(
8961 packet_num++, GetQpackDecoderStreamId(), true, false,
8962 StreamCancellationQpackDecoderInstruction(1)));
8963 }
Yixin Wang46a273ec302018-01-23 17:59:568964 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418965 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238966 ConstructClientRstPacket(packet_num++,
8967 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418968 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568969
8970 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8971
8972 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8973 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8974
8975 SSLSocketDataProvider ssl_data(ASYNC, OK);
8976 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8977
8978 CreateSession();
8979
8980 request_.url = GURL("https://mail.example.org/");
8981 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8982 HeadersHandler headers_handler;
8983 trans.SetBeforeHeadersSentCallback(
8984 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8985 base::Unretained(&headers_handler)));
8986 TestCompletionCallback callback;
8987 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8988 EXPECT_EQ(ERR_IO_PENDING, rv);
8989 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8990
8991 rv = trans.RestartIgnoringLastError(callback.callback());
8992 EXPECT_EQ(ERR_IO_PENDING, rv);
8993 EXPECT_EQ(OK, callback.WaitForResult());
8994
8995 CheckWasHttpResponse(&trans);
8996 CheckResponsePort(&trans, 70);
8997 CheckResponseData(&trans, "0123456789");
8998 EXPECT_EQ(true, headers_handler.was_proxied());
8999 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
9000
9001 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
9002 // proxy socket to disconnect.
9003 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
9004
9005 base::RunLoop().RunUntilIdle();
9006 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9007 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9008}
9009
9010// Checks if a request's specified "user-agent" header shows up correctly in the
9011// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:149012TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:009013 const char kConfiguredUserAgent[] = "Configured User-Agent";
9014 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:569015 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:149016 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:569017 proxy_resolution_service_ =
9018 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
9019 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:569020
Ryan Hamiltonabad59e2019-06-06 04:02:599021 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:239022 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259023 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239024 mock_quic_data.AddWrite(SYNCHRONOUS,
9025 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:499026 mock_quic_data.AddWrite(
9027 SYNCHRONOUS, client_maker_.MakePriorityPacket(
9028 packet_num++, true,
9029 GetNthClientInitiatedBidirectionalStreamId(0), 0,
9030 ConvertRequestPriorityToQuicPriority(
9031 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:239032 }
Yixin Wang46a273ec302018-01-23 17:59:569033
Ryan Hamilton0239aac2018-05-19 00:03:139034 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:009035 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:339036 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:029037 SYNCHRONOUS,
9038 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239039 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:499040 false,
9041 VersionUsesHttp3(version_.transport_version)
9042 ? MEDIUM
9043 : HttpProxyConnectJob::kH2QuicTunnelPriority,
9044 std::move(headers), 0));
Yixin Wang46a273ec302018-01-23 17:59:569045 // Return an error, so the transaction stops here (this test isn't interested
9046 // in the rest).
9047 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
9048
9049 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9050
Matt Menked732ea42019-03-08 12:05:009051 StaticHttpUserAgentSettings http_user_agent_settings(
9052 std::string() /* accept_language */, kConfiguredUserAgent);
9053 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:569054 CreateSession();
9055
9056 request_.url = GURL("https://mail.example.org/");
9057 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:009058 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:569059 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9060 HeadersHandler headers_handler;
9061 trans.SetBeforeHeadersSentCallback(
9062 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
9063 base::Unretained(&headers_handler)));
9064 TestCompletionCallback callback;
9065 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9066 EXPECT_EQ(ERR_IO_PENDING, rv);
9067 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
9068
9069 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9070 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9071}
9072
Yixin Wang00fc44c2018-01-23 21:12:209073// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
9074// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:149075TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:209076 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:149077 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:569078 proxy_resolution_service_ =
9079 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
9080 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:209081
9082 const RequestPriority request_priority = MEDIUM;
9083
Ryan Hamiltonabad59e2019-06-06 04:02:599084 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:239085 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259086 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239087 mock_quic_data.AddWrite(SYNCHRONOUS,
9088 ConstructInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:499089 mock_quic_data.AddWrite(
9090 SYNCHRONOUS, client_maker_.MakePriorityPacket(
9091 packet_num++, true,
9092 GetNthClientInitiatedBidirectionalStreamId(0), 0,
9093 ConvertRequestPriorityToQuicPriority(
9094 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:239095 }
Zhongyi Shi32f2fd02018-04-16 18:23:439096 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239097 SYNCHRONOUS,
9098 ConstructClientRequestHeadersPacket(
9099 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
Renjie Tangee921d12020-02-06 00:41:499100 false,
9101 VersionUsesHttp3(version_.transport_version)
9102 ? MEDIUM
9103 : HttpProxyConnectJob::kH2QuicTunnelPriority,
Renjie Tangaadb84b2019-08-31 01:00:239104 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:209105 // Return an error, so the transaction stops here (this test isn't interested
9106 // in the rest).
9107 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
9108
9109 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9110
9111 CreateSession();
9112
9113 request_.url = GURL("https://mail.example.org/");
9114 HttpNetworkTransaction trans(request_priority, session_.get());
9115 TestCompletionCallback callback;
9116 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9117 EXPECT_EQ(ERR_IO_PENDING, rv);
9118 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
9119
9120 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9121 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9122}
9123
Matt Menkeedaf3b82019-03-14 21:39:449124// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
9125// HTTP/2 stream dependency and weights given the request priority.
9126TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
9127 session_params_.enable_quic = true;
9128 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:569129 proxy_resolution_service_ =
9130 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
9131 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeedaf3b82019-03-14 21:39:449132
9133 const RequestPriority kRequestPriority = MEDIUM;
9134 const RequestPriority kRequestPriority2 = LOWEST;
9135
Ryan Hamiltonabad59e2019-06-06 04:02:599136 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:259137 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239138 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
9139 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
9140 } else {
9141 mock_quic_data.AddWrite(
9142 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
9143 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
9144 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
9145 ConnectRequestHeaders("mail.example.org:443"), 0));
9146 }
Matt Menkeedaf3b82019-03-14 21:39:449147 // This should never be reached.
9148 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
9149 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9150
9151 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:599152 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:449153 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
9154 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9155
9156 int original_max_sockets_per_group =
9157 ClientSocketPoolManager::max_sockets_per_group(
9158 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
9159 ClientSocketPoolManager::set_max_sockets_per_group(
9160 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
9161 int original_max_sockets_per_pool =
9162 ClientSocketPoolManager::max_sockets_per_pool(
9163 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
9164 ClientSocketPoolManager::set_max_sockets_per_pool(
9165 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
9166 CreateSession();
9167
9168 request_.url = GURL("https://mail.example.org/");
9169 HttpNetworkTransaction trans(kRequestPriority, session_.get());
9170 TestCompletionCallback callback;
9171 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9172 EXPECT_EQ(ERR_IO_PENDING, rv);
9173
9174 HttpRequestInfo request2;
9175 request2.url = GURL("https://mail.example.org/some/other/path/");
9176 request2.traffic_annotation =
9177 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9178
9179 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
9180 TestCompletionCallback callback2;
9181 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
9182 EXPECT_EQ(ERR_IO_PENDING, rv2);
9183
9184 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
9185 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9186
9187 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
9188
9189 ClientSocketPoolManager::set_max_sockets_per_pool(
9190 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
9191 original_max_sockets_per_pool);
9192 ClientSocketPoolManager::set_max_sockets_per_group(
9193 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
9194 original_max_sockets_per_group);
9195}
9196
Yixin Wang46a273ec302018-01-23 17:59:569197// Test the request-challenge-retry sequence for basic auth, over a QUIC
9198// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:149199TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:569200 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
9201 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:569202
Yixin Wang46a273ec302018-01-23 17:59:569203 // On the second pass, the body read of the auth challenge is synchronous, so
9204 // IsConnectedAndIdle returns false. The socket should still be drained and
9205 // reused. See http://crbug.com/544255.
9206 for (int i = 0; i < 2; ++i) {
Bence Béky6e243aa2019-12-13 19:01:079207 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229208 version_,
9209 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9210 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky6e243aa2019-12-13 19:01:079211 client_headers_include_h2_stream_dependency_);
9212 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229213 version_,
9214 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9215 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Bence Béky6e243aa2019-12-13 19:01:079216 false);
Yixin Wang46a273ec302018-01-23 17:59:569217
9218 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:149219 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:569220 proxy_resolution_service_ =
Nicolas Arciniegad2013f92020-02-07 23:00:569221 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:499222 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:569223
Ryan Hamiltonabad59e2019-06-06 04:02:599224 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:529225 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:569226
Renjie Tangaadb84b2019-08-31 01:00:239227 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259228 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239229 mock_quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:079230 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:499231 mock_quic_data.AddWrite(
9232 SYNCHRONOUS, client_maker.MakePriorityPacket(
9233 packet_num++, true,
9234 GetNthClientInitiatedBidirectionalStreamId(0), 0,
9235 ConvertRequestPriorityToQuicPriority(
9236 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:239237 }
Yixin Wang46a273ec302018-01-23 17:59:569238
9239 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:439240 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:079241 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239242 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9243 false,
Renjie Tangee921d12020-02-06 00:41:499244 VersionUsesHttp3(version_.transport_version)
9245 ? 1
9246 : ConvertRequestPriorityToQuicPriority(
9247 HttpProxyConnectJob::kH2QuicTunnelPriority),
Bence Béky6e243aa2019-12-13 19:01:079248 client_maker.ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:029249 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569250
Ryan Hamilton0239aac2018-05-19 00:03:139251 spdy::SpdyHeaderBlock headers =
Bence Béky6e243aa2019-12-13 19:01:079252 server_maker.GetResponseHeaders("407 Proxy Authentication Required");
Yixin Wang46a273ec302018-01-23 17:59:569253 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
9254 headers["content-length"] = "10";
9255 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079256 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:339257 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:029258 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569259
9260 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:439261 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079262 ASYNC, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:339263 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179264 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:569265 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:439266 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079267 SYNCHRONOUS, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:339268 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:179269 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:569270 }
9271 server_data_offset += 10;
9272
Renjie Tangaadb84b2019-08-31 01:00:239273 mock_quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:079274 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 2, 1, 1, true));
9275
9276 if (VersionUsesHttp3(version_.transport_version)) {
9277 mock_quic_data.AddWrite(
9278 SYNCHRONOUS,
9279 client_maker.MakeDataPacket(
9280 packet_num++, GetQpackDecoderStreamId(),
9281 /* should_include_version = */ true,
9282 /* fin = */ false, StreamCancellationQpackDecoderInstruction(0)));
9283 }
Yixin Wang46a273ec302018-01-23 17:59:569284
9285 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:339286 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:079287 client_maker.MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:239288 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:419289 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:189290 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:569291
Bence Béky6e243aa2019-12-13 19:01:079292 headers = client_maker.ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:569293 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
Renjie Tangee921d12020-02-06 00:41:499294 if (VersionUsesHttp3(version_.transport_version)) {
9295 mock_quic_data.AddWrite(
9296 SYNCHRONOUS, client_maker.MakePriorityPacket(
9297 packet_num++, true,
9298 GetNthClientInitiatedBidirectionalStreamId(1), 0,
9299 ConvertRequestPriorityToQuicPriority(
9300 HttpProxyConnectJob::kH2QuicTunnelPriority)));
9301 }
Yixin Wang46a273ec302018-01-23 17:59:569302 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:049303 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:079304 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239305 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
9306 false,
Renjie Tangee921d12020-02-06 00:41:499307 VersionUsesHttp3(version_.transport_version)
9308 ? 1
9309 : ConvertRequestPriorityToQuicPriority(
9310 HttpProxyConnectJob::kH2QuicTunnelPriority),
Matt Menke6e879bd2019-03-18 17:26:049311 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:029312 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569313
9314 // Response to wrong password
9315 headers =
Bence Béky6e243aa2019-12-13 19:01:079316 server_maker.GetResponseHeaders("407 Proxy Authentication Required");
Yixin Wang46a273ec302018-01-23 17:59:569317 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
9318 headers["content-length"] = "10";
9319 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079320 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:339321 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:029322 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569323 mock_quic_data.AddRead(SYNCHRONOUS,
9324 ERR_IO_PENDING); // No more data to read
9325
Bence Béky6e243aa2019-12-13 19:01:079326 if (VersionUsesHttp3(version_.transport_version)) {
9327 mock_quic_data.AddWrite(
9328 SYNCHRONOUS,
9329 client_maker.MakeAckAndDataPacket(
9330 packet_num++, false, GetQpackDecoderStreamId(), 3, 3, 1, false,
9331 StreamCancellationQpackDecoderInstruction(1)));
9332 mock_quic_data.AddWrite(SYNCHRONOUS,
9333 client_maker.MakeRstPacket(
9334 packet_num++, false,
9335 GetNthClientInitiatedBidirectionalStreamId(1),
9336 quic::QUIC_STREAM_CANCELLED));
9337 } else {
9338 mock_quic_data.AddWrite(SYNCHRONOUS,
9339 client_maker.MakeAckAndRstPacket(
9340 packet_num++, false,
9341 GetNthClientInitiatedBidirectionalStreamId(1),
9342 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
9343 }
Yixin Wang46a273ec302018-01-23 17:59:569344
9345 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9346 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
9347
9348 CreateSession();
9349
9350 request_.url = GURL("https://mail.example.org/");
9351 // Ensure that proxy authentication is attempted even
9352 // when the no authentication data flag is set.
9353 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
9354 {
9355 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9356 HeadersHandler headers_handler;
9357 trans.SetBeforeHeadersSentCallback(
9358 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
9359 base::Unretained(&headers_handler)));
9360 RunTransaction(&trans);
9361
9362 const HttpResponseInfo* response = trans.GetResponseInfo();
9363 ASSERT_TRUE(response != nullptr);
9364 ASSERT_TRUE(response->headers.get() != nullptr);
9365 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
9366 response->headers->GetStatusLine());
9367 EXPECT_TRUE(response->headers->IsKeepAlive());
9368 EXPECT_EQ(407, response->headers->response_code());
9369 EXPECT_EQ(10, response->headers->GetContentLength());
9370 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589371 base::Optional<AuthChallengeInfo> auth_challenge =
9372 response->auth_challenge;
9373 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:569374 EXPECT_TRUE(auth_challenge->is_proxy);
9375 EXPECT_EQ("https://proxy.example.org:70",
9376 auth_challenge->challenger.Serialize());
9377 EXPECT_EQ("MyRealm1", auth_challenge->realm);
9378 EXPECT_EQ("basic", auth_challenge->scheme);
9379
9380 TestCompletionCallback callback;
9381 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
9382 callback.callback());
9383 EXPECT_EQ(ERR_IO_PENDING, rv);
9384 EXPECT_EQ(OK, callback.WaitForResult());
9385
9386 response = trans.GetResponseInfo();
9387 ASSERT_TRUE(response != nullptr);
9388 ASSERT_TRUE(response->headers.get() != nullptr);
9389 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
9390 response->headers->GetStatusLine());
9391 EXPECT_TRUE(response->headers->IsKeepAlive());
9392 EXPECT_EQ(407, response->headers->response_code());
9393 EXPECT_EQ(10, response->headers->GetContentLength());
9394 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589395 auth_challenge = response->auth_challenge;
9396 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:569397 EXPECT_TRUE(auth_challenge->is_proxy);
9398 EXPECT_EQ("https://proxy.example.org:70",
9399 auth_challenge->challenger.Serialize());
9400 EXPECT_EQ("MyRealm1", auth_challenge->realm);
9401 EXPECT_EQ("basic", auth_challenge->scheme);
9402 }
9403 // HttpNetworkTransaction is torn down now that it's out of scope, causing
9404 // the QUIC stream to be cleaned up (since the proxy socket cannot be
9405 // reused because it's not connected).
9406 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9407 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9408 }
9409}
9410
Yixin Wang385652a2018-02-16 02:37:239411TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
Ryan Hamilton6c6493102019-12-05 21:36:509412 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
9413 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
9414
Yixin Wang385652a2018-02-16 02:37:239415 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
9416 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:569417 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:239418 !client_headers_include_h2_stream_dependency_) {
9419 return;
9420 }
9421
Victor Vasiliev7da08172019-10-14 06:04:259422 if (quic::VersionUsesHttp3(version_.transport_version)) {
Renjie Tangba21e032019-09-27 21:52:289423 // HTTP/3 currently doesn't support PRIORITY.
Ryan Hamiltone940bd12019-06-30 02:46:459424 return;
9425 }
9426
Victor Vasilieva1e66d72019-12-05 17:55:389427 context_.params()->origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:239428 HostPortPair::FromString("mail.example.org:443"));
9429
Fan Yang32c5a112018-12-10 20:06:339430 const quic::QuicStreamId client_stream_0 =
9431 GetNthClientInitiatedBidirectionalStreamId(0);
9432 const quic::QuicStreamId client_stream_1 =
9433 GetNthClientInitiatedBidirectionalStreamId(1);
9434 const quic::QuicStreamId client_stream_2 =
9435 GetNthClientInitiatedBidirectionalStreamId(2);
9436 const quic::QuicStreamId push_stream_0 =
9437 GetNthServerInitiatedUnidirectionalStreamId(0);
9438 const quic::QuicStreamId push_stream_1 =
9439 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:239440
Ryan Hamiltonabad59e2019-06-06 04:02:599441 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:239442 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259443 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239444 mock_quic_data.AddWrite(SYNCHRONOUS,
9445 ConstructInitialSettingsPacket(packet_num++));
9446 }
Yixin Wang385652a2018-02-16 02:37:239447
9448 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:239449 mock_quic_data.AddWrite(
9450 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
9451 packet_num++, client_stream_0, true, true, HIGHEST,
9452 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:029453 mock_quic_data.AddWrite(
9454 SYNCHRONOUS,
9455 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239456 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:029457 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
9458 mock_quic_data.AddWrite(
9459 SYNCHRONOUS,
9460 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239461 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:029462 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:239463
9464 // Server replies "OK" for the three requests.
Ryan Hamilton0d65a8c2019-06-07 00:46:029465 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9466 1, client_stream_0, false, false,
9467 GetResponseHeaders("200 OK")));
9468 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9469 2, client_stream_1, false, false,
9470 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:239471 mock_quic_data.AddWrite(SYNCHRONOUS,
9472 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton0d65a8c2019-06-07 00:46:029473 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9474 3, client_stream_2, false, false,
9475 GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:239476
9477 // Server sends two push promises associated with |client_stream_0|; client
9478 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
9479 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:029480 mock_quic_data.AddRead(
9481 ASYNC,
9482 ConstructServerPushPromisePacket(
9483 4, client_stream_0, push_stream_0, false,
9484 GetRequestHeaders("GET", "https", "/pushed_0.jpg"), &server_maker_));
Yixin Wang385652a2018-02-16 02:37:239485 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:439486 SYNCHRONOUS,
9487 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:239488 packet_num++, false, 4, 3, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:439489 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:029490 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
9491 mock_quic_data.AddRead(
9492 ASYNC,
9493 ConstructServerPushPromisePacket(
9494 5, client_stream_0, push_stream_1, false,
9495 GetRequestHeaders("GET", "https", "/pushed_1.jpg"), &server_maker_));
9496 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientPriorityPacket(
Renjie Tangaadb84b2019-08-31 01:00:239497 packet_num++, false, push_stream_1,
Ryan Hamilton0d65a8c2019-06-07 00:46:029498 push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:239499
9500 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:439501 mock_quic_data.AddRead(
9502 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:029503 6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:239504 mock_quic_data.AddWrite(SYNCHRONOUS,
9505 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439506 mock_quic_data.AddRead(
9507 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:029508 7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:239509
9510 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
9511 // priority updates to match the request's priority. Client sends PRIORITY
9512 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:439513 mock_quic_data.AddWrite(
9514 SYNCHRONOUS,
9515 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:239516 packet_num++, false, 7, 7, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:439517 {{push_stream_1, client_stream_2,
9518 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
9519 {push_stream_0, client_stream_0,
Ryan Hamilton0d65a8c2019-06-07 00:46:029520 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:239521
9522 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:439523 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:439524 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179525 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Renjief49758b2019-01-11 23:32:419526 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:439527 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179528 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Renjief49758b2019-01-11 23:32:419529 header + "hello 1!"));
Renjie Tangaadb84b2019-08-31 01:00:239530 mock_quic_data.AddWrite(SYNCHRONOUS,
9531 ConstructClientAckPacket(packet_num++, 9, 8, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439532 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179533 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Renjief49758b2019-01-11 23:32:419534 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:439535 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:439536 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179537 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true,
Renjief49758b2019-01-11 23:32:419538 header2 + "and hello 0!"));
Renjie Tangaadb84b2019-08-31 01:00:239539 mock_quic_data.AddWrite(SYNCHRONOUS,
9540 ConstructClientAckPacket(packet_num++, 11, 10, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439541 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179542 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Renjief49758b2019-01-11 23:32:419543 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:239544
Yixin Wang385652a2018-02-16 02:37:239545 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9546 mock_quic_data.AddRead(ASYNC, 0); // EOF
9547 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9548
9549 // The non-alternate protocol job needs to hang in order to guarantee that
9550 // the alternate-protocol job will "win".
9551 AddHangingNonAlternateProtocolSocketData();
9552
9553 CreateSession();
9554
9555 request_.url = GURL("https://mail.example.org/0.jpg");
9556 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
9557 TestCompletionCallback callback_0;
9558 EXPECT_EQ(ERR_IO_PENDING,
9559 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
9560 base::RunLoop().RunUntilIdle();
9561
9562 request_.url = GURL("https://mail.example.org/1.jpg");
9563 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
9564 TestCompletionCallback callback_1;
9565 EXPECT_EQ(ERR_IO_PENDING,
9566 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
9567 base::RunLoop().RunUntilIdle();
9568
9569 request_.url = GURL("https://mail.example.org/2.jpg");
9570 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
9571 TestCompletionCallback callback_2;
9572 EXPECT_EQ(ERR_IO_PENDING,
9573 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
9574 base::RunLoop().RunUntilIdle();
9575
9576 // Client makes request that matches resource pushed in |pushed_stream_0|.
9577 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
9578 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
9579 TestCompletionCallback callback_3;
9580 EXPECT_EQ(ERR_IO_PENDING,
9581 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
9582 base::RunLoop().RunUntilIdle();
9583
9584 EXPECT_TRUE(callback_0.have_result());
9585 EXPECT_EQ(OK, callback_0.WaitForResult());
9586 EXPECT_TRUE(callback_1.have_result());
9587 EXPECT_EQ(OK, callback_1.WaitForResult());
9588 EXPECT_TRUE(callback_2.have_result());
9589 EXPECT_EQ(OK, callback_2.WaitForResult());
9590
9591 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
9592 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
9593 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
9594 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
9595
9596 mock_quic_data.Resume();
9597 base::RunLoop().RunUntilIdle();
9598 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9599 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9600}
9601
Matt Menke26e41542019-06-05 01:09:519602// Test that NetworkIsolationKey is respected by QUIC connections, when
9603// kPartitionConnectionsByNetworkIsolationKey is enabled.
9604TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Shivani Sharma8ae506c2019-07-21 21:08:279605 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9606 const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
9607 NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
9608 NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
Matt Menke26e41542019-06-05 01:09:519609
Victor Vasilieva1e66d72019-12-05 17:55:389610 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519611 HostPortPair::FromString("mail.example.org:443"));
9612
9613 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
9614 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
9615 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
9616 // the same way as the HTTP over H2 proxy case.
9617 for (bool use_proxy : {false, true}) {
9618 SCOPED_TRACE(use_proxy);
9619
9620 if (use_proxy) {
9621 proxy_resolution_service_ =
Nicolas Arciniegad2013f92020-02-07 23:00:569622 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
Matt Menke26e41542019-06-05 01:09:519623 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
9624 } else {
Nicolas Arciniegad2013f92020-02-07 23:00:569625 proxy_resolution_service_ =
9626 ConfiguredProxyResolutionService::CreateDirect();
Matt Menke26e41542019-06-05 01:09:519627 }
9628
9629 GURL url1;
9630 GURL url2;
9631 GURL url3;
9632 if (use_proxy) {
9633 url1 = GURL("http://mail.example.org/1");
9634 url2 = GURL("http://mail.example.org/2");
9635 url3 = GURL("http://mail.example.org/3");
9636 } else {
9637 url1 = GURL("https://mail.example.org/1");
9638 url2 = GURL("https://mail.example.org/2");
9639 url3 = GURL("https://mail.example.org/3");
9640 }
9641
9642 for (bool partition_connections : {false, true}) {
9643 SCOPED_TRACE(partition_connections);
9644
9645 base::test::ScopedFeatureList feature_list;
9646 if (partition_connections) {
9647 feature_list.InitAndEnableFeature(
9648 features::kPartitionConnectionsByNetworkIsolationKey);
9649 } else {
9650 feature_list.InitAndDisableFeature(
9651 features::kPartitionConnectionsByNetworkIsolationKey);
9652 }
9653
9654 // Reads and writes for the unpartitioned case, where only one socket is
9655 // used.
9656
Victor Vasilieva1e66d72019-12-05 17:55:389657 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519658 HostPortPair::FromString("mail.example.org:443"));
9659
Ryan Hamiltonabad59e2019-06-06 04:02:599660 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:519661 QuicTestPacketMaker client_maker1(
9662 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229663 quic::QuicUtils::CreateRandomConnectionId(
9664 context_.random_generator()),
9665 context_.clock(), kDefaultServerHostName,
9666 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519667 client_headers_include_h2_stream_dependency_);
9668 QuicTestPacketMaker server_maker1(
9669 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229670 quic::QuicUtils::CreateRandomConnectionId(
9671 context_.random_generator()),
9672 context_.clock(), kDefaultServerHostName,
9673 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519674
Renjie Tangaadb84b2019-08-31 01:00:239675 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259676 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239677 unpartitioned_mock_quic_data.AddWrite(
9678 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
9679 }
Matt Menke26e41542019-06-05 01:09:519680
9681 unpartitioned_mock_quic_data.AddWrite(
9682 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029683 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239684 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9685 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029686 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519687 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029688 ASYNC, server_maker1.MakeResponseHeadersPacket(
9689 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9690 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519691 unpartitioned_mock_quic_data.AddRead(
9692 ASYNC, server_maker1.MakeDataPacket(
9693 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179694 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519695 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239696 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke26e41542019-06-05 01:09:519697
9698 unpartitioned_mock_quic_data.AddWrite(
9699 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029700 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239701 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
9702 false, true,
Matt Menke26e41542019-06-05 01:09:519703 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029704 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519705 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029706 ASYNC, server_maker1.MakeResponseHeadersPacket(
9707 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9708 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519709 unpartitioned_mock_quic_data.AddRead(
9710 ASYNC, server_maker1.MakeDataPacket(
9711 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179712 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519713 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239714 SYNCHRONOUS,
9715 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
Matt Menke26e41542019-06-05 01:09:519716
9717 unpartitioned_mock_quic_data.AddWrite(
9718 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029719 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239720 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
9721 false, true,
Matt Menke26e41542019-06-05 01:09:519722 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029723 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519724 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029725 ASYNC, server_maker1.MakeResponseHeadersPacket(
9726 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
9727 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519728 unpartitioned_mock_quic_data.AddRead(
9729 ASYNC, server_maker1.MakeDataPacket(
9730 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Ryan Hamilton7505eb92019-06-08 00:22:179731 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519732 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239733 SYNCHRONOUS,
9734 ConstructClientAckAndConnectionClosePacket(packet_num++, 6, 5, 1));
Matt Menke26e41542019-06-05 01:09:519735
9736 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9737
9738 // Reads and writes for the partitioned case, where two sockets are used.
9739
Ryan Hamiltonabad59e2019-06-06 04:02:599740 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:519741 QuicTestPacketMaker client_maker2(
9742 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229743 quic::QuicUtils::CreateRandomConnectionId(
9744 context_.random_generator()),
9745 context_.clock(), kDefaultServerHostName,
9746 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519747 client_headers_include_h2_stream_dependency_);
9748 QuicTestPacketMaker server_maker2(
9749 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229750 quic::QuicUtils::CreateRandomConnectionId(
9751 context_.random_generator()),
9752 context_.clock(), kDefaultServerHostName,
9753 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519754
Renjie Tangaadb84b2019-08-31 01:00:239755 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259756 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239757 partitioned_mock_quic_data1.AddWrite(
9758 SYNCHRONOUS,
9759 client_maker2.MakeInitialSettingsPacket(packet_num2++));
9760 }
Matt Menke26e41542019-06-05 01:09:519761
9762 partitioned_mock_quic_data1.AddWrite(
9763 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029764 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239765 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
9766 true, true,
Matt Menke26e41542019-06-05 01:09:519767 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029768 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519769 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029770 ASYNC, server_maker2.MakeResponseHeadersPacket(
9771 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9772 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519773 partitioned_mock_quic_data1.AddRead(
9774 ASYNC, server_maker2.MakeDataPacket(
9775 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179776 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519777 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239778 SYNCHRONOUS,
9779 client_maker2.MakeAckPacket(packet_num2++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519780
9781 partitioned_mock_quic_data1.AddWrite(
9782 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029783 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239784 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
9785 false, true,
Matt Menke26e41542019-06-05 01:09:519786 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029787 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519788 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029789 ASYNC, server_maker2.MakeResponseHeadersPacket(
9790 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9791 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519792 partitioned_mock_quic_data1.AddRead(
9793 ASYNC, server_maker2.MakeDataPacket(
9794 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179795 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519796 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239797 SYNCHRONOUS,
9798 client_maker2.MakeAckPacket(packet_num2++, 4, 3, 1, true));
Matt Menke26e41542019-06-05 01:09:519799
9800 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9801
Ryan Hamiltonabad59e2019-06-06 04:02:599802 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:519803 QuicTestPacketMaker client_maker3(
9804 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229805 quic::QuicUtils::CreateRandomConnectionId(
9806 context_.random_generator()),
9807 context_.clock(), kDefaultServerHostName,
9808 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519809 client_headers_include_h2_stream_dependency_);
9810 QuicTestPacketMaker server_maker3(
9811 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229812 quic::QuicUtils::CreateRandomConnectionId(
9813 context_.random_generator()),
9814 context_.clock(), kDefaultServerHostName,
9815 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519816
Renjie Tangaadb84b2019-08-31 01:00:239817 int packet_num3 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259818 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239819 partitioned_mock_quic_data2.AddWrite(
9820 SYNCHRONOUS,
9821 client_maker3.MakeInitialSettingsPacket(packet_num3++));
9822 }
Matt Menke26e41542019-06-05 01:09:519823
9824 partitioned_mock_quic_data2.AddWrite(
9825 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029826 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239827 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9828 true, true,
Matt Menke26e41542019-06-05 01:09:519829 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029830 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519831 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029832 ASYNC, server_maker3.MakeResponseHeadersPacket(
9833 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9834 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519835 partitioned_mock_quic_data2.AddRead(
9836 ASYNC, server_maker3.MakeDataPacket(
9837 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179838 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519839 partitioned_mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239840 SYNCHRONOUS,
9841 client_maker3.MakeAckPacket(packet_num3++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519842
9843 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9844
9845 if (partition_connections) {
9846 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9847 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9848 } else {
9849 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9850 }
9851
9852 CreateSession();
9853
9854 TestCompletionCallback callback;
9855 HttpRequestInfo request1;
9856 request1.method = "GET";
9857 request1.url = GURL(url1);
9858 request1.traffic_annotation =
9859 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9860 request1.network_isolation_key = network_isolation_key1;
9861 HttpNetworkTransaction trans1(LOWEST, session_.get());
9862 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9863 EXPECT_THAT(callback.GetResult(rv), IsOk());
9864 std::string response_data1;
9865 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9866 EXPECT_EQ("1", response_data1);
9867
9868 HttpRequestInfo request2;
9869 request2.method = "GET";
9870 request2.url = GURL(url2);
9871 request2.traffic_annotation =
9872 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9873 request2.network_isolation_key = network_isolation_key2;
9874 HttpNetworkTransaction trans2(LOWEST, session_.get());
9875 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9876 EXPECT_THAT(callback.GetResult(rv), IsOk());
9877 std::string response_data2;
9878 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9879 EXPECT_EQ("2", response_data2);
9880
9881 HttpRequestInfo request3;
9882 request3.method = "GET";
9883 request3.url = GURL(url3);
9884 request3.traffic_annotation =
9885 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9886 request3.network_isolation_key = network_isolation_key1;
9887 HttpNetworkTransaction trans3(LOWEST, session_.get());
9888 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9889 EXPECT_THAT(callback.GetResult(rv), IsOk());
9890 std::string response_data3;
9891 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9892 EXPECT_EQ("3", response_data3);
9893
9894 if (partition_connections) {
9895 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9896 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9897 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9898 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9899 } else {
9900 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9901 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9902 }
9903 }
9904 }
9905}
9906
9907// Test that two requests to the same origin over QUIC tunnels use different
9908// QUIC sessions if their NetworkIsolationKeys don't match, and
9909// kPartitionConnectionsByNetworkIsolationKey is enabled.
9910TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9911 base::test::ScopedFeatureList feature_list;
9912 feature_list.InitAndEnableFeature(
9913 features::kPartitionConnectionsByNetworkIsolationKey);
9914
9915 session_params_.enable_quic = true;
9916 session_params_.enable_quic_proxies_for_https_urls = true;
Nicolas Arciniegad2013f92020-02-07 23:00:569917 proxy_resolution_service_ =
9918 ConfiguredProxyResolutionService::CreateFixedFromPacResult(
9919 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menke26e41542019-06-05 01:09:519920
9921 const char kGetRequest[] =
9922 "GET / HTTP/1.1\r\n"
9923 "Host: mail.example.org\r\n"
9924 "Connection: keep-alive\r\n\r\n";
9925 const char kGetResponse[] =
9926 "HTTP/1.1 200 OK\r\n"
9927 "Content-Length: 10\r\n\r\n";
9928
Ryan Hamiltonabad59e2019-06-06 04:02:599929 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9930 std::make_unique<MockQuicData>(version_),
9931 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519932
9933 for (int index : {0, 1}) {
9934 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229935 version_,
9936 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9937 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519938 client_headers_include_h2_stream_dependency_);
9939 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229940 version_,
9941 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9942 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9943 false);
Matt Menke26e41542019-06-05 01:09:519944
Renjie Tangaadb84b2019-08-31 01:00:239945 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259946 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239947 mock_quic_data[index]->AddWrite(
9948 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Renjie Tangee921d12020-02-06 00:41:499949 mock_quic_data[index]->AddWrite(
9950 SYNCHRONOUS, client_maker.MakePriorityPacket(
9951 packet_num++, true,
9952 GetNthClientInitiatedBidirectionalStreamId(0), 0,
9953 ConvertRequestPriorityToQuicPriority(
9954 HttpProxyConnectJob::kH2QuicTunnelPriority)));
Renjie Tangaadb84b2019-08-31 01:00:239955 }
Matt Menke26e41542019-06-05 01:09:519956
Ryan Hamiltonabad59e2019-06-06 04:02:599957 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519958 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029959 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239960 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9961 false,
Renjie Tangee921d12020-02-06 00:41:499962 VersionUsesHttp3(version_.transport_version)
9963 ? 1
9964 : ConvertRequestPriorityToQuicPriority(
9965 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:029966 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:599967 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029968 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:519969 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9970 false, GetResponseHeaders("200 OK"), nullptr));
9971
9972 std::string header = ConstructDataHeader(strlen(kGetRequest));
9973 if (version_.transport_version != quic::QUIC_VERSION_99) {
Ryan Hamiltonabad59e2019-06-06 04:02:599974 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239975 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
9976 packet_num++, false,
9977 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
Zhongyi Shid1c00fc42019-12-14 06:05:099978 1, false, quiche::QuicheStringPiece(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:519979 } else {
Ryan Hamiltonabad59e2019-06-06 04:02:599980 mock_quic_data[index]->AddWrite(
Renjie Tangd5133972019-12-06 00:20:289981 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:239982 packet_num++, false,
9983 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
Renjie Tangd5133972019-12-06 00:20:289984 1, false, {header + std::string(kGetRequest)}));
Matt Menke26e41542019-06-05 01:09:519985 }
9986
9987 std::string header2 = ConstructDataHeader(strlen(kGetResponse));
Ryan Hamiltonabad59e2019-06-06 04:02:599988 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519989 ASYNC, server_maker.MakeDataPacket(
9990 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179991 false, header2 + std::string(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599992 mock_quic_data[index]->AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179993 SYNCHRONOUS,
9994 server_maker.MakeDataPacket(
9995 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
9996 ConstructDataHeader(10) + std::string("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599997 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239998 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2, 1, true));
Ryan Hamiltonabad59e2019-06-06 04:02:599999 mock_quic_data[index]->AddRead(SYNCHRONOUS,
10000 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:5110001
Ryan Hamiltonabad59e2019-06-06 04:02:5910002 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:5110003 }
10004
10005 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
10006 SSLSocketDataProvider ssl_data2(ASYNC, OK);
10007 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
10008
10009 CreateSession();
10010
10011 request_.url = GURL("https://mail.example.org/");
10012 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
10013 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
10014 RunTransaction(&trans);
10015 CheckResponseData(&trans, "0123456789");
10016
10017 HttpRequestInfo request2;
Shivani Sharma8ae506c2019-07-21 21:08:2710018 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
10019 request_.network_isolation_key = NetworkIsolationKey(kOrigin1, kOrigin1);
Matt Menke26e41542019-06-05 01:09:5110020 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
10021 RunTransaction(&trans2);
10022 CheckResponseData(&trans2, "0123456789");
10023
Ryan Hamiltonabad59e2019-06-06 04:02:5910024 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
10025 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
10026 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
10027 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:5110028}
10029
[email protected]61a527782013-02-21 03:58:0010030} // namespace test
10031} // namespace net