blob: 86a7ad6eafc9ae3ec2bf16d02a22888b86016a82 [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"
Lily Houghton582d4622018-01-22 22:43:4045#include "net/proxy_resolution/proxy_config_service_fixed.h"
Lily Houghtonffe89daa02018-03-09 18:30:0346#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4047#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"
50#include "net/quic/mock_quic_data.h"
51#include "net/quic/quic_chromium_alarm_factory.h"
52#include "net/quic/quic_http_stream.h"
53#include "net/quic/quic_http_utils.h"
54#include "net/quic/quic_stream_factory_peer.h"
55#include "net/quic/quic_test_packet_maker.h"
56#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0057#include "net/socket/client_socket_factory.h"
58#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2159#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2860#include "net/socket/socket_performance_watcher.h"
61#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0062#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5863#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5764#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2965#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0166#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4367#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4068#include "net/test/test_with_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5169#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
70#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
71#include "net/third_party/quiche/src/quic/core/quic_framer.h"
72#include "net/third_party/quiche/src/quic/core/quic_utils.h"
73#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
74#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
75#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
76#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
77#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
78#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
79#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
80#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1481#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
82#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2983#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0084#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4885#include "net/url_request/url_request.h"
86#include "net/url_request/url_request_job_factory_impl.h"
87#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0188#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0089#include "testing/gtest/include/gtest/gtest.h"
90#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4691#include "url/gurl.h"
Matt Menke3233d8f22019-08-20 21:01:4992#include "url/origin.h"
[email protected]61a527782013-02-21 03:58:0093
Reilly Grant89a7e512018-01-20 01:57:1694using ::testing::ElementsAre;
95using ::testing::Key;
96
bnc508835902015-05-12 20:10:2997namespace net {
98namespace test {
[email protected]61a527782013-02-21 03:58:0099
100namespace {
101
bnc359ed2a2016-04-29 20:43:45102enum DestinationType {
103 // In pooling tests with two requests for different origins to the same
104 // destination, the destination should be
105 SAME_AS_FIRST, // the same as the first origin,
106 SAME_AS_SECOND, // the same as the second origin, or
107 DIFFERENT, // different from both.
108};
109
rchf114d982015-10-21 01:34:56110static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52111 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12112static const char kQuicAlternativeServiceWithProbabilityHeader[] =
113 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56114static const char kQuicAlternativeServiceDifferentPortHeader[] =
115 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20116
rch9ae5b3b2016-02-11 00:36:29117const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45118const char kDifferentHostname[] = "different.example.com";
119
David Schinazi09e9a6012019-10-03 17:37:57120struct TestParams {
121 quic::ParsedQuicVersion version;
122 bool client_headers_include_h2_stream_dependency;
123};
124
125// Used by ::testing::PrintToStringParamName().
126std::string PrintToString(const TestParams& p) {
127 return quic::QuicStrCat(
128 ParsedQuicVersionToString(p.version), "_",
129 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
130 "Dependency");
131}
132
bnc359ed2a2016-04-29 20:43:45133// Run QuicNetworkTransactionWithDestinationTest instances with all value
134// combinations of version and destination_type.
135struct PoolingTestParams {
Nick Harper23290b82019-05-02 00:02:56136 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45137 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05138 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45139};
140
David Schinazi09e9a6012019-10-03 17:37:57141// Used by ::testing::PrintToStringParamName().
142std::string PrintToString(const PoolingTestParams& p) {
143 const char* destination_string = "";
144 switch (p.destination_type) {
145 case SAME_AS_FIRST:
146 destination_string = "SAME_AS_FIRST";
147 break;
148 case SAME_AS_SECOND:
149 destination_string = "SAME_AS_SECOND";
150 break;
151 case DIFFERENT:
152 destination_string = "DIFFERENT";
153 break;
154 }
155 return quic::QuicStrCat(
156 ParsedQuicVersionToString(p.version), "_", destination_string, "_",
157 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
158 "Dependency");
159}
160
zhongyie537a002017-06-27 16:48:21161std::string GenerateQuicVersionsListForAltSvcHeader(
Nick Harper23290b82019-05-02 00:02:56162 const quic::ParsedQuicVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21163 std::string result = "";
Nick Harper23290b82019-05-02 00:02:56164 for (const quic::ParsedQuicVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21165 if (!result.empty())
166 result.append(",");
Nick Harper23290b82019-05-02 00:02:56167 result.append(base::NumberToString(version.transport_version));
zhongyie537a002017-06-27 16:48:21168 }
169 return result;
170}
171
David Schinazi09e9a6012019-10-03 17:37:57172std::vector<TestParams> GetTestParams() {
173 std::vector<TestParams> params;
174 quic::ParsedQuicVersionVector all_supported_versions =
175 quic::AllSupportedVersions();
176 for (const quic::ParsedQuicVersion version : all_supported_versions) {
177 // TODO(rch): crbug.com/978745 - Make this work with TLS
178 if (version.handshake_protocol != quic::PROTOCOL_TLS1_3) {
179 params.push_back(TestParams{version, false});
180 params.push_back(TestParams{version, true});
181 }
182 }
183 return params;
184}
185
bnc359ed2a2016-04-29 20:43:45186std::vector<PoolingTestParams> GetPoolingTestParams() {
187 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56188 quic::ParsedQuicVersionVector all_supported_versions =
Ryan Hamilton93424eb82019-08-23 04:28:40189 quic::AllSupportedVersions();
Nick Harper23290b82019-05-02 00:02:56190 for (const quic::ParsedQuicVersion version : all_supported_versions) {
Ryan Hamiltone940bd12019-06-30 02:46:45191 // TODO(rch): crbug.com/978745 - Make this work with TLS
192 if (version.handshake_protocol != quic::PROTOCOL_TLS1_3) {
193 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
194 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
195 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
196 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
197 params.push_back(PoolingTestParams{version, DIFFERENT, false});
198 params.push_back(PoolingTestParams{version, DIFFERENT, true});
199 }
bnc359ed2a2016-04-29 20:43:45200 }
201 return params;
202}
bncb07c05532015-05-14 19:07:20203
[email protected]61a527782013-02-21 03:58:00204} // namespace
205
ryansturm49a8cb12016-06-15 16:51:09206class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12207 public:
ryansturm49a8cb12016-06-15 16:51:09208 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12209
ryansturm49a8cb12016-06-15 16:51:09210 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12211
ryansturm49a8cb12016-06-15 16:51:09212 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
213 HttpRequestHeaders* request_headers) {
214 if (!proxy_info.is_http() && !proxy_info.is_https() &&
215 !proxy_info.is_quic()) {
216 return;
217 }
218 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12219 }
220
221 private:
ryansturm49a8cb12016-06-15 16:51:09222 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12223};
224
tbansal0f56a39a2016-04-07 22:03:38225class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40226 public:
tbansal180587c2017-02-16 15:13:23227 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
228 bool* rtt_notification_received)
229 : should_notify_updated_rtt_(should_notify_updated_rtt),
230 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38231 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40232
tbansal180587c2017-02-16 15:13:23233 bool ShouldNotifyUpdatedRTT() const override {
234 return *should_notify_updated_rtt_;
235 }
tbansalfdf5665b2015-09-21 22:46:40236
tbansal0f56a39a2016-04-07 22:03:38237 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
238 *rtt_notification_received_ = true;
239 }
240
241 void OnConnectionChanged() override {}
242
243 private:
tbansal180587c2017-02-16 15:13:23244 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38245 bool* rtt_notification_received_;
246
247 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
248};
249
250class TestSocketPerformanceWatcherFactory
251 : public SocketPerformanceWatcherFactory {
252 public:
253 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23254 : watcher_count_(0u),
255 should_notify_updated_rtt_(true),
256 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38257 ~TestSocketPerformanceWatcherFactory() override {}
258
259 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42260 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41261 const Protocol protocol,
262 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51263 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38264 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51265 }
266 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42267 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23268 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
269 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40270 }
271
tbansalc8a94ea2015-11-02 23:58:51272 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40273
tbansalc8a94ea2015-11-02 23:58:51274 bool rtt_notification_received() const { return rtt_notification_received_; }
275
tbansal180587c2017-02-16 15:13:23276 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
277 should_notify_updated_rtt_ = should_notify_updated_rtt;
278 }
279
tbansalc8a94ea2015-11-02 23:58:51280 private:
tbansal0f56a39a2016-04-07 22:03:38281 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23282 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51283 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38284
285 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51286};
287
Ryan Hamilton8d9ee76e2018-05-29 23:52:52288class QuicNetworkTransactionTest
289 : public PlatformTest,
David Schinazi09e9a6012019-10-03 17:37:57290 public ::testing::WithParamInterface<TestParams>,
Gabriel Charette694c3c332019-08-19 14:53:05291 public WithTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00292 protected:
[email protected]1c04f9522013-02-21 20:32:43293 QuicNetworkTransactionTest()
David Schinazi09e9a6012019-10-03 17:37:57294 : version_(GetParam().version),
295 client_headers_include_h2_stream_dependency_(
296 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:56297 supported_versions_(quic::test::SupportedVersions(version_)),
David Schinazic8281052019-01-24 06:14:17298 random_generator_(0),
299 client_maker_(
300 version_,
301 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
302 &clock_,
303 kDefaultServerHostName,
304 quic::Perspective::IS_CLIENT,
305 client_headers_include_h2_stream_dependency_),
306 server_maker_(
307 version_,
308 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
309 &clock_,
310 kDefaultServerHostName,
311 quic::Perspective::IS_SERVER,
312 false),
Nick Harpereb483e12019-05-14 00:18:09313 quic_task_runner_(new TestTaskRunner(&clock_)),
rtenneti052774e2015-11-24 21:00:12314 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43315 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59316 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11317 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke3233d8f22019-08-20 21:01:49318 http_server_properties_(std::make_unique<HttpServerProperties>()),
rchf114d982015-10-21 01:34:56319 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19320 request_.method = "GET";
rchf114d982015-10-21 01:34:56321 std::string url("https://");
bncb07c05532015-05-14 19:07:20322 url.append(kDefaultServerHostName);
323 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19324 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10325 request_.traffic_annotation =
326 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52327 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56328
329 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29330 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56331 verify_details_.cert_verify_result.verified_cert = cert;
332 verify_details_.cert_verify_result.is_issued_by_known_root = true;
333 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43334 }
[email protected]61a527782013-02-21 03:58:00335
dcheng67be2b1f2014-10-27 21:47:29336 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00337 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55338 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00339 }
340
dcheng67be2b1f2014-10-27 21:47:29341 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00342 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
343 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55344 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00345 PlatformTest::TearDown();
346 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55347 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40348 session_.reset();
[email protected]61a527782013-02-21 03:58:00349 }
350
Ryan Hamilton8d9ee76e2018-05-29 23:52:52351 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23352 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03353 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52354 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30355 }
356
Ryan Hamilton8d9ee76e2018-05-29 23:52:52357 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23358 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03359 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52360 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58361 }
362
Ryan Hamilton8d9ee76e2018-05-29 23:52:52363 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23364 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52365 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20366 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58367 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20368 }
369
Ryan Hamilton8d9ee76e2018-05-29 23:52:52370 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23371 uint64_t packet_number,
372 uint64_t largest_received,
373 uint64_t smallest_received,
374 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37375 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49376 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37377 }
378
Ryan Hamilton8d9ee76e2018-05-29 23:52:52379 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23380 uint64_t packet_number,
381 uint64_t largest_received,
382 uint64_t smallest_received,
383 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52384 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23385 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49386 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23387 ack_delay_time);
388 }
389
Ryan Hamilton8d9ee76e2018-05-29 23:52:52390 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23391 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52392 quic::QuicStreamId stream_id,
393 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23394 uint64_t largest_received,
395 uint64_t smallest_received,
396 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58397 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49398 num, false, stream_id, error_code, largest_received, smallest_received,
399 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20400 }
401
Ryan Hamilton8d9ee76e2018-05-29 23:52:52402 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23403 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52404 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41405 quic::QuicRstStreamErrorCode error_code) {
Yixin Wang46a273ec302018-01-23 17:59:56406 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18407 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56408 }
409
Ryan Hamilton8d9ee76e2018-05-29 23:52:52410 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23411 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
412 uint64_t largest_received,
413 uint64_t smallest_received,
414 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58415 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49416 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20417 }
[email protected]61a527782013-02-21 03:58:00418
Ryan Hamilton8d9ee76e2018-05-29 23:52:52419 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58420 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23421 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52422 quic::QuicTime::Delta delta_time_largest_observed,
Fan Yangac867502019-01-28 21:10:23423 uint64_t largest_received,
424 uint64_t smallest_received,
425 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52426 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29427 const std::string& quic_error_details,
428 uint64_t frame_type) {
alyssar2adf3ac2016-05-03 17:12:58429 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12430 num, false, delta_time_largest_observed, largest_received,
Renjie Tangff0d6372019-08-30 22:03:29431 smallest_received, least_unacked, quic_error, quic_error_details,
432 frame_type);
zhongyica364fbb2015-12-12 03:39:12433 }
434
Ryan Hamilton8d9ee76e2018-05-29 23:52:52435 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23436 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12437 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52438 quic::QuicStreamId stream_id,
439 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58440 return server_maker_.MakeRstPacket(num, include_version, stream_id,
441 error_code);
zhongyica364fbb2015-12-12 03:39:12442 }
443
Ryan Hamilton8d9ee76e2018-05-29 23:52:52444 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02445 uint64_t packet_number) {
446 return client_maker_.MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37447 }
448
Ryan Hamilton8d9ee76e2018-05-29 23:52:52449 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23450 uint64_t packet_number,
451 uint64_t largest_received,
452 uint64_t smallest_received,
453 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37454 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49455 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37456 }
457
Ryan Hamilton8d9ee76e2018-05-29 23:52:52458 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23459 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57460 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52461 quic::QuicStreamId id,
462 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02463 RequestPriority request_priority) {
Yixin Wangb470bc882018-02-15 18:43:57464 return client_maker_.MakePriorityPacket(
465 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02466 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wang385652a2018-02-16 02:37:23467 }
468
Ryan Hamilton8d9ee76e2018-05-29 23:52:52469 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25470 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23471 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23472 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23473 uint64_t largest_received,
474 uint64_t smallest_received,
475 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25476 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
Ryan Hamilton0d65a8c2019-06-07 00:46:02477 priority_frames) {
Yixin Wange7ecc472018-03-06 19:00:25478 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23479 packet_number, should_include_version, largest_received,
Ryan Hamilton0d65a8c2019-06-07 00:46:02480 smallest_received, least_unacked, priority_frames);
Yixin Wangb470bc882018-02-15 18:43:57481 }
482
zhongyi32569c62016-01-08 02:54:30483 // Uses default 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) {
alyssar2adf3ac2016-05-03 17:12:58487 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30488 }
489
490 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13491 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
492 const std::string& scheme,
493 const std::string& path,
494 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50495 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00496 }
497
Ryan Hamilton0239aac2018-05-19 00:03:13498 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56499 return client_maker_.ConnectRequestHeaders(host_port);
500 }
501
Ryan Hamilton0239aac2018-05-19 00:03:13502 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58503 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00504 }
505
zhongyi32569c62016-01-08 02:54:30506 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13507 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
508 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58509 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30510 }
511
Ryan Hamilton8d9ee76e2018-05-29 23:52:52512 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23513 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52514 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05515 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00516 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52517 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17518 return server_maker_.MakeDataPacket(packet_number, stream_id,
519 should_include_version, fin, data);
[email protected]61a527782013-02-21 03:58:00520 }
521
Ryan Hamilton8d9ee76e2018-05-29 23:52:52522 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23523 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52524 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36525 bool should_include_version,
526 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52527 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17528 return client_maker_.MakeDataPacket(packet_number, stream_id,
529 should_include_version, fin, data);
ckrasicda193a82016-07-09 00:39:36530 }
531
Renjied172e812019-01-16 05:12:35532 std::unique_ptr<quic::QuicEncryptedPacket>
533 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23534 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35535 quic::QuicStreamId stream_id,
536 bool should_include_version,
537 bool fin,
Renjied172e812019-01-16 05:12:35538 const std::vector<std::string> data_writes) {
Ryan Hamilton7505eb92019-06-08 00:22:17539 return client_maker_.MakeMultipleDataFramesPacket(
540 packet_number, stream_id, should_include_version, fin, data_writes);
Renjied172e812019-01-16 05:12:35541 }
542
Ryan Hamilton8d9ee76e2018-05-29 23:52:52543 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23544 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56545 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52546 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23547 uint64_t largest_received,
548 uint64_t smallest_received,
549 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56550 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52551 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56552 return client_maker_.MakeAckAndDataPacket(
553 packet_number, include_version, stream_id, largest_received,
Ryan Hamilton7505eb92019-06-08 00:22:17554 smallest_received, least_unacked, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56555 }
556
Renjied172e812019-01-16 05:12:35557 std::unique_ptr<quic::QuicEncryptedPacket>
558 ConstructClientAckAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23559 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35560 bool include_version,
561 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23562 uint64_t largest_received,
563 uint64_t smallest_received,
564 uint64_t least_unacked,
Renjied172e812019-01-16 05:12:35565 bool fin,
Renjied172e812019-01-16 05:12:35566 const std::vector<std::string> data_writes) {
567 return client_maker_.MakeAckAndMultipleDataFramesPacket(
568 packet_number, include_version, stream_id, largest_received,
Ryan Hamilton7505eb92019-06-08 00:22:17569 smallest_received, least_unacked, fin, data_writes);
Renjied172e812019-01-16 05:12:35570 }
571
Ryan Hamilton8d9ee76e2018-05-29 23:52:52572 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
Fan Yangac867502019-01-28 21:10:23573 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52574 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36575 bool should_include_version,
576 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52577 quic::QuicStreamOffset* offset,
578 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36579 return client_maker_.MakeForceHolDataPacket(
580 packet_number, stream_id, should_include_version, fin, offset, data);
581 }
582
Ryan Hamilton8d9ee76e2018-05-29 23:52:52583 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23584 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52585 quic::QuicStreamId stream_id,
586 bool should_include_version,
587 bool fin,
588 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56589 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
590 should_include_version, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02591 std::move(headers), 0);
Yixin Wang46a273ec302018-01-23 17:59:56592 }
593
Ryan Hamilton8d9ee76e2018-05-29 23:52:52594 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23595 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52596 quic::QuicStreamId stream_id,
597 bool should_include_version,
598 bool fin,
599 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02600 quic::QuicStreamId parent_stream_id) {
Yixin Wang46a273ec302018-01-23 17:59:56601 return ConstructClientRequestHeadersPacket(
602 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:02603 std::move(headers), parent_stream_id);
zhongyi32569c62016-01-08 02:54:30604 }
605
Ryan Hamilton8d9ee76e2018-05-29 23:52:52606 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23607 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52608 quic::QuicStreamId stream_id,
609 bool should_include_version,
610 bool fin,
611 RequestPriority request_priority,
612 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02613 quic::QuicStreamId parent_stream_id) {
Ryan Hamilton0239aac2018-05-19 00:03:13614 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56615 ConvertRequestPriorityToQuicPriority(request_priority);
Ryan Hamilton0d65a8c2019-06-07 00:46:02616 return client_maker_.MakeRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56617 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02618 std::move(headers), parent_stream_id, nullptr);
[email protected]61a527782013-02-21 03:58:00619 }
620
Ryan Hamilton8d9ee76e2018-05-29 23:52:52621 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25622 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23623 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52624 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25625 bool should_include_version,
626 bool fin,
627 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13628 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52629 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25630 size_t* spdy_headers_frame_length,
631 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13632 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25633 ConvertRequestPriorityToQuicPriority(request_priority);
634 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
635 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02636 std::move(headers), parent_stream_id, spdy_headers_frame_length,
Yixin Wange7ecc472018-03-06 19:00:25637 data_writes);
638 }
639
Ryan Hamilton8d9ee76e2018-05-29 23:52:52640 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23641 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52642 quic::QuicStreamId stream_id,
643 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13644 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13645 spdy::SpdyHeaderBlock headers,
ckrasic769733c2016-06-30 00:42:13646 QuicTestPacketMaker* maker) {
647 return maker->MakePushPromisePacket(
648 packet_number, stream_id, promised_stream_id, should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02649 false, std::move(headers), nullptr);
ckrasic769733c2016-06-30 00:42:13650 }
651
Ryan Hamilton8d9ee76e2018-05-29 23:52:52652 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23653 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52654 quic::QuicStreamId stream_id,
655 bool should_include_version,
656 bool fin,
657 spdy::SpdyHeaderBlock headers) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02658 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
659 should_include_version, fin,
660 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30661 }
662
Victor Vasiliev076657c2019-03-12 02:46:43663 std::string ConstructDataHeader(size_t body_len) {
Nick Harper23290b82019-05-02 00:02:56664 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:41665 return "";
666 }
Renjief49758b2019-01-11 23:32:41667 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:57668 auto header_length =
669 quic::HttpEncoder::SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43670 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41671 }
672
Nick Harper23290b82019-05-02 00:02:56673 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41674 session_params_.enable_quic = true;
Nick Harper72ade192019-07-17 03:30:42675 session_params_.quic_params.supported_versions = supported_versions;
Bence Béky1ceba552019-07-19 17:11:05676 session_params_.quic_params.max_allowed_push_id = quic::kMaxQuicStreamId;
Nick Harper72ade192019-07-17 03:30:42677 session_params_.quic_params.headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:05678 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00679
mmenke6ddfbea2017-05-31 21:48:41680 session_context_.quic_clock = &clock_;
681 session_context_.quic_random = &random_generator_;
682 session_context_.client_socket_factory = &socket_factory_;
683 session_context_.quic_crypto_client_stream_factory =
684 &crypto_client_stream_factory_;
685 session_context_.host_resolver = &host_resolver_;
686 session_context_.cert_verifier = &cert_verifier_;
687 session_context_.transport_security_state = &transport_security_state_;
688 session_context_.cert_transparency_verifier =
689 cert_transparency_verifier_.get();
690 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
691 session_context_.socket_performance_watcher_factory =
692 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59693 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41694 session_context_.ssl_config_service = ssl_config_service_.get();
695 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49696 session_context_.http_server_properties = http_server_properties_.get();
mmenke6ddfbea2017-05-31 21:48:41697 session_context_.net_log = net_log_.bound().net_log();
698
699 session_.reset(new HttpNetworkSession(session_params_, session_context_));
Matt Menkeb566c392019-09-11 23:22:43700 session_->quic_stream_factory()
701 ->set_is_quic_known_to_work_on_current_network(true);
Yixin Wang46a273ec302018-01-23 17:59:56702 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
703 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00704 }
705
zhongyi86838d52017-06-30 01:19:44706 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21707
bnc691fda62016-08-12 00:43:16708 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19709 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42710 ASSERT_TRUE(response != nullptr);
711 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19712 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
713 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52714 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:08715 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19716 response->connection_info);
717 }
718
bnc691fda62016-08-12 00:43:16719 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41720 const HttpResponseInfo* response = trans->GetResponseInfo();
721 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37722 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41723 }
724
bnc691fda62016-08-12 00:43:16725 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19726 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42727 ASSERT_TRUE(response != nullptr);
728 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19729 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
730 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52731 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52732 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19733 response->connection_info);
734 }
735
Yixin Wang46a273ec302018-01-23 17:59:56736 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
737 const HttpResponseInfo* response = trans->GetResponseInfo();
738 ASSERT_TRUE(response != nullptr);
739 ASSERT_TRUE(response->headers.get() != nullptr);
740 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
741 EXPECT_TRUE(response->was_fetched_via_spdy);
742 EXPECT_TRUE(response->was_alpn_negotiated);
743 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
744 response->connection_info);
745 }
746
bnc691fda62016-08-12 00:43:16747 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19748 const std::string& expected) {
749 std::string response_data;
bnc691fda62016-08-12 00:43:16750 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19751 EXPECT_EQ(expected, response_data);
752 }
753
bnc691fda62016-08-12 00:43:16754 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19755 TestCompletionCallback callback;
756 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01757 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
758 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19759 }
760
761 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16762 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
763 RunTransaction(&trans);
764 CheckWasHttpResponse(&trans);
765 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19766 }
767
tbansalc3308d72016-08-27 10:25:04768 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
769 bool used_proxy,
770 uint16_t port) {
771 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
772 HeadersHandler headers_handler;
773 trans.SetBeforeHeadersSentCallback(
774 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
775 base::Unretained(&headers_handler)));
776 RunTransaction(&trans);
777 CheckWasHttpResponse(&trans);
778 CheckResponsePort(&trans, port);
779 CheckResponseData(&trans, expected);
780 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47781 if (used_proxy) {
782 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
783 } else {
784 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
785 }
tbansalc3308d72016-08-27 10:25:04786 }
787
[email protected]aa9b14d2013-05-10 23:45:19788 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56789 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12790 }
791
bnc62a44f022015-04-02 15:59:41792 void SendRequestAndExpectQuicResponseFromProxyOnPort(
793 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46794 uint16_t port) {
bnc62a44f022015-04-02 15:59:41795 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19796 }
797
798 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05799 MockCryptoClientStream::HandshakeMode handshake_mode,
800 const NetworkIsolationKey& network_isolation_key =
801 NetworkIsolationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19802 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46803 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21804 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12805 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49806 http_server_properties_->SetQuicAlternativeService(
Matt Menkeb32ba5122019-09-10 19:17:05807 server, network_isolation_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07808 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19809 }
810
rchbe69cb902016-02-11 01:10:48811 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27812 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48813 const HostPortPair& alternative) {
814 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46815 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21816 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48817 alternative.port());
818 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49819 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07820 server, NetworkIsolationKey(), alternative_service, expiration,
821 supported_versions_);
rchbe69cb902016-02-11 01:10:48822 }
823
Matt Menkeb32ba5122019-09-10 19:17:05824 void ExpectBrokenAlternateProtocolMapping(
825 const NetworkIsolationKey& network_isolation_key =
826 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46827 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34828 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49829 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05830 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34831 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49832 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05833 alternative_service_info_vector[0].alternative_service(),
834 network_isolation_key));
[email protected]aa9b14d2013-05-10 23:45:19835 }
836
Matt Menkeb32ba5122019-09-10 19:17:05837 void ExpectQuicAlternateProtocolMapping(
838 const NetworkIsolationKey& network_isolation_key =
839 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46840 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34841 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49842 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05843 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34844 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54845 EXPECT_EQ(
846 kProtoQUIC,
847 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49848 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05849 alternative_service_info_vector[0].alternative_service(),
850 network_isolation_key));
[email protected]4d590c9c2014-05-02 05:14:33851 }
852
[email protected]aa9b14d2013-05-10 23:45:19853 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42854 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30855 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30856 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30857 hanging_data->set_connect_data(hanging_connect);
858 hanging_data_.push_back(std::move(hanging_data));
859 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56860 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19861 }
862
Zhongyi Shia6b68d112018-09-24 07:49:03863 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Nick Harper72ade192019-07-17 03:30:42864 session_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
865 session_params_.quic_params.migrate_sessions_early_v2 = true;
866 session_params_.quic_params.retry_on_alternate_network_before_handshake =
867 true;
Zhongyi Shia6b68d112018-09-24 07:49:03868 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
869 MockNetworkChangeNotifier* mock_ncn =
870 scoped_mock_change_notifier_->mock_network_change_notifier();
871 mock_ncn->ForceNetworkHandlesSupported();
872 mock_ncn->SetConnectedNetworksList(
873 {kDefaultNetworkForTests, kNewNetworkForTests});
874 }
875
tbansalc3308d72016-08-27 10:25:04876 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
877 // alternative proxy. Verifies that if the alternative proxy job returns
878 // |error_code|, the request is fetched successfully by the main job.
879 void TestAlternativeProxy(int error_code) {
880 // Use a non-cryptographic scheme for the request URL since this request
881 // will be fetched via proxy with QUIC as the alternative service.
882 request_.url = GURL("http://example.org/");
883 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27884 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04885 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27886 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04887 };
888
Ryan Sleevib8d7ea02018-05-07 20:01:01889 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04890 socket_factory_.AddSocketDataProvider(&quic_data);
891
892 // Main job succeeds and the alternative job fails.
893 // Add data for two requests that will be read by the main job.
894 MockRead http_reads_1[] = {
895 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
896 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
897 MockRead(ASYNC, OK)};
898
899 MockRead http_reads_2[] = {
900 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
901 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
902 MockRead(ASYNC, OK)};
903
Ryan Sleevib8d7ea02018-05-07 20:01:01904 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
905 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04906 socket_factory_.AddSocketDataProvider(&http_data_1);
907 socket_factory_.AddSocketDataProvider(&http_data_2);
908 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
909 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
910
911 TestProxyDelegate test_proxy_delegate;
912 // Proxy URL is different from the request URL.
913 test_proxy_delegate.set_alternative_proxy_server(
914 ProxyServer::FromPacString("QUIC myproxy.org:443"));
915
Lily Houghton8c2f97d2018-01-22 05:06:59916 proxy_resolution_service_ =
917 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49918 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52919 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04920
921 CreateSession();
922 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
923
924 // The first request should be fetched via the HTTPS proxy.
925 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
926
Reilly Grant89a7e512018-01-20 01:57:16927 // Since the main job succeeded only the alternative proxy server should be
928 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59929 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16930 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04931
932 // Verify that the second request completes successfully, and the
933 // alternative proxy server job is not started.
934 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
935 }
936
Matt Menkeb32ba5122019-09-10 19:17:05937 // Adds a new socket data provider for an HTTP request, and runs a request,
938 // expecting it to be used.
939 void AddHttpDataAndRunRequest() {
940 MockWrite http_writes[] = {
941 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
942 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
943 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
944
945 MockRead http_reads[] = {
946 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
947 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
948 MockRead(SYNCHRONOUS, 5, "http used"),
949 // Connection closed.
950 MockRead(SYNCHRONOUS, OK, 6)};
951 SequencedSocketData http_data(http_reads, http_writes);
952 socket_factory_.AddSocketDataProvider(&http_data);
953 SSLSocketDataProvider ssl_data(ASYNC, OK);
954 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
955 SendRequestAndExpectHttpResponse("http used");
956 EXPECT_TRUE(http_data.AllWriteDataConsumed());
957 EXPECT_TRUE(http_data.AllReadDataConsumed());
958 }
959
960 // Adds a new socket data provider for a QUIC request, and runs a request,
961 // expecting it to be used. The new QUIC session is not closed.
962 void AddQuicDataAndRunRequest() {
963 QuicTestPacketMaker client_maker(
964 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
965 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
966 client_headers_include_h2_stream_dependency_);
967 QuicTestPacketMaker server_maker(
968 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
969 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
970 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56971 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05972 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:25973 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:56974 quic_data.AddWrite(
975 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_number++));
976 }
Matt Menkeb32ba5122019-09-10 19:17:05977 quic_data.AddWrite(
978 SYNCHRONOUS,
979 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56980 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
981 true, true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Matt Menkeb32ba5122019-09-10 19:17:05982 GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
983 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
984 quic_data.AddRead(
985 ASYNC, server_maker.MakeResponseHeadersPacket(
986 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
987 false, server_maker.GetResponseHeaders("200 OK"), nullptr));
988 std::string header = ConstructDataHeader(9);
989 quic_data.AddRead(
990 ASYNC, server_maker.MakeDataPacket(
991 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
992 true, header + "quic used"));
993 // Don't care about the final ack.
994 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
995 // No more data to read.
996 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
997 quic_data.AddSocketDataToFactory(&socket_factory_);
998 SendRequestAndExpectQuicResponse("quic used");
999
1000 EXPECT_TRUE(quic_data.AllReadDataConsumed());
1001 }
1002
Fan Yang32c5a112018-12-10 20:06:331003 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:561004 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
1005 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:361006 }
1007
Fan Yang32c5a112018-12-10 20:06:331008 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:561009 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
1010 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:361011 }
1012
Bence Béky230ac612017-08-30 19:17:081013 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:491014 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:081015 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:491016 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:081017 }
1018
Nick Harper23290b82019-05-02 00:02:561019 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:051020 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:561021 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:011022 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521023 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:171024 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:581025 QuicTestPacketMaker client_maker_;
1026 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:091027 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:421028 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:001029 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:561030 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:051031 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:431032 MockHostResolver host_resolver_;
1033 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:111034 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:421035 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:231036 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:381037 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:071038 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:591039 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:421040 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:491041 std::unique_ptr<HttpServerProperties> http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:411042 HttpNetworkSession::Params session_params_;
1043 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:191044 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:511045 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:421046 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:561047 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:031048 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:121049
1050 private:
1051 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1052 const std::string& expected,
bnc62a44f022015-04-02 15:59:411053 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:461054 uint16_t port) {
bnc691fda62016-08-12 00:43:161055 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:091056 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:161057 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091058 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
1059 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:161060 RunTransaction(&trans);
1061 CheckWasQuicResponse(&trans);
1062 CheckResponsePort(&trans, port);
1063 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:091064 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:471065 if (used_proxy) {
1066 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
1067 } else {
1068 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1069 }
tbansal7cec3812015-02-05 21:25:121070 }
[email protected]61a527782013-02-21 03:58:001071};
1072
David Schinazi09e9a6012019-10-03 17:37:571073INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1074 QuicNetworkTransactionTest,
1075 ::testing::ValuesIn(GetTestParams()),
1076 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201077
Shivani Sharma8ae506c2019-07-21 21:08:271078// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
1079// kAppendInitiatingFrameOriginToNetworkIsolationKey.
1080
Ryan Hamiltona64a5bcf2017-11-30 07:35:281081TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:421082 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281083 base::HistogramTester histograms;
Nick Harper72ade192019-07-17 03:30:421084 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281085 HostPortPair::FromString("mail.example.org:443"));
1086 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271087 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281088
Ryan Hamiltonabad59e2019-06-06 04:02:591089 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251090 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231091 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281092 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1093 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1094 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1095
1096 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1097
1098 CreateSession();
1099
1100 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1101 TestCompletionCallback callback;
1102 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1103 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1104 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1105
1106 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1107 -ERR_INTERNET_DISCONNECTED, 1);
1108 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1109 -ERR_INTERNET_DISCONNECTED, 1);
1110}
1111
1112TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Nick Harper72ade192019-07-17 03:30:421113 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281114 base::HistogramTester histograms;
Nick Harper72ade192019-07-17 03:30:421115 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281116 HostPortPair::FromString("mail.example.org:443"));
1117 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271118 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281119
Ryan Hamiltonabad59e2019-06-06 04:02:591120 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251121 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231122 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281123 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1124 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1125 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1126
1127 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1128
1129 CreateSession();
1130
1131 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1132 TestCompletionCallback callback;
1133 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1135 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1136
1137 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1138 -ERR_INTERNET_DISCONNECTED, 1);
1139 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1140 -ERR_INTERNET_DISCONNECTED, 1);
1141}
1142
tbansal180587c2017-02-16 15:13:231143TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Nick Harper72ade192019-07-17 03:30:421144 session_params_.quic_params.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231145 HostPortPair::FromString("mail.example.org:443"));
1146
Ryan Hamiltonabad59e2019-06-06 04:02:591147 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231148 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251149 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231150 mock_quic_data.AddWrite(SYNCHRONOUS,
1151 ConstructInitialSettingsPacket(packet_num++));
1152 }
rch5cb522462017-04-25 20:18:361153 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231154 SYNCHRONOUS,
1155 ConstructClientRequestHeadersPacket(
1156 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1157 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431158 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331159 ASYNC, ConstructServerResponseHeadersPacket(
1160 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1161 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431162 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331163 mock_quic_data.AddRead(
1164 ASYNC, ConstructServerDataPacket(
1165 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171166 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231167 mock_quic_data.AddWrite(SYNCHRONOUS,
1168 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231169 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1170
1171 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1172
1173 CreateSession();
1174 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1175
1176 EXPECT_FALSE(
1177 test_socket_performance_watcher_factory_.rtt_notification_received());
1178 SendRequestAndExpectQuicResponse("hello!");
1179 EXPECT_TRUE(
1180 test_socket_performance_watcher_factory_.rtt_notification_received());
1181}
1182
1183TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Nick Harper72ade192019-07-17 03:30:421184 session_params_.quic_params.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231185 HostPortPair::FromString("mail.example.org:443"));
1186
Ryan Hamiltonabad59e2019-06-06 04:02:591187 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231188 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251189 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231190 mock_quic_data.AddWrite(SYNCHRONOUS,
1191 ConstructInitialSettingsPacket(packet_num++));
1192 }
rch5cb522462017-04-25 20:18:361193 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231194 SYNCHRONOUS,
1195 ConstructClientRequestHeadersPacket(
1196 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1197 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431198 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331199 ASYNC, ConstructServerResponseHeadersPacket(
1200 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1201 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431202 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331203 mock_quic_data.AddRead(
1204 ASYNC, ConstructServerDataPacket(
1205 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171206 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231207 mock_quic_data.AddWrite(SYNCHRONOUS,
1208 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231209 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1210
1211 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1212
1213 CreateSession();
1214 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1215
1216 EXPECT_FALSE(
1217 test_socket_performance_watcher_factory_.rtt_notification_received());
1218 SendRequestAndExpectQuicResponse("hello!");
1219 EXPECT_FALSE(
1220 test_socket_performance_watcher_factory_.rtt_notification_received());
1221}
1222
[email protected]1e960032013-12-20 19:00:201223TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Nick Harper72ade192019-07-17 03:30:421224 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571225 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471226
Ryan Hamiltonabad59e2019-06-06 04:02:591227 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231228 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251229 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231230 mock_quic_data.AddWrite(SYNCHRONOUS,
1231 ConstructInitialSettingsPacket(packet_num++));
1232 }
rch5cb522462017-04-25 20:18:361233 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231234 SYNCHRONOUS,
1235 ConstructClientRequestHeadersPacket(
1236 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1237 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431238 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331239 ASYNC, ConstructServerResponseHeadersPacket(
1240 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1241 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431242 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331243 mock_quic_data.AddRead(
1244 ASYNC, ConstructServerDataPacket(
1245 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171246 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231247 mock_quic_data.AddWrite(SYNCHRONOUS,
1248 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591249 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471250
rcha5399e02015-04-21 19:32:041251 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471252
[email protected]4dca587c2013-03-07 16:54:471253 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471254
[email protected]aa9b14d2013-05-10 23:45:191255 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471256
[email protected]98b20ce2013-05-10 05:55:261257 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:541258 auto entries = net_log_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261259 EXPECT_LT(0u, entries.size());
1260
1261 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291262 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001263 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1264 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261265 EXPECT_LT(0, pos);
1266
rchfd527212015-08-25 00:41:261267 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291268 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261269 entries, 0,
mikecirone8b85c432016-09-08 19:11:001270 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1271 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261272 EXPECT_LT(0, pos);
1273
Eric Roman79cc7552019-07-19 02:17:541274 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261275
rchfd527212015-08-25 00:41:261276 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1277 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001278 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1279 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261280 EXPECT_LT(0, pos);
1281
[email protected]98b20ce2013-05-10 05:55:261282 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291283 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001284 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1285 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261286 EXPECT_LT(0, pos);
1287
Eric Roman79cc7552019-07-19 02:17:541288 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Victor Vasiliev7da08172019-10-14 06:04:251289 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451290 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1291 static_cast<quic::QuicStreamId>(log_stream_id));
1292 } else {
1293 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1294 static_cast<quic::QuicStreamId>(log_stream_id));
1295 }
[email protected]4dca587c2013-03-07 16:54:471296}
1297
rchbd089ab2017-05-26 23:05:041298TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Nick Harper72ade192019-07-17 03:30:421299 session_params_.quic_params.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041300 HostPortPair::FromString("mail.example.org:443"));
1301
Ryan Hamiltonabad59e2019-06-06 04:02:591302 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231303 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251304 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231305 mock_quic_data.AddWrite(SYNCHRONOUS,
1306 ConstructInitialSettingsPacket(packet_num++));
1307 }
rchbd089ab2017-05-26 23:05:041308 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231309 SYNCHRONOUS,
1310 ConstructClientRequestHeadersPacket(
1311 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1312 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0239aac2018-05-19 00:03:131313 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041314 response_headers["key1"] = std::string(30000, 'A');
1315 response_headers["key2"] = std::string(30000, 'A');
1316 response_headers["key3"] = std::string(30000, 'A');
1317 response_headers["key4"] = std::string(30000, 'A');
1318 response_headers["key5"] = std::string(30000, 'A');
1319 response_headers["key6"] = std::string(30000, 'A');
1320 response_headers["key7"] = std::string(30000, 'A');
1321 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451322 quic::QuicStreamId stream_id;
1323 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251324 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451325 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1326 std::vector<std::string> encoded = server_maker_.QpackEncodeHeaders(
1327 stream_id, std::move(response_headers), nullptr);
1328 for (const auto& e : encoded) {
1329 response_data += e;
1330 }
1331 } else {
1332 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1333 spdy::SpdyHeadersIR headers_frame(
1334 GetNthClientInitiatedBidirectionalStreamId(0),
1335 std::move(response_headers));
1336 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1337 spdy::SpdySerializedFrame spdy_frame =
1338 response_framer.SerializeFrame(headers_frame);
1339 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1340 }
rchbd089ab2017-05-26 23:05:041341
Fan Yangac867502019-01-28 21:10:231342 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041343 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451344 for (size_t offset = 0; offset < response_data.length();
1345 offset += chunk_size) {
1346 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431347 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451348 ASYNC, ConstructServerDataPacket(
1349 packet_number++, stream_id, false, false,
1350 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041351 }
1352
Victor Vasiliev076657c2019-03-12 02:46:431353 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041354 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331355 ASYNC, ConstructServerDataPacket(
1356 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171357 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041358 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431359 mock_quic_data.AddWrite(ASYNC,
Renjie Tangaadb84b2019-08-31 01:00:231360 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1361 mock_quic_data.AddWrite(
1362 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041363
1364 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1365
1366 CreateSession();
1367
1368 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421369 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1370 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041371}
1372
1373TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Nick Harper72ade192019-07-17 03:30:421374 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
1375 session_params_.quic_params.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041376 HostPortPair::FromString("mail.example.org:443"));
1377
Ryan Hamiltonabad59e2019-06-06 04:02:591378 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231379 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251380 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231381 mock_quic_data.AddWrite(SYNCHRONOUS,
1382 ConstructInitialSettingsPacket(packet_num++));
1383 }
rchbd089ab2017-05-26 23:05:041384 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231385 SYNCHRONOUS,
1386 ConstructClientRequestHeadersPacket(
1387 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1388 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451389
Ryan Hamilton0239aac2018-05-19 00:03:131390 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041391 response_headers["key1"] = std::string(30000, 'A');
1392 response_headers["key2"] = std::string(30000, 'A');
1393 response_headers["key3"] = std::string(30000, 'A');
1394 response_headers["key4"] = std::string(30000, 'A');
1395 response_headers["key5"] = std::string(30000, 'A');
1396 response_headers["key6"] = std::string(30000, 'A');
1397 response_headers["key7"] = std::string(30000, 'A');
1398 response_headers["key8"] = std::string(30000, 'A');
1399 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451400
1401 quic::QuicStreamId stream_id;
1402 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251403 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451404 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1405 std::vector<std::string> encoded = server_maker_.QpackEncodeHeaders(
1406 stream_id, std::move(response_headers), nullptr);
1407 for (const auto& e : encoded) {
1408 response_data += e;
1409 }
1410 } else {
1411 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1412 spdy::SpdyHeadersIR headers_frame(
1413 GetNthClientInitiatedBidirectionalStreamId(0),
1414 std::move(response_headers));
1415 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1416 spdy::SpdySerializedFrame spdy_frame =
1417 response_framer.SerializeFrame(headers_frame);
1418 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1419 }
rchbd089ab2017-05-26 23:05:041420
Fan Yangac867502019-01-28 21:10:231421 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041422 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451423 for (size_t offset = 0; offset < response_data.length();
1424 offset += chunk_size) {
1425 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431426 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451427 ASYNC, ConstructServerDataPacket(
1428 packet_number++, stream_id, false, false,
1429 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041430 }
1431
Victor Vasiliev076657c2019-03-12 02:46:431432 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411433
rchbd089ab2017-05-26 23:05:041434 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331435 ASYNC, ConstructServerDataPacket(
1436 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171437 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041438 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:231439 mock_quic_data.AddWrite(ASYNC,
1440 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431441 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331442 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231443 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:331444 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041445
1446 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1447
1448 CreateSession();
1449
1450 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1451 TestCompletionCallback callback;
1452 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1453 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1454 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1455}
1456
rcha2bd44b2016-07-02 00:42:551457TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Nick Harper72ade192019-07-17 03:30:421458 session_params_.quic_params.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551459
Ryan Hamilton9835e662018-08-02 05:36:271460 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551461
Ryan Hamiltonabad59e2019-06-06 04:02:591462 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231463 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251464 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231465 mock_quic_data.AddWrite(SYNCHRONOUS,
1466 ConstructInitialSettingsPacket(packet_num++));
1467 }
rch5cb522462017-04-25 20:18:361468 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231469 SYNCHRONOUS,
1470 ConstructClientRequestHeadersPacket(
1471 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1472 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431473 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331474 ASYNC, ConstructServerResponseHeadersPacket(
1475 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1476 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431477 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331478 mock_quic_data.AddRead(
1479 ASYNC, ConstructServerDataPacket(
1480 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171481 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231482 mock_quic_data.AddWrite(SYNCHRONOUS,
1483 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551484 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1485
1486 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1487
1488 CreateSession();
1489
1490 SendRequestAndExpectQuicResponse("hello!");
1491 EXPECT_TRUE(
1492 test_socket_performance_watcher_factory_.rtt_notification_received());
1493}
1494
[email protected]cf3e3cd62014-02-05 16:16:161495TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411496 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591497 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491498 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161499
Ryan Hamiltonabad59e2019-06-06 04:02:591500 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231501 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251502 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231503 mock_quic_data.AddWrite(SYNCHRONOUS,
1504 ConstructInitialSettingsPacket(packet_num++));
1505 }
rch5cb522462017-04-25 20:18:361506 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231507 SYNCHRONOUS,
1508 ConstructClientRequestHeadersPacket(
1509 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1510 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431511 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331512 ASYNC, ConstructServerResponseHeadersPacket(
1513 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1514 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431515 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331516 mock_quic_data.AddRead(
1517 ASYNC, ConstructServerDataPacket(
1518 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171519 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231520 mock_quic_data.AddWrite(SYNCHRONOUS,
1521 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501522 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591523 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161524
rcha5399e02015-04-21 19:32:041525 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161526
tbansal0f56a39a2016-04-07 22:03:381527 EXPECT_FALSE(
1528 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161529 // There is no need to set up an alternate protocol job, because
1530 // no attempt will be made to speak to the proxy over TCP.
1531
rch9ae5b3b2016-02-11 00:36:291532 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161533 CreateSession();
1534
bnc62a44f022015-04-02 15:59:411535 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381536 EXPECT_TRUE(
1537 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161538}
1539
bnc313ba9c2015-06-11 15:42:311540// Regression test for https://crbug.com/492458. Test that for an HTTP
1541// connection through a QUIC proxy, the certificate exhibited by the proxy is
1542// checked against the proxy hostname, not the origin hostname.
1543TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291544 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311545 const std::string proxy_host = "www.example.org";
1546
mmenke6ddfbea2017-05-31 21:48:411547 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591548 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491549 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311550
alyssar2adf3ac2016-05-03 17:12:581551 client_maker_.set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591552 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231553 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251554 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231555 mock_quic_data.AddWrite(SYNCHRONOUS,
1556 ConstructInitialSettingsPacket(packet_num++));
1557 }
rch5cb522462017-04-25 20:18:361558 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231559 SYNCHRONOUS,
1560 ConstructClientRequestHeadersPacket(
1561 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1562 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431563 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331564 ASYNC, ConstructServerResponseHeadersPacket(
1565 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1566 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431567 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331568 mock_quic_data.AddRead(
1569 ASYNC, ConstructServerDataPacket(
1570 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171571 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231572 mock_quic_data.AddWrite(SYNCHRONOUS,
1573 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501574 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591575 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311576 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1577
1578 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291579 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311580 ASSERT_TRUE(cert.get());
1581 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241582 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1583 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311584 ProofVerifyDetailsChromium verify_details;
1585 verify_details.cert_verify_result.verified_cert = cert;
1586 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561587 ProofVerifyDetailsChromium verify_details2;
1588 verify_details2.cert_verify_result.verified_cert = cert;
1589 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311590
1591 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091592 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321593 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271594 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311595 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1596}
1597
rchbe69cb902016-02-11 01:10:481598TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Nick Harper72ade192019-07-17 03:30:421599 session_params_.quic_params.allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481600 HostPortPair origin("www.example.org", 443);
1601 HostPortPair alternative("mail.example.org", 443);
1602
1603 base::FilePath certs_dir = GetTestCertsDirectory();
1604 scoped_refptr<X509Certificate> cert(
1605 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1606 ASSERT_TRUE(cert.get());
1607 // TODO(rch): the connection should be "to" the origin, so if the cert is
1608 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241609 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1610 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481611 ProofVerifyDetailsChromium verify_details;
1612 verify_details.cert_verify_result.verified_cert = cert;
1613 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1614
alyssar2adf3ac2016-05-03 17:12:581615 client_maker_.set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591616 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021617
Renjie Tangaadb84b2019-08-31 01:00:231618 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251619 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231620 mock_quic_data.AddWrite(SYNCHRONOUS,
1621 ConstructInitialSettingsPacket(packet_num++));
1622 }
rch5cb522462017-04-25 20:18:361623 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231624 SYNCHRONOUS,
1625 ConstructClientRequestHeadersPacket(
1626 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1627 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431628 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331629 ASYNC, ConstructServerResponseHeadersPacket(
1630 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1631 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431632 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331633 mock_quic_data.AddRead(
1634 ASYNC, ConstructServerDataPacket(
1635 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171636 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231637 mock_quic_data.AddWrite(SYNCHRONOUS,
1638 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481639 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1640 mock_quic_data.AddRead(ASYNC, 0);
1641 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1642
1643 request_.url = GURL("https://" + origin.host());
1644 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271645 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091646 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321647 CreateSession();
rchbe69cb902016-02-11 01:10:481648
1649 SendRequestAndExpectQuicResponse("hello!");
1650}
1651
zhongyief3f4ce52017-07-05 23:53:281652TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:561653 quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
zhongyief3f4ce52017-07-05 23:53:281654 // Add support for another QUIC version besides |version_|. Also find a
1655 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561656 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281657 if (version == version_)
1658 continue;
1659 if (supported_versions_.size() != 2) {
1660 supported_versions_.push_back(version);
1661 continue;
1662 }
1663 unsupported_version = version;
1664 break;
1665 }
Nick Harper23290b82019-05-02 00:02:561666 DCHECK_NE(unsupported_version, quic::UnsupportedQuicVersion());
zhongyief3f4ce52017-07-05 23:53:281667
1668 // Set up alternative service to use QUIC with a version that is not
1669 // supported.
1670 url::SchemeHostPort server(request_.url);
1671 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1672 443);
1673 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491674 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071675 server, NetworkIsolationKey(), alternative_service, expiration,
1676 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281677
1678 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491679 http_server_properties_->GetAlternativeServiceInfos(
1680 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281681 EXPECT_EQ(1u, alt_svc_info_vector.size());
1682 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1683 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1684 EXPECT_EQ(unsupported_version,
1685 alt_svc_info_vector[0].advertised_versions()[0]);
1686
1687 // First request should still be sent via TCP as the QUIC version advertised
1688 // in the stored AlternativeService is not supported by the client. However,
1689 // the response from the server will advertise new Alt-Svc with supported
1690 // versions.
Ryan Hamilton8380c652019-06-04 02:25:061691 quic::ParsedQuicVersionVector versions;
1692 for (quic::QuicTransportVersion version :
1693 quic::AllSupportedTransportVersions()) {
1694 versions.push_back(
1695 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
1696 }
zhongyief3f4ce52017-07-05 23:53:281697 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:061698 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyief3f4ce52017-07-05 23:53:281699 std::string altsvc_header =
1700 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1701 advertised_versions_list_str.c_str());
1702 MockRead http_reads[] = {
1703 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1704 MockRead("hello world"),
1705 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1706 MockRead(ASYNC, OK)};
1707
Ryan Sleevib8d7ea02018-05-07 20:01:011708 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281709 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081710 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281711 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1712
1713 // Second request should be sent via QUIC as a new list of verions supported
1714 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591715 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231716 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251717 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231718 mock_quic_data.AddWrite(SYNCHRONOUS,
1719 ConstructInitialSettingsPacket(packet_num++));
1720 }
zhongyief3f4ce52017-07-05 23:53:281721 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231722 SYNCHRONOUS,
1723 ConstructClientRequestHeadersPacket(
1724 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1725 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431726 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331727 ASYNC, ConstructServerResponseHeadersPacket(
1728 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1729 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431730 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331731 mock_quic_data.AddRead(
1732 ASYNC, ConstructServerDataPacket(
1733 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171734 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231735 mock_quic_data.AddWrite(SYNCHRONOUS,
1736 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281737 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1738 mock_quic_data.AddRead(ASYNC, 0); // EOF
1739
1740 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1741
1742 AddHangingNonAlternateProtocolSocketData();
1743
1744 CreateSession(supported_versions_);
1745
1746 SendRequestAndExpectHttpResponse("hello world");
1747 SendRequestAndExpectQuicResponse("hello!");
1748
1749 // Check alternative service list is updated with new versions.
1750 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491751 session_->http_server_properties()->GetAlternativeServiceInfos(
1752 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281753 EXPECT_EQ(1u, alt_svc_info_vector.size());
1754 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1755 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1756 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:561757 std::sort(
1758 supported_versions_.begin(), supported_versions_.end(),
1759 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
1760 return a.transport_version < b.transport_version;
1761 });
zhongyief3f4ce52017-07-05 23:53:281762 EXPECT_EQ(supported_versions_[0],
1763 alt_svc_info_vector[0].advertised_versions()[0]);
1764 EXPECT_EQ(supported_versions_[1],
1765 alt_svc_info_vector[0].advertised_versions()[1]);
1766}
1767
bncaccd4962017-04-06 21:00:261768// Regression test for https://crbug.com/546991.
1769// The server might not be able to serve a request on an alternative connection,
1770// and might send a 421 Misdirected Request response status to indicate this.
1771// HttpNetworkTransaction should reset the request and retry without using
1772// alternative services.
1773TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1774 // Set up alternative service to use QUIC.
1775 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1776 // that overrides |enable_alternative_services|.
1777 url::SchemeHostPort server(request_.url);
1778 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1779 443);
1780 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491781 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071782 server, NetworkIsolationKey(), alternative_service, expiration,
1783 supported_versions_);
bncaccd4962017-04-06 21:00:261784
davidbena4449722017-05-05 23:30:531785 // First try: The alternative job uses QUIC and reports an HTTP 421
1786 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1787 // paused at Connect(), so it will never exit the socket pool. This ensures
1788 // that the alternate job always wins the race and keeps whether the
1789 // |http_data| exits the socket pool before the main job is aborted
1790 // deterministic. The first main job gets aborted without the socket pool ever
1791 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591792 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231793 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251794 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231795 mock_quic_data.AddWrite(SYNCHRONOUS,
1796 ConstructInitialSettingsPacket(packet_num++));
1797 }
rch5cb522462017-04-25 20:18:361798 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231799 SYNCHRONOUS,
1800 ConstructClientRequestHeadersPacket(
1801 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1802 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331803 mock_quic_data.AddRead(
1804 ASYNC, ConstructServerResponseHeadersPacket(
1805 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021806 GetResponseHeaders("421")));
bncaccd4962017-04-06 21:00:261807 mock_quic_data.AddRead(ASYNC, OK);
1808 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1809
davidbena4449722017-05-05 23:30:531810 // Second try: The main job uses TCP, and there is no alternate job. Once the
1811 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1812 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261813 // Note that if there was an alternative QUIC Job created for the second try,
1814 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1815 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531816 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1817 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1818 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1819 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1820 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1821 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011822 reads, writes);
bncaccd4962017-04-06 21:00:261823 socket_factory_.AddSocketDataProvider(&http_data);
1824 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1825
bncaccd4962017-04-06 21:00:261826 CreateSession();
1827 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531828
1829 // Run until |mock_quic_data| has failed and |http_data| has paused.
1830 TestCompletionCallback callback;
1831 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1832 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1833 base::RunLoop().RunUntilIdle();
1834
1835 // |mock_quic_data| must have run to completion.
1836 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1837 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1838
1839 // Now that the QUIC data has been consumed, unblock |http_data|.
1840 http_data.socket()->OnConnectComplete(MockConnect());
1841
1842 // The retry logic must hide the 421 status. The transaction succeeds on
1843 // |http_data|.
1844 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261845 CheckWasHttpResponse(&trans);
1846 CheckResponsePort(&trans, 443);
1847 CheckResponseData(&trans, "hello!");
1848}
1849
[email protected]1e960032013-12-20 19:00:201850TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Nick Harper72ade192019-07-17 03:30:421851 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571852 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301853
Ryan Hamiltonabad59e2019-06-06 04:02:591854 MockQuicData mock_quic_data1(version_);
Victor Vasiliev7da08172019-10-14 06:04:251855 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231856 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401857 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Ryan Hamilton0d65a8c2019-06-07 00:46:021858 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591859 MockQuicData mock_quic_data2(version_);
Victor Vasiliev7da08172019-10-14 06:04:251860 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231861 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301862 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401863 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431864 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401865
1866 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1867 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301868
1869 CreateSession();
1870
tbansal0f56a39a2016-04-07 22:03:381871 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401872 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161873 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401874 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161875 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011876 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1877 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381878 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531879
1880 NetErrorDetails details;
1881 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521882 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401883 }
[email protected]cebe3282013-05-22 23:49:301884}
1885
tbansalc8a94ea2015-11-02 23:58:511886TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1887 // Attempt to "force" quic on 443, which will not be honored.
Nick Harper72ade192019-07-17 03:30:421888 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571889 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511890
1891 MockRead http_reads[] = {
1892 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1893 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1894 MockRead(ASYNC, OK)};
1895
Ryan Sleevib8d7ea02018-05-07 20:01:011896 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511897 socket_factory_.AddSocketDataProvider(&data);
1898 SSLSocketDataProvider ssl(ASYNC, OK);
1899 socket_factory_.AddSSLSocketDataProvider(&ssl);
1900
1901 CreateSession();
1902
1903 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381904 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511905}
1906
bncc958faa2015-07-31 18:14:521907TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521908 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561909 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1910 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521911 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1912 MockRead(ASYNC, OK)};
1913
Ryan Sleevib8d7ea02018-05-07 20:01:011914 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521915 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081916 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561917 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521918
Ryan Hamiltonabad59e2019-06-06 04:02:591919 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231920 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251921 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231922 mock_quic_data.AddWrite(SYNCHRONOUS,
1923 ConstructInitialSettingsPacket(packet_num++));
1924 }
rch5cb522462017-04-25 20:18:361925 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231926 SYNCHRONOUS,
1927 ConstructClientRequestHeadersPacket(
1928 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1929 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431930 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331931 ASYNC, ConstructServerResponseHeadersPacket(
1932 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1933 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431934 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331935 mock_quic_data.AddRead(
1936 ASYNC, ConstructServerDataPacket(
1937 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171938 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231939 mock_quic_data.AddWrite(SYNCHRONOUS,
1940 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:521941 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591942 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521943
1944 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1945
rtennetib8e80fb2016-05-16 00:12:091946 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321947 CreateSession();
bncc958faa2015-07-31 18:14:521948
1949 SendRequestAndExpectHttpResponse("hello world");
1950 SendRequestAndExpectQuicResponse("hello!");
1951}
1952
Ryan Hamilton64f21d52019-08-31 07:10:511953TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
1954 std::string alt_svc_header =
1955 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
1956 MockRead http_reads[] = {
1957 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
1958 MockRead("hello world"),
1959 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1960 MockRead(ASYNC, OK)};
1961
1962 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
1963 socket_factory_.AddSocketDataProvider(&http_data);
1964 AddCertificate(&ssl_data_);
1965 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1966
1967 MockQuicData mock_quic_data(version_);
1968 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251969 if (VersionUsesHttp3(version_.transport_version)) {
Ryan Hamilton64f21d52019-08-31 07:10:511970 mock_quic_data.AddWrite(SYNCHRONOUS,
1971 ConstructInitialSettingsPacket(packet_num++));
1972 }
1973 mock_quic_data.AddWrite(
1974 SYNCHRONOUS,
1975 ConstructClientRequestHeadersPacket(
1976 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1977 true, GetRequestHeaders("GET", "https", "/")));
1978 mock_quic_data.AddRead(
1979 ASYNC, ConstructServerResponseHeadersPacket(
1980 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1981 GetResponseHeaders("200 OK")));
1982 std::string header = ConstructDataHeader(6);
1983 mock_quic_data.AddRead(
1984 ASYNC, ConstructServerDataPacket(
1985 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1986 header + "hello!"));
1987 mock_quic_data.AddWrite(SYNCHRONOUS,
1988 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1989 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1990 mock_quic_data.AddRead(ASYNC, 0); // EOF
1991
1992 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1993
1994 AddHangingNonAlternateProtocolSocketData();
1995 CreateSession();
1996
1997 SendRequestAndExpectHttpResponse("hello world");
1998 SendRequestAndExpectQuicResponse("hello!");
1999}
2000
Matt Menke3233d8f22019-08-20 21:01:492001// Much like above, but makes sure NetworkIsolationKey is respected.
2002TEST_P(QuicNetworkTransactionTest,
2003 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
2004 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:052005 feature_list.InitWithFeatures(
2006 // enabled_features
2007 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2008 features::kPartitionConnectionsByNetworkIsolationKey},
2009 // disabled_features
2010 {});
Matt Menke3233d8f22019-08-20 21:01:492011 // Since HttpServerProperties caches the feature value, have to create a new
2012 // one.
2013 http_server_properties_ = std::make_unique<HttpServerProperties>();
2014
2015 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2016 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2017 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2018 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2019
2020 MockRead http_reads[] = {
2021 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
2022 MockRead("hello world"),
2023 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2024 MockRead(ASYNC, OK)};
2025
2026 AddCertificate(&ssl_data_);
2027
2028 // Request with empty NetworkIsolationKey.
2029 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2030 socket_factory_.AddSocketDataProvider(&http_data1);
2031 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2032
2033 // First request with kNetworkIsolationKey1.
2034 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2035 socket_factory_.AddSocketDataProvider(&http_data2);
2036 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2037
2038 // Request with kNetworkIsolationKey2.
2039 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2040 socket_factory_.AddSocketDataProvider(&http_data3);
2041 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2042
2043 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2044 // alternative service infrmation has been received in this context before.
2045 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232046 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252047 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232048 mock_quic_data.AddWrite(SYNCHRONOUS,
2049 ConstructInitialSettingsPacket(packet_num++));
2050 }
Matt Menke3233d8f22019-08-20 21:01:492051 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232052 SYNCHRONOUS,
2053 ConstructClientRequestHeadersPacket(
2054 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2055 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492056 mock_quic_data.AddRead(
2057 ASYNC, ConstructServerResponseHeadersPacket(
2058 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2059 GetResponseHeaders("200 OK")));
2060 std::string header = ConstructDataHeader(6);
2061 mock_quic_data.AddRead(
2062 ASYNC, ConstructServerDataPacket(
2063 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2064 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232065 mock_quic_data.AddWrite(SYNCHRONOUS,
2066 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke3233d8f22019-08-20 21:01:492067 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2068 mock_quic_data.AddRead(ASYNC, 0); // EOF
2069
2070 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2071
2072 AddHangingNonAlternateProtocolSocketData();
2073 CreateSession();
2074
2075 // This is first so that the test fails if alternative service info is
2076 // written with the right NetworkIsolationKey, but always queried with an
2077 // empty one.
2078 request_.network_isolation_key = NetworkIsolationKey();
2079 SendRequestAndExpectHttpResponse("hello world");
2080 request_.network_isolation_key = kNetworkIsolationKey1;
2081 SendRequestAndExpectHttpResponse("hello world");
2082 request_.network_isolation_key = kNetworkIsolationKey2;
2083 SendRequestAndExpectHttpResponse("hello world");
2084
2085 // Only use QUIC when using a NetworkIsolationKey which has been used when
2086 // alternative service information was received.
2087 request_.network_isolation_key = kNetworkIsolationKey1;
2088 SendRequestAndExpectQuicResponse("hello!");
2089}
2090
zhongyia00ca012017-07-06 23:36:392091TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
2092 // Both server advertises and client supports two QUIC versions.
2093 // Only |version_| is advertised and supported.
2094 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2095 // PacketMakers are using |version_|.
2096
2097 // Add support for another QUIC version besides |version_| on the client side.
2098 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:562099 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
2100 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392101 if (version == version_)
2102 continue;
2103 if (supported_versions_.size() != 2) {
2104 supported_versions_.push_back(version);
2105 continue;
2106 }
2107 advertised_version_2 = version;
2108 break;
2109 }
Nick Harper23290b82019-05-02 00:02:562110 DCHECK_NE(advertised_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392111
Nick Harper23290b82019-05-02 00:02:562112 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
2113 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2114 advertised_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392115
2116 MockRead http_reads[] = {
2117 MockRead("HTTP/1.1 200 OK\r\n"),
2118 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2119 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2120 MockRead(ASYNC, OK)};
2121
Ryan Sleevib8d7ea02018-05-07 20:01:012122 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392123 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082124 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392125 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2126
Ryan Hamiltonabad59e2019-06-06 04:02:592127 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232128 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252129 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232130 mock_quic_data.AddWrite(SYNCHRONOUS,
2131 ConstructInitialSettingsPacket(packet_num++));
2132 }
zhongyia00ca012017-07-06 23:36:392133 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232134 SYNCHRONOUS,
2135 ConstructClientRequestHeadersPacket(
2136 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2137 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432138 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332139 ASYNC, ConstructServerResponseHeadersPacket(
2140 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2141 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432142 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332143 mock_quic_data.AddRead(
2144 ASYNC, ConstructServerDataPacket(
2145 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172146 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232147 mock_quic_data.AddWrite(SYNCHRONOUS,
2148 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392149 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2150 mock_quic_data.AddRead(ASYNC, 0); // EOF
2151
2152 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2153
2154 AddHangingNonAlternateProtocolSocketData();
2155 CreateSession(supported_versions_);
2156
2157 SendRequestAndExpectHttpResponse("hello world");
2158 SendRequestAndExpectQuicResponse("hello!");
2159}
2160
2161TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
2162 // Client and server mutually support more than one QUIC_VERSION.
2163 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
2164 // which is verified as the PacketMakers are using |version_|.
2165
Nick Harper23290b82019-05-02 00:02:562166 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
2167 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392168 if (version == version_)
2169 continue;
2170 common_version_2 = version;
2171 break;
2172 }
Nick Harper23290b82019-05-02 00:02:562173 DCHECK_NE(common_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392174
2175 supported_versions_.push_back(
2176 common_version_2); // Supported but unpreferred.
2177
2178 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:562179 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2180 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392181
2182 MockRead http_reads[] = {
2183 MockRead("HTTP/1.1 200 OK\r\n"),
2184 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2185 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2186 MockRead(ASYNC, OK)};
2187
Ryan Sleevib8d7ea02018-05-07 20:01:012188 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392189 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082190 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392191 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2192
Ryan Hamiltonabad59e2019-06-06 04:02:592193 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232194 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252195 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232196 mock_quic_data.AddWrite(SYNCHRONOUS,
2197 ConstructInitialSettingsPacket(packet_num++));
2198 }
zhongyia00ca012017-07-06 23:36:392199 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232200 SYNCHRONOUS,
2201 ConstructClientRequestHeadersPacket(
2202 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2203 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432204 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332205 ASYNC, ConstructServerResponseHeadersPacket(
2206 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2207 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432208 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332209 mock_quic_data.AddRead(
2210 ASYNC, ConstructServerDataPacket(
2211 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172212 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232213 mock_quic_data.AddWrite(SYNCHRONOUS,
2214 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392215 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2216 mock_quic_data.AddRead(ASYNC, 0); // EOF
2217
2218 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2219
2220 AddHangingNonAlternateProtocolSocketData();
2221 CreateSession(supported_versions_);
2222
2223 SendRequestAndExpectHttpResponse("hello world");
2224 SendRequestAndExpectQuicResponse("hello!");
2225}
2226
rchf47265dc2016-03-21 21:33:122227TEST_P(QuicNetworkTransactionTest,
2228 UseAlternativeServiceWithProbabilityForQuic) {
2229 MockRead http_reads[] = {
2230 MockRead("HTTP/1.1 200 OK\r\n"),
2231 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
2232 MockRead("hello world"),
2233 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2234 MockRead(ASYNC, OK)};
2235
Ryan Sleevib8d7ea02018-05-07 20:01:012236 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:122237 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082238 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:122239 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2240
Ryan Hamiltonabad59e2019-06-06 04:02:592241 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232242 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252243 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232244 mock_quic_data.AddWrite(SYNCHRONOUS,
2245 ConstructInitialSettingsPacket(packet_num++));
2246 }
rch5cb522462017-04-25 20:18:362247 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232248 SYNCHRONOUS,
2249 ConstructClientRequestHeadersPacket(
2250 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2251 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432252 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332253 ASYNC, ConstructServerResponseHeadersPacket(
2254 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2255 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432256 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332257 mock_quic_data.AddRead(
2258 ASYNC, ConstructServerDataPacket(
2259 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172260 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232261 mock_quic_data.AddWrite(SYNCHRONOUS,
2262 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchf47265dc2016-03-21 21:33:122263 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2264 mock_quic_data.AddRead(ASYNC, 0); // EOF
2265
2266 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2267
rtennetib8e80fb2016-05-16 00:12:092268 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:122269 CreateSession();
2270
2271 SendRequestAndExpectHttpResponse("hello world");
2272 SendRequestAndExpectQuicResponse("hello!");
2273}
2274
zhongyi3d4a55e72016-04-22 20:36:462275TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2276 MockRead http_reads[] = {
2277 MockRead("HTTP/1.1 200 OK\r\n"),
2278 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2279 MockRead("hello world"),
2280 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2281 MockRead(ASYNC, OK)};
2282
Ryan Sleevib8d7ea02018-05-07 20:01:012283 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462284 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082285 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462286 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2287
2288 CreateSession();
bncb26024382016-06-29 02:39:452289 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462290 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452291 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462292 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402293 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462294 session_->http_server_properties();
2295 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2296 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2297 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462298 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492299 2u, http_server_properties
2300 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2301 .size());
bncb26024382016-06-29 02:39:452302 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492303 http_server_properties
2304 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2305 .empty());
zhongyi3d4a55e72016-04-22 20:36:462306}
2307
2308TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2309 MockRead http_reads[] = {
2310 MockRead("HTTP/1.1 200 OK\r\n"),
2311 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2312 MockRead("hello world"),
2313 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2314 MockRead(ASYNC, OK)};
2315
Ryan Sleevib8d7ea02018-05-07 20:01:012316 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082317 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462318
2319 socket_factory_.AddSocketDataProvider(&http_data);
2320 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2321 socket_factory_.AddSocketDataProvider(&http_data);
2322 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2323
2324 CreateSession();
2325
2326 // Send https request and set alternative services if response header
2327 // advertises alternative service for mail.example.org.
2328 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402329 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462330 session_->http_server_properties();
2331
2332 const url::SchemeHostPort https_server(request_.url);
2333 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342334 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492335 2u, http_server_properties
2336 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2337 .size());
zhongyi3d4a55e72016-04-22 20:36:462338
2339 // Send http request to the same origin but with diffrent scheme, should not
2340 // use QUIC.
2341 request_.url = GURL("http://mail.example.org:443");
2342 SendRequestAndExpectHttpResponse("hello world");
2343}
2344
zhongyie537a002017-06-27 16:48:212345TEST_P(QuicNetworkTransactionTest,
2346 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442347 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562348 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyi86838d52017-06-30 01:19:442349 if (version == version_)
2350 continue;
2351 supported_versions_.push_back(version);
2352 break;
2353 }
2354
Ryan Hamilton8380c652019-06-04 02:25:062355 quic::ParsedQuicVersionVector versions;
2356 for (quic::QuicTransportVersion version :
2357 quic::AllSupportedTransportVersions()) {
2358 versions.push_back(
2359 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
2360 }
zhongyie537a002017-06-27 16:48:212361 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:062362 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyie537a002017-06-27 16:48:212363 std::string altsvc_header =
2364 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2365 advertised_versions_list_str.c_str());
2366 MockRead http_reads[] = {
2367 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2368 MockRead("hello world"),
2369 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2370 MockRead(ASYNC, OK)};
2371
Ryan Sleevib8d7ea02018-05-07 20:01:012372 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212373 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082374 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212375 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2376
Ryan Hamiltonabad59e2019-06-06 04:02:592377 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232378 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252379 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232380 mock_quic_data.AddWrite(SYNCHRONOUS,
2381 ConstructInitialSettingsPacket(packet_num++));
2382 }
zhongyie537a002017-06-27 16:48:212383 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232384 SYNCHRONOUS,
2385 ConstructClientRequestHeadersPacket(
2386 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2387 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432388 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332389 ASYNC, ConstructServerResponseHeadersPacket(
2390 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2391 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432392 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332393 mock_quic_data.AddRead(
2394 ASYNC, ConstructServerDataPacket(
2395 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172396 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232397 mock_quic_data.AddWrite(SYNCHRONOUS,
2398 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212399 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2400 mock_quic_data.AddRead(ASYNC, 0); // EOF
2401
2402 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2403
2404 AddHangingNonAlternateProtocolSocketData();
2405
zhongyi86838d52017-06-30 01:19:442406 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212407
2408 SendRequestAndExpectHttpResponse("hello world");
2409 SendRequestAndExpectQuicResponse("hello!");
2410
2411 // Check alternative service is set with only mutually supported versions.
2412 const url::SchemeHostPort https_server(request_.url);
2413 const AlternativeServiceInfoVector alt_svc_info_vector =
2414 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492415 https_server, NetworkIsolationKey());
zhongyie537a002017-06-27 16:48:212416 EXPECT_EQ(1u, alt_svc_info_vector.size());
2417 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2418 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2419 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:562420 std::sort(
2421 supported_versions_.begin(), supported_versions_.end(),
2422 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
2423 return a.transport_version < b.transport_version;
2424 });
zhongyi86838d52017-06-30 01:19:442425 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212426 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442427 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212428 alt_svc_info_vector[0].advertised_versions()[1]);
2429}
2430
danzh3134c2562016-08-12 14:07:522431TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562432 std::string altsvc_header = base::StringPrintf(
2433 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_.transport_version);
bnc8be55ebb2015-10-30 14:12:072434 MockRead http_reads[] = {
2435 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2436 MockRead("hello world"),
2437 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2438 MockRead(ASYNC, OK)};
2439
Ryan Sleevib8d7ea02018-05-07 20:01:012440 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072441 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082442 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072443 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2444
Ryan Hamiltonabad59e2019-06-06 04:02:592445 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232446 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252447 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232448 mock_quic_data.AddWrite(SYNCHRONOUS,
2449 ConstructInitialSettingsPacket(packet_num++));
2450 }
rch5cb522462017-04-25 20:18:362451 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232452 SYNCHRONOUS,
2453 ConstructClientRequestHeadersPacket(
2454 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2455 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432456 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332457 ASYNC, ConstructServerResponseHeadersPacket(
2458 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2459 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432460 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332461 mock_quic_data.AddRead(
2462 ASYNC, ConstructServerDataPacket(
2463 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172464 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232465 mock_quic_data.AddWrite(SYNCHRONOUS,
2466 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072467 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592468 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072469
2470 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2471
rtennetib8e80fb2016-05-16 00:12:092472 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322473 CreateSession();
bnc8be55ebb2015-10-30 14:12:072474
2475 SendRequestAndExpectHttpResponse("hello world");
2476 SendRequestAndExpectQuicResponse("hello!");
2477}
2478
zhongyi6b5a3892016-03-12 04:46:202479TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562480 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjie Tangba21e032019-09-27 21:52:282481 // GoAway is not available under version 99
Frank Kastenholz6e4c5382018-06-21 23:00:092482 return;
2483 }
Ryan Hamiltonabad59e2019-06-06 04:02:592484 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232485 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252486 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232487 mock_quic_data.AddWrite(SYNCHRONOUS,
2488 ConstructInitialSettingsPacket(packet_num++));
2489 }
rch5cb522462017-04-25 20:18:362490 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232491 SYNCHRONOUS,
2492 ConstructClientRequestHeadersPacket(
2493 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2494 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332495 mock_quic_data.AddRead(
2496 ASYNC, ConstructServerResponseHeadersPacket(
2497 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2498 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202499 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522500 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432501 mock_quic_data.AddRead(SYNCHRONOUS,
2502 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522503 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432504 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232505 mock_quic_data.AddWrite(SYNCHRONOUS,
2506 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432507 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332508 mock_quic_data.AddRead(
2509 SYNCHRONOUS, ConstructServerDataPacket(
2510 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:172511 true, header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232512 mock_quic_data.AddWrite(
2513 SYNCHRONOUS,
2514 ConstructClientAckAndRstPacket(
2515 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2516 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202517 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2518 mock_quic_data.AddRead(ASYNC, 0); // EOF
2519
2520 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2521
2522 // The non-alternate protocol job needs to hang in order to guarantee that
2523 // the alternate-protocol job will "win".
2524 AddHangingNonAlternateProtocolSocketData();
2525
2526 // In order for a new QUIC session to be established via alternate-protocol
2527 // without racing an HTTP connection, we need the host resolution to happen
2528 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2529 // connection to the the server, in this test we require confirmation
2530 // before encrypting so the HTTP job will still start.
2531 host_resolver_.set_synchronous_mode(true);
2532 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2533 "");
zhongyi6b5a3892016-03-12 04:46:202534
2535 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432536 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2537 false);
Ryan Hamilton9835e662018-08-02 05:36:272538 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202539
bnc691fda62016-08-12 00:43:162540 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202541 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362542 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012543 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202544
2545 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522546 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012547 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202548
2549 // Check whether this transaction is correctly marked as received a go-away
2550 // because of migrating port.
2551 NetErrorDetails details;
2552 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162553 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202554 EXPECT_TRUE(details.quic_port_migration_detected);
2555}
2556
Zhongyi Shia6b68d112018-09-24 07:49:032557// This test verifies that a new QUIC connection will be attempted on the
2558// alternate network if the original QUIC connection fails with idle timeout
2559// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2560// alternate network as well, QUIC is marked as broken and the brokenness will
2561// not expire when default network changes.
2562TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2563 SetUpTestForRetryConnectionOnAlternateNetwork();
2564
Michael Warres167db3e2019-03-01 21:38:032565 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032566
2567 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592568 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032569 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2570 int packet_num = 1;
2571 quic_data.AddWrite(SYNCHRONOUS,
2572 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2573 // Retranmit the handshake messages.
2574 quic_data.AddWrite(SYNCHRONOUS,
2575 client_maker_.MakeDummyCHLOPacket(packet_num++));
2576 quic_data.AddWrite(SYNCHRONOUS,
2577 client_maker_.MakeDummyCHLOPacket(packet_num++));
2578 quic_data.AddWrite(SYNCHRONOUS,
2579 client_maker_.MakeDummyCHLOPacket(packet_num++));
2580 quic_data.AddWrite(SYNCHRONOUS,
2581 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032582 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2583 quic_data.AddWrite(SYNCHRONOUS,
2584 client_maker_.MakeConnectionClosePacket(
2585 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2586 "No recent network activity."));
2587 quic_data.AddSocketDataToFactory(&socket_factory_);
2588
2589 // Add successful TCP data so that TCP job will succeed.
2590 MockWrite http_writes[] = {
2591 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2592 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2593 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2594
2595 MockRead http_reads[] = {
2596 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2597 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2598 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2599 SequencedSocketData http_data(http_reads, http_writes);
2600 socket_factory_.AddSocketDataProvider(&http_data);
2601 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2602
2603 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592604 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032605 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2606 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2607 quic_data2.AddSocketDataToFactory(&socket_factory_);
2608
2609 // Resolve the host resolution synchronously.
2610 host_resolver_.set_synchronous_mode(true);
2611 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2612 "");
Zhongyi Shia6b68d112018-09-24 07:49:032613
2614 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432615 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2616 false);
Zhongyi Shia6b68d112018-09-24 07:49:032617 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032618 QuicStreamFactoryPeer::SetAlarmFactory(
2619 session_->quic_stream_factory(),
2620 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2621 &clock_));
2622 // Add alternate protocol mapping to race QUIC and TCP.
2623 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2624 // peer.
2625 AddQuicAlternateProtocolMapping(
2626 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2627
2628 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2629 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362630 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2632
2633 // Pump the message loop to get the request started.
2634 // Request will be served with TCP job.
2635 base::RunLoop().RunUntilIdle();
2636 EXPECT_THAT(callback.WaitForResult(), IsOk());
2637 CheckResponseData(&trans, "TCP succeeds");
2638
Zhongyi Shia6b68d112018-09-24 07:49:032639 // Fast forward to idle timeout the original connection. A new connection will
2640 // be kicked off on the alternate network.
2641 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2642 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2643 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2644
2645 // Run the message loop to execute posted tasks, which will report job status.
2646 base::RunLoop().RunUntilIdle();
2647
2648 // Verify that QUIC is marked as broken.
2649 ExpectBrokenAlternateProtocolMapping();
2650
2651 // Deliver a message to notify the new network becomes default, the brokenness
2652 // will not expire as QUIC is broken on both networks.
2653 scoped_mock_change_notifier_->mock_network_change_notifier()
2654 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2655 ExpectBrokenAlternateProtocolMapping();
2656
2657 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2658 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2659}
2660
2661// This test verifies that a new QUIC connection will be attempted on the
2662// alternate network if the original QUIC connection fails with idle timeout
2663// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2664// alternate network, QUIC is marked as broken. The brokenness will expire when
2665// the default network changes.
2666TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2667 SetUpTestForRetryConnectionOnAlternateNetwork();
2668
Michael Warres167db3e2019-03-01 21:38:032669 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032670
2671 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592672 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032673 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2674 int packet_num = 1;
2675 quic_data.AddWrite(SYNCHRONOUS,
2676 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2677 // Retranmit the handshake messages.
2678 quic_data.AddWrite(SYNCHRONOUS,
2679 client_maker_.MakeDummyCHLOPacket(packet_num++));
2680 quic_data.AddWrite(SYNCHRONOUS,
2681 client_maker_.MakeDummyCHLOPacket(packet_num++));
2682 quic_data.AddWrite(SYNCHRONOUS,
2683 client_maker_.MakeDummyCHLOPacket(packet_num++));
2684 quic_data.AddWrite(SYNCHRONOUS,
2685 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032686 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2687 quic_data.AddWrite(SYNCHRONOUS,
2688 client_maker_.MakeConnectionClosePacket(
2689 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2690 "No recent network activity."));
2691 quic_data.AddSocketDataToFactory(&socket_factory_);
2692
2693 // Add successful TCP data so that TCP job will succeed.
2694 MockWrite http_writes[] = {
2695 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2696 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2697 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2698
2699 MockRead http_reads[] = {
2700 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2701 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2702 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2703 SequencedSocketData http_data(http_reads, http_writes);
2704 socket_factory_.AddSocketDataProvider(&http_data);
2705 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2706
2707 // Quic connection will be retried on the alternate network after the initial
2708 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592709 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032710 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2711 quic_data2.AddWrite(SYNCHRONOUS,
2712 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2713
2714 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252715 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232716 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032717 quic_data2.AddSocketDataToFactory(&socket_factory_);
2718
2719 // Resolve the host resolution synchronously.
2720 host_resolver_.set_synchronous_mode(true);
2721 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2722 "");
Zhongyi Shia6b68d112018-09-24 07:49:032723
2724 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432725 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2726 false);
Zhongyi Shia6b68d112018-09-24 07:49:032727 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032728 QuicStreamFactoryPeer::SetAlarmFactory(
2729 session_->quic_stream_factory(),
2730 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2731 &clock_));
2732 // Add alternate protocol mapping to race QUIC and TCP.
2733 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2734 // peer.
2735 AddQuicAlternateProtocolMapping(
2736 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2737
2738 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2739 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362740 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032741 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2742
2743 // Pump the message loop to get the request started.
2744 // Request will be served with TCP job.
2745 base::RunLoop().RunUntilIdle();
2746 EXPECT_THAT(callback.WaitForResult(), IsOk());
2747 CheckResponseData(&trans, "TCP succeeds");
2748
Zhongyi Shia6b68d112018-09-24 07:49:032749 // Fast forward to idle timeout the original connection. A new connection will
2750 // be kicked off on the alternate network.
2751 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2752 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2753 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2754
2755 // The second connection hasn't finish handshake, verify that QUIC is not
2756 // marked as broken.
2757 ExpectQuicAlternateProtocolMapping();
2758 // Explicitly confirm the handshake on the second connection.
2759 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2760 quic::QuicSession::HANDSHAKE_CONFIRMED);
2761 // Run message loop to execute posted tasks, which will notify JoController
2762 // about the orphaned job status.
2763 base::RunLoop().RunUntilIdle();
2764
2765 // Verify that QUIC is marked as broken.
2766 ExpectBrokenAlternateProtocolMapping();
2767
2768 // Deliver a message to notify the new network becomes default, the previous
2769 // brokenness will be clear as the brokenness is bond with old default
2770 // network.
2771 scoped_mock_change_notifier_->mock_network_change_notifier()
2772 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2773 ExpectQuicAlternateProtocolMapping();
2774
2775 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2776 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2777}
2778
Matt Menkeb32ba5122019-09-10 19:17:052779// Much like above test, but verifies NetworkIsolationKeys are respected.
2780TEST_P(QuicNetworkTransactionTest,
2781 RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
2782 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2783 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2784 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2785 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2786
2787 base::test::ScopedFeatureList feature_list;
2788 feature_list.InitWithFeatures(
2789 // enabled_features
2790 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2791 // Need to partition connections by NetworkIsolationKey for
2792 // QuicSessionAliasKey to include NetworkIsolationKeys.
2793 features::kPartitionConnectionsByNetworkIsolationKey},
2794 // disabled_features
2795 {});
2796 // Since HttpServerProperties caches the feature value, have to create a new
2797 // one.
2798 http_server_properties_ = std::make_unique<HttpServerProperties>();
2799
2800 SetUpTestForRetryConnectionOnAlternateNetwork();
2801
2802 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
2803
2804 // The request will initially go out over QUIC.
2805 MockQuicData quic_data(version_);
2806 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2807 int packet_num = 1;
2808 quic_data.AddWrite(SYNCHRONOUS,
2809 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2810 // Retranmit the handshake messages.
2811 quic_data.AddWrite(SYNCHRONOUS,
2812 client_maker_.MakeDummyCHLOPacket(packet_num++));
2813 quic_data.AddWrite(SYNCHRONOUS,
2814 client_maker_.MakeDummyCHLOPacket(packet_num++));
2815 quic_data.AddWrite(SYNCHRONOUS,
2816 client_maker_.MakeDummyCHLOPacket(packet_num++));
2817 quic_data.AddWrite(SYNCHRONOUS,
2818 client_maker_.MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052819 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2820 quic_data.AddWrite(SYNCHRONOUS,
2821 client_maker_.MakeConnectionClosePacket(
2822 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2823 "No recent network activity."));
2824 quic_data.AddSocketDataToFactory(&socket_factory_);
2825
2826 // Add successful TCP data so that TCP job will succeed.
2827 MockWrite http_writes[] = {
2828 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2829 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2830 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2831
2832 MockRead http_reads[] = {
2833 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2834 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2835 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2836 SequencedSocketData http_data(http_reads, http_writes);
2837 socket_factory_.AddSocketDataProvider(&http_data);
2838 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2839
2840 // Quic connection will be retried on the alternate network after the initial
2841 // one fails on the default network.
2842 MockQuicData quic_data2(version_);
2843 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2844 quic_data2.AddWrite(SYNCHRONOUS,
2845 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2846
2847 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252848 if (VersionUsesHttp3(version_.transport_version))
Matt Menkeb32ba5122019-09-10 19:17:052849 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
2850 quic_data2.AddSocketDataToFactory(&socket_factory_);
2851
2852 // Resolve the host resolution synchronously.
2853 host_resolver_.set_synchronous_mode(true);
2854 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2855 "");
2856
2857 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432858 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2859 false);
Matt Menkeb32ba5122019-09-10 19:17:052860 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2861 QuicStreamFactoryPeer::SetAlarmFactory(
2862 session_->quic_stream_factory(),
2863 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2864 &clock_));
2865 // Add alternate protocol mapping to race QUIC and TCP.
2866 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2867 // peer.
2868 AddQuicAlternateProtocolMapping(
2869 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
2870 AddQuicAlternateProtocolMapping(
2871 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
2872
2873 request_.network_isolation_key = kNetworkIsolationKey1;
2874 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2875 TestCompletionCallback callback;
2876 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2877 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2878
2879 // Pump the message loop to get the request started.
2880 // Request will be served with TCP job.
2881 base::RunLoop().RunUntilIdle();
2882 EXPECT_THAT(callback.WaitForResult(), IsOk());
2883 CheckResponseData(&trans, "TCP succeeds");
2884
2885 // Fast forward to idle timeout the original connection. A new connection will
2886 // be kicked off on the alternate network.
2887 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2888 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2889 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2890
2891 // The second connection hasn't finish handshake, verify that QUIC is not
2892 // marked as broken.
2893 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2894 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2895 // Explicitly confirm the handshake on the second connection.
2896 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2897 quic::QuicSession::HANDSHAKE_CONFIRMED);
2898 // Run message loop to execute posted tasks, which will notify JoController
2899 // about the orphaned job status.
2900 base::RunLoop().RunUntilIdle();
2901
2902 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
2903 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
2904 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2905
2906 // Deliver a message to notify the new network becomes default, the previous
2907 // brokenness will be clear as the brokenness is bond with old default
2908 // network.
2909 scoped_mock_change_notifier_->mock_network_change_notifier()
2910 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2911 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2912 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2913
2914 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2915 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2916}
2917
Zhongyi Shia6b68d112018-09-24 07:49:032918// This test verifies that a new QUIC connection will be attempted on the
2919// alternate network if the original QUIC connection fails with idle timeout
2920// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2921// alternative network succeeds, QUIC is not marked as broken.
2922TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2923 SetUpTestForRetryConnectionOnAlternateNetwork();
2924
Michael Warres167db3e2019-03-01 21:38:032925 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032926
2927 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592928 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032929 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2930 int packet_num = 1;
2931 quic_data.AddWrite(SYNCHRONOUS,
2932 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2933 // Retranmit the handshake messages.
2934 quic_data.AddWrite(SYNCHRONOUS,
2935 client_maker_.MakeDummyCHLOPacket(packet_num++));
2936 quic_data.AddWrite(SYNCHRONOUS,
2937 client_maker_.MakeDummyCHLOPacket(packet_num++));
2938 quic_data.AddWrite(SYNCHRONOUS,
2939 client_maker_.MakeDummyCHLOPacket(packet_num++));
2940 quic_data.AddWrite(SYNCHRONOUS,
2941 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032942 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2943 quic_data.AddWrite(SYNCHRONOUS,
2944 client_maker_.MakeConnectionClosePacket(
2945 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2946 "No recent network activity."));
2947 quic_data.AddSocketDataToFactory(&socket_factory_);
2948
2949 // Add hanging TCP data so that TCP job will never succeeded.
2950 AddHangingNonAlternateProtocolSocketData();
2951
2952 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:592953 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:232954 packet_num = 1;
Zhongyi Shia6b68d112018-09-24 07:49:032955 quic_data2.AddWrite(SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:232956 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:032957
Victor Vasiliev076657c2019-03-12 02:46:432958 const std::string body = "hello!";
2959 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:412960
Zhongyi Shia6b68d112018-09-24 07:49:032961 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252962 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232963 quic_data2.AddWrite(SYNCHRONOUS,
2964 ConstructInitialSettingsPacket(packet_num++));
2965 }
Zhongyi Shia6b68d112018-09-24 07:49:032966 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232967 SYNCHRONOUS,
2968 ConstructClientRequestHeadersPacket(
2969 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2970 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:032971 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332972 ASYNC, ConstructServerResponseHeadersPacket(
2973 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2974 GetResponseHeaders("200 OK")));
2975 quic_data2.AddRead(
2976 ASYNC, ConstructServerDataPacket(
2977 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172978 header + body));
Renjie Tangaadb84b2019-08-31 01:00:232979 quic_data2.AddWrite(SYNCHRONOUS,
2980 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia6b68d112018-09-24 07:49:032981 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2982 quic_data2.AddSocketDataToFactory(&socket_factory_);
2983
2984 // Resolve the host resolution synchronously.
2985 host_resolver_.set_synchronous_mode(true);
2986 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2987 "");
Zhongyi Shia6b68d112018-09-24 07:49:032988
2989 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432990 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2991 false);
Zhongyi Shia6b68d112018-09-24 07:49:032992 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032993 QuicStreamFactoryPeer::SetAlarmFactory(
2994 session_->quic_stream_factory(),
2995 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2996 &clock_));
2997 // Add alternate protocol mapping to race QUIC and TCP.
2998 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2999 // peer.
3000 AddQuicAlternateProtocolMapping(
3001 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3002
3003 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3004 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363005 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:033006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3007
3008 // Pump the message loop to get the request started.
3009 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:033010
3011 // Fast forward to idle timeout the original connection. A new connection will
3012 // be kicked off on the alternate network.
3013 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3014 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3015 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3016
3017 // Verify that QUIC is not marked as broken.
3018 ExpectQuicAlternateProtocolMapping();
3019 // Explicitly confirm the handshake on the second connection.
3020 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
3021 quic::QuicSession::HANDSHAKE_CONFIRMED);
3022
3023 // Read the response.
3024 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:413025 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:033026 // Verify that QUIC is not marked as broken.
3027 ExpectQuicAlternateProtocolMapping();
3028
3029 // Deliver a message to notify the new network becomes default.
3030 scoped_mock_change_notifier_->mock_network_change_notifier()
3031 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3032 ExpectQuicAlternateProtocolMapping();
3033 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3034 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3035}
3036
rch9ecde09b2017-04-08 00:18:233037// Verify that if a QUIC connection times out, the QuicHttpStream will
3038// return QUIC_PROTOCOL_ERROR.
3039TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:423040 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Sleevi2e8255b2019-07-17 21:02:213041 session_params_.quic_params.idle_connection_timeout =
3042 base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:233043
3044 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593045 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133046 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233047 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3048
Ryan Hamiltone940bd12019-06-30 02:46:453049 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033050 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493051 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253052 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493053 quic_data.AddWrite(SYNCHRONOUS,
3054 ConstructInitialSettingsPacket(packet_num++));
3055 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023056 quic_data.AddWrite(
3057 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453058 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493059 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3060 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453061
3062 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233063
Victor Vasiliev7da08172019-10-14 06:04:253064 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493065 // TLP 1
3066 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3067 1, packet_num++, true));
3068 // TLP 2
3069 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3070 2, packet_num++, true));
3071 // RTO 1
3072 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3073 1, packet_num++, true));
3074 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3075 2, packet_num++, true));
3076 // RTO 2
3077 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3078 1, packet_num++, true));
3079 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3080 2, packet_num++, true));
3081 // RTO 3
3082 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3083 1, packet_num++, true));
3084 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3085 2, packet_num++, true));
Ryan Hamilton3cc2c152019-07-09 19:36:013086
Nick Harper057264a82019-09-12 23:33:493087 quic_data.AddWrite(SYNCHRONOUS,
3088 client_maker_.MakeConnectionClosePacket(
3089 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3090 "No recent network activity."));
3091 } else {
3092 // Settings were sent in the request packet so there is only 1 packet to
3093 // retransmit.
3094 // TLP 1
3095 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3096 1, packet_num++, true));
3097 // TLP 2
3098 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3099 1, packet_num++, true));
3100 // RTO 1
3101 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3102 1, packet_num++, true));
3103 // RTO 2
3104 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3105 1, packet_num++, true));
3106 // RTO 3
3107 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3108 1, packet_num++, true));
3109
3110 quic_data.AddWrite(SYNCHRONOUS,
3111 client_maker_.MakeConnectionClosePacket(
3112 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3113 "No recent network activity."));
3114 }
Fan Yang928f1632017-12-14 18:55:223115
rch9ecde09b2017-04-08 00:18:233116 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3117 quic_data.AddRead(ASYNC, OK);
3118 quic_data.AddSocketDataToFactory(&socket_factory_);
3119
3120 // In order for a new QUIC session to be established via alternate-protocol
3121 // without racing an HTTP connection, we need the host resolution to happen
3122 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3123 // connection to the the server, in this test we require confirmation
3124 // before encrypting so the HTTP job will still start.
3125 host_resolver_.set_synchronous_mode(true);
3126 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3127 "");
rch9ecde09b2017-04-08 00:18:233128
3129 CreateSession();
3130 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233131 QuicStreamFactoryPeer::SetAlarmFactory(
3132 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193133 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553134 &clock_));
rch9ecde09b2017-04-08 00:18:233135
Ryan Hamilton9835e662018-08-02 05:36:273136 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233137
3138 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3139 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363140 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233141 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3142
3143 // Pump the message loop to get the request started.
3144 base::RunLoop().RunUntilIdle();
3145 // Explicitly confirm the handshake.
3146 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523147 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233148
3149 // Run the QUIC session to completion.
3150 quic_task_runner_->RunUntilIdle();
3151
3152 ExpectQuicAlternateProtocolMapping();
3153 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3154 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3155}
3156
3157// Verify that if a QUIC connection RTOs, the QuicHttpStream will
3158// return QUIC_PROTOCOL_ERROR.
3159TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:423160 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
3161 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233162
3163 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593164 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133165 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233166 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3167
Ryan Hamiltone940bd12019-06-30 02:46:453168 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033169 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493170 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:253171 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493172 quic_data.AddWrite(
3173 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3174 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023175 quic_data.AddWrite(
3176 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453177 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493178 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3179 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453180
3181 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253182 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493183 // TLP 1
3184 quic_data.AddWrite(SYNCHRONOUS,
3185 client_maker_.MakeRetransmissionPacket(1, 3, true));
3186 // TLP 2
3187 quic_data.AddWrite(SYNCHRONOUS,
3188 client_maker_.MakeRetransmissionPacket(2, 4, true));
3189 // RTO 1
3190 quic_data.AddWrite(SYNCHRONOUS,
3191 client_maker_.MakeRetransmissionPacket(1, 5, true));
3192 quic_data.AddWrite(SYNCHRONOUS,
3193 client_maker_.MakeRetransmissionPacket(2, 6, true));
3194 // RTO 2
3195 quic_data.AddWrite(SYNCHRONOUS,
3196 client_maker_.MakeRetransmissionPacket(1, 7, true));
3197 quic_data.AddWrite(SYNCHRONOUS,
3198 client_maker_.MakeRetransmissionPacket(2, 8, true));
3199 // RTO 3
3200 quic_data.AddWrite(SYNCHRONOUS,
3201 client_maker_.MakeRetransmissionPacket(1, 9, true));
3202 quic_data.AddWrite(SYNCHRONOUS,
3203 client_maker_.MakeRetransmissionPacket(2, 10, true));
3204 // RTO 4
3205 quic_data.AddWrite(SYNCHRONOUS,
3206 client_maker_.MakeRetransmissionPacket(1, 11, true));
3207 quic_data.AddWrite(SYNCHRONOUS,
3208 client_maker_.MakeRetransmissionPacket(2, 12, true));
3209 // RTO 5
3210 quic_data.AddWrite(SYNCHRONOUS,
3211 client_maker_.MakeConnectionClosePacket(
3212 13, true, quic::QUIC_TOO_MANY_RTOS,
3213 "5 consecutive retransmission timeouts"));
3214 } else {
3215 // TLP 1
3216 quic_data.AddWrite(SYNCHRONOUS,
3217 client_maker_.MakeRetransmissionPacket(1, 2, true));
3218 // TLP 2
3219 quic_data.AddWrite(SYNCHRONOUS,
3220 client_maker_.MakeRetransmissionPacket(1, 3, true));
3221 // RTO 1
3222 quic_data.AddWrite(SYNCHRONOUS,
3223 client_maker_.MakeRetransmissionPacket(1, 4, true));
3224 // RTO 2
3225 quic_data.AddWrite(SYNCHRONOUS,
3226 client_maker_.MakeRetransmissionPacket(1, 5, true));
3227 // RTO 3
3228 quic_data.AddWrite(SYNCHRONOUS,
3229 client_maker_.MakeRetransmissionPacket(1, 6, true));
3230 // RTO 4
3231 quic_data.AddWrite(SYNCHRONOUS,
3232 client_maker_.MakeRetransmissionPacket(1, 7, true));
3233 // RTO 5
3234 quic_data.AddWrite(SYNCHRONOUS,
3235 client_maker_.MakeConnectionClosePacket(
3236 8, true, quic::QUIC_TOO_MANY_RTOS,
3237 "5 consecutive retransmission timeouts"));
3238 }
rch9ecde09b2017-04-08 00:18:233239
3240 quic_data.AddRead(ASYNC, OK);
3241 quic_data.AddSocketDataToFactory(&socket_factory_);
3242
3243 // In order for a new QUIC session to be established via alternate-protocol
3244 // without racing an HTTP connection, we need the host resolution to happen
3245 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3246 // connection to the the server, in this test we require confirmation
3247 // before encrypting so the HTTP job will still start.
3248 host_resolver_.set_synchronous_mode(true);
3249 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3250 "");
rch9ecde09b2017-04-08 00:18:233251
3252 CreateSession();
3253 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233254 QuicStreamFactoryPeer::SetAlarmFactory(
3255 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193256 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553257 &clock_));
rch9ecde09b2017-04-08 00:18:233258
Ryan Hamilton9835e662018-08-02 05:36:273259 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233260
3261 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3262 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363263 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233264 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3265
3266 // Pump the message loop to get the request started.
3267 base::RunLoop().RunUntilIdle();
3268 // Explicitly confirm the handshake.
3269 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523270 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233271
3272 // Run the QUIC session to completion.
3273 quic_task_runner_->RunUntilIdle();
3274
3275 ExpectQuicAlternateProtocolMapping();
3276 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3277 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3278}
3279
3280// Verify that if a QUIC connection RTOs, while there are no active streams
3281// QUIC will not be marked as broken.
3282TEST_P(QuicNetworkTransactionTest,
3283 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Nick Harper72ade192019-07-17 03:30:423284 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233285
3286 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593287 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133288 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233289 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3290
Ryan Hamiltone940bd12019-06-30 02:46:453291 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033292 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493293 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:253294 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493295 quic_data.AddWrite(
3296 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3297 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023298 quic_data.AddWrite(
3299 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453300 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493301 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3302 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453303
3304 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233305
Victor Vasiliev7da08172019-10-14 06:04:253306 if (!VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493307 quic_data.AddWrite(SYNCHRONOUS,
3308 client_maker_.MakeRstPacket(
3309 packet_number++, true,
3310 GetNthClientInitiatedBidirectionalStreamId(0),
3311 quic::QUIC_STREAM_CANCELLED));
3312 // TLP 1
3313 quic_data.AddWrite(SYNCHRONOUS,
3314 client_maker_.MakeRetransmissionPacket(1, 3, true));
3315 // TLP 2
3316 quic_data.AddWrite(SYNCHRONOUS,
3317 client_maker_.MakeRetransmissionPacket(2, 4, true));
3318 // RTO 1
3319 quic_data.AddWrite(SYNCHRONOUS,
3320 client_maker_.MakeRetransmissionPacket(1, 5, true));
3321 quic_data.AddWrite(SYNCHRONOUS,
3322 client_maker_.MakeRetransmissionPacket(2, 6, true));
3323 // RTO 2
3324 quic_data.AddWrite(SYNCHRONOUS,
3325 client_maker_.MakeRetransmissionPacket(1, 7, true));
3326 quic_data.AddWrite(SYNCHRONOUS,
3327 client_maker_.MakeRetransmissionPacket(2, 8, true));
3328 // RTO 3
3329 quic_data.AddWrite(SYNCHRONOUS,
3330 client_maker_.MakeRetransmissionPacket(1, 9, true));
3331 quic_data.AddWrite(SYNCHRONOUS,
3332 client_maker_.MakeRetransmissionPacket(2, 10, true));
3333 // RTO 4
3334 quic_data.AddWrite(SYNCHRONOUS,
3335 client_maker_.MakeRetransmissionPacket(1, 11, true));
3336 quic_data.AddWrite(SYNCHRONOUS,
3337 client_maker_.MakeRetransmissionPacket(2, 12, true));
3338 // RTO 5
3339 quic_data.AddWrite(SYNCHRONOUS,
3340 client_maker_.MakeConnectionClosePacket(
3341 13, true, quic::QUIC_TOO_MANY_RTOS,
3342 "5 consecutive retransmission timeouts"));
Renjie Tang33f43ce2019-09-23 22:11:423343 } else if (FLAGS_quic_allow_http3_priority) {
Nick Harper057264a82019-09-12 23:33:493344 quic_data.AddWrite(
3345 SYNCHRONOUS, client_maker_.MakeRstPacket(
3346 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb01f886f2019-07-10 02:25:553347 quic::QUIC_STREAM_CANCELLED));
Nick Harper057264a82019-09-12 23:33:493348 client_maker_.RemoveSavedStreamFrames(
3349 GetNthClientInitiatedBidirectionalStreamId(0));
3350 // TLP 1
3351 quic_data.AddWrite(SYNCHRONOUS,
3352 client_maker_.MakeRetransmissionPacket(1, 4, true));
3353 // TLP 2
3354 quic_data.AddWrite(SYNCHRONOUS,
3355 client_maker_.MakeRetransmissionPacket(2, 5, true));
3356 // RTO 1
3357 quic_data.AddWrite(SYNCHRONOUS,
3358 client_maker_.MakeRetransmissionPacket(3, 6, true));
3359 quic_data.AddWrite(SYNCHRONOUS,
3360 client_maker_.MakeRetransmissionPacket(1, 7, true));
3361 // RTO 2
3362 quic_data.AddWrite(SYNCHRONOUS,
3363 client_maker_.MakeRetransmissionPacket(2, 8, true));
3364 quic_data.AddWrite(SYNCHRONOUS,
3365 client_maker_.MakeRetransmissionPacket(3, 9, true));
3366 // RTO 3
3367 quic_data.AddWrite(SYNCHRONOUS,
3368 client_maker_.MakeRetransmissionPacket(1, 10, true));
3369 quic_data.AddWrite(SYNCHRONOUS,
3370 client_maker_.MakeRetransmissionPacket(2, 11, true));
3371 // RTO 4
3372 quic_data.AddWrite(SYNCHRONOUS,
3373 client_maker_.MakeRetransmissionPacket(3, 12, true));
3374 quic_data.AddWrite(SYNCHRONOUS,
3375 client_maker_.MakeRetransmissionPacket(1, 13, true));
3376 // RTO 5
3377 quic_data.AddWrite(SYNCHRONOUS,
3378 client_maker_.MakeConnectionClosePacket(
3379 14, true, quic::QUIC_TOO_MANY_RTOS,
3380 "5 consecutive retransmission timeouts"));
Renjie Tang33f43ce2019-09-23 22:11:423381 } else {
3382 quic_data.AddWrite(
3383 SYNCHRONOUS, client_maker_.MakeRstPacket(
3384 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3385 quic::QUIC_STREAM_CANCELLED));
3386 client_maker_.RemoveSavedStreamFrames(
3387 GetNthClientInitiatedBidirectionalStreamId(0));
3388 // When PRIORITY is disabled, packet 2 only contains request headers. And
3389 // since the request stream is reset, packet 2 will not be retransmitted.
3390 // TLP 1
3391 quic_data.AddWrite(SYNCHRONOUS,
3392 client_maker_.MakeRetransmissionPacket(1, 4, true));
3393 // TLP 2
3394 quic_data.AddWrite(SYNCHRONOUS,
3395 client_maker_.MakeRetransmissionPacket(3, 5, true));
3396 // RTO 1
3397 quic_data.AddWrite(SYNCHRONOUS,
3398 client_maker_.MakeRetransmissionPacket(1, 6, true));
3399 quic_data.AddWrite(SYNCHRONOUS,
3400 client_maker_.MakeRetransmissionPacket(3, 7, true));
3401 // RTO 2
3402 quic_data.AddWrite(SYNCHRONOUS,
3403 client_maker_.MakeRetransmissionPacket(1, 8, true));
3404 quic_data.AddWrite(SYNCHRONOUS,
3405 client_maker_.MakeRetransmissionPacket(3, 9, true));
3406 // RTO 3
3407 quic_data.AddWrite(SYNCHRONOUS,
3408 client_maker_.MakeRetransmissionPacket(1, 10, true));
3409 quic_data.AddWrite(SYNCHRONOUS,
3410 client_maker_.MakeRetransmissionPacket(3, 11, true));
3411 // RTO 4
3412 quic_data.AddWrite(SYNCHRONOUS,
3413 client_maker_.MakeRetransmissionPacket(1, 12, true));
3414 quic_data.AddWrite(SYNCHRONOUS,
3415 client_maker_.MakeRetransmissionPacket(3, 13, true));
3416 // RTO 5
3417 quic_data.AddWrite(SYNCHRONOUS,
3418 client_maker_.MakeConnectionClosePacket(
3419 14, true, quic::QUIC_TOO_MANY_RTOS,
3420 "5 consecutive retransmission timeouts"));
Nick Harper057264a82019-09-12 23:33:493421 }
rch9ecde09b2017-04-08 00:18:233422
3423 quic_data.AddRead(ASYNC, OK);
3424 quic_data.AddSocketDataToFactory(&socket_factory_);
3425
3426 // In order for a new QUIC session to be established via alternate-protocol
3427 // without racing an HTTP connection, we need the host resolution to happen
3428 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3429 // connection to the the server, in this test we require confirmation
3430 // before encrypting so the HTTP job will still start.
3431 host_resolver_.set_synchronous_mode(true);
3432 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3433 "");
rch9ecde09b2017-04-08 00:18:233434
3435 CreateSession();
3436 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233437 QuicStreamFactoryPeer::SetAlarmFactory(
3438 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193439 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553440 &clock_));
rch9ecde09b2017-04-08 00:18:233441
Ryan Hamilton9835e662018-08-02 05:36:273442 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233443
Jeremy Roman0579ed62017-08-29 15:56:193444 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233445 session_.get());
3446 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363447 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3449
3450 // Pump the message loop to get the request started.
3451 base::RunLoop().RunUntilIdle();
3452 // Explicitly confirm the handshake.
3453 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523454 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233455
3456 // Now cancel the request.
3457 trans.reset();
3458
3459 // Run the QUIC session to completion.
3460 quic_task_runner_->RunUntilIdle();
3461
3462 ExpectQuicAlternateProtocolMapping();
3463
3464 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3465}
3466
rch2f2991c2017-04-13 19:28:173467// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3468// the request fails with QUIC_PROTOCOL_ERROR.
3469TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:423470 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173471 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593472 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033473 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493474 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253475 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493476 quic_data.AddWrite(SYNCHRONOUS,
3477 ConstructInitialSettingsPacket(packet_num++));
3478 }
3479 quic_data.AddWrite(
3480 SYNCHRONOUS,
3481 ConstructClientRequestHeadersPacket(
3482 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3483 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023484 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553485 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173486 // Peer sending data from an non-existing stream causes this end to raise
3487 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333488 quic_data.AddRead(
3489 ASYNC, ConstructServerRstPacket(
3490 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3491 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173492 std::string quic_error_details = "Data for nonexistent stream";
Nick Harper057264a82019-09-12 23:33:493493 quic_data.AddWrite(SYNCHRONOUS,
3494 ConstructClientAckAndConnectionClosePacket(
3495 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3496 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3497 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173498 quic_data.AddSocketDataToFactory(&socket_factory_);
3499
3500 // In order for a new QUIC session to be established via alternate-protocol
3501 // without racing an HTTP connection, we need the host resolution to happen
3502 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3503 // connection to the the server, in this test we require confirmation
3504 // before encrypting so the HTTP job will still start.
3505 host_resolver_.set_synchronous_mode(true);
3506 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3507 "");
rch2f2991c2017-04-13 19:28:173508
3509 CreateSession();
3510
Ryan Hamilton9835e662018-08-02 05:36:273511 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173512
3513 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3514 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363515 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173516 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3517
3518 // Pump the message loop to get the request started.
3519 base::RunLoop().RunUntilIdle();
3520 // Explicitly confirm the handshake.
3521 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523522 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173523
3524 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553525 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173526
3527 // Run the QUIC session to completion.
3528 base::RunLoop().RunUntilIdle();
3529 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3530 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3531
3532 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3533 ExpectQuicAlternateProtocolMapping();
3534 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3535}
3536
rch2f2991c2017-04-13 19:28:173537// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3538// connection times out, then QUIC will be marked as broken and the request
3539// retried over TCP.
3540TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Ryan Sleevi2e8255b2019-07-17 21:02:213541 session_params_.quic_params.idle_connection_timeout =
3542 base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173543
3544 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593545 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133546 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173547 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3548
Ryan Hamiltone940bd12019-06-30 02:46:453549 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033550 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493551 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253552 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493553 quic_data.AddWrite(SYNCHRONOUS,
3554 client_maker_.MakeInitialSettingsPacket(packet_num++));
3555 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023556 quic_data.AddWrite(
3557 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453558 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493559 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3560 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453561
3562 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253563 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493564 // TLP 1
3565 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3566 1, packet_num++, true));
3567 // TLP 2
3568 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3569 2, packet_num++, true));
3570 // RTO 1
3571 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3572 1, packet_num++, true));
3573 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3574 2, packet_num++, true));
3575 // RTO 2
3576 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3577 1, packet_num++, true));
3578 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3579 2, packet_num++, true));
3580 // RTO 3
3581 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3582 1, packet_num++, true));
3583 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3584 2, packet_num++, true));
rch2f2991c2017-04-13 19:28:173585
Nick Harper057264a82019-09-12 23:33:493586 quic_data.AddWrite(SYNCHRONOUS,
3587 client_maker_.MakeConnectionClosePacket(
3588 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3589 "No recent network activity."));
3590 } else {
3591 // TLP 1
3592 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3593 1, packet_num++, true));
3594 // TLP 2
3595 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3596 1, packet_num++, true));
3597 // RTO 1
3598 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3599 1, packet_num++, true));
3600 // RTO 2
3601 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3602 1, packet_num++, true));
3603 // RTO 3
3604 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3605 1, packet_num++, true));
3606
3607 quic_data.AddWrite(SYNCHRONOUS,
3608 client_maker_.MakeConnectionClosePacket(
3609 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3610 "No recent network activity."));
3611 }
Fan Yang928f1632017-12-14 18:55:223612
rch2f2991c2017-04-13 19:28:173613 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3614 quic_data.AddRead(ASYNC, OK);
3615 quic_data.AddSocketDataToFactory(&socket_factory_);
3616
3617 // After that fails, it will be resent via TCP.
3618 MockWrite http_writes[] = {
3619 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3620 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3621 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3622
3623 MockRead http_reads[] = {
3624 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3625 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3626 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013627 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173628 socket_factory_.AddSocketDataProvider(&http_data);
3629 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3630
3631 // In order for a new QUIC session to be established via alternate-protocol
3632 // without racing an HTTP connection, we need the host resolution to happen
3633 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3634 // connection to the the server, in this test we require confirmation
3635 // before encrypting so the HTTP job will still start.
3636 host_resolver_.set_synchronous_mode(true);
3637 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3638 "");
rch2f2991c2017-04-13 19:28:173639
3640 CreateSession();
3641 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173642 QuicStreamFactoryPeer::SetAlarmFactory(
3643 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193644 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553645 &clock_));
rch2f2991c2017-04-13 19:28:173646
Ryan Hamilton9835e662018-08-02 05:36:273647 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173648
3649 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3650 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363651 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3653
3654 // Pump the message loop to get the request started.
3655 base::RunLoop().RunUntilIdle();
3656 // Explicitly confirm the handshake.
3657 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523658 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173659
3660 // Run the QUIC session to completion.
3661 quic_task_runner_->RunUntilIdle();
3662 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3663
3664 ExpectQuicAlternateProtocolMapping();
3665
3666 // Let the transaction proceed which will result in QUIC being marked
3667 // as broken and the request falling back to TCP.
3668 EXPECT_THAT(callback.WaitForResult(), IsOk());
3669
3670 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3671 ASSERT_FALSE(http_data.AllReadDataConsumed());
3672
3673 // Read the response body over TCP.
3674 CheckResponseData(&trans, "hello world");
3675 ExpectBrokenAlternateProtocolMapping();
3676 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3677 ASSERT_TRUE(http_data.AllReadDataConsumed());
3678}
3679
rch2f2991c2017-04-13 19:28:173680// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3681// protocol error occurs after the handshake is confirmed, the request
3682// retried over TCP and the QUIC will be marked as broken.
3683TEST_P(QuicNetworkTransactionTest,
3684 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Ryan Sleevi2e8255b2019-07-17 21:02:213685 session_params_.quic_params.idle_connection_timeout =
3686 base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173687
3688 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593689 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033690 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493691 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253692 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493693 quic_data.AddWrite(SYNCHRONOUS,
3694 ConstructInitialSettingsPacket(packet_num++));
3695 }
3696 quic_data.AddWrite(
3697 SYNCHRONOUS,
3698 ConstructClientRequestHeadersPacket(
3699 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3700 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023701 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553702 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3703
rch2f2991c2017-04-13 19:28:173704 // Peer sending data from an non-existing stream causes this end to raise
3705 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333706 quic_data.AddRead(
3707 ASYNC, ConstructServerRstPacket(
3708 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3709 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173710 std::string quic_error_details = "Data for nonexistent stream";
Nick Harper057264a82019-09-12 23:33:493711 quic_data.AddWrite(SYNCHRONOUS,
3712 ConstructClientAckAndConnectionClosePacket(
3713 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3714 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3715 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173716 quic_data.AddSocketDataToFactory(&socket_factory_);
3717
3718 // After that fails, it will be resent via TCP.
3719 MockWrite http_writes[] = {
3720 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3721 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3722 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3723
3724 MockRead http_reads[] = {
3725 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3726 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3727 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013728 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173729 socket_factory_.AddSocketDataProvider(&http_data);
3730 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3731
3732 // In order for a new QUIC session to be established via alternate-protocol
3733 // without racing an HTTP connection, we need the host resolution to happen
3734 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3735 // connection to the the server, in this test we require confirmation
3736 // before encrypting so the HTTP job will still start.
3737 host_resolver_.set_synchronous_mode(true);
3738 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3739 "");
rch2f2991c2017-04-13 19:28:173740
3741 CreateSession();
3742
Ryan Hamilton9835e662018-08-02 05:36:273743 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173744
3745 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3746 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363747 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173748 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3749
3750 // Pump the message loop to get the request started.
3751 base::RunLoop().RunUntilIdle();
3752 // Explicitly confirm the handshake.
3753 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523754 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553755 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173756
3757 // Run the QUIC session to completion.
3758 base::RunLoop().RunUntilIdle();
3759 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3760
3761 ExpectQuicAlternateProtocolMapping();
3762
3763 // Let the transaction proceed which will result in QUIC being marked
3764 // as broken and the request falling back to TCP.
3765 EXPECT_THAT(callback.WaitForResult(), IsOk());
3766
3767 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3768 ASSERT_FALSE(http_data.AllReadDataConsumed());
3769
3770 // Read the response body over TCP.
3771 CheckResponseData(&trans, "hello world");
3772 ExpectBrokenAlternateProtocolMapping();
3773 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3774 ASSERT_TRUE(http_data.AllReadDataConsumed());
3775}
3776
Matt Menkeb32ba5122019-09-10 19:17:053777// Much like above test, but verifies that NetworkIsolationKey is respected.
3778TEST_P(QuicNetworkTransactionTest,
3779 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
3780 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
3781 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
3782 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
3783 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
3784
3785 base::test::ScopedFeatureList feature_list;
3786 feature_list.InitWithFeatures(
3787 // enabled_features
3788 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3789 features::kPartitionConnectionsByNetworkIsolationKey},
3790 // disabled_features
3791 {});
3792 // Since HttpServerProperties caches the feature value, have to create a new
3793 // one.
3794 http_server_properties_ = std::make_unique<HttpServerProperties>();
3795
3796 session_params_.quic_params.idle_connection_timeout =
3797 base::TimeDelta::FromSeconds(5);
3798
3799 // The request will initially go out over QUIC.
3800 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:563801 uint64_t packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:053802 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:253803 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:563804 quic_data.AddWrite(SYNCHRONOUS,
3805 ConstructInitialSettingsPacket(packet_number++));
3806 }
3807 quic_data.AddWrite(
3808 SYNCHRONOUS,
3809 ConstructClientRequestHeadersPacket(
3810 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3811 true, GetRequestHeaders("GET", "https", "/")));
Matt Menkeb32ba5122019-09-10 19:17:053812 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:053813 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3814
3815 // Peer sending data from an non-existing stream causes this end to raise
3816 // error and close connection.
3817 quic_data.AddRead(
3818 ASYNC, ConstructServerRstPacket(
3819 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3820 quic::QUIC_STREAM_LAST_ERROR));
3821 std::string quic_error_details = "Data for nonexistent stream";
3822 quic_data.AddWrite(
3823 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
3824 packet_number++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3825 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3826 quic::IETF_RST_STREAM));
3827 quic_data.AddSocketDataToFactory(&socket_factory_);
3828
3829 // After that fails, it will be resent via TCP.
3830 MockWrite http_writes[] = {
3831 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3832 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3833 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3834
3835 MockRead http_reads[] = {
3836 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3837 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3838 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3839 SequencedSocketData http_data(http_reads, http_writes);
3840 socket_factory_.AddSocketDataProvider(&http_data);
3841 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3842
3843 // In order for a new QUIC session to be established via alternate-protocol
3844 // without racing an HTTP connection, we need the host resolution to happen
3845 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3846 // connection to the the server, in this test we require confirmation
3847 // before encrypting so the HTTP job will still start.
3848 host_resolver_.set_synchronous_mode(true);
3849 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3850 "");
3851
3852 CreateSession();
3853
3854 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3855 kNetworkIsolationKey1);
3856 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3857 kNetworkIsolationKey2);
3858
3859 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3860 TestCompletionCallback callback;
3861 request_.network_isolation_key = kNetworkIsolationKey1;
3862 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3864
3865 // Pump the message loop to get the request started.
3866 base::RunLoop().RunUntilIdle();
3867 // Explicitly confirm the handshake.
3868 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
3869 quic::QuicSession::HANDSHAKE_CONFIRMED);
3870 quic_data.Resume();
3871
3872 // Run the QUIC session to completion.
3873 base::RunLoop().RunUntilIdle();
3874 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3875
3876 // Let the transaction proceed which will result in QUIC being marked
3877 // as broken and the request falling back to TCP.
3878 EXPECT_THAT(callback.WaitForResult(), IsOk());
3879 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3880 ASSERT_FALSE(http_data.AllReadDataConsumed());
3881
3882 // Read the response body over TCP.
3883 CheckResponseData(&trans, "hello world");
3884 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3885 ASSERT_TRUE(http_data.AllReadDataConsumed());
3886
3887 // The alternative service shouldhave been marked as broken under
3888 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3889 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3890 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3891
3892 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3893 AddHttpDataAndRunRequest();
3894 // Requests using other NetworkIsolationKeys can still use QUIC.
3895 request_.network_isolation_key = kNetworkIsolationKey2;
3896 AddQuicDataAndRunRequest();
3897
3898 // The last two requests should not have changed the alternative service
3899 // mappings.
3900 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3901 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3902}
3903
rch30943ee2017-06-12 21:28:443904// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3905// request is reset from, then QUIC will be marked as broken and the request
3906// retried over TCP.
3907TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443908 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593909 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133910 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443911 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3912
Michael Warres167db3e2019-03-01 21:38:033913 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493914 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253915 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493916 quic_data.AddWrite(SYNCHRONOUS,
3917 ConstructInitialSettingsPacket(packet_num++));
3918 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023919 quic_data.AddWrite(
3920 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453921 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493922 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3923 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453924
3925 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553926 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443927
Fan Yang32c5a112018-12-10 20:06:333928 quic_data.AddRead(ASYNC,
3929 ConstructServerRstPacket(
3930 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3931 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443932
3933 quic_data.AddRead(ASYNC, OK);
3934 quic_data.AddSocketDataToFactory(&socket_factory_);
3935
3936 // After that fails, it will be resent via TCP.
3937 MockWrite http_writes[] = {
3938 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3939 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3940 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3941
3942 MockRead http_reads[] = {
3943 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3944 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3945 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013946 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443947 socket_factory_.AddSocketDataProvider(&http_data);
3948 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3949
3950 // In order for a new QUIC session to be established via alternate-protocol
3951 // without racing an HTTP connection, we need the host resolution to happen
3952 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3953 // connection to the the server, in this test we require confirmation
3954 // before encrypting so the HTTP job will still start.
3955 host_resolver_.set_synchronous_mode(true);
3956 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3957 "");
rch30943ee2017-06-12 21:28:443958
3959 CreateSession();
3960
Ryan Hamilton9835e662018-08-02 05:36:273961 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443962
3963 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3964 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363965 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443966 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3967
3968 // Pump the message loop to get the request started.
3969 base::RunLoop().RunUntilIdle();
3970 // Explicitly confirm the handshake.
3971 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523972 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553973 quic_data.Resume();
rch30943ee2017-06-12 21:28:443974
3975 // Run the QUIC session to completion.
3976 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3977
3978 ExpectQuicAlternateProtocolMapping();
3979
3980 // Let the transaction proceed which will result in QUIC being marked
3981 // as broken and the request falling back to TCP.
3982 EXPECT_THAT(callback.WaitForResult(), IsOk());
3983
3984 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3985 ASSERT_FALSE(http_data.AllReadDataConsumed());
3986
3987 // Read the response body over TCP.
3988 CheckResponseData(&trans, "hello world");
3989 ExpectBrokenAlternateProtocolMapping();
3990 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3991 ASSERT_TRUE(http_data.AllReadDataConsumed());
3992}
3993
Ryan Hamilton6c2a2a82017-12-15 02:06:283994// Verify that when an origin has two alt-svc advertisements, one local and one
3995// remote, that when the local is broken the request will go over QUIC via
3996// the remote Alt-Svc.
3997// This is a regression test for crbug/825646.
3998TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Nick Harper72ade192019-07-17 03:30:423999 session_params_.quic_params.allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:284000
4001 GURL origin1 = request_.url; // mail.example.org
4002 GURL origin2("https://www.example.org/");
4003 ASSERT_NE(origin1.host(), origin2.host());
4004
4005 scoped_refptr<X509Certificate> cert(
4006 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244007 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4008 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:284009
4010 ProofVerifyDetailsChromium verify_details;
4011 verify_details.cert_verify_result.verified_cert = cert;
4012 verify_details.cert_verify_result.is_issued_by_known_root = true;
4013 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4014
Ryan Hamiltonabad59e2019-06-06 04:02:594015 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234016 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254017 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234018 mock_quic_data.AddWrite(SYNCHRONOUS,
4019 ConstructInitialSettingsPacket(packet_num++));
4020 }
Ryan Hamilton6c2a2a82017-12-15 02:06:284021 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234022 SYNCHRONOUS,
4023 ConstructClientRequestHeadersPacket(
4024 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4025 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434026 mock_quic_data.AddRead(
4027 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334028 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024029 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434030 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434031 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334032 ASYNC, ConstructServerDataPacket(
4033 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174034 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234035 mock_quic_data.AddWrite(SYNCHRONOUS,
4036 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284037 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4038 mock_quic_data.AddRead(ASYNC, 0); // EOF
4039
4040 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:594041 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:284042 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4043 AddHangingNonAlternateProtocolSocketData();
4044
4045 CreateSession();
4046
4047 // Set up alternative service for |origin1|.
4048 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4049 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4050 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4051 AlternativeServiceInfoVector alternative_services;
4052 alternative_services.push_back(
4053 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4054 local_alternative, expiration,
Nick Harper72ade192019-07-17 03:30:424055 session_->params().quic_params.supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:284056 alternative_services.push_back(
4057 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4058 remote_alternative, expiration,
Nick Harper72ade192019-07-17 03:30:424059 session_->params().quic_params.supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494060 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4061 NetworkIsolationKey(),
4062 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:284063
Matt Menkeb32ba5122019-09-10 19:17:054064 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4065 NetworkIsolationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:284066
4067 SendRequestAndExpectQuicResponse("hello!");
4068}
4069
rch30943ee2017-06-12 21:28:444070// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4071// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:054072// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:444073// connection instead of going back to the broken QUIC connection.
4074// This is a regression tests for crbug/731303.
4075TEST_P(QuicNetworkTransactionTest,
4076 ResetPooledAfterHandshakeConfirmedThenBroken) {
Nick Harper72ade192019-07-17 03:30:424077 session_params_.quic_params.allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444078
4079 GURL origin1 = request_.url;
4080 GURL origin2("https://www.example.org/");
4081 ASSERT_NE(origin1.host(), origin2.host());
4082
Ryan Hamiltonabad59e2019-06-06 04:02:594083 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:444084
4085 scoped_refptr<X509Certificate> cert(
4086 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244087 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4088 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444089
4090 ProofVerifyDetailsChromium verify_details;
4091 verify_details.cert_verify_result.verified_cert = cert;
4092 verify_details.cert_verify_result.is_issued_by_known_root = true;
4093 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4094
Renjie Tangaadb84b2019-08-31 01:00:234095 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254096 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234097 mock_quic_data.AddWrite(SYNCHRONOUS,
4098 ConstructInitialSettingsPacket(packet_num++));
4099 }
rch30943ee2017-06-12 21:28:444100 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434101 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234102 SYNCHRONOUS,
4103 ConstructClientRequestHeadersPacket(
4104 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4105 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434106 mock_quic_data.AddRead(
4107 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334108 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024109 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434110 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434111 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334112 ASYNC, ConstructServerDataPacket(
4113 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174114 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234115 mock_quic_data.AddWrite(SYNCHRONOUS,
4116 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rch30943ee2017-06-12 21:28:444117
4118 // Second request will go over the pooled QUIC connection, but will be
4119 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054120 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174121 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4122 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054123 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174124 QuicTestPacketMaker server_maker2(
4125 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4126 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434127 mock_quic_data.AddWrite(
4128 SYNCHRONOUS,
4129 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234130 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4131 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024132 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334133 mock_quic_data.AddRead(
4134 ASYNC, ConstructServerRstPacket(
4135 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4136 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444137 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4138 mock_quic_data.AddRead(ASYNC, 0); // EOF
4139
4140 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4141
4142 // After that fails, it will be resent via TCP.
4143 MockWrite http_writes[] = {
4144 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4145 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4146 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4147
4148 MockRead http_reads[] = {
4149 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4150 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4151 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014152 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444153 socket_factory_.AddSocketDataProvider(&http_data);
4154 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4155
Ryan Hamilton6c2a2a82017-12-15 02:06:284156 // Then the next request to the second origin will be sent over TCP.
4157 socket_factory_.AddSocketDataProvider(&http_data);
4158 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444159
4160 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564161 QuicStreamFactoryPeer::SetAlarmFactory(
4162 session_->quic_stream_factory(),
4163 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4164 &clock_));
rch30943ee2017-06-12 21:28:444165
4166 // Set up alternative service for |origin1|.
4167 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244168 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494169 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074170 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4171 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:444172
4173 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244174 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494175 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074176 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4177 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344178
rch30943ee2017-06-12 21:28:444179 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524180 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444181 SendRequestAndExpectQuicResponse("hello!");
4182
4183 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524184 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:054185 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:444186 request_.url = origin2;
4187 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:054188 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
4189 alternative1, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244190 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:054191 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
4192 alternative2, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244193 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444194
Matt Menkeb32ba5122019-09-10 19:17:054195 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:444196 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284197 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444198}
4199
bnc8be55ebb2015-10-30 14:12:074200TEST_P(QuicNetworkTransactionTest,
4201 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564202 std::string altsvc_header =
4203 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4204 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074205 MockRead http_reads[] = {
4206 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4207 MockRead("hello world"),
4208 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4209 MockRead(ASYNC, OK)};
4210
Ryan Sleevib8d7ea02018-05-07 20:01:014211 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074212 socket_factory_.AddSocketDataProvider(&http_data);
4213 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4214 socket_factory_.AddSocketDataProvider(&http_data);
4215 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4216
rch3f4b8452016-02-23 16:59:324217 CreateSession();
bnc8be55ebb2015-10-30 14:12:074218
4219 SendRequestAndExpectHttpResponse("hello world");
4220 SendRequestAndExpectHttpResponse("hello world");
4221}
4222
Xida Chen9bfe0b62018-04-24 19:52:214223// When multiple alternative services are advertised, HttpStreamFactory should
4224// select the alternative service which uses existing QUIC session if available.
4225// If no existing QUIC session can be used, use the first alternative service
4226// from the list.
zhongyi32569c62016-01-08 02:54:304227TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Nick Harper72ade192019-07-17 03:30:424228 session_params_.quic_params.allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524229 MockRead http_reads[] = {
4230 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294231 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524232 MockRead("hello world"),
4233 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4234 MockRead(ASYNC, OK)};
4235
Ryan Sleevib8d7ea02018-05-07 20:01:014236 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524237 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084238 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564239 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524240
zhongyi32569c62016-01-08 02:54:304241 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294242 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304243 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594244 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234245 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254246 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234247 mock_quic_data.AddWrite(SYNCHRONOUS,
4248 ConstructInitialSettingsPacket(packet_num++));
4249 }
rch5cb522462017-04-25 20:18:364250 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234251 SYNCHRONOUS,
4252 ConstructClientRequestHeadersPacket(
4253 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4254 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304255
4256 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294257 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4258 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434259 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024260 ASYNC, ConstructServerResponseHeadersPacket(
4261 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4262 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434263 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434264 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334265 ASYNC, ConstructServerDataPacket(
4266 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174267 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234268 mock_quic_data.AddWrite(SYNCHRONOUS,
4269 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304270
4271 // Second QUIC request data.
4272 // Connection pooling, using existing session, no need to include version
4273 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584274 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234275 SYNCHRONOUS,
4276 ConstructClientRequestHeadersPacket(
4277 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4278 true, GetRequestHeaders("GET", "https", "/"),
4279 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434280 mock_quic_data.AddRead(
4281 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334282 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024283 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434284 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334285 ASYNC, ConstructServerDataPacket(
4286 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174287 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434288 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234289 SYNCHRONOUS,
4290 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bncc958faa2015-07-31 18:14:524291 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594292 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524293
4294 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4295
rtennetib8e80fb2016-05-16 00:12:094296 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324297 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564298 QuicStreamFactoryPeer::SetAlarmFactory(
4299 session_->quic_stream_factory(),
4300 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4301 &clock_));
bncc958faa2015-07-31 18:14:524302
4303 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304304
bnc359ed2a2016-04-29 20:43:454305 SendRequestAndExpectQuicResponse("hello!");
4306 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304307}
4308
tbansal6490783c2016-09-20 17:55:274309// Check that an existing QUIC connection to an alternative proxy server is
4310// used.
4311TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4312 base::HistogramTester histogram_tester;
4313
tbansal6490783c2016-09-20 17:55:274314 // First QUIC request data.
4315 // Open a session to foo.example.org:443 using the first entry of the
4316 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594317 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234318 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254319 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234320 mock_quic_data.AddWrite(SYNCHRONOUS,
4321 ConstructInitialSettingsPacket(packet_num++));
4322 }
rch5cb522462017-04-25 20:18:364323 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234324 SYNCHRONOUS,
4325 ConstructClientRequestHeadersPacket(
4326 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4327 true, GetRequestHeaders("GET", "http", "/")));
tbansal6490783c2016-09-20 17:55:274328
4329 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434330 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024331 ASYNC, ConstructServerResponseHeadersPacket(
4332 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4333 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434334 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434335 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334336 ASYNC, ConstructServerDataPacket(
4337 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174338 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234339 mock_quic_data.AddWrite(SYNCHRONOUS,
4340 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274341
4342 // Second QUIC request data.
4343 // Connection pooling, using existing session, no need to include version
4344 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274345 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234346 SYNCHRONOUS,
4347 ConstructClientRequestHeadersPacket(
4348 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4349 true, GetRequestHeaders("GET", "http", "/"),
4350 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434351 mock_quic_data.AddRead(
4352 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334353 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024354 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434355 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334356 ASYNC, ConstructServerDataPacket(
4357 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174358 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434359 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234360 SYNCHRONOUS,
4361 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274362 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4363 mock_quic_data.AddRead(ASYNC, 0); // EOF
4364
4365 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4366
4367 AddHangingNonAlternateProtocolSocketData();
4368
4369 TestProxyDelegate test_proxy_delegate;
4370
Lily Houghton8c2f97d2018-01-22 05:06:594371 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494372 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274373
4374 test_proxy_delegate.set_alternative_proxy_server(
4375 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524376 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274377
4378 request_.url = GURL("http://mail.example.org/");
4379
4380 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564381 QuicStreamFactoryPeer::SetAlarmFactory(
4382 session_->quic_stream_factory(),
4383 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4384 &clock_));
tbansal6490783c2016-09-20 17:55:274385
4386 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4387 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4388 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4389 1);
4390
4391 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4392 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4393 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4394 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4395 1);
4396}
4397
Ryan Hamilton8d9ee76e2018-05-29 23:52:524398// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454399// even if alternative service destination is different.
4400TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Nick Harper72ade192019-07-17 03:30:424401 session_params_.quic_params.allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594402 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454403
Renjie Tangaadb84b2019-08-31 01:00:234404 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254405 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234406 mock_quic_data.AddWrite(SYNCHRONOUS,
4407 ConstructInitialSettingsPacket(packet_num++));
4408 }
bnc359ed2a2016-04-29 20:43:454409 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434410 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234411 SYNCHRONOUS,
4412 ConstructClientRequestHeadersPacket(
4413 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4414 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434415 mock_quic_data.AddRead(
4416 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334417 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024418 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434419 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434420 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334421 ASYNC, ConstructServerDataPacket(
4422 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174423 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234424 mock_quic_data.AddWrite(SYNCHRONOUS,
4425 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304426
bnc359ed2a2016-04-29 20:43:454427 // Second request.
alyssar2adf3ac2016-05-03 17:12:584428 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234429 SYNCHRONOUS,
4430 ConstructClientRequestHeadersPacket(
4431 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4432 true, GetRequestHeaders("GET", "https", "/"),
4433 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434434 mock_quic_data.AddRead(
4435 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334436 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024437 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434438 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334439 ASYNC, ConstructServerDataPacket(
4440 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174441 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434442 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234443 SYNCHRONOUS,
4444 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304445 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4446 mock_quic_data.AddRead(ASYNC, 0); // EOF
4447
4448 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454449
4450 AddHangingNonAlternateProtocolSocketData();
4451 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304452
rch3f4b8452016-02-23 16:59:324453 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564454 QuicStreamFactoryPeer::SetAlarmFactory(
4455 session_->quic_stream_factory(),
4456 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4457 &clock_));
zhongyi32569c62016-01-08 02:54:304458
bnc359ed2a2016-04-29 20:43:454459 const char destination1[] = "first.example.com";
4460 const char destination2[] = "second.example.com";
4461
4462 // Set up alternative service entry to destination1.
4463 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214464 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454465 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494466 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074467 server, NetworkIsolationKey(), alternative_service, expiration,
4468 supported_versions_);
bnc359ed2a2016-04-29 20:43:454469 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524470 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454471 SendRequestAndExpectQuicResponse("hello!");
4472
4473 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214474 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494475 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074476 server, NetworkIsolationKey(), alternative_service, expiration,
4477 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524478 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454479 // even though alternative service destination is different.
4480 SendRequestAndExpectQuicResponse("hello!");
4481}
4482
4483// Pool to existing session with matching destination and matching certificate
4484// even if origin is different, and even if the alternative service with
4485// matching destination is not the first one on the list.
4486TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Nick Harper72ade192019-07-17 03:30:424487 session_params_.quic_params.allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454488 GURL origin1 = request_.url;
4489 GURL origin2("https://www.example.org/");
4490 ASSERT_NE(origin1.host(), origin2.host());
4491
Ryan Hamiltonabad59e2019-06-06 04:02:594492 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454493
Renjie Tangaadb84b2019-08-31 01:00:234494 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254495 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234496 mock_quic_data.AddWrite(SYNCHRONOUS,
4497 ConstructInitialSettingsPacket(packet_num++));
4498 }
bnc359ed2a2016-04-29 20:43:454499 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434500 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234501 SYNCHRONOUS,
4502 ConstructClientRequestHeadersPacket(
4503 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4504 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434505 mock_quic_data.AddRead(
4506 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334507 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024508 GetResponseHeaders("200 OK")));
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));
bnc359ed2a2016-04-29 20:43:454516
4517 // Second request.
Yixin Wang079ad542018-01-11 04:06:054518 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174519 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4520 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054521 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174522 QuicTestPacketMaker server_maker2(
4523 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4524 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584525 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434526 SYNCHRONOUS,
4527 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234528 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4529 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024530 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434531 mock_quic_data.AddRead(
4532 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334533 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024534 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434535 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334536 ASYNC, ConstructServerDataPacket(
4537 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174538 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434539 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234540 SYNCHRONOUS,
4541 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454542 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4543 mock_quic_data.AddRead(ASYNC, 0); // EOF
4544
4545 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4546
4547 AddHangingNonAlternateProtocolSocketData();
4548 AddHangingNonAlternateProtocolSocketData();
4549
4550 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564551 QuicStreamFactoryPeer::SetAlarmFactory(
4552 session_->quic_stream_factory(),
4553 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4554 &clock_));
bnc359ed2a2016-04-29 20:43:454555
4556 const char destination1[] = "first.example.com";
4557 const char destination2[] = "second.example.com";
4558
4559 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214560 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454561 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494562 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074563 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4564 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454565
4566 // Set up multiple alternative service entries for |origin2|,
4567 // the first one with a different destination as for |origin1|,
4568 // the second one with the same. The second one should be used,
4569 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214570 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454571 AlternativeServiceInfoVector alternative_services;
4572 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214573 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4574 alternative_service2, expiration,
Nick Harper72ade192019-07-17 03:30:424575 session_->params().quic_params.supported_versions));
bnc359ed2a2016-04-29 20:43:454576 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214577 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4578 alternative_service1, expiration,
Nick Harper72ade192019-07-17 03:30:424579 session_->params().quic_params.supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494580 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4581 NetworkIsolationKey(),
4582 alternative_services);
bnc359ed2a2016-04-29 20:43:454583 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524584 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454585 SendRequestAndExpectQuicResponse("hello!");
4586
4587 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524588 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454589 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584590
bnc359ed2a2016-04-29 20:43:454591 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304592}
4593
4594// Multiple origins have listed the same alternative services. When there's a
4595// existing QUIC session opened by a request to other origin,
4596// if the cert is valid, should select this QUIC session to make the request
4597// if this is also the first existing QUIC session.
4598TEST_P(QuicNetworkTransactionTest,
4599 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Nick Harper72ade192019-07-17 03:30:424600 session_params_.quic_params.allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294601 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304602
rch9ae5b3b2016-02-11 00:36:294603 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304604 MockRead http_reads[] = {
4605 MockRead("HTTP/1.1 200 OK\r\n"),
4606 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294607 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304608 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4609 MockRead(ASYNC, OK)};
4610
Ryan Sleevib8d7ea02018-05-07 20:01:014611 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304612 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084613 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304614 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4615
4616 // HTTP data for request to mail.example.org.
4617 MockRead http_reads2[] = {
4618 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294619 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304620 MockRead("hello world from mail.example.org"),
4621 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4622 MockRead(ASYNC, OK)};
4623
Ryan Sleevib8d7ea02018-05-07 20:01:014624 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304625 socket_factory_.AddSocketDataProvider(&http_data2);
4626 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4627
Yixin Wang079ad542018-01-11 04:06:054628 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174629 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4630 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054631 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584632 server_maker_.set_hostname("www.example.org");
4633 client_maker_.set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594634 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234635 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254636 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234637 mock_quic_data.AddWrite(SYNCHRONOUS,
4638 ConstructInitialSettingsPacket(packet_num++));
4639 }
zhongyi32569c62016-01-08 02:54:304640 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584641 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234642 SYNCHRONOUS,
4643 ConstructClientRequestHeadersPacket(
4644 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4645 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434646
4647 mock_quic_data.AddRead(
4648 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334649 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024650 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434651 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334652 mock_quic_data.AddRead(
4653 ASYNC, ConstructServerDataPacket(
4654 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174655 header + "hello from mail QUIC!"));
Renjie Tangaadb84b2019-08-31 01:00:234656 mock_quic_data.AddWrite(SYNCHRONOUS,
4657 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434658 // Second QUIC request data.
4659 mock_quic_data.AddWrite(
4660 SYNCHRONOUS,
4661 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234662 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4663 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024664 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434665 mock_quic_data.AddRead(
4666 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334667 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024668 GetResponseHeaders("200 OK")));
Fan Yang32c5a112018-12-10 20:06:334669 mock_quic_data.AddRead(
4670 ASYNC, ConstructServerDataPacket(
4671 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174672 header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434673 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234674 SYNCHRONOUS,
4675 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304676 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4677 mock_quic_data.AddRead(ASYNC, 0); // EOF
4678
4679 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304680
rtennetib8e80fb2016-05-16 00:12:094681 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324682 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564683 QuicStreamFactoryPeer::SetAlarmFactory(
4684 session_->quic_stream_factory(),
4685 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4686 &clock_));
zhongyi32569c62016-01-08 02:54:304687
4688 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294689 request_.url = GURL("https://www.example.org/");
4690 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304691 request_.url = GURL("https://mail.example.org/");
4692 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4693
rch9ae5b3b2016-02-11 00:36:294694 // Open a QUIC session to mail.example.org:443 when making request
4695 // to mail.example.org.
4696 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454697 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304698
rch9ae5b3b2016-02-11 00:36:294699 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304700 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454701 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524702}
4703
4704TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524705 MockRead http_reads[] = {
4706 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564707 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524708 MockRead("hello world"),
4709 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4710 MockRead(ASYNC, OK)};
4711
Ryan Sleevib8d7ea02018-05-07 20:01:014712 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524713 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084714 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564715 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524716
rtennetib8e80fb2016-05-16 00:12:094717 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324718 CreateSession();
bncc958faa2015-07-31 18:14:524719
4720 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454721
4722 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344723 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494724 http_server_properties_->GetAlternativeServiceInfos(
4725 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344726 ASSERT_EQ(1u, alternative_service_info_vector.size());
4727 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544728 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344729 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4730 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4731 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524732}
4733
4734TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524735 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564736 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4737 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524738 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4739 MockRead(ASYNC, OK)};
4740
Ryan Sleevib8d7ea02018-05-07 20:01:014741 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524742 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084743 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564744 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524745
Ryan Hamiltonabad59e2019-06-06 04:02:594746 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234747 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254748 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234749 mock_quic_data.AddWrite(SYNCHRONOUS,
4750 ConstructInitialSettingsPacket(packet_num++));
4751 }
rch5cb522462017-04-25 20:18:364752 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234753 SYNCHRONOUS,
4754 ConstructClientRequestHeadersPacket(
4755 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4756 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434757 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334758 ASYNC, ConstructServerResponseHeadersPacket(
4759 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4760 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434761 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334762 mock_quic_data.AddRead(
4763 ASYNC, ConstructServerDataPacket(
4764 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174765 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234766 mock_quic_data.AddWrite(SYNCHRONOUS,
4767 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524768 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4769 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524770
4771 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4772
rtennetib8e80fb2016-05-16 00:12:094773 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324774 CreateSession();
bncc958faa2015-07-31 18:14:524775
bnc3472afd2016-11-17 15:27:214776 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524777 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494778 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054779 alternative_service, NetworkIsolationKey());
Matt Menke3233d8f22019-08-20 21:01:494780 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054781 alternative_service, NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524782
4783 SendRequestAndExpectHttpResponse("hello world");
4784 SendRequestAndExpectQuicResponse("hello!");
4785
mmenkee24011922015-12-17 22:12:594786 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524787
Matt Menke3233d8f22019-08-20 21:01:494788 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054789 alternative_service, NetworkIsolationKey()));
Matt Menke19475f72019-08-21 18:57:444790 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4791 url::SchemeHostPort("https", request_.url.host(), 443),
4792 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524793}
4794
Matt Menkeb32ba5122019-09-10 19:17:054795TEST_P(QuicNetworkTransactionTest,
4796 ConfirmAlternativeServiceWithNetworkIsolationKey) {
4797 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
4798 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
4799 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
4800 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
4801
4802 base::test::ScopedFeatureList feature_list;
4803 feature_list.InitWithFeatures(
4804 // enabled_features
4805 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4806 features::kPartitionConnectionsByNetworkIsolationKey},
4807 // disabled_features
4808 {});
4809 // Since HttpServerProperties caches the feature value, have to create a new
4810 // one.
4811 http_server_properties_ = std::make_unique<HttpServerProperties>();
4812
4813 MockRead http_reads[] = {
4814 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4815 MockRead("hello world"),
4816 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4817 MockRead(ASYNC, OK)};
4818
4819 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4820 socket_factory_.AddSocketDataProvider(&http_data);
4821 AddCertificate(&ssl_data_);
4822 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4823
4824 MockQuicData mock_quic_data(version_);
4825 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254826 if (VersionUsesHttp3(version_.transport_version)) {
Matt Menkeb32ba5122019-09-10 19:17:054827 mock_quic_data.AddWrite(SYNCHRONOUS,
4828 ConstructInitialSettingsPacket(packet_num++));
4829 }
4830 mock_quic_data.AddWrite(
4831 SYNCHRONOUS,
4832 ConstructClientRequestHeadersPacket(
4833 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4834 true, GetRequestHeaders("GET", "https", "/")));
4835 mock_quic_data.AddRead(
4836 ASYNC, ConstructServerResponseHeadersPacket(
4837 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4838 GetResponseHeaders("200 OK")));
4839 std::string header = ConstructDataHeader(6);
4840 mock_quic_data.AddRead(
4841 ASYNC, ConstructServerDataPacket(
4842 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4843 header + "hello!"));
4844 mock_quic_data.AddWrite(SYNCHRONOUS,
4845 ConstructClientAckPacket(packet_num++, 2, 1, 1));
4846 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4847 mock_quic_data.AddRead(ASYNC, 0); // EOF
4848
4849 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4850
4851 CreateSession();
4852
4853 AlternativeService alternative_service(kProtoQUIC,
4854 HostPortPair::FromURL(request_.url));
4855 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4856 alternative_service, kNetworkIsolationKey1);
4857 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4858 alternative_service, kNetworkIsolationKey2);
4859 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4860 alternative_service, kNetworkIsolationKey1));
4861 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4862 alternative_service, kNetworkIsolationKey2));
4863
4864 request_.network_isolation_key = kNetworkIsolationKey1;
4865 SendRequestAndExpectHttpResponse("hello world");
4866 SendRequestAndExpectQuicResponse("hello!");
4867
4868 mock_quic_data.Resume();
4869
4870 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4871 alternative_service, kNetworkIsolationKey1));
4872 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4873 url::SchemeHostPort("https", request_.url.host(), 443),
4874 kNetworkIsolationKey1));
4875 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4876 alternative_service, kNetworkIsolationKey2));
4877 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4878 url::SchemeHostPort("https", request_.url.host(), 443),
4879 kNetworkIsolationKey2));
4880}
4881
bncc958faa2015-07-31 18:14:524882TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524883 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564884 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4885 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524886 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4887 MockRead(ASYNC, OK)};
4888
Ryan Sleevib8d7ea02018-05-07 20:01:014889 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524890 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564891 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524892
Ryan Hamiltonabad59e2019-06-06 04:02:594893 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234894 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254895 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234896 mock_quic_data.AddWrite(SYNCHRONOUS,
4897 ConstructInitialSettingsPacket(packet_num++));
4898 }
rch5cb522462017-04-25 20:18:364899 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234900 SYNCHRONOUS,
4901 ConstructClientRequestHeadersPacket(
4902 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4903 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434904 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334905 ASYNC, ConstructServerResponseHeadersPacket(
4906 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4907 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434908 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334909 mock_quic_data.AddRead(
4910 ASYNC, ConstructServerDataPacket(
4911 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174912 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234913 mock_quic_data.AddWrite(SYNCHRONOUS,
4914 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524915 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4916
4917 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4918
4919 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324920 CreateSession();
bncc958faa2015-07-31 18:14:524921
4922 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4923 SendRequestAndExpectHttpResponse("hello world");
4924}
4925
tbansalc3308d72016-08-27 10:25:044926// Tests that the connection to an HTTPS proxy is raced with an available
4927// alternative proxy server.
4928TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274929 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594930 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494931 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044932
Ryan Hamiltonabad59e2019-06-06 04:02:594933 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234934 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254935 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234936 mock_quic_data.AddWrite(SYNCHRONOUS,
4937 ConstructInitialSettingsPacket(packet_num++));
4938 }
rch5cb522462017-04-25 20:18:364939 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234940 SYNCHRONOUS,
4941 ConstructClientRequestHeadersPacket(
4942 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4943 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434944 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334945 ASYNC, ConstructServerResponseHeadersPacket(
4946 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4947 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434948 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334949 mock_quic_data.AddRead(
4950 ASYNC, ConstructServerDataPacket(
4951 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174952 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234953 mock_quic_data.AddWrite(SYNCHRONOUS,
4954 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044955 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4956 mock_quic_data.AddRead(ASYNC, 0); // EOF
4957
4958 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4959
4960 // There is no need to set up main job, because no attempt will be made to
4961 // speak to the proxy over TCP.
4962 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044963 TestProxyDelegate test_proxy_delegate;
4964 const HostPortPair host_port_pair("mail.example.org", 443);
4965
4966 test_proxy_delegate.set_alternative_proxy_server(
4967 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524968 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044969 CreateSession();
4970 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4971
4972 // The main job needs to hang in order to guarantee that the alternative
4973 // proxy server job will "win".
4974 AddHangingNonAlternateProtocolSocketData();
4975
4976 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4977
4978 // Verify that the alternative proxy server is not marked as broken.
4979 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4980
4981 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594982 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274983
4984 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4985 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4986 1);
tbansalc3308d72016-08-27 10:25:044987}
4988
bnc1c196c6e2016-05-28 13:51:484989TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304990 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274991 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304992
4993 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564994 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294995 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564996 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304997
4998 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564999 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485000 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565001 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:305002
Ryan Sleevib8d7ea02018-05-07 20:01:015003 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:505004 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:085005 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:505006 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:305007
5008 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:455009 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:305010 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:455011 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:305012 };
Ryan Sleevib8d7ea02018-05-07 20:01:015013 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:505014 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:305015
5016 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:015017 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:505018 socket_factory_.AddSocketDataProvider(&http_data2);
5019 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:305020
bnc912a04b2016-04-20 14:19:505021 CreateSession();
[email protected]dda75ab2013-06-22 22:43:305022
5023 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:305024 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:175025 ASSERT_TRUE(http_data.AllReadDataConsumed());
5026 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305027
5028 // Now run the second request in which the QUIC socket hangs,
5029 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:305030 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:455031 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:305032
rch37de576c2015-05-17 20:28:175033 ASSERT_TRUE(http_data2.AllReadDataConsumed());
5034 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:455035 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305036}
5037
[email protected]1e960032013-12-20 19:00:205038TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:595039 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035040 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495041 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255042 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495043 mock_quic_data.AddWrite(SYNCHRONOUS,
5044 ConstructInitialSettingsPacket(packet_num++));
5045 }
Zhongyi Shi32f2fd02018-04-16 18:23:435046 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495047 SYNCHRONOUS,
5048 ConstructClientRequestHeadersPacket(
5049 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5050 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435051 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335052 ASYNC, ConstructServerResponseHeadersPacket(
5053 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5054 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435055 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335056 mock_quic_data.AddRead(
5057 ASYNC, ConstructServerDataPacket(
5058 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175059 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495060 mock_quic_data.AddWrite(SYNCHRONOUS,
5061 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505062 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595063 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:485064
rcha5399e02015-04-21 19:32:045065 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:485066
rtennetib8e80fb2016-05-16 00:12:095067 // The non-alternate protocol job needs to hang in order to guarantee that
5068 // the alternate-protocol job will "win".
5069 AddHangingNonAlternateProtocolSocketData();
5070
rch3f4b8452016-02-23 16:59:325071 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275072 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:195073 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:305074
Matt Menke19475f72019-08-21 18:57:445075 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5076 url::SchemeHostPort("https", request_.url.host(), 443),
5077 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:485078}
5079
[email protected]1e960032013-12-20 19:00:205080TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:595081 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035082 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495083 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255084 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495085 mock_quic_data.AddWrite(
5086 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5087 }
Fan Yang32c5a112018-12-10 20:06:335088 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495089 SYNCHRONOUS,
5090 ConstructClientRequestHeadersPacket(
5091 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5092 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435093 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335094 ASYNC, ConstructServerResponseHeadersPacket(
5095 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5096 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435097 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335098 mock_quic_data.AddRead(
5099 ASYNC, ConstructServerDataPacket(
5100 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175101 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495102 mock_quic_data.AddWrite(SYNCHRONOUS,
5103 ConstructClientAckPacket(packet_number++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505104 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595105 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:045106 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275107
5108 // In order for a new QUIC session to be established via alternate-protocol
5109 // without racing an HTTP connection, we need the host resolution to happen
5110 // synchronously.
5111 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295112 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565113 "");
[email protected]3a120a6b2013-06-25 01:08:275114
rtennetib8e80fb2016-05-16 00:12:095115 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325116 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275117 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:275118 SendRequestAndExpectQuicResponse("hello!");
5119}
5120
[email protected]0fc924b2014-03-31 04:34:155121TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:495122 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5123 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155124
5125 // Since we are using a proxy, the QUIC job will not succeed.
5126 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295127 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5128 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565129 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155130
5131 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565132 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485133 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565134 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155135
Ryan Sleevib8d7ea02018-05-07 20:01:015136 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155137 socket_factory_.AddSocketDataProvider(&http_data);
5138
5139 // In order for a new QUIC session to be established via alternate-protocol
5140 // without racing an HTTP connection, we need the host resolution to happen
5141 // synchronously.
5142 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295143 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565144 "");
[email protected]0fc924b2014-03-31 04:34:155145
rch9ae5b3b2016-02-11 00:36:295146 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325147 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275148 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155149 SendRequestAndExpectHttpResponse("hello world");
5150}
5151
[email protected]1e960032013-12-20 19:00:205152TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:595153 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235154 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495155 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255156 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235157 mock_quic_data.AddWrite(SYNCHRONOUS,
5158 ConstructInitialSettingsPacket(packet_num++));
5159 }
Nick Harper057264a82019-09-12 23:33:495160 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365161 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235162 SYNCHRONOUS,
5163 ConstructClientRequestHeadersPacket(
5164 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5165 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435166 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335167 ASYNC, ConstructServerResponseHeadersPacket(
5168 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5169 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435170 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335171 mock_quic_data.AddRead(
5172 ASYNC, ConstructServerDataPacket(
5173 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175174 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235175 mock_quic_data.AddWrite(SYNCHRONOUS,
5176 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595177 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045178 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125179
rtennetib8e80fb2016-05-16 00:12:095180 // The non-alternate protocol job needs to hang in order to guarantee that
5181 // the alternate-protocol job will "win".
5182 AddHangingNonAlternateProtocolSocketData();
5183
[email protected]11c05872013-08-20 02:04:125184 // In order for a new QUIC session to be established via alternate-protocol
5185 // without racing an HTTP connection, we need the host resolution to happen
5186 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5187 // connection to the the server, in this test we require confirmation
5188 // before encrypting so the HTTP job will still start.
5189 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295190 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565191 "");
[email protected]11c05872013-08-20 02:04:125192
rch3f4b8452016-02-23 16:59:325193 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435194 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5195 false);
Ryan Hamilton9835e662018-08-02 05:36:275196 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125197
bnc691fda62016-08-12 00:43:165198 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125199 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365200 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015201 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125202
5203 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525204 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015205 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505206
bnc691fda62016-08-12 00:43:165207 CheckWasQuicResponse(&trans);
5208 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125209}
5210
Steven Valdez58097ec32018-07-16 18:29:045211TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015212 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595213 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035214 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255215 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495216 mock_quic_data.AddWrite(
5217 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5218 }
Steven Valdez58097ec32018-07-16 18:29:045219 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015220 SYNCHRONOUS,
5221 ConstructClientRequestHeadersPacket(
5222 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5223 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335224 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025225 ASYNC, ConstructServerResponseHeadersPacket(
5226 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5227 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015228 mock_quic_data.AddWrite(
5229 SYNCHRONOUS,
5230 ConstructClientAckAndRstPacket(
5231 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5232 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045233
5234 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5235
Steven Valdez58097ec32018-07-16 18:29:045236 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015237 SYNCHRONOUS,
5238 ConstructClientRequestHeadersPacket(
5239 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5240 true, GetRequestHeaders("GET", "https", "/"),
5241 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045242 mock_quic_data.AddRead(
5243 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335244 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025245 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435246 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045247 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335248 ASYNC, ConstructServerDataPacket(
5249 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175250 header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045251 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015252 SYNCHRONOUS,
5253 ConstructClientAckAndConnectionClosePacket(packet_number++, 3, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045254 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5255 mock_quic_data.AddRead(ASYNC, 0); // EOF
5256
5257 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5258
5259 // In order for a new QUIC session to be established via alternate-protocol
5260 // without racing an HTTP connection, we need the host resolution to happen
5261 // synchronously.
5262 host_resolver_.set_synchronous_mode(true);
5263 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5264 "");
Steven Valdez58097ec32018-07-16 18:29:045265
5266 AddHangingNonAlternateProtocolSocketData();
5267 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275268 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565269 QuicStreamFactoryPeer::SetAlarmFactory(
5270 session_->quic_stream_factory(),
5271 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5272 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045273
5274 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5275 TestCompletionCallback callback;
5276 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5278
5279 // Confirm the handshake after the 425 Too Early.
5280 base::RunLoop().RunUntilIdle();
5281
5282 // The handshake hasn't been confirmed yet, so the retry should not have
5283 // succeeded.
5284 EXPECT_FALSE(callback.have_result());
5285
5286 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5287 quic::QuicSession::HANDSHAKE_CONFIRMED);
5288
5289 EXPECT_THAT(callback.WaitForResult(), IsOk());
5290 CheckWasQuicResponse(&trans);
5291 CheckResponseData(&trans, "hello!");
5292}
5293
5294TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015295 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595296 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035297 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255298 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495299 mock_quic_data.AddWrite(
5300 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5301 }
Steven Valdez58097ec32018-07-16 18:29:045302 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015303 SYNCHRONOUS,
5304 ConstructClientRequestHeadersPacket(
5305 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5306 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335307 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025308 ASYNC, ConstructServerResponseHeadersPacket(
5309 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5310 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015311 mock_quic_data.AddWrite(
5312 SYNCHRONOUS,
5313 ConstructClientAckAndRstPacket(
5314 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5315 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045316
5317 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5318
Steven Valdez58097ec32018-07-16 18:29:045319 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015320 SYNCHRONOUS,
5321 ConstructClientRequestHeadersPacket(
5322 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5323 true, GetRequestHeaders("GET", "https", "/"),
5324 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335325 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025326 ASYNC, ConstructServerResponseHeadersPacket(
5327 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5328 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015329 mock_quic_data.AddWrite(
5330 SYNCHRONOUS,
5331 ConstructClientAckAndRstPacket(
5332 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
5333 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045334 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5335 mock_quic_data.AddRead(ASYNC, 0); // EOF
5336
5337 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5338
5339 // In order for a new QUIC session to be established via alternate-protocol
5340 // without racing an HTTP connection, we need the host resolution to happen
5341 // synchronously.
5342 host_resolver_.set_synchronous_mode(true);
5343 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5344 "");
Steven Valdez58097ec32018-07-16 18:29:045345
5346 AddHangingNonAlternateProtocolSocketData();
5347 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275348 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565349 QuicStreamFactoryPeer::SetAlarmFactory(
5350 session_->quic_stream_factory(),
5351 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5352 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045353
5354 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5355 TestCompletionCallback callback;
5356 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5357 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5358
5359 // Confirm the handshake after the 425 Too Early.
5360 base::RunLoop().RunUntilIdle();
5361
5362 // The handshake hasn't been confirmed yet, so the retry should not have
5363 // succeeded.
5364 EXPECT_FALSE(callback.have_result());
5365
5366 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5367 quic::QuicSession::HANDSHAKE_CONFIRMED);
5368
5369 EXPECT_THAT(callback.WaitForResult(), IsOk());
5370 const HttpResponseInfo* response = trans.GetResponseInfo();
5371 ASSERT_TRUE(response != nullptr);
5372 ASSERT_TRUE(response->headers.get() != nullptr);
5373 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5374 EXPECT_TRUE(response->was_fetched_via_spdy);
5375 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085376 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5377 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045378}
5379
zhongyica364fbb2015-12-12 03:39:125380TEST_P(QuicNetworkTransactionTest,
5381 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Nick Harper72ade192019-07-17 03:30:425382 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595383 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235384 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495385 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255386 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235387 mock_quic_data.AddWrite(SYNCHRONOUS,
5388 ConstructInitialSettingsPacket(packet_num++));
5389 }
Nick Harper057264a82019-09-12 23:33:495390 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365391 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235392 SYNCHRONOUS,
5393 ConstructClientRequestHeadersPacket(
5394 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5395 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125396 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525397 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435398 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125399 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5400
5401 // The non-alternate protocol job needs to hang in order to guarantee that
5402 // the alternate-protocol job will "win".
5403 AddHangingNonAlternateProtocolSocketData();
5404
5405 // In order for a new QUIC session to be established via alternate-protocol
5406 // without racing an HTTP connection, we need the host resolution to happen
5407 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5408 // connection to the the server, in this test we require confirmation
5409 // before encrypting so the HTTP job will still start.
5410 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295411 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125412 "");
zhongyica364fbb2015-12-12 03:39:125413
rch3f4b8452016-02-23 16:59:325414 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435415 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5416 false);
Ryan Hamilton9835e662018-08-02 05:36:275417 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125418
bnc691fda62016-08-12 00:43:165419 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125420 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365421 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015422 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125423
5424 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525425 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015426 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125427
5428 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525429 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125430
bnc691fda62016-08-12 00:43:165431 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125432 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525433 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5434 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125435}
5436
5437TEST_P(QuicNetworkTransactionTest,
5438 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Nick Harper72ade192019-07-17 03:30:425439 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595440 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235441 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495442 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255443 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235444 mock_quic_data.AddWrite(SYNCHRONOUS,
5445 ConstructInitialSettingsPacket(packet_num++));
5446 }
Nick Harper057264a82019-09-12 23:33:495447 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365448 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235449 SYNCHRONOUS,
5450 ConstructClientRequestHeadersPacket(
5451 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5452 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215453 // Peer sending data from an non-existing stream causes this end to raise
5454 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335455 mock_quic_data.AddRead(
5456 ASYNC, ConstructServerRstPacket(
5457 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5458 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215459 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tangaadb84b2019-08-31 01:00:235460 mock_quic_data.AddWrite(
5461 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5462 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5463 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
5464 quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125465 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5466
5467 // The non-alternate protocol job needs to hang in order to guarantee that
5468 // the alternate-protocol job will "win".
5469 AddHangingNonAlternateProtocolSocketData();
5470
5471 // In order for a new QUIC session to be established via alternate-protocol
5472 // without racing an HTTP connection, we need the host resolution to happen
5473 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5474 // connection to the the server, in this test we require confirmation
5475 // before encrypting so the HTTP job will still start.
5476 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295477 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125478 "");
zhongyica364fbb2015-12-12 03:39:125479
rch3f4b8452016-02-23 16:59:325480 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435481 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5482 false);
Ryan Hamilton9835e662018-08-02 05:36:275483 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125484
bnc691fda62016-08-12 00:43:165485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125486 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365487 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015488 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125489
5490 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525491 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015492 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125493 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525494 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125495
bnc691fda62016-08-12 00:43:165496 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525497 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125498}
5499
Nick Harper057264a82019-09-12 23:33:495500TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:595501 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235502 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495503 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255504 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235505 mock_quic_data.AddWrite(SYNCHRONOUS,
5506 ConstructInitialSettingsPacket(packet_num++));
5507 }
Nick Harper057264a82019-09-12 23:33:495508 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365509 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235510 SYNCHRONOUS,
5511 ConstructClientRequestHeadersPacket(
5512 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5513 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485514 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335515 mock_quic_data.AddRead(
5516 ASYNC, ConstructServerResponseHeadersPacket(
5517 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5518 GetResponseHeaders("200 OK")));
5519 mock_quic_data.AddRead(
5520 ASYNC, ConstructServerRstPacket(
5521 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5522 quic::QUIC_STREAM_CANCELLED));
Renjie Tangaadb84b2019-08-31 01:00:235523 mock_quic_data.AddWrite(SYNCHRONOUS,
5524 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485525 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5526 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5527
5528 // The non-alternate protocol job needs to hang in order to guarantee that
5529 // the alternate-protocol job will "win".
5530 AddHangingNonAlternateProtocolSocketData();
5531
5532 // In order for a new QUIC session to be established via alternate-protocol
5533 // without racing an HTTP connection, we need the host resolution to happen
5534 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5535 // connection to the the server, in this test we require confirmation
5536 // before encrypting so the HTTP job will still start.
5537 host_resolver_.set_synchronous_mode(true);
5538 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5539 "");
rchcd5f1c62016-06-23 02:43:485540
5541 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435542 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5543 false);
Ryan Hamilton9835e662018-08-02 05:36:275544 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485545
bnc691fda62016-08-12 00:43:165546 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485547 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365548 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015549 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485550
5551 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525552 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485553 // Read the headers.
robpercival214763f2016-07-01 23:27:015554 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485555
bnc691fda62016-08-12 00:43:165556 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485557 ASSERT_TRUE(response != nullptr);
5558 ASSERT_TRUE(response->headers.get() != nullptr);
5559 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5560 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525561 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085562 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5563 response->connection_info);
rchcd5f1c62016-06-23 02:43:485564
5565 std::string response_data;
bnc691fda62016-08-12 00:43:165566 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485567}
5568
Nick Harper057264a82019-09-12 23:33:495569TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Nick Harper72ade192019-07-17 03:30:425570 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595571 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235572 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495573 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255574 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235575 mock_quic_data.AddWrite(SYNCHRONOUS,
5576 ConstructInitialSettingsPacket(packet_num++));
5577 }
Nick Harper057264a82019-09-12 23:33:495578 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365579 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235580 SYNCHRONOUS,
5581 ConstructClientRequestHeadersPacket(
5582 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5583 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335584 mock_quic_data.AddRead(
5585 ASYNC, ConstructServerRstPacket(
5586 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5587 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485588 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5589 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5590
5591 // The non-alternate protocol job needs to hang in order to guarantee that
5592 // the alternate-protocol job will "win".
5593 AddHangingNonAlternateProtocolSocketData();
5594
5595 // In order for a new QUIC session to be established via alternate-protocol
5596 // without racing an HTTP connection, we need the host resolution to happen
5597 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5598 // connection to the the server, in this test we require confirmation
5599 // before encrypting so the HTTP job will still start.
5600 host_resolver_.set_synchronous_mode(true);
5601 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5602 "");
rchcd5f1c62016-06-23 02:43:485603
5604 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435605 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5606 false);
Ryan Hamilton9835e662018-08-02 05:36:275607 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485608
bnc691fda62016-08-12 00:43:165609 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485610 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365611 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015612 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485613
5614 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525615 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485616 // Read the headers.
robpercival214763f2016-07-01 23:27:015617 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485618}
5619
[email protected]1e960032013-12-20 19:00:205620TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305621 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525622 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585623 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305624 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505625 MockRead(ASYNC, close->data(), close->length()),
5626 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5627 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305628 };
Ryan Sleevib8d7ea02018-05-07 20:01:015629 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305630 socket_factory_.AddSocketDataProvider(&quic_data);
5631
5632 // Main job which will succeed even though the alternate job fails.
5633 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025634 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5635 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5636 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305637
Ryan Sleevib8d7ea02018-05-07 20:01:015638 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305639 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565640 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305641
rch3f4b8452016-02-23 16:59:325642 CreateSession();
David Schinazic8281052019-01-24 06:14:175643 AddQuicAlternateProtocolMapping(
5644 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195645 SendRequestAndExpectHttpResponse("hello from http");
5646 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305647}
5648
Matt Menkeb32ba5122019-09-10 19:17:055649TEST_P(QuicNetworkTransactionTest,
5650 BrokenAlternateProtocolWithNetworkIsolationKey) {
5651 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5652 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5653 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5654 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5655
5656 base::test::ScopedFeatureList feature_list;
5657 feature_list.InitWithFeatures(
5658 // enabled_features
5659 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5660 features::kPartitionConnectionsByNetworkIsolationKey},
5661 // disabled_features
5662 {});
5663 // Since HttpServerProperties caches the feature value, have to create a new
5664 // one.
5665 http_server_properties_ = std::make_unique<HttpServerProperties>();
5666
5667 // Alternate-protocol job
5668 std::unique_ptr<quic::QuicEncryptedPacket> close(
5669 ConstructServerConnectionClosePacket(1));
5670 MockRead quic_reads[] = {
5671 MockRead(ASYNC, close->data(), close->length()),
5672 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5673 MockRead(ASYNC, OK), // EOF
5674 };
5675 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5676 socket_factory_.AddSocketDataProvider(&quic_data);
5677
5678 // Main job which will succeed even though the alternate job fails.
5679 MockRead http_reads[] = {
5680 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5681 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5682 MockRead(ASYNC, OK)};
5683
5684 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5685 socket_factory_.AddSocketDataProvider(&http_data);
5686 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5687
5688 CreateSession();
5689 AddQuicAlternateProtocolMapping(
5690 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5691 AddQuicAlternateProtocolMapping(
5692 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5693 request_.network_isolation_key = kNetworkIsolationKey1;
5694 SendRequestAndExpectHttpResponse("hello from http");
5695
5696 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5697 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5698}
5699
[email protected]1e960032013-12-20 19:00:205700TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595701 // Alternate-protocol job
5702 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025703 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595704 };
Ryan Sleevib8d7ea02018-05-07 20:01:015705 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595706 socket_factory_.AddSocketDataProvider(&quic_data);
5707
5708 // Main job which will succeed even though the alternate job fails.
5709 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025710 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5711 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5712 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595713
Ryan Sleevib8d7ea02018-05-07 20:01:015714 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595715 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565716 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595717
rch3f4b8452016-02-23 16:59:325718 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595719
Ryan Hamilton9835e662018-08-02 05:36:275720 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195721 SendRequestAndExpectHttpResponse("hello from http");
5722 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595723}
5724
[email protected]00c159f2014-05-21 22:38:165725TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535726 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165727 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025728 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165729 };
Ryan Sleevib8d7ea02018-05-07 20:01:015730 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165731 socket_factory_.AddSocketDataProvider(&quic_data);
5732
[email protected]eb71ab62014-05-23 07:57:535733 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165734 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025735 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165736 };
5737
Ryan Sleevib8d7ea02018-05-07 20:01:015738 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165739 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5740 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565741 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165742
rtennetib8e80fb2016-05-16 00:12:095743 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325744 CreateSession();
[email protected]00c159f2014-05-21 22:38:165745
Ryan Hamilton9835e662018-08-02 05:36:275746 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165747 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165748 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165749 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015750 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5751 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165752 ExpectQuicAlternateProtocolMapping();
5753}
5754
Zhongyi Shia0cef1082017-08-25 01:49:505755TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5756 // Tests that TCP job is delayed and QUIC job does not require confirmation
5757 // if QUIC was recently supported on the same IP on start.
5758
5759 // Set QUIC support on the last IP address, which is same with the local IP
5760 // address. Require confirmation mode will be turned off immediately when
5761 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435762 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5763 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:505764
Ryan Hamiltonabad59e2019-06-06 04:02:595765 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035766 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495767 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255768 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495769 mock_quic_data.AddWrite(SYNCHRONOUS,
5770 ConstructInitialSettingsPacket(packet_number++));
5771 }
Zhongyi Shi32f2fd02018-04-16 18:23:435772 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495773 SYNCHRONOUS,
5774 ConstructClientRequestHeadersPacket(
5775 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5776 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435777 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335778 ASYNC, ConstructServerResponseHeadersPacket(
5779 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5780 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435781 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335782 mock_quic_data.AddRead(
5783 ASYNC, ConstructServerDataPacket(
5784 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175785 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495786 mock_quic_data.AddWrite(SYNCHRONOUS,
5787 ConstructClientAckPacket(packet_number++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505788 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5789 mock_quic_data.AddRead(ASYNC, 0); // EOF
5790
5791 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5792 // No HTTP data is mocked as TCP job never starts in this case.
5793
5794 CreateSession();
5795 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:435796 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5797 false);
Zhongyi Shia0cef1082017-08-25 01:49:505798
Ryan Hamilton9835e662018-08-02 05:36:275799 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505800
5801 // Stall host resolution so that QUIC job will not succeed synchronously.
5802 // Socket will not be configured immediately and QUIC support is not sorted
5803 // out, TCP job will still be delayed as server properties indicates QUIC
5804 // support on last IP address.
5805 host_resolver_.set_synchronous_mode(false);
5806
5807 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5808 TestCompletionCallback callback;
5809 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5810 IsError(ERR_IO_PENDING));
5811 // Complete host resolution in next message loop so that QUIC job could
5812 // proceed.
5813 base::RunLoop().RunUntilIdle();
5814 EXPECT_THAT(callback.WaitForResult(), IsOk());
5815
5816 CheckWasQuicResponse(&trans);
5817 CheckResponseData(&trans, "hello!");
5818}
5819
5820TEST_P(QuicNetworkTransactionTest,
5821 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5822 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5823 // was recently supported on a different IP address on start.
5824
5825 // Set QUIC support on the last IP address, which is different with the local
5826 // IP address. Require confirmation mode will remain when local IP address is
5827 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435828 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5829 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:505830
Ryan Hamiltonabad59e2019-06-06 04:02:595831 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235832 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495833 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255834 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235835 mock_quic_data.AddWrite(SYNCHRONOUS,
5836 ConstructInitialSettingsPacket(packet_num++));
5837 }
Nick Harper057264a82019-09-12 23:33:495838 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:505839 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235840 SYNCHRONOUS,
5841 ConstructClientRequestHeadersPacket(
5842 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5843 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435844 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335845 ASYNC, ConstructServerResponseHeadersPacket(
5846 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5847 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435848 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335849 mock_quic_data.AddRead(
5850 ASYNC, ConstructServerDataPacket(
5851 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175852 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235853 mock_quic_data.AddWrite(SYNCHRONOUS,
5854 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505855 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5856 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5857 // No HTTP data is mocked as TCP job will be delayed and never starts.
5858
5859 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435860 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5861 false);
Ryan Hamilton9835e662018-08-02 05:36:275862 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505863
5864 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5865 // Socket will not be configured immediately and QUIC support is not sorted
5866 // out, TCP job will still be delayed as server properties indicates QUIC
5867 // support on last IP address.
5868 host_resolver_.set_synchronous_mode(false);
5869
5870 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5871 TestCompletionCallback callback;
5872 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5873 IsError(ERR_IO_PENDING));
5874
5875 // Complete host resolution in next message loop so that QUIC job could
5876 // proceed.
5877 base::RunLoop().RunUntilIdle();
5878 // Explicitly confirm the handshake so that QUIC job could succeed.
5879 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525880 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505881 EXPECT_THAT(callback.WaitForResult(), IsOk());
5882
5883 CheckWasQuicResponse(&trans);
5884 CheckResponseData(&trans, "hello!");
5885}
5886
Ryan Hamilton75f197262017-08-17 14:00:075887TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5888 // Test that NetErrorDetails is correctly populated, even if the
5889 // handshake has not yet been confirmed and no stream has been created.
5890
5891 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595892 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075893 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5894 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5895 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5896
5897 // Main job will also fail.
5898 MockRead http_reads[] = {
5899 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5900 };
5901
Ryan Sleevib8d7ea02018-05-07 20:01:015902 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075903 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5904 socket_factory_.AddSocketDataProvider(&http_data);
5905 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5906
5907 AddHangingNonAlternateProtocolSocketData();
5908 CreateSession();
5909 // Require handshake confirmation to ensure that no QUIC streams are
5910 // created, and to ensure that the TCP job does not wait for the QUIC
5911 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:435912 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5913 false);
Ryan Hamilton75f197262017-08-17 14:00:075914
Ryan Hamilton9835e662018-08-02 05:36:275915 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075916 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5917 TestCompletionCallback callback;
5918 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5919 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5920 // Allow the TCP job to fail.
5921 base::RunLoop().RunUntilIdle();
5922 // Now let the QUIC job fail.
5923 mock_quic_data.Resume();
5924 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5925 ExpectQuicAlternateProtocolMapping();
5926 NetErrorDetails details;
5927 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525928 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075929}
5930
[email protected]1e960032013-12-20 19:00:205931TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455932 // Alternate-protocol job
5933 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025934 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455935 };
Ryan Sleevib8d7ea02018-05-07 20:01:015936 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455937 socket_factory_.AddSocketDataProvider(&quic_data);
5938
[email protected]c92c1b52014-05-31 04:16:065939 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015940 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065941 socket_factory_.AddSocketDataProvider(&quic_data2);
5942
[email protected]4d283b32013-10-17 12:57:275943 // Final job that will proceed when the QUIC job fails.
5944 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025945 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5946 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5947 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275948
Ryan Sleevib8d7ea02018-05-07 20:01:015949 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275950 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565951 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275952
rch3f4b8452016-02-23 16:59:325953 CreateSession();
[email protected]77c6c162013-08-17 02:57:455954
Ryan Hamilton9835e662018-08-02 05:36:275955 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455956
[email protected]4d283b32013-10-17 12:57:275957 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455958
5959 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275960
rch37de576c2015-05-17 20:28:175961 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5962 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455963}
5964
Matt Menkeb32ba5122019-09-10 19:17:055965TEST_P(QuicNetworkTransactionTest,
5966 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
5967 base::test::ScopedFeatureList feature_list;
5968 feature_list.InitWithFeatures(
5969 // enabled_features
5970 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5971 features::kPartitionConnectionsByNetworkIsolationKey},
5972 // disabled_features
5973 {});
5974 // Since HttpServerProperties caches the feature value, have to create a new
5975 // one.
5976 http_server_properties_ = std::make_unique<HttpServerProperties>();
5977
5978 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5979 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5980 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5981 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5982
5983 // Alternate-protocol job
5984 MockRead quic_reads[] = {
5985 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5986 };
5987 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5988 socket_factory_.AddSocketDataProvider(&quic_data);
5989
5990 // Second Alternate-protocol job which will race with the TCP job.
5991 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
5992 socket_factory_.AddSocketDataProvider(&quic_data2);
5993
5994 // Final job that will proceed when the QUIC job fails.
5995 MockRead http_reads[] = {
5996 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5997 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5998 MockRead(ASYNC, OK)};
5999
6000 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
6001 socket_factory_.AddSocketDataProvider(&http_data);
6002 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6003
6004 CreateSession();
6005
6006 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6007 kNetworkIsolationKey1);
6008 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6009 kNetworkIsolationKey2);
6010
6011 request_.network_isolation_key = kNetworkIsolationKey1;
6012 SendRequestAndExpectHttpResponse("hello from http");
6013 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6014 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
6015
6016 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6017 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6018
6019 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
6020 AddHttpDataAndRunRequest();
6021 // Requests using other NetworkIsolationKeys can still use QUIC.
6022 request_.network_isolation_key = kNetworkIsolationKey2;
6023 AddQuicDataAndRunRequest();
6024
6025 // The last two requests should not have changed the alternative service
6026 // mappings.
6027 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6028 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6029}
6030
[email protected]93b31772014-06-19 08:03:356031TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:036032 // Alternate-protocol job
6033 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:596034 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:036035 };
Ryan Sleevib8d7ea02018-05-07 20:01:016036 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036037 socket_factory_.AddSocketDataProvider(&quic_data);
6038
6039 // Main job that will proceed when the QUIC job fails.
6040 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026041 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6042 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6043 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:036044
Ryan Sleevib8d7ea02018-05-07 20:01:016045 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036046 socket_factory_.AddSocketDataProvider(&http_data);
6047
rtennetib8e80fb2016-05-16 00:12:096048 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326049 CreateSession();
[email protected]65768442014-06-06 23:37:036050
Ryan Hamilton9835e662018-08-02 05:36:276051 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:036052
6053 SendRequestAndExpectHttpResponse("hello from http");
6054}
6055
[email protected]eb71ab62014-05-23 07:57:536056TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:336057 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:016058 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:496059 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:336060 socket_factory_.AddSocketDataProvider(&quic_data);
6061
6062 // Main job which will succeed even though the alternate job fails.
6063 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026064 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6065 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6066 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:336067
Ryan Sleevib8d7ea02018-05-07 20:01:016068 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:336069 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566070 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:336071
rch3f4b8452016-02-23 16:59:326072 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276073 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:336074 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:536075
6076 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:336077}
6078
[email protected]4fee9672014-01-08 14:47:156079TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltonabad59e2019-06-06 04:02:596080 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:176081 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
6082 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:046083 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:156084
6085 // When the QUIC connection fails, we will try the request again over HTTP.
6086 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:486087 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:566088 MockRead("hello world"),
6089 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6090 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:156091
Ryan Sleevib8d7ea02018-05-07 20:01:016092 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:156093 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566094 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:156095
6096 // In order for a new QUIC session to be established via alternate-protocol
6097 // without racing an HTTP connection, we need the host resolution to happen
6098 // synchronously.
6099 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:296100 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:566101 "");
[email protected]4fee9672014-01-08 14:47:156102
rch3f4b8452016-02-23 16:59:326103 CreateSession();
David Schinazic8281052019-01-24 06:14:176104 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
6105 AddQuicAlternateProtocolMapping(
6106 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:156107 SendRequestAndExpectHttpResponse("hello world");
6108}
6109
tbansalc3308d72016-08-27 10:25:046110// For an alternative proxy that supports QUIC, test that the request is
6111// successfully fetched by the main job when the alternate proxy job encounters
6112// an error.
6113TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
6114 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
6115}
6116TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
6117 TestAlternativeProxy(ERR_CONNECTION_FAILED);
6118}
6119TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
6120 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
6121}
6122TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
6123 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
6124}
6125TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
6126 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
6127}
6128TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
6129 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
6130}
6131TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
6132 TestAlternativeProxy(ERR_IO_PENDING);
6133}
6134TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
6135 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
6136}
6137
6138TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltonabad59e2019-06-06 04:02:596139 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:176140 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
6141 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:336142 mock_quic_data.AddWrite(
6143 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6144 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
6145 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436146 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:046147 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6148
6149 // When the QUIC connection fails, we will try the request again over HTTP.
6150 MockRead http_reads[] = {
6151 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6152 MockRead("hello world"),
6153 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6154 MockRead(ASYNC, OK)};
6155
Ryan Sleevib8d7ea02018-05-07 20:01:016156 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:046157 socket_factory_.AddSocketDataProvider(&http_data);
6158 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6159
6160 TestProxyDelegate test_proxy_delegate;
6161 const HostPortPair host_port_pair("myproxy.org", 443);
6162 test_proxy_delegate.set_alternative_proxy_server(
6163 ProxyServer::FromPacString("QUIC myproxy.org:443"));
6164 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6165
Ramin Halavatica8d5252018-03-12 05:33:496166 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
6167 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526168 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046169 request_.url = GURL("http://mail.example.org/");
6170
6171 // In order for a new QUIC session to be established via alternate-protocol
6172 // without racing an HTTP connection, we need the host resolution to happen
6173 // synchronously.
6174 host_resolver_.set_synchronous_mode(true);
6175 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:046176
6177 CreateSession();
David Schinazic8281052019-01-24 06:14:176178 crypto_client_stream_factory_.set_handshake_mode(
6179 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:046180 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596181 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166182 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046183}
6184
bnc508835902015-05-12 20:10:296185TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:586186 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386187 EXPECT_FALSE(
6188 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:596189 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236190 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256191 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236192 mock_quic_data.AddWrite(SYNCHRONOUS,
6193 ConstructInitialSettingsPacket(packet_num++));
6194 }
rch5cb522462017-04-25 20:18:366195 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236196 SYNCHRONOUS,
6197 ConstructClientRequestHeadersPacket(
6198 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6199 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436200 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336201 ASYNC, ConstructServerResponseHeadersPacket(
6202 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6203 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436204 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336205 mock_quic_data.AddRead(
6206 ASYNC, ConstructServerDataPacket(
6207 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176208 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236209 mock_quic_data.AddWrite(SYNCHRONOUS,
6210 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:506211 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296212 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6213
bncb07c05532015-05-14 19:07:206214 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096215 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326216 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276217 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296218 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386219 EXPECT_TRUE(
6220 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296221}
6222
zhongyi363c91c2017-03-23 23:16:086223// TODO(zhongyi): disabled this broken test as it was not testing the correct
6224// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
6225TEST_P(QuicNetworkTransactionTest,
6226 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:276227 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:596228 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496229 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:046230
6231 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:046232
6233 test_proxy_delegate.set_alternative_proxy_server(
6234 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:526235 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046236
6237 request_.url = GURL("http://mail.example.org/");
6238
6239 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6240 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016241 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:046242 socket_factory_.AddSocketDataProvider(&socket_data);
6243
6244 // The non-alternate protocol job needs to hang in order to guarantee that
6245 // the alternate-protocol job will "win".
6246 AddHangingNonAlternateProtocolSocketData();
6247
6248 CreateSession();
6249 request_.method = "POST";
6250 ChunkedUploadDataStream upload_data(0);
6251 upload_data.AppendData("1", 1, true);
6252
6253 request_.upload_data_stream = &upload_data;
6254
6255 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6256 TestCompletionCallback callback;
6257 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6258 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6259 EXPECT_NE(OK, callback.WaitForResult());
6260
6261 // Verify that the alternative proxy server is not marked as broken.
6262 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6263
6264 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596265 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276266
6267 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6268 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6269 1);
tbansalc3308d72016-08-27 10:25:046270}
6271
rtenneti56977812016-01-15 19:26:566272TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Nick Harper72ade192019-07-17 03:30:426273 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576274 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566275
Renjie Tangaadb84b2019-08-31 01:00:236276 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:256277 if (!VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236278 mock_quic_data.AddRead(SYNCHRONOUS, OK);
6279 else
6280 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6281 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6282 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6283
6284 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6285 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
6286 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:016287 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:236288 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:566289
rtennetib8e80fb2016-05-16 00:12:096290 // The non-alternate protocol job needs to hang in order to guarantee that
6291 // the alternate-protocol job will "win".
6292 AddHangingNonAlternateProtocolSocketData();
6293
rtenneti56977812016-01-15 19:26:566294 CreateSession();
6295 request_.method = "POST";
6296 ChunkedUploadDataStream upload_data(0);
6297 upload_data.AppendData("1", 1, true);
6298
6299 request_.upload_data_stream = &upload_data;
6300
bnc691fda62016-08-12 00:43:166301 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566302 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166303 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566305 EXPECT_NE(OK, callback.WaitForResult());
6306}
6307
rche11300ef2016-09-02 01:44:286308TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Nick Harper72ade192019-07-17 03:30:426309 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286310 ScopedMockNetworkChangeNotifier network_change_notifier;
6311 MockNetworkChangeNotifier* mock_ncn =
6312 network_change_notifier.mock_network_change_notifier();
6313 mock_ncn->ForceNetworkHandlesSupported();
6314 mock_ncn->SetConnectedNetworksList(
6315 {kDefaultNetworkForTests, kNewNetworkForTests});
6316
Nick Harper72ade192019-07-17 03:30:426317 session_params_.quic_params.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286318 HostPortPair::FromString("mail.example.org:443"));
Nick Harper72ade192019-07-17 03:30:426319 session_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286320
Ryan Hamiltonabad59e2019-06-06 04:02:596321 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286322 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236323 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256324 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236325 socket_data.AddWrite(SYNCHRONOUS,
6326 ConstructInitialSettingsPacket(packet_num++));
6327 }
Fan Yang32c5a112018-12-10 20:06:336328 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236329 SYNCHRONOUS,
6330 ConstructClientRequestHeadersPacket(
6331 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6332 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:286333 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6334 socket_data.AddSocketDataToFactory(&socket_factory_);
6335
Ryan Hamiltonabad59e2019-06-06 04:02:596336 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286337 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6338 socket_data2.AddSocketDataToFactory(&socket_factory_);
6339
6340 // The non-alternate protocol job needs to hang in order to guarantee that
6341 // the alternate-protocol job will "win".
6342 AddHangingNonAlternateProtocolSocketData();
6343
6344 CreateSession();
6345 request_.method = "POST";
6346 ChunkedUploadDataStream upload_data(0);
6347
6348 request_.upload_data_stream = &upload_data;
6349
rdsmith1d343be52016-10-21 20:37:506350 std::unique_ptr<HttpNetworkTransaction> trans(
6351 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286352 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506353 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286354 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6355
6356 base::RunLoop().RunUntilIdle();
6357 upload_data.AppendData("1", 1, true);
6358 base::RunLoop().RunUntilIdle();
6359
6360 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506361 trans.reset();
rche11300ef2016-09-02 01:44:286362 session_.reset();
6363}
6364
Ryan Hamilton4b3574532017-10-30 20:17:256365TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426366 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256367 HostPortPair::FromString("mail.example.org:443"));
6368
Ryan Hamiltonabad59e2019-06-06 04:02:596369 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236370 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256371 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236372 socket_data.AddWrite(SYNCHRONOUS,
6373 ConstructInitialSettingsPacket(packet_num++));
6374 }
Ryan Hamilton4b3574532017-10-30 20:17:256375 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336376 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236377 SYNCHRONOUS,
6378 ConstructClientRequestHeadersPacket(
6379 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6380 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436381 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336382 ASYNC, ConstructServerResponseHeadersPacket(
6383 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6384 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436385 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336386 socket_data.AddRead(
6387 ASYNC, ConstructServerDataPacket(
6388 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176389 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236390 socket_data.AddWrite(SYNCHRONOUS,
6391 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256392 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166393 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236394 SYNCHRONOUS,
6395 client_maker_.MakeAckAndConnectionClosePacket(
6396 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2, 1,
6397 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256398
6399 socket_data.AddSocketDataToFactory(&socket_factory_);
6400
6401 CreateSession();
6402
6403 SendRequestAndExpectQuicResponse("hello!");
6404 session_.reset();
6405}
6406
6407TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426408 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256409 HostPortPair::FromString("mail.example.org:443"));
6410
Ryan Hamiltonabad59e2019-06-06 04:02:596411 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236412 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256413 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236414 socket_data.AddWrite(SYNCHRONOUS,
6415 ConstructInitialSettingsPacket(packet_num++));
6416 }
Ryan Hamilton4b3574532017-10-30 20:17:256417 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336418 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236419 SYNCHRONOUS,
6420 ConstructClientRequestHeadersPacket(
6421 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6422 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436423 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336424 ASYNC, ConstructServerResponseHeadersPacket(
6425 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6426 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436427 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336428 socket_data.AddRead(
6429 ASYNC, ConstructServerDataPacket(
6430 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176431 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236432 socket_data.AddWrite(SYNCHRONOUS,
6433 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256434 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166435 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236436 SYNCHRONOUS,
6437 client_maker_.MakeAckAndConnectionClosePacket(
6438 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2, 1,
6439 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256440
6441 socket_data.AddSocketDataToFactory(&socket_factory_);
6442
6443 CreateSession();
6444
6445 SendRequestAndExpectQuicResponse("hello!");
6446 session_.reset();
6447}
6448
Ryan Hamilton9edcf1a2017-11-22 05:55:176449TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426450 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6451 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256452 HostPortPair::FromString("mail.example.org:443"));
6453
Ryan Hamiltonabad59e2019-06-06 04:02:596454 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256455 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256456 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236457 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176458 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256459 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6460 }
6461 socket_data.AddSocketDataToFactory(&socket_factory_);
6462
6463 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176464 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176465 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6466 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256467
Ryan Hamilton8d9ee76e2018-05-29 23:52:526468 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256469 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6470 TestCompletionCallback callback;
6471 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6472 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176473 while (!callback.have_result()) {
6474 base::RunLoop().RunUntilIdle();
6475 quic_task_runner_->RunUntilIdle();
6476 }
6477 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256478 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176479 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6480 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6481 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526482 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6483 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256484}
6485
Ryan Hamilton9edcf1a2017-11-22 05:55:176486TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426487 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6488 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256489 HostPortPair::FromString("mail.example.org:443"));
6490
Ryan Hamiltonabad59e2019-06-06 04:02:596491 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256492 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256493 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236494 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176495 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256496 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6497 }
6498 socket_data.AddSocketDataToFactory(&socket_factory_);
6499
6500 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176501 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176502 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6503 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256504
Ryan Hamilton8d9ee76e2018-05-29 23:52:526505 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256506 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6507 TestCompletionCallback callback;
6508 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6509 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176510 while (!callback.have_result()) {
6511 base::RunLoop().RunUntilIdle();
6512 quic_task_runner_->RunUntilIdle();
6513 }
6514 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256515 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176516 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6517 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6518 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526519 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6520 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256521}
6522
Cherie Shi7596de632018-02-22 07:28:186523TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Nick Harper72ade192019-07-17 03:30:426524 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6525 session_params_.quic_params.origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186526 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436527 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:526528 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6529 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186530
Ryan Hamiltonabad59e2019-06-06 04:02:596531 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186532 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236533 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256534 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236535 socket_data.AddWrite(SYNCHRONOUS,
6536 ConstructInitialSettingsPacket(packet_num++));
6537 }
Cherie Shi7596de632018-02-22 07:28:186538 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6539 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526540 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236541 SYNCHRONOUS,
6542 client_maker_.MakeConnectionClosePacket(
6543 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186544 socket_data.AddSocketDataToFactory(&socket_factory_);
6545
6546 CreateSession();
6547
6548 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6549 TestCompletionCallback callback;
6550 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6551 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6552 base::RunLoop().RunUntilIdle();
6553 ASSERT_TRUE(callback.have_result());
6554 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6555 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6556 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6557}
6558
ckrasic769733c2016-06-30 00:42:136559// Adds coverage to catch regression such as https://crbug.com/622043
6560TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Nick Harper72ade192019-07-17 03:30:426561 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136562 HostPortPair::FromString("mail.example.org:443"));
6563
Ryan Hamiltonabad59e2019-06-06 04:02:596564 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236565 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:256566 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236567 mock_quic_data.AddWrite(
6568 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6569 }
Zhongyi Shi32f2fd02018-04-16 18:23:436570 mock_quic_data.AddWrite(
6571 SYNCHRONOUS,
6572 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336573 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026574 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436575 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026576 ASYNC,
6577 ConstructServerPushPromisePacket(
6578 1, GetNthClientInitiatedBidirectionalStreamId(0),
6579 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6580 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316581 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:426582 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:256583 !VersionUsesHttp3(version_.transport_version)) ||
6584 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:426585 FLAGS_quic_allow_http3_priority)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026586 mock_quic_data.AddWrite(
6587 SYNCHRONOUS,
6588 ConstructClientPriorityPacket(
6589 client_packet_number++, false,
6590 GetNthServerInitiatedUnidirectionalStreamId(0),
6591 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576592 }
Zhongyi Shi32f2fd02018-04-16 18:23:436593 mock_quic_data.AddRead(
6594 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336595 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026596 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:576597 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436598 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6599 mock_quic_data.AddRead(
6600 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336601 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026602 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436603 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436604 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336605 ASYNC, ConstructServerDataPacket(
6606 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176607 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576608 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436609 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436610 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436611 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336612 ASYNC, ConstructServerDataPacket(
6613 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176614 header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336615 mock_quic_data.AddWrite(SYNCHRONOUS,
6616 ConstructClientAckAndRstPacket(
6617 client_packet_number++,
6618 GetNthServerInitiatedUnidirectionalStreamId(0),
6619 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136620 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6621 mock_quic_data.AddRead(ASYNC, 0); // EOF
6622 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6623
6624 // The non-alternate protocol job needs to hang in order to guarantee that
6625 // the alternate-protocol job will "win".
6626 AddHangingNonAlternateProtocolSocketData();
6627
6628 CreateSession();
6629
6630 // PUSH_PROMISE handling in the http layer gets exercised here.
6631 SendRequestAndExpectQuicResponse("hello!");
6632
6633 request_.url = GURL("https://mail.example.org/pushed.jpg");
6634 SendRequestAndExpectQuicResponse("and hello!");
6635
6636 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:546637 auto entries = net_log_.GetEntries();
ckrasic769733c2016-06-30 00:42:136638 EXPECT_LT(0u, entries.size());
6639
6640 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6641 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006642 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6643 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136644 EXPECT_LT(0, pos);
6645}
6646
rch56ec40a2017-06-23 14:48:446647// Regression test for http://crbug.com/719461 in which a promised stream
6648// is closed before the pushed headers arrive, but after the connection
6649// is closed and before the callbacks are executed.
6650TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Nick Harper72ade192019-07-17 03:30:426651 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6652 session_params_.quic_params.origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446653 HostPortPair::FromString("mail.example.org:443"));
6654
Ryan Hamiltonabad59e2019-06-06 04:02:596655 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236656 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446657 // Initial SETTINGS frame.
Victor Vasiliev7da08172019-10-14 06:04:256658 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236659 mock_quic_data.AddWrite(
6660 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6661 }
rch56ec40a2017-06-23 14:48:446662 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436663 mock_quic_data.AddWrite(
6664 SYNCHRONOUS,
6665 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336666 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026667 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446668 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436669 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026670 ASYNC,
6671 ConstructServerPushPromisePacket(
6672 1, GetNthClientInitiatedBidirectionalStreamId(0),
6673 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6674 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316675 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:426676 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:256677 !VersionUsesHttp3(version_.transport_version)) ||
6678 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:426679 FLAGS_quic_allow_http3_priority)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026680 mock_quic_data.AddWrite(
6681 SYNCHRONOUS,
6682 ConstructClientPriorityPacket(
6683 client_packet_number++, false,
6684 GetNthServerInitiatedUnidirectionalStreamId(0),
6685 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576686 }
rch56ec40a2017-06-23 14:48:446687 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436688 mock_quic_data.AddRead(
6689 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336690 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026691 GetResponseHeaders("200 OK")));
rch56ec40a2017-06-23 14:48:446692 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576693 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436694 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446695 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:436696 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436697 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336698 ASYNC, ConstructServerDataPacket(
6699 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176700 header + "hello!"));
rch56ec40a2017-06-23 14:48:446701 // Write error for the third request.
6702 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6703 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6704 mock_quic_data.AddRead(ASYNC, 0); // EOF
6705 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6706
6707 CreateSession();
6708
6709 // Send a request which triggers a push promise from the server.
6710 SendRequestAndExpectQuicResponse("hello!");
6711
6712 // Start a push transaction that will be cancelled after the connection
6713 // is closed, but before the callback is executed.
6714 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196715 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446716 session_.get());
6717 TestCompletionCallback callback2;
6718 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6720 base::RunLoop().RunUntilIdle();
6721
6722 // Cause the connection to close on a write error.
6723 HttpRequestInfo request3;
6724 request3.method = "GET";
6725 request3.url = GURL("https://mail.example.org/");
6726 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106727 request3.traffic_annotation =
6728 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446729 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6730 TestCompletionCallback callback3;
6731 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6732 IsError(ERR_IO_PENDING));
6733
6734 base::RunLoop().RunUntilIdle();
6735
6736 // When |trans2| is destroyed, the underlying stream will be closed.
6737 EXPECT_FALSE(callback2.have_result());
6738 trans2 = nullptr;
6739
6740 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6741}
6742
ckrasicda193a82016-07-09 00:39:366743TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Nick Harper72ade192019-07-17 03:30:426744 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366745 HostPortPair::FromString("mail.example.org:443"));
6746
Ryan Hamiltonabad59e2019-06-06 04:02:596747 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:366748
Renjief49758b2019-01-11 23:32:416749 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:256750 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236751 mock_quic_data.AddWrite(
6752 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
6753 }
ckrasicda193a82016-07-09 00:39:366754
Victor Vasiliev076657c2019-03-12 02:46:436755 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:566756 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416757 mock_quic_data.AddWrite(
6758 SYNCHRONOUS,
6759 ConstructClientRequestHeadersAndDataFramesPacket(
6760 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6761 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:026762 GetRequestHeaders("POST", "https", "/"), 0, nullptr, {"1"}));
Renjief49758b2019-01-11 23:32:416763 } else {
6764 mock_quic_data.AddWrite(
6765 SYNCHRONOUS,
6766 ConstructClientRequestHeadersAndDataFramesPacket(
6767 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6768 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:026769 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
Renjief49758b2019-01-11 23:32:416770 {header, "1"}));
6771 }
ckrasicda193a82016-07-09 00:39:366772
Zhongyi Shi32f2fd02018-04-16 18:23:436773 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336774 ASYNC, ConstructServerResponseHeadersPacket(
6775 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6776 GetResponseHeaders("200 OK")));
6777
Victor Vasiliev076657c2019-03-12 02:46:436778 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336779 mock_quic_data.AddRead(
6780 ASYNC, ConstructServerDataPacket(
6781 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176782 header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366783
Renjief49758b2019-01-11 23:32:416784 mock_quic_data.AddWrite(
6785 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366786
6787 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6788 mock_quic_data.AddRead(ASYNC, 0); // EOF
6789 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6790
6791 // The non-alternate protocol job needs to hang in order to guarantee that
6792 // the alternate-protocol job will "win".
6793 AddHangingNonAlternateProtocolSocketData();
6794
6795 CreateSession();
6796 request_.method = "POST";
6797 ChunkedUploadDataStream upload_data(0);
6798 upload_data.AppendData("1", 1, true);
6799
6800 request_.upload_data_stream = &upload_data;
6801
6802 SendRequestAndExpectQuicResponse("hello!");
6803}
6804
allada71b2efb2016-09-09 04:57:486805class QuicURLRequestContext : public URLRequestContext {
6806 public:
6807 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6808 MockClientSocketFactory* socket_factory)
6809 : storage_(this) {
6810 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076811 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046812 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486813 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046814 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596815 storage_.set_proxy_resolution_service(
6816 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076817 storage_.set_ssl_config_service(
6818 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486819 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:116820 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:486821 storage_.set_http_server_properties(
Matt Menke609160742019-08-02 18:47:266822 std::make_unique<HttpServerProperties>());
Bence Béky8f9d7d3952017-10-09 19:58:046823 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486824 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046825 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6826 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6827 false));
allada71b2efb2016-09-09 04:57:486828 }
6829
6830 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6831
6832 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6833
6834 private:
6835 MockClientSocketFactory* socket_factory_;
6836 URLRequestContextStorage storage_;
6837};
6838
6839TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
Nick Harper72ade192019-07-17 03:30:426840 session_params_.quic_params.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486841 HostPortPair::FromString("mail.example.org:443"));
6842
Ryan Hamiltonabad59e2019-06-06 04:02:596843 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236844 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256845 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236846 mock_quic_data.AddWrite(SYNCHRONOUS,
6847 ConstructInitialSettingsPacket(packet_num++));
6848 }
Ryan Hamilton0239aac2018-05-19 00:03:136849 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486850 headers["user-agent"] = "";
6851 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336852 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236853 SYNCHRONOUS,
6854 ConstructClientRequestHeadersPacket(
6855 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6856 true, std::move(headers)));
allada71b2efb2016-09-09 04:57:486857
Fan Yang32c5a112018-12-10 20:06:336858 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026859 ASYNC, ConstructServerResponseHeadersPacket(
6860 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6861 GetResponseHeaders("200 OK")));
6862 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:456863 server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:256864 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:456865 ? GetNthClientInitiatedBidirectionalStreamId(0)
6866 : quic::QuicUtils::GetHeadersStreamId(
6867 version_.transport_version));
allada71b2efb2016-09-09 04:57:486868
Victor Vasiliev076657c2019-03-12 02:46:436869 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366870 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336871 ASYNC, ConstructServerDataPacket(
6872 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176873 "Main Resource Data"));
Renjie Tangaadb84b2019-08-31 01:00:236874 mock_quic_data.AddWrite(SYNCHRONOUS,
6875 ConstructClientAckPacket(packet_num++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486876
6877 mock_quic_data.AddRead(ASYNC, 0); // EOF
6878
6879 CreateSession();
6880
6881 TestDelegate delegate;
6882 QuicURLRequestContext quic_url_request_context(std::move(session_),
6883 &socket_factory_);
6884
6885 mock_quic_data.AddSocketDataToFactory(
6886 &quic_url_request_context.socket_factory());
6887 TestNetworkDelegate network_delegate;
6888 quic_url_request_context.set_network_delegate(&network_delegate);
6889
6890 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296891 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6892 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486893 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6894 &ssl_data_);
6895
6896 request->Start();
Wez2a31b222018-06-07 22:07:156897 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486898
6899 EXPECT_LT(0, request->GetTotalSentBytes());
6900 EXPECT_LT(0, request->GetTotalReceivedBytes());
allada71b2efb2016-09-09 04:57:486901 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6902 request->raw_header_size());
Wez0e717112018-06-18 23:09:226903
6904 // Pump the message loop to allow all data to be consumed.
6905 base::RunLoop().RunUntilIdle();
6906
allada71b2efb2016-09-09 04:57:486907 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6908 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6909}
6910
6911TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
Nick Harper72ade192019-07-17 03:30:426912 session_params_.quic_params.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486913 HostPortPair::FromString("mail.example.org:443"));
6914
Ryan Hamiltonabad59e2019-06-06 04:02:596915 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236916 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:256917 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236918 mock_quic_data.AddWrite(
6919 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6920 }
Ryan Hamilton0239aac2018-05-19 00:03:136921 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486922 headers["user-agent"] = "";
6923 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436924 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336925 SYNCHRONOUS,
6926 ConstructClientRequestHeadersPacket(
6927 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026928 true, true, std::move(headers)));
allada71b2efb2016-09-09 04:57:486929
Fan Yang2330d182019-08-05 14:50:506930 const quic::QuicStreamOffset initial = server_maker_.stream_offset(
6931 GetNthClientInitiatedBidirectionalStreamId(0));
Zhongyi Shi32f2fd02018-04-16 18:23:436932 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026933 ASYNC,
6934 ConstructServerPushPromisePacket(
6935 1, GetNthClientInitiatedBidirectionalStreamId(0),
6936 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6937 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Fan Yang2330d182019-08-05 14:50:506938 quic::QuicStreamOffset push_promise_offset = 0;
Victor Vasiliev7da08172019-10-14 06:04:256939 if (VersionUsesHttp3(version_.transport_version)) {
Fan Yang2330d182019-08-05 14:50:506940 push_promise_offset = server_maker_.stream_offset(
6941 GetNthClientInitiatedBidirectionalStreamId(0)) -
6942 initial;
6943 }
allada71b2efb2016-09-09 04:57:486944
Renjie Tang703fea92019-07-23 21:08:316945 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:426946 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:256947 !VersionUsesHttp3(version_.transport_version)) ||
6948 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:426949 (FLAGS_quic_allow_http3_priority))) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026950 mock_quic_data.AddWrite(
6951 SYNCHRONOUS,
6952 ConstructClientPriorityPacket(
6953 client_packet_number++, false,
6954 GetNthServerInitiatedUnidirectionalStreamId(0),
6955 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576956 }
6957
Ryan Hamiltone940bd12019-06-30 02:46:456958 const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:256959 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:456960 ? GetNthClientInitiatedBidirectionalStreamId(0)
6961 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Zhongyi Shi32f2fd02018-04-16 18:23:436962 mock_quic_data.AddRead(
6963 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336964 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026965 GetResponseHeaders("200 OK")));
Ryan Hamiltone940bd12019-06-30 02:46:456966 const quic::QuicStreamOffset final_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:256967 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:456968 ? GetNthClientInitiatedBidirectionalStreamId(0)
6969 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Ryan Hamilton0d65a8c2019-06-07 00:46:026970 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:456971 final_offset - initial_offset;
allada71b2efb2016-09-09 04:57:486972
Yixin Wangb470bc882018-02-15 18:43:576973 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436974 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486975
ckrasicbf2f59c2017-05-04 23:54:366976 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436977 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336978 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026979 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436980 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436981 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336982 ASYNC, ConstructServerDataPacket(
6983 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176984 header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486985
Yixin Wangb470bc882018-02-15 18:43:576986 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436987 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436988 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366989 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336990 ASYNC, ConstructServerDataPacket(
6991 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176992 header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486993
Zhongyi Shi32f2fd02018-04-16 18:23:436994 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486995
6996 CreateSession();
6997
6998 TestDelegate delegate;
6999 QuicURLRequestContext quic_url_request_context(std::move(session_),
7000 &socket_factory_);
7001
7002 mock_quic_data.AddSocketDataToFactory(
7003 &quic_url_request_context.socket_factory());
7004 TestNetworkDelegate network_delegate;
7005 quic_url_request_context.set_network_delegate(&network_delegate);
7006
7007 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:297008 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
7009 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:487010 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
7011 &ssl_data_);
7012
7013 request->Start();
Wez2a31b222018-06-07 22:07:157014 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:487015
7016 EXPECT_LT(0, request->GetTotalSentBytes());
7017 EXPECT_LT(0, request->GetTotalReceivedBytes());
Fan Yang2330d182019-08-05 14:50:507018 EXPECT_EQ(
7019 static_cast<int>(expected_raw_header_response_size + push_promise_offset),
7020 request->raw_header_size());
Wez0e717112018-06-18 23:09:227021
7022 // Pump the message loop to allow all data to be consumed.
7023 base::RunLoop().RunUntilIdle();
7024
allada71b2efb2016-09-09 04:57:487025 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7026 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7027}
7028
Ryan Sleevia9d6aa62019-07-26 13:32:187029TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
7030 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:207031
7032 MockRead http_reads[] = {
7033 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7034 MockRead("hello world"),
7035 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7036 MockRead(ASYNC, OK)};
7037
Ryan Sleevib8d7ea02018-05-07 20:01:017038 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207039 socket_factory_.AddSocketDataProvider(&http_data);
7040 AddCertificate(&ssl_data_);
7041 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7042
Ryan Hamiltonabad59e2019-06-06 04:02:597043 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237044 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257045 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237046 mock_quic_data.AddWrite(SYNCHRONOUS,
7047 ConstructInitialSettingsPacket(packet_num++));
7048 }
Yixin Wang10f477ed2017-11-21 04:20:207049 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237050 SYNCHRONOUS,
7051 ConstructClientRequestHeadersPacket(
7052 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7053 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437054 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337055 ASYNC, ConstructServerResponseHeadersPacket(
7056 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7057 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437058 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:337059 mock_quic_data.AddRead(
7060 ASYNC, ConstructServerDataPacket(
7061 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177062 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:237063 mock_quic_data.AddWrite(SYNCHRONOUS,
7064 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:207065 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7066 mock_quic_data.AddRead(ASYNC, 0); // EOF
7067
7068 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7069
7070 AddHangingNonAlternateProtocolSocketData();
7071 CreateSession();
7072
7073 SendRequestAndExpectHttpResponse("hello world");
7074 SendRequestAndExpectQuicResponse("hello!");
7075}
7076
Ryan Sleevia9d6aa62019-07-26 13:32:187077TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
7078 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:207079
7080 MockRead http_reads[] = {
7081 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7082 MockRead("hello world"),
7083 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7084 MockRead(ASYNC, OK)};
7085
Ryan Sleevib8d7ea02018-05-07 20:01:017086 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207087 socket_factory_.AddSocketDataProvider(&http_data);
7088 AddCertificate(&ssl_data_);
7089 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7090 socket_factory_.AddSocketDataProvider(&http_data);
7091 AddCertificate(&ssl_data_);
7092 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7093
7094 AddHangingNonAlternateProtocolSocketData();
7095 CreateSession();
7096
7097 SendRequestAndExpectHttpResponse("hello world");
7098 SendRequestAndExpectHttpResponse("hello world");
7099}
7100
bnc359ed2a2016-04-29 20:43:457101class QuicNetworkTransactionWithDestinationTest
7102 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:017103 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:057104 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:457105 protected:
7106 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:557107 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:057108 client_headers_include_h2_stream_dependency_(
7109 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:567110 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:457111 destination_type_(GetParam().destination_type),
7112 cert_transparency_verifier_(new MultiLogCTVerifier()),
7113 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:597114 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:117115 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:457116 random_generator_(0),
7117 ssl_data_(ASYNC, OK) {}
7118
7119 void SetUp() override {
7120 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557121 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457122
mmenke6ddfbea2017-05-31 21:48:417123 HttpNetworkSession::Params session_params;
7124 session_params.enable_quic = true;
Nick Harper72ade192019-07-17 03:30:427125 session_params.quic_params.allow_remote_alt_svc = true;
7126 session_params.quic_params.supported_versions = supported_versions_;
7127 session_params.quic_params.headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:057128 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:417129
7130 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:457131
Ryan Hamilton8d9ee76e2018-05-29 23:52:527132 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:417133 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:457134
7135 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277136 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:417137 session_context.quic_crypto_client_stream_factory =
7138 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:457139
mmenke6ddfbea2017-05-31 21:48:417140 session_context.quic_random = &random_generator_;
7141 session_context.client_socket_factory = &socket_factory_;
7142 session_context.host_resolver = &host_resolver_;
7143 session_context.cert_verifier = &cert_verifier_;
7144 session_context.transport_security_state = &transport_security_state_;
7145 session_context.cert_transparency_verifier =
7146 cert_transparency_verifier_.get();
7147 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
7148 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:457149 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:417150 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:597151 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:417152 session_context.http_auth_handler_factory = auth_handler_factory_.get();
7153 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:457154
mmenke6ddfbea2017-05-31 21:48:417155 session_.reset(new HttpNetworkSession(session_params, session_context));
Matt Menkeb566c392019-09-11 23:22:437156 session_->quic_stream_factory()
7157 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:457158 }
7159
7160 void TearDown() override {
7161 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7162 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557163 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457164 PlatformTest::TearDown();
7165 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557166 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:407167 session_.reset();
bnc359ed2a2016-04-29 20:43:457168 }
7169
zhongyie537a002017-06-27 16:48:217170 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:457171 HostPortPair destination;
7172 switch (destination_type_) {
7173 case SAME_AS_FIRST:
7174 destination = HostPortPair(origin1_, 443);
7175 break;
7176 case SAME_AS_SECOND:
7177 destination = HostPortPair(origin2_, 443);
7178 break;
7179 case DIFFERENT:
7180 destination = HostPortPair(kDifferentHostname, 443);
7181 break;
7182 }
bnc3472afd2016-11-17 15:27:217183 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:457184 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:217185 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:077186 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
7187 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:457188 }
7189
Ryan Hamilton8d9ee76e2018-05-29 23:52:527190 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237191 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527192 quic::QuicStreamId stream_id,
7193 bool should_include_version,
7194 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527195 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137196 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457197 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:137198 spdy::SpdyHeaderBlock headers(
7199 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027200 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457201 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027202 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:457203 }
7204
Ryan Hamilton8d9ee76e2018-05-29 23:52:527205 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237206 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527207 quic::QuicStreamId stream_id,
7208 bool should_include_version,
7209 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587210 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:027211 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:457212 }
7213
Ryan Hamilton8d9ee76e2018-05-29 23:52:527214 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237215 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527216 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527217 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137218 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027219 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
7220 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:457221 }
7222
Ryan Hamilton8d9ee76e2018-05-29 23:52:527223 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237224 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527225 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457226 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:437227 std::string header = "";
Nick Harper23290b82019-05-02 00:02:567228 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417229 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:577230 auto header_length =
7231 quic::HttpEncoder::SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:437232 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:417233 }
Ryan Hamilton7505eb92019-06-08 00:22:177234 return maker->MakeDataPacket(packet_number, stream_id, false, true,
Renjief49758b2019-01-11 23:32:417235 header + "hello");
bnc359ed2a2016-04-29 20:43:457236 }
7237
Ryan Hamilton8d9ee76e2018-05-29 23:52:527238 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237239 uint64_t packet_number,
7240 uint64_t largest_received,
7241 uint64_t smallest_received,
7242 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:457243 QuicTestPacketMaker* maker) {
7244 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:497245 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:457246 }
7247
Ryan Hamilton8d9ee76e2018-05-29 23:52:527248 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237249 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:377250 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027251 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:377252 }
7253
bnc359ed2a2016-04-29 20:43:457254 void AddRefusedSocketData() {
7255 std::unique_ptr<StaticSocketDataProvider> refused_data(
7256 new StaticSocketDataProvider());
7257 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7258 refused_data->set_connect_data(refused_connect);
7259 socket_factory_.AddSocketDataProvider(refused_data.get());
7260 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7261 }
7262
7263 void AddHangingSocketData() {
7264 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7265 new StaticSocketDataProvider());
7266 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7267 hanging_data->set_connect_data(hanging_connect);
7268 socket_factory_.AddSocketDataProvider(hanging_data.get());
7269 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7270 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7271 }
7272
7273 bool AllDataConsumed() {
7274 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7275 if (!socket_data_ptr->AllReadDataConsumed() ||
7276 !socket_data_ptr->AllWriteDataConsumed()) {
7277 return false;
7278 }
7279 }
7280 return true;
7281 }
7282
7283 void SendRequestAndExpectQuicResponse(const std::string& host) {
7284 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7285 HttpRequestInfo request;
7286 std::string url("https://");
7287 url.append(host);
7288 request.url = GURL(url);
7289 request.load_flags = 0;
7290 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107291 request.traffic_annotation =
7292 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457293 TestCompletionCallback callback;
7294 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017295 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457296
7297 std::string response_data;
robpercival214763f2016-07-01 23:27:017298 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457299 EXPECT_EQ("hello", response_data);
7300
7301 const HttpResponseInfo* response = trans.GetResponseInfo();
7302 ASSERT_TRUE(response != nullptr);
7303 ASSERT_TRUE(response->headers.get() != nullptr);
7304 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7305 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527306 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:087307 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457308 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377309 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457310 }
7311
Fan Yang32c5a112018-12-10 20:06:337312 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567313 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7314 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367315 }
7316
Ryan Hamilton8d9ee76e2018-05-29 23:52:527317 quic::MockClock clock_;
Nick Harper23290b82019-05-02 00:02:567318 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057319 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567320 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457321 DestinationType destination_type_;
7322 std::string origin1_;
7323 std::string origin2_;
7324 std::unique_ptr<HttpNetworkSession> session_;
7325 MockClientSocketFactory socket_factory_;
7326 MockHostResolver host_resolver_;
7327 MockCertVerifier cert_verifier_;
7328 TransportSecurityState transport_security_state_;
7329 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237330 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457331 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077332 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597333 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457334 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527335 quic::test::MockRandom random_generator_;
Matt Menke609160742019-08-02 18:47:267336 HttpServerProperties http_server_properties_;
bnc359ed2a2016-04-29 20:43:457337 BoundTestNetLog net_log_;
7338 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7339 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7340 static_socket_data_provider_vector_;
7341 SSLSocketDataProvider ssl_data_;
7342};
7343
Victor Costane635086f2019-01-27 05:20:307344INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7345 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:577346 ::testing::ValuesIn(GetPoolingTestParams()),
7347 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:457348
7349// A single QUIC request fails because the certificate does not match the origin
7350// hostname, regardless of whether it matches the alternative service hostname.
7351TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7352 if (destination_type_ == DIFFERENT)
7353 return;
7354
7355 GURL url("https://mail.example.com/");
7356 origin1_ = url.host();
7357
7358 // Not used for requests, but this provides a test case where the certificate
7359 // is valid for the hostname of the alternative service.
7360 origin2_ = "mail.example.org";
7361
zhongyie537a002017-06-27 16:48:217362 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457363
7364 scoped_refptr<X509Certificate> cert(
7365 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247366 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7367 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457368
7369 ProofVerifyDetailsChromium verify_details;
7370 verify_details.cert_verify_result.verified_cert = cert;
7371 verify_details.cert_verify_result.is_issued_by_known_root = true;
7372 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7373
Ryan Hamiltonabad59e2019-06-06 04:02:597374 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457375 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7376 mock_quic_data.AddRead(ASYNC, 0);
7377
7378 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7379
7380 AddRefusedSocketData();
7381
7382 HttpRequestInfo request;
7383 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107384 request.traffic_annotation =
7385 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457386
7387 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7388 TestCompletionCallback callback;
7389 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017390 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457391
7392 EXPECT_TRUE(AllDataConsumed());
7393}
7394
7395// First request opens QUIC session to alternative service. Second request
7396// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527397// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457398TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7399 origin1_ = "mail.example.org";
7400 origin2_ = "news.example.org";
7401
zhongyie537a002017-06-27 16:48:217402 SetQuicAlternativeService(origin1_);
7403 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457404
7405 scoped_refptr<X509Certificate> cert(
7406 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247407 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7408 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7409 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457410
7411 ProofVerifyDetailsChromium verify_details;
7412 verify_details.cert_verify_result.verified_cert = cert;
7413 verify_details.cert_verify_result.is_issued_by_known_root = true;
7414 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7415
Yixin Wang079ad542018-01-11 04:06:057416 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177417 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7418 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057419 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177420 QuicTestPacketMaker server_maker(
7421 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7422 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457423
Ryan Hamiltonabad59e2019-06-06 04:02:597424 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237425 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257426 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237427 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7428 packet_num++, &client_maker));
7429 }
Fan Yang32c5a112018-12-10 20:06:337430 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237431 SYNCHRONOUS,
7432 ConstructClientRequestHeadersPacket(
7433 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7434 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:027435 mock_quic_data.AddRead(
7436 ASYNC,
7437 ConstructServerResponseHeadersPacket(
7438 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437439 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337440 ASYNC,
7441 ConstructServerDataPacket(
7442 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237443 mock_quic_data.AddWrite(
7444 SYNCHRONOUS,
7445 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457446
Yixin Wang079ad542018-01-11 04:06:057447 client_maker.set_hostname(origin2_);
7448 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457449
Zhongyi Shi32f2fd02018-04-16 18:23:437450 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027451 SYNCHRONOUS,
7452 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237453 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027454 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7455 mock_quic_data.AddRead(
7456 ASYNC,
7457 ConstructServerResponseHeadersPacket(
7458 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437459 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337460 ASYNC,
7461 ConstructServerDataPacket(
7462 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237463 mock_quic_data.AddWrite(
7464 SYNCHRONOUS,
7465 ConstructClientAckPacket(packet_num++, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457466 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7467 mock_quic_data.AddRead(ASYNC, 0); // EOF
7468
7469 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7470
7471 AddHangingSocketData();
7472 AddHangingSocketData();
7473
Nick Harpereb483e12019-05-14 00:18:097474 scoped_refptr<TestTaskRunner> quic_task_runner(new TestTaskRunner(&clock_));
Fan Yangc9e00dc2018-10-09 14:17:567475 QuicStreamFactoryPeer::SetAlarmFactory(
7476 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097477 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Fan Yangc9e00dc2018-10-09 14:17:567478 &clock_));
7479
bnc359ed2a2016-04-29 20:43:457480 SendRequestAndExpectQuicResponse(origin1_);
7481 SendRequestAndExpectQuicResponse(origin2_);
7482
7483 EXPECT_TRUE(AllDataConsumed());
7484}
7485
7486// First request opens QUIC session to alternative service. Second request does
7487// not pool to it, even though destination matches, because certificate is not
7488// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527489// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457490TEST_P(QuicNetworkTransactionWithDestinationTest,
7491 DoNotPoolIfCertificateInvalid) {
7492 origin1_ = "news.example.org";
7493 origin2_ = "mail.example.com";
7494
zhongyie537a002017-06-27 16:48:217495 SetQuicAlternativeService(origin1_);
7496 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457497
7498 scoped_refptr<X509Certificate> cert1(
7499 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247500 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7501 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7502 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457503
7504 scoped_refptr<X509Certificate> cert2(
7505 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247506 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7507 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457508
7509 ProofVerifyDetailsChromium verify_details1;
7510 verify_details1.cert_verify_result.verified_cert = cert1;
7511 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7512 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7513
7514 ProofVerifyDetailsChromium verify_details2;
7515 verify_details2.cert_verify_result.verified_cert = cert2;
7516 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7517 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7518
Yixin Wang079ad542018-01-11 04:06:057519 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177520 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7521 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057522 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177523 QuicTestPacketMaker server_maker1(
7524 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7525 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457526
Ryan Hamiltonabad59e2019-06-06 04:02:597527 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:237528 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257529 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237530 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7531 packet_num++, &client_maker1));
7532 }
Fan Yang32c5a112018-12-10 20:06:337533 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237534 SYNCHRONOUS,
7535 ConstructClientRequestHeadersPacket(
7536 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7537 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437538 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337539 ASYNC,
7540 ConstructServerResponseHeadersPacket(
7541 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437542 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337543 ASYNC,
7544 ConstructServerDataPacket(
7545 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437546 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237547 SYNCHRONOUS,
7548 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457549 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7550 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7551
7552 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7553
Yixin Wang079ad542018-01-11 04:06:057554 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177555 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7556 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057557 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177558 QuicTestPacketMaker server_maker2(
7559 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7560 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457561
Ryan Hamiltonabad59e2019-06-06 04:02:597562 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:237563 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:257564 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237565 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7566 packet_num2++, &client_maker2));
7567 }
Fan Yang32c5a112018-12-10 20:06:337568 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237569 SYNCHRONOUS,
7570 ConstructClientRequestHeadersPacket(
7571 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7572 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437573 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337574 ASYNC,
7575 ConstructServerResponseHeadersPacket(
7576 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437577 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337578 ASYNC,
7579 ConstructServerDataPacket(
7580 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437581 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237582 SYNCHRONOUS,
7583 ConstructClientAckPacket(packet_num2++, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457584 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7585 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7586
7587 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7588
bnc359ed2a2016-04-29 20:43:457589 SendRequestAndExpectQuicResponse(origin1_);
7590 SendRequestAndExpectQuicResponse(origin2_);
7591
7592 EXPECT_TRUE(AllDataConsumed());
7593}
7594
ckrasicdee37572017-04-06 22:42:277595// crbug.com/705109 - this confirms that matching request with a body
7596// triggers a crash (pre-fix).
7597TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Nick Harper72ade192019-07-17 03:30:427598 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277599 HostPortPair::FromString("mail.example.org:443"));
7600
Ryan Hamiltonabad59e2019-06-06 04:02:597601 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237602 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257603 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237604 mock_quic_data.AddWrite(
7605 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7606 }
Zhongyi Shi32f2fd02018-04-16 18:23:437607 mock_quic_data.AddWrite(
7608 SYNCHRONOUS,
7609 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337610 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027611 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437612 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027613 ASYNC,
7614 ConstructServerPushPromisePacket(
7615 1, GetNthClientInitiatedBidirectionalStreamId(0),
7616 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7617 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:317618
7619 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:427620 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:257621 !VersionUsesHttp3(version_.transport_version)) ||
7622 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:427623 FLAGS_quic_allow_http3_priority)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027624 mock_quic_data.AddWrite(
7625 SYNCHRONOUS,
7626 ConstructClientPriorityPacket(
7627 client_packet_number++, false,
7628 GetNthServerInitiatedUnidirectionalStreamId(0),
7629 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577630 }
Zhongyi Shi32f2fd02018-04-16 18:23:437631 mock_quic_data.AddRead(
7632 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337633 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027634 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:577635 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437636 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7637 mock_quic_data.AddRead(
7638 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337639 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027640 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437641 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437642 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337643 ASYNC, ConstructServerDataPacket(
7644 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177645 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577646 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437647 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417648
Victor Vasiliev076657c2019-03-12 02:46:437649 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437650 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337651 ASYNC, ConstructServerDataPacket(
7652 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177653 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277654
7655 // Because the matching request has a body, we will see the push
7656 // stream get cancelled, and the matching request go out on the
7657 // wire.
Fan Yang32c5a112018-12-10 20:06:337658 mock_quic_data.AddWrite(SYNCHRONOUS,
7659 ConstructClientAckAndRstPacket(
7660 client_packet_number++,
7661 GetNthServerInitiatedUnidirectionalStreamId(0),
7662 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277663 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437664 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567665 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417666 mock_quic_data.AddWrite(
7667 SYNCHRONOUS,
7668 ConstructClientRequestHeadersAndDataFramesPacket(
7669 client_packet_number++,
7670 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7671 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027672 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, {kBody}));
Renjief49758b2019-01-11 23:32:417673 } else {
7674 mock_quic_data.AddWrite(
7675 SYNCHRONOUS,
7676 ConstructClientRequestHeadersAndDataFramesPacket(
7677 client_packet_number++,
7678 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7679 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027680 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7681 {header3, kBody}));
Renjief49758b2019-01-11 23:32:417682 }
ckrasicdee37572017-04-06 22:42:277683
7684 // We see the same response as for the earlier pushed and cancelled
7685 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437686 mock_quic_data.AddRead(
7687 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337688 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027689 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:437690 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337691 ASYNC, ConstructServerDataPacket(
7692 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177693 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277694
Yixin Wangb470bc882018-02-15 18:43:577695 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437696 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277697 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7698 mock_quic_data.AddRead(ASYNC, 0); // EOF
7699 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7700
7701 // The non-alternate protocol job needs to hang in order to guarantee that
7702 // the alternate-protocol job will "win".
7703 AddHangingNonAlternateProtocolSocketData();
7704
7705 CreateSession();
7706
7707 // PUSH_PROMISE handling in the http layer gets exercised here.
7708 SendRequestAndExpectQuicResponse("hello!");
7709
7710 request_.url = GURL("https://mail.example.org/pushed.jpg");
7711 ChunkedUploadDataStream upload_data(0);
7712 upload_data.AppendData("1", 1, true);
7713 request_.upload_data_stream = &upload_data;
7714 SendRequestAndExpectQuicResponse("and hello!");
7715}
7716
Bence Béky7538a952018-02-01 16:59:527717// Regression test for https://crbug.com/797825: If pushed headers describe a
7718// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7719// not be called (otherwise a DCHECK fails).
7720TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137721 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527722 pushed_request_headers[":authority"] = "";
7723 pushed_request_headers[":method"] = "GET";
7724 pushed_request_headers[":path"] = "/";
7725 pushed_request_headers[":scheme"] = "nosuchscheme";
7726
Nick Harper72ade192019-07-17 03:30:427727 session_params_.quic_params.origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:527728 HostPortPair::FromString("mail.example.org:443"));
7729
Ryan Hamiltonabad59e2019-06-06 04:02:597730 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:527731
Renjie Tangaadb84b2019-08-31 01:00:237732 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257733 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237734 mock_quic_data.AddWrite(SYNCHRONOUS,
7735 ConstructInitialSettingsPacket(packet_num++));
7736 }
Bence Béky7538a952018-02-01 16:59:527737 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237738 SYNCHRONOUS,
7739 ConstructClientRequestHeadersPacket(
7740 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7741 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:527742
Fan Yang32c5a112018-12-10 20:06:337743 mock_quic_data.AddRead(
7744 ASYNC, ConstructServerPushPromisePacket(
7745 1, GetNthClientInitiatedBidirectionalStreamId(0),
7746 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027747 std::move(pushed_request_headers), &server_maker_));
Renjie Tangaadb84b2019-08-31 01:00:237748 mock_quic_data.AddWrite(
7749 SYNCHRONOUS,
7750 ConstructClientRstPacket(packet_num++,
7751 GetNthServerInitiatedUnidirectionalStreamId(0),
7752 quic::QUIC_INVALID_PROMISE_URL));
Bence Béky7538a952018-02-01 16:59:527753
Zhongyi Shi32f2fd02018-04-16 18:23:437754 mock_quic_data.AddRead(
7755 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337756 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027757 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:237758 mock_quic_data.AddWrite(SYNCHRONOUS,
7759 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527760
Zhongyi Shi32f2fd02018-04-16 18:23:437761 mock_quic_data.AddRead(
7762 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337763 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027764 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437765 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437766 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337767 ASYNC, ConstructServerDataPacket(
7768 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177769 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:237770 mock_quic_data.AddWrite(SYNCHRONOUS,
7771 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527772
7773 mock_quic_data.AddRead(ASYNC, 0);
7774 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7775
7776 // The non-alternate protocol job needs to hang in order to guarantee that
7777 // the alternate-protocol job will "win".
7778 AddHangingNonAlternateProtocolSocketData();
7779
7780 CreateSession();
7781
7782 // PUSH_PROMISE handling in the http layer gets exercised here.
7783 SendRequestAndExpectQuicResponse("hello!");
7784
7785 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7786 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7787}
7788
Yixin Wang46a273ec302018-01-23 17:59:567789// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147790TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567791 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147792 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567793 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497794 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567795
Ryan Hamiltonabad59e2019-06-06 04:02:597796 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237797 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257798 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237799 mock_quic_data.AddWrite(SYNCHRONOUS,
7800 ConstructInitialSettingsPacket(packet_num++));
7801 }
Fan Yang32c5a112018-12-10 20:06:337802 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237803 SYNCHRONOUS,
7804 ConstructClientRequestHeadersPacket(
7805 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7806 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7807 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337808 mock_quic_data.AddRead(
7809 ASYNC, ConstructServerResponseHeadersPacket(
7810 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7811 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567812
7813 const char get_request[] =
7814 "GET / HTTP/1.1\r\n"
7815 "Host: mail.example.org\r\n"
7816 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437817 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567818 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417819 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357820 SYNCHRONOUS,
7821 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237822 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7823 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417824 } else {
7825 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417826 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357827 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:237828 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7829 1, 1, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417830 }
7831
Yixin Wang46a273ec302018-01-23 17:59:567832 const char get_response[] =
7833 "HTTP/1.1 200 OK\r\n"
7834 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437835 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437836 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337837 ASYNC, ConstructServerDataPacket(
7838 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177839 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:437840 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337841 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417842 SYNCHRONOUS, ConstructServerDataPacket(
7843 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:177844 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:237845 mock_quic_data.AddWrite(SYNCHRONOUS,
7846 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567847 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7848
7849 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417850 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237851 ConstructClientRstPacket(packet_num++,
7852 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417853 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567854
7855 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7856
7857 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7858
7859 CreateSession();
7860
7861 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097862 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567863 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7864 HeadersHandler headers_handler;
7865 trans.SetBeforeHeadersSentCallback(
7866 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7867 base::Unretained(&headers_handler)));
7868 RunTransaction(&trans);
7869 CheckWasHttpResponse(&trans);
7870 CheckResponsePort(&trans, 70);
7871 CheckResponseData(&trans, "0123456789");
7872 EXPECT_TRUE(headers_handler.was_proxied());
7873 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7874
7875 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7876 // proxy socket to disconnect.
7877 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7878
7879 base::RunLoop().RunUntilIdle();
7880 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7881 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7882}
7883
7884// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147885TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567886 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147887 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567888 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497889 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567890
Ryan Hamiltonabad59e2019-06-06 04:02:597891 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237892 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257893 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237894 mock_quic_data.AddWrite(SYNCHRONOUS,
7895 ConstructInitialSettingsPacket(packet_num++));
7896 }
Fan Yang32c5a112018-12-10 20:06:337897 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237898 SYNCHRONOUS,
7899 ConstructClientRequestHeadersPacket(
7900 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7901 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7902 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337903 mock_quic_data.AddRead(
7904 ASYNC, ConstructServerResponseHeadersPacket(
7905 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7906 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567907
7908 SpdyTestUtil spdy_util;
7909
Ryan Hamilton0239aac2018-05-19 00:03:137910 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567911 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437912 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567913 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417914 mock_quic_data.AddWrite(
7915 SYNCHRONOUS,
7916 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237917 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7918 1, 1, 1, false,
7919 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:417920 } else {
7921 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417922 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357923 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:237924 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7925 1, 1, 1, false,
7926 {header, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417927 }
Ryan Hamilton0239aac2018-05-19 00:03:137928 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567929 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437930 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437931 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177932 ASYNC, ConstructServerDataPacket(
7933 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7934 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567935
Ryan Hamilton0239aac2018-05-19 00:03:137936 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197937 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:437938 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437939 mock_quic_data.AddRead(
7940 SYNCHRONOUS,
7941 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337942 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437943 header3 + std::string(data_frame.data(), data_frame.size())));
Renjie Tangaadb84b2019-08-31 01:00:237944 mock_quic_data.AddWrite(SYNCHRONOUS,
7945 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567946 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7947
7948 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437949 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237950 ConstructClientRstPacket(packet_num++,
7951 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417952 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567953
7954 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7955
7956 SSLSocketDataProvider ssl_data(ASYNC, OK);
7957 ssl_data.next_proto = kProtoHTTP2;
7958 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7959
7960 CreateSession();
7961
7962 request_.url = GURL("https://mail.example.org/");
7963 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7964 HeadersHandler headers_handler;
7965 trans.SetBeforeHeadersSentCallback(
7966 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7967 base::Unretained(&headers_handler)));
7968 RunTransaction(&trans);
7969 CheckWasSpdyResponse(&trans);
7970 CheckResponsePort(&trans, 70);
7971 CheckResponseData(&trans, "0123456789");
7972 EXPECT_TRUE(headers_handler.was_proxied());
7973 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7974
Wez0e717112018-06-18 23:09:227975 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7976 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567977 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7978
7979 base::RunLoop().RunUntilIdle();
7980 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7981 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7982}
7983
7984// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7985// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147986TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567987 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147988 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567989 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497990 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567991
Ryan Hamiltonabad59e2019-06-06 04:02:597992 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:417993 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:257994 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237995 mock_quic_data.AddWrite(
7996 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7997 }
Fan Yang32c5a112018-12-10 20:06:337998 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417999 SYNCHRONOUS,
8000 ConstructClientRequestHeadersPacket(
8001 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:048002 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:028003 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338004 mock_quic_data.AddRead(
8005 ASYNC, ConstructServerResponseHeadersPacket(
8006 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8007 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568008
Ryan Hamilton8d9ee76e2018-05-29 23:52:528009 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568010 const char get_request_1[] =
8011 "GET / HTTP/1.1\r\n"
8012 "Host: mail.example.org\r\n"
8013 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438014 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:568015 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418016 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:178017 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8018 write_packet_index++, false,
8019 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
8020 false, quic::QuicStringPiece(get_request_1)));
Renjief49758b2019-01-11 23:32:418021 } else {
8022 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:178023 SYNCHRONOUS, ConstructClientAckAndMultipleDataFramesPacket(
8024 write_packet_index++, false,
8025 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
8026 false, {header, std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:418027 }
8028
Yixin Wang46a273ec302018-01-23 17:59:568029 const char get_response_1[] =
8030 "HTTP/1.1 200 OK\r\n"
8031 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438032 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:438033 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438034 ASYNC, ConstructServerDataPacket(
8035 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178036 header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:418037 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:568038
Victor Vasiliev076657c2019-03-12 02:46:438039 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338040 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178041 SYNCHRONOUS, ConstructServerDataPacket(
8042 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
8043 false, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:418044 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:568045
Renjief49758b2019-01-11 23:32:418046 mock_quic_data.AddWrite(
8047 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568048
8049 const char get_request_2[] =
8050 "GET /2 HTTP/1.1\r\n"
8051 "Host: mail.example.org\r\n"
8052 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438053 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:568054 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418055 mock_quic_data.AddWrite(
8056 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358057 ConstructClientMultipleDataFramesPacket(
8058 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:178059 false, false, {header4, std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:358060 } else {
8061 mock_quic_data.AddWrite(
8062 SYNCHRONOUS,
Ryan Hamilton7505eb92019-06-08 00:22:178063 ConstructClientDataPacket(
8064 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
8065 false, false, quic::QuicStringPiece(get_request_2)));
Renjief49758b2019-01-11 23:32:418066 }
Yixin Wang46a273ec302018-01-23 17:59:568067
8068 const char get_response_2[] =
8069 "HTTP/1.1 200 OK\r\n"
8070 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438071 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:438072 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438073 ASYNC, ConstructServerDataPacket(
8074 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178075 header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:418076 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:568077
Victor Vasiliev076657c2019-03-12 02:46:438078 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528079 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178080 SYNCHRONOUS, ConstructServerDataPacket(
8081 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
8082 false, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:418083 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:568084
Renjief49758b2019-01-11 23:32:418085 mock_quic_data.AddWrite(
8086 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:568087 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8088
Renjief49758b2019-01-11 23:32:418089 mock_quic_data.AddWrite(
8090 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418091 ConstructClientRstPacket(write_packet_index++,
8092 GetNthClientInitiatedBidirectionalStreamId(0),
8093 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568094
8095 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8096
8097 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8098
8099 CreateSession();
8100
8101 request_.url = GURL("https://mail.example.org/");
8102 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8103 HeadersHandler headers_handler_1;
8104 trans_1.SetBeforeHeadersSentCallback(
8105 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8106 base::Unretained(&headers_handler_1)));
8107 RunTransaction(&trans_1);
8108 CheckWasHttpResponse(&trans_1);
8109 CheckResponsePort(&trans_1, 70);
8110 CheckResponseData(&trans_1, "0123456789");
8111 EXPECT_TRUE(headers_handler_1.was_proxied());
8112 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8113
8114 request_.url = GURL("https://mail.example.org/2");
8115 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8116 HeadersHandler headers_handler_2;
8117 trans_2.SetBeforeHeadersSentCallback(
8118 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8119 base::Unretained(&headers_handler_2)));
8120 RunTransaction(&trans_2);
8121 CheckWasHttpResponse(&trans_2);
8122 CheckResponsePort(&trans_2, 70);
8123 CheckResponseData(&trans_2, "0123456");
8124 EXPECT_TRUE(headers_handler_2.was_proxied());
8125 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8126
8127 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8128 // proxy socket to disconnect.
8129 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8130
8131 base::RunLoop().RunUntilIdle();
8132 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8133 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8134}
8135
8136// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
8137// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
8138// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:148139TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:568140 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148141 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568142 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498143 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568144
Ryan Hamiltonabad59e2019-06-06 04:02:598145 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238146 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258147 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238148 mock_quic_data.AddWrite(SYNCHRONOUS,
8149 ConstructInitialSettingsPacket(packet_num++));
8150 }
Yixin Wang46a273ec302018-01-23 17:59:568151
8152 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:338153 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238154 SYNCHRONOUS,
8155 ConstructClientRequestHeadersPacket(
8156 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8157 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8158 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438159 mock_quic_data.AddRead(
8160 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338161 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028162 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568163
8164 // GET request, response, and data over QUIC tunnel for first request
8165 const char get_request[] =
8166 "GET / HTTP/1.1\r\n"
8167 "Host: mail.example.org\r\n"
8168 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438169 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568170 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418171 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358172 SYNCHRONOUS,
8173 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238174 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8175 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418176 } else {
8177 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418178 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358179 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238180 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8181 1, 1, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418182 }
8183
Yixin Wang46a273ec302018-01-23 17:59:568184 const char get_response[] =
8185 "HTTP/1.1 200 OK\r\n"
8186 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438187 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:568188 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338189 ASYNC, ConstructServerDataPacket(
8190 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178191 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:438192 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338193 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418194 SYNCHRONOUS, ConstructServerDataPacket(
8195 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178196 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238197 mock_quic_data.AddWrite(SYNCHRONOUS,
8198 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568199
8200 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438201 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238202 SYNCHRONOUS,
8203 ConstructClientRequestHeadersPacket(
8204 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8205 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8206 ConnectRequestHeaders("different.example.org:443"),
8207 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438208 mock_quic_data.AddRead(
8209 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338210 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028211 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568212
8213 // GET request, response, and data over QUIC tunnel for second request
8214 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138215 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568216 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438217 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:568218 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418219 mock_quic_data.AddWrite(
8220 SYNCHRONOUS,
8221 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238222 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8223 4, 4, 1, false,
8224 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:418225 } else {
8226 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418227 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358228 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238229 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8230 4, 4, 1, false,
8231 {header4, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418232 }
Yixin Wang46a273ec302018-01-23 17:59:568233
Ryan Hamilton0239aac2018-05-19 00:03:138234 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568235 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438236 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438237 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178238 ASYNC, ConstructServerDataPacket(
8239 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8240 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568241
Ryan Hamilton0239aac2018-05-19 00:03:138242 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198243 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:438244 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438245 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438246 ASYNC, ConstructServerDataPacket(
8247 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438248 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568249
Renjie Tangaadb84b2019-08-31 01:00:238250 mock_quic_data.AddWrite(SYNCHRONOUS,
8251 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:568252 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8253
8254 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418255 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238256 ConstructClientRstPacket(packet_num++,
8257 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418258 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568259 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438260 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238261 ConstructClientRstPacket(packet_num++,
8262 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418263 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568264
8265 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8266
8267 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8268
8269 SSLSocketDataProvider ssl_data(ASYNC, OK);
8270 ssl_data.next_proto = kProtoHTTP2;
8271 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8272
8273 CreateSession();
8274
8275 request_.url = GURL("https://mail.example.org/");
8276 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8277 HeadersHandler headers_handler_1;
8278 trans_1.SetBeforeHeadersSentCallback(
8279 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8280 base::Unretained(&headers_handler_1)));
8281 RunTransaction(&trans_1);
8282 CheckWasHttpResponse(&trans_1);
8283 CheckResponsePort(&trans_1, 70);
8284 CheckResponseData(&trans_1, "0123456789");
8285 EXPECT_TRUE(headers_handler_1.was_proxied());
8286 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8287
8288 request_.url = GURL("https://different.example.org/");
8289 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8290 HeadersHandler headers_handler_2;
8291 trans_2.SetBeforeHeadersSentCallback(
8292 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8293 base::Unretained(&headers_handler_2)));
8294 RunTransaction(&trans_2);
8295 CheckWasSpdyResponse(&trans_2);
8296 CheckResponsePort(&trans_2, 70);
8297 CheckResponseData(&trans_2, "0123456");
8298 EXPECT_TRUE(headers_handler_2.was_proxied());
8299 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8300
8301 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8302 // proxy socket to disconnect.
8303 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8304
8305 base::RunLoop().RunUntilIdle();
8306 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8307 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8308}
8309
8310// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148311TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568312 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148313 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568314 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498315 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568316
Ryan Hamiltonabad59e2019-06-06 04:02:598317 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238318 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258319 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238320 mock_quic_data.AddWrite(SYNCHRONOUS,
8321 ConstructInitialSettingsPacket(packet_num++));
8322 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:528323 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238324 SYNCHRONOUS,
8325 ConstructClientRequestHeadersPacket(
8326 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8327 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8328 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338329 mock_quic_data.AddRead(
8330 ASYNC, ConstructServerResponseHeadersPacket(
8331 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8332 GetResponseHeaders("500")));
8333 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:238334 mock_quic_data.AddWrite(
8335 SYNCHRONOUS,
8336 ConstructClientAckAndRstPacket(
8337 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8338 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568339
8340 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8341
8342 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8343
8344 CreateSession();
8345
8346 request_.url = GURL("https://mail.example.org/");
8347 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8348 HeadersHandler headers_handler;
8349 trans.SetBeforeHeadersSentCallback(
8350 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8351 base::Unretained(&headers_handler)));
8352 TestCompletionCallback callback;
8353 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8354 EXPECT_EQ(ERR_IO_PENDING, rv);
8355 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8356 EXPECT_EQ(false, headers_handler.was_proxied());
8357
8358 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8359 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8360}
8361
8362// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148363TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568364 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148365 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568366 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498367 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568368
Ryan Hamiltonabad59e2019-06-06 04:02:598369 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238370 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258371 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238372 mock_quic_data.AddWrite(SYNCHRONOUS,
8373 ConstructInitialSettingsPacket(packet_num++));
8374 }
Fan Yang32c5a112018-12-10 20:06:338375 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238376 SYNCHRONOUS,
8377 ConstructClientRequestHeadersPacket(
8378 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8379 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8380 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:568381 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8382
8383 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8384
8385 CreateSession();
8386
8387 request_.url = GURL("https://mail.example.org/");
8388 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8389 HeadersHandler headers_handler;
8390 trans.SetBeforeHeadersSentCallback(
8391 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8392 base::Unretained(&headers_handler)));
8393 TestCompletionCallback callback;
8394 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8395 EXPECT_EQ(ERR_IO_PENDING, rv);
8396 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8397
8398 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8399 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8400}
8401
8402// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8403// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148404TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568405 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148406 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568407 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498408 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568409
Ryan Hamiltonabad59e2019-06-06 04:02:598410 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238411 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258412 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238413 mock_quic_data.AddWrite(SYNCHRONOUS,
8414 ConstructInitialSettingsPacket(packet_num++));
8415 }
Fan Yang32c5a112018-12-10 20:06:338416 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238417 SYNCHRONOUS,
8418 ConstructClientRequestHeadersPacket(
8419 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8420 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8421 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438422 mock_quic_data.AddRead(
8423 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338424 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028425 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238426 mock_quic_data.AddWrite(
8427 SYNCHRONOUS,
8428 ConstructClientAckAndRstPacket(
8429 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8430 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568431
Zhongyi Shi32f2fd02018-04-16 18:23:438432 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238433 SYNCHRONOUS,
8434 ConstructClientRequestHeadersPacket(
8435 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8436 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8437 ConnectRequestHeaders("mail.example.org:443"),
8438 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438439 mock_quic_data.AddRead(
8440 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338441 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028442 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568443
8444 const char get_request[] =
8445 "GET / HTTP/1.1\r\n"
8446 "Host: mail.example.org\r\n"
8447 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438448 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568449 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418450 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358451 SYNCHRONOUS,
8452 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238453 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8454 2, 2, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418455 } else {
8456 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418457 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358458 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238459 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8460 2, 2, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418461 }
Yixin Wang46a273ec302018-01-23 17:59:568462 const char get_response[] =
8463 "HTTP/1.1 200 OK\r\n"
8464 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438465 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438466 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338467 ASYNC, ConstructServerDataPacket(
8468 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178469 header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528470
Victor Vasiliev076657c2019-03-12 02:46:438471 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338472 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418473 SYNCHRONOUS, ConstructServerDataPacket(
8474 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178475 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238476 mock_quic_data.AddWrite(SYNCHRONOUS,
8477 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568478 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8479
8480 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418481 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238482 ConstructClientRstPacket(packet_num++,
8483 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418484 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568485
8486 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8487
8488 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8489 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8490
8491 SSLSocketDataProvider ssl_data(ASYNC, OK);
8492 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8493
8494 CreateSession();
8495
8496 request_.url = GURL("https://mail.example.org/");
8497 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8498 HeadersHandler headers_handler;
8499 trans.SetBeforeHeadersSentCallback(
8500 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8501 base::Unretained(&headers_handler)));
8502 TestCompletionCallback callback;
8503 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8504 EXPECT_EQ(ERR_IO_PENDING, rv);
8505 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8506
8507 rv = trans.RestartIgnoringLastError(callback.callback());
8508 EXPECT_EQ(ERR_IO_PENDING, rv);
8509 EXPECT_EQ(OK, callback.WaitForResult());
8510
8511 CheckWasHttpResponse(&trans);
8512 CheckResponsePort(&trans, 70);
8513 CheckResponseData(&trans, "0123456789");
8514 EXPECT_EQ(true, headers_handler.was_proxied());
8515 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8516
8517 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8518 // proxy socket to disconnect.
8519 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8520
8521 base::RunLoop().RunUntilIdle();
8522 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8523 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8524}
8525
8526// Checks if a request's specified "user-agent" header shows up correctly in the
8527// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148528TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008529 const char kConfiguredUserAgent[] = "Configured User-Agent";
8530 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568531 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148532 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568533 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498534 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568535
Ryan Hamiltonabad59e2019-06-06 04:02:598536 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238537 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258538 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238539 mock_quic_data.AddWrite(SYNCHRONOUS,
8540 ConstructInitialSettingsPacket(packet_num++));
8541 }
Yixin Wang46a273ec302018-01-23 17:59:568542
Ryan Hamilton0239aac2018-05-19 00:03:138543 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008544 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338545 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028546 SYNCHRONOUS,
8547 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238548 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8549 false, HttpProxyConnectJob::kH2QuicTunnelPriority, std::move(headers),
8550 0));
Yixin Wang46a273ec302018-01-23 17:59:568551 // Return an error, so the transaction stops here (this test isn't interested
8552 // in the rest).
8553 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8554
8555 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8556
Matt Menked732ea42019-03-08 12:05:008557 StaticHttpUserAgentSettings http_user_agent_settings(
8558 std::string() /* accept_language */, kConfiguredUserAgent);
8559 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568560 CreateSession();
8561
8562 request_.url = GURL("https://mail.example.org/");
8563 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008564 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568565 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8566 HeadersHandler headers_handler;
8567 trans.SetBeforeHeadersSentCallback(
8568 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8569 base::Unretained(&headers_handler)));
8570 TestCompletionCallback callback;
8571 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8572 EXPECT_EQ(ERR_IO_PENDING, rv);
8573 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8574
8575 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8576 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8577}
8578
Yixin Wang00fc44c2018-01-23 21:12:208579// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8580// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148581TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208582 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148583 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208584 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498585 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208586
8587 const RequestPriority request_priority = MEDIUM;
8588
Ryan Hamiltonabad59e2019-06-06 04:02:598589 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238590 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258591 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238592 mock_quic_data.AddWrite(SYNCHRONOUS,
8593 ConstructInitialSettingsPacket(packet_num++));
8594 }
Zhongyi Shi32f2fd02018-04-16 18:23:438595 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238596 SYNCHRONOUS,
8597 ConstructClientRequestHeadersPacket(
8598 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8599 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8600 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:208601 // Return an error, so the transaction stops here (this test isn't interested
8602 // in the rest).
8603 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8604
8605 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8606
8607 CreateSession();
8608
8609 request_.url = GURL("https://mail.example.org/");
8610 HttpNetworkTransaction trans(request_priority, session_.get());
8611 TestCompletionCallback callback;
8612 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8613 EXPECT_EQ(ERR_IO_PENDING, rv);
8614 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8615
8616 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8617 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8618}
8619
Matt Menkeedaf3b82019-03-14 21:39:448620// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8621// HTTP/2 stream dependency and weights given the request priority.
8622TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8623 session_params_.enable_quic = true;
8624 session_params_.enable_quic_proxies_for_https_urls = true;
8625 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8626 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8627
8628 const RequestPriority kRequestPriority = MEDIUM;
8629 const RequestPriority kRequestPriority2 = LOWEST;
8630
Ryan Hamiltonabad59e2019-06-06 04:02:598631 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:258632 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238633 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
8634 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8635 } else {
8636 mock_quic_data.AddWrite(
8637 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8638 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
8639 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8640 ConnectRequestHeaders("mail.example.org:443"), 0));
8641 }
Matt Menkeedaf3b82019-03-14 21:39:448642 // This should never be reached.
8643 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8644 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8645
8646 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:598647 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:448648 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8649 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8650
8651 int original_max_sockets_per_group =
8652 ClientSocketPoolManager::max_sockets_per_group(
8653 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8654 ClientSocketPoolManager::set_max_sockets_per_group(
8655 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8656 int original_max_sockets_per_pool =
8657 ClientSocketPoolManager::max_sockets_per_pool(
8658 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8659 ClientSocketPoolManager::set_max_sockets_per_pool(
8660 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8661 CreateSession();
8662
8663 request_.url = GURL("https://mail.example.org/");
8664 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8665 TestCompletionCallback callback;
8666 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8667 EXPECT_EQ(ERR_IO_PENDING, rv);
8668
8669 HttpRequestInfo request2;
8670 request2.url = GURL("https://mail.example.org/some/other/path/");
8671 request2.traffic_annotation =
8672 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8673
8674 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8675 TestCompletionCallback callback2;
8676 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8677 EXPECT_EQ(ERR_IO_PENDING, rv2);
8678
8679 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8680 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8681
8682 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8683
8684 ClientSocketPoolManager::set_max_sockets_per_pool(
8685 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8686 original_max_sockets_per_pool);
8687 ClientSocketPoolManager::set_max_sockets_per_group(
8688 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8689 original_max_sockets_per_group);
8690}
8691
Yixin Wang46a273ec302018-01-23 17:59:568692// Test the request-challenge-retry sequence for basic auth, over a QUIC
8693// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148694TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568695 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8696 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:568697
8698 std::unique_ptr<QuicTestPacketMaker> client_maker;
8699 std::unique_ptr<QuicTestPacketMaker> server_maker;
8700
8701 // On the second pass, the body read of the auth challenge is synchronous, so
8702 // IsConnectedAndIdle returns false. The socket should still be drained and
8703 // reused. See http://crbug.com/544255.
8704 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338705 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178706 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8707 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338708 client_headers_include_h2_stream_dependency_));
8709 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178710 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8711 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568712
8713 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148714 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568715 proxy_resolution_service_ =
8716 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498717 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568718
Ryan Hamiltonabad59e2019-06-06 04:02:598719 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528720 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568721
Renjie Tangaadb84b2019-08-31 01:00:238722 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258723 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238724 mock_quic_data.AddWrite(
8725 SYNCHRONOUS, client_maker->MakeInitialSettingsPacket(packet_num++));
8726 }
Yixin Wang46a273ec302018-01-23 17:59:568727
8728 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438729 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028730 client_maker->MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238731 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8732 false,
Matt Menke6e879bd2019-03-18 17:26:048733 ConvertRequestPriorityToQuicPriority(
8734 HttpProxyConnectJob::kH2QuicTunnelPriority),
Yixin Wang46a273ec302018-01-23 17:59:568735 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028736 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568737
Ryan Hamilton0239aac2018-05-19 00:03:138738 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568739 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8740 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8741 headers["content-length"] = "10";
8742 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028743 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338744 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028745 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568746
8747 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438748 mock_quic_data.AddRead(
8749 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338750 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178751 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568752 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438753 mock_quic_data.AddRead(
8754 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338755 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:178756 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568757 }
8758 server_data_offset += 10;
8759
Renjie Tangaadb84b2019-08-31 01:00:238760 mock_quic_data.AddWrite(
8761 SYNCHRONOUS, client_maker->MakeAckPacket(packet_num++, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568762
8763 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338764 SYNCHRONOUS,
8765 client_maker->MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:238766 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418767 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:188768 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568769
8770 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8771 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8772 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048773 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028774 client_maker->MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238775 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8776 false,
Matt Menke6e879bd2019-03-18 17:26:048777 ConvertRequestPriorityToQuicPriority(
8778 HttpProxyConnectJob::kH2QuicTunnelPriority),
8779 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:028780 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568781
8782 // Response to wrong password
8783 headers =
8784 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8785 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8786 headers["content-length"] = "10";
8787 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028788 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338789 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028790 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568791 mock_quic_data.AddRead(SYNCHRONOUS,
8792 ERR_IO_PENDING); // No more data to read
8793
Fan Yang32c5a112018-12-10 20:06:338794 mock_quic_data.AddWrite(
8795 SYNCHRONOUS,
8796 client_maker->MakeAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:238797 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Fan Yang32c5a112018-12-10 20:06:338798 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568799
8800 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8801 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8802
8803 CreateSession();
8804
8805 request_.url = GURL("https://mail.example.org/");
8806 // Ensure that proxy authentication is attempted even
8807 // when the no authentication data flag is set.
8808 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8809 {
8810 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8811 HeadersHandler headers_handler;
8812 trans.SetBeforeHeadersSentCallback(
8813 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8814 base::Unretained(&headers_handler)));
8815 RunTransaction(&trans);
8816
8817 const HttpResponseInfo* response = trans.GetResponseInfo();
8818 ASSERT_TRUE(response != nullptr);
8819 ASSERT_TRUE(response->headers.get() != nullptr);
8820 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8821 response->headers->GetStatusLine());
8822 EXPECT_TRUE(response->headers->IsKeepAlive());
8823 EXPECT_EQ(407, response->headers->response_code());
8824 EXPECT_EQ(10, response->headers->GetContentLength());
8825 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588826 base::Optional<AuthChallengeInfo> auth_challenge =
8827 response->auth_challenge;
8828 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568829 EXPECT_TRUE(auth_challenge->is_proxy);
8830 EXPECT_EQ("https://proxy.example.org:70",
8831 auth_challenge->challenger.Serialize());
8832 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8833 EXPECT_EQ("basic", auth_challenge->scheme);
8834
8835 TestCompletionCallback callback;
8836 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8837 callback.callback());
8838 EXPECT_EQ(ERR_IO_PENDING, rv);
8839 EXPECT_EQ(OK, callback.WaitForResult());
8840
8841 response = trans.GetResponseInfo();
8842 ASSERT_TRUE(response != nullptr);
8843 ASSERT_TRUE(response->headers.get() != nullptr);
8844 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8845 response->headers->GetStatusLine());
8846 EXPECT_TRUE(response->headers->IsKeepAlive());
8847 EXPECT_EQ(407, response->headers->response_code());
8848 EXPECT_EQ(10, response->headers->GetContentLength());
8849 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588850 auth_challenge = response->auth_challenge;
8851 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568852 EXPECT_TRUE(auth_challenge->is_proxy);
8853 EXPECT_EQ("https://proxy.example.org:70",
8854 auth_challenge->challenger.Serialize());
8855 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8856 EXPECT_EQ("basic", auth_challenge->scheme);
8857 }
8858 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8859 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8860 // reused because it's not connected).
8861 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8862 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8863 }
8864}
8865
Yixin Wang385652a2018-02-16 02:37:238866TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8867 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8868 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:568869 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238870 !client_headers_include_h2_stream_dependency_) {
8871 return;
8872 }
8873
Victor Vasiliev7da08172019-10-14 06:04:258874 if (quic::VersionUsesHttp3(version_.transport_version)) {
Renjie Tangba21e032019-09-27 21:52:288875 // HTTP/3 currently doesn't support PRIORITY.
Ryan Hamiltone940bd12019-06-30 02:46:458876 return;
8877 }
8878
Nick Harper72ade192019-07-17 03:30:428879 session_params_.quic_params.origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:238880 HostPortPair::FromString("mail.example.org:443"));
8881
Fan Yang32c5a112018-12-10 20:06:338882 const quic::QuicStreamId client_stream_0 =
8883 GetNthClientInitiatedBidirectionalStreamId(0);
8884 const quic::QuicStreamId client_stream_1 =
8885 GetNthClientInitiatedBidirectionalStreamId(1);
8886 const quic::QuicStreamId client_stream_2 =
8887 GetNthClientInitiatedBidirectionalStreamId(2);
8888 const quic::QuicStreamId push_stream_0 =
8889 GetNthServerInitiatedUnidirectionalStreamId(0);
8890 const quic::QuicStreamId push_stream_1 =
8891 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238892
Ryan Hamiltonabad59e2019-06-06 04:02:598893 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238894 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258895 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238896 mock_quic_data.AddWrite(SYNCHRONOUS,
8897 ConstructInitialSettingsPacket(packet_num++));
8898 }
Yixin Wang385652a2018-02-16 02:37:238899
8900 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:238901 mock_quic_data.AddWrite(
8902 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8903 packet_num++, client_stream_0, true, true, HIGHEST,
8904 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:028905 mock_quic_data.AddWrite(
8906 SYNCHRONOUS,
8907 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238908 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028909 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
8910 mock_quic_data.AddWrite(
8911 SYNCHRONOUS,
8912 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238913 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028914 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:238915
8916 // Server replies "OK" for the three requests.
Ryan Hamilton0d65a8c2019-06-07 00:46:028917 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8918 1, client_stream_0, false, false,
8919 GetResponseHeaders("200 OK")));
8920 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8921 2, client_stream_1, false, false,
8922 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238923 mock_quic_data.AddWrite(SYNCHRONOUS,
8924 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton0d65a8c2019-06-07 00:46:028925 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8926 3, client_stream_2, false, false,
8927 GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:238928
8929 // Server sends two push promises associated with |client_stream_0|; client
8930 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8931 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:028932 mock_quic_data.AddRead(
8933 ASYNC,
8934 ConstructServerPushPromisePacket(
8935 4, client_stream_0, push_stream_0, false,
8936 GetRequestHeaders("GET", "https", "/pushed_0.jpg"), &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238937 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438938 SYNCHRONOUS,
8939 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238940 packet_num++, false, 4, 3, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:438941 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:028942 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
8943 mock_quic_data.AddRead(
8944 ASYNC,
8945 ConstructServerPushPromisePacket(
8946 5, client_stream_0, push_stream_1, false,
8947 GetRequestHeaders("GET", "https", "/pushed_1.jpg"), &server_maker_));
8948 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientPriorityPacket(
Renjie Tangaadb84b2019-08-31 01:00:238949 packet_num++, false, push_stream_1,
Ryan Hamilton0d65a8c2019-06-07 00:46:028950 push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:238951
8952 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438953 mock_quic_data.AddRead(
8954 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:028955 6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238956 mock_quic_data.AddWrite(SYNCHRONOUS,
8957 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:438958 mock_quic_data.AddRead(
8959 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:028960 7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:238961
8962 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8963 // priority updates to match the request's priority. Client sends PRIORITY
8964 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438965 mock_quic_data.AddWrite(
8966 SYNCHRONOUS,
8967 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238968 packet_num++, false, 7, 7, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:438969 {{push_stream_1, client_stream_2,
8970 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8971 {push_stream_0, client_stream_0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028972 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:238973
8974 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:438975 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438976 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178977 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Renjief49758b2019-01-11 23:32:418978 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438979 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178980 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Renjief49758b2019-01-11 23:32:418981 header + "hello 1!"));
Renjie Tangaadb84b2019-08-31 01:00:238982 mock_quic_data.AddWrite(SYNCHRONOUS,
8983 ConstructClientAckPacket(packet_num++, 9, 8, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:438984 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178985 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Renjief49758b2019-01-11 23:32:418986 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:438987 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438988 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178989 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true,
Renjief49758b2019-01-11 23:32:418990 header2 + "and hello 0!"));
Renjie Tangaadb84b2019-08-31 01:00:238991 mock_quic_data.AddWrite(SYNCHRONOUS,
8992 ConstructClientAckPacket(packet_num++, 11, 10, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:438993 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178994 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Renjief49758b2019-01-11 23:32:418995 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238996
Yixin Wang385652a2018-02-16 02:37:238997 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8998 mock_quic_data.AddRead(ASYNC, 0); // EOF
8999 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9000
9001 // The non-alternate protocol job needs to hang in order to guarantee that
9002 // the alternate-protocol job will "win".
9003 AddHangingNonAlternateProtocolSocketData();
9004
9005 CreateSession();
9006
9007 request_.url = GURL("https://mail.example.org/0.jpg");
9008 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
9009 TestCompletionCallback callback_0;
9010 EXPECT_EQ(ERR_IO_PENDING,
9011 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
9012 base::RunLoop().RunUntilIdle();
9013
9014 request_.url = GURL("https://mail.example.org/1.jpg");
9015 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
9016 TestCompletionCallback callback_1;
9017 EXPECT_EQ(ERR_IO_PENDING,
9018 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
9019 base::RunLoop().RunUntilIdle();
9020
9021 request_.url = GURL("https://mail.example.org/2.jpg");
9022 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
9023 TestCompletionCallback callback_2;
9024 EXPECT_EQ(ERR_IO_PENDING,
9025 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
9026 base::RunLoop().RunUntilIdle();
9027
9028 // Client makes request that matches resource pushed in |pushed_stream_0|.
9029 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
9030 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
9031 TestCompletionCallback callback_3;
9032 EXPECT_EQ(ERR_IO_PENDING,
9033 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
9034 base::RunLoop().RunUntilIdle();
9035
9036 EXPECT_TRUE(callback_0.have_result());
9037 EXPECT_EQ(OK, callback_0.WaitForResult());
9038 EXPECT_TRUE(callback_1.have_result());
9039 EXPECT_EQ(OK, callback_1.WaitForResult());
9040 EXPECT_TRUE(callback_2.have_result());
9041 EXPECT_EQ(OK, callback_2.WaitForResult());
9042
9043 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
9044 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
9045 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
9046 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
9047
9048 mock_quic_data.Resume();
9049 base::RunLoop().RunUntilIdle();
9050 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9051 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9052}
9053
Matt Menke26e41542019-06-05 01:09:519054// Test that NetworkIsolationKey is respected by QUIC connections, when
9055// kPartitionConnectionsByNetworkIsolationKey is enabled.
9056TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Shivani Sharma8ae506c2019-07-21 21:08:279057 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9058 const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
9059 NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
9060 NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
Matt Menke26e41542019-06-05 01:09:519061
Nick Harper72ade192019-07-17 03:30:429062 session_params_.quic_params.origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519063 HostPortPair::FromString("mail.example.org:443"));
9064
9065 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
9066 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
9067 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
9068 // the same way as the HTTP over H2 proxy case.
9069 for (bool use_proxy : {false, true}) {
9070 SCOPED_TRACE(use_proxy);
9071
9072 if (use_proxy) {
9073 proxy_resolution_service_ =
9074 ProxyResolutionService::CreateFixedFromPacResult(
9075 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
9076 } else {
9077 proxy_resolution_service_ = ProxyResolutionService::CreateDirect();
9078 }
9079
9080 GURL url1;
9081 GURL url2;
9082 GURL url3;
9083 if (use_proxy) {
9084 url1 = GURL("http://mail.example.org/1");
9085 url2 = GURL("http://mail.example.org/2");
9086 url3 = GURL("http://mail.example.org/3");
9087 } else {
9088 url1 = GURL("https://mail.example.org/1");
9089 url2 = GURL("https://mail.example.org/2");
9090 url3 = GURL("https://mail.example.org/3");
9091 }
9092
9093 for (bool partition_connections : {false, true}) {
9094 SCOPED_TRACE(partition_connections);
9095
9096 base::test::ScopedFeatureList feature_list;
9097 if (partition_connections) {
9098 feature_list.InitAndEnableFeature(
9099 features::kPartitionConnectionsByNetworkIsolationKey);
9100 } else {
9101 feature_list.InitAndDisableFeature(
9102 features::kPartitionConnectionsByNetworkIsolationKey);
9103 }
9104
9105 // Reads and writes for the unpartitioned case, where only one socket is
9106 // used.
9107
Nick Harper72ade192019-07-17 03:30:429108 session_params_.quic_params.origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519109 HostPortPair::FromString("mail.example.org:443"));
9110
Ryan Hamiltonabad59e2019-06-06 04:02:599111 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:519112 QuicTestPacketMaker client_maker1(
9113 version_,
9114 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9115 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9116 client_headers_include_h2_stream_dependency_);
9117 QuicTestPacketMaker server_maker1(
9118 version_,
9119 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9120 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
9121
Renjie Tangaadb84b2019-08-31 01:00:239122 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259123 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239124 unpartitioned_mock_quic_data.AddWrite(
9125 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
9126 }
Matt Menke26e41542019-06-05 01:09:519127
9128 unpartitioned_mock_quic_data.AddWrite(
9129 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029130 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239131 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9132 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029133 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519134 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029135 ASYNC, server_maker1.MakeResponseHeadersPacket(
9136 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9137 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519138 unpartitioned_mock_quic_data.AddRead(
9139 ASYNC, server_maker1.MakeDataPacket(
9140 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179141 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519142 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239143 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke26e41542019-06-05 01:09:519144
9145 unpartitioned_mock_quic_data.AddWrite(
9146 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029147 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239148 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
9149 false, true,
Matt Menke26e41542019-06-05 01:09:519150 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029151 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519152 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029153 ASYNC, server_maker1.MakeResponseHeadersPacket(
9154 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9155 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519156 unpartitioned_mock_quic_data.AddRead(
9157 ASYNC, server_maker1.MakeDataPacket(
9158 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179159 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519160 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239161 SYNCHRONOUS,
9162 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
Matt Menke26e41542019-06-05 01:09:519163
9164 unpartitioned_mock_quic_data.AddWrite(
9165 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029166 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239167 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
9168 false, true,
Matt Menke26e41542019-06-05 01:09:519169 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029170 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519171 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029172 ASYNC, server_maker1.MakeResponseHeadersPacket(
9173 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
9174 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519175 unpartitioned_mock_quic_data.AddRead(
9176 ASYNC, server_maker1.MakeDataPacket(
9177 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Ryan Hamilton7505eb92019-06-08 00:22:179178 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519179 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239180 SYNCHRONOUS,
9181 ConstructClientAckAndConnectionClosePacket(packet_num++, 6, 5, 1));
Matt Menke26e41542019-06-05 01:09:519182
9183 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9184
9185 // Reads and writes for the partitioned case, where two sockets are used.
9186
Ryan Hamiltonabad59e2019-06-06 04:02:599187 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:519188 QuicTestPacketMaker client_maker2(
9189 version_,
9190 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9191 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9192 client_headers_include_h2_stream_dependency_);
9193 QuicTestPacketMaker server_maker2(
9194 version_,
9195 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9196 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
9197
Renjie Tangaadb84b2019-08-31 01:00:239198 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259199 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239200 partitioned_mock_quic_data1.AddWrite(
9201 SYNCHRONOUS,
9202 client_maker2.MakeInitialSettingsPacket(packet_num2++));
9203 }
Matt Menke26e41542019-06-05 01:09:519204
9205 partitioned_mock_quic_data1.AddWrite(
9206 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029207 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239208 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
9209 true, true,
Matt Menke26e41542019-06-05 01:09:519210 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029211 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519212 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029213 ASYNC, server_maker2.MakeResponseHeadersPacket(
9214 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9215 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519216 partitioned_mock_quic_data1.AddRead(
9217 ASYNC, server_maker2.MakeDataPacket(
9218 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179219 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519220 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239221 SYNCHRONOUS,
9222 client_maker2.MakeAckPacket(packet_num2++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519223
9224 partitioned_mock_quic_data1.AddWrite(
9225 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029226 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239227 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
9228 false, true,
Matt Menke26e41542019-06-05 01:09:519229 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029230 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519231 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029232 ASYNC, server_maker2.MakeResponseHeadersPacket(
9233 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9234 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519235 partitioned_mock_quic_data1.AddRead(
9236 ASYNC, server_maker2.MakeDataPacket(
9237 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179238 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519239 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239240 SYNCHRONOUS,
9241 client_maker2.MakeAckPacket(packet_num2++, 4, 3, 1, true));
Matt Menke26e41542019-06-05 01:09:519242
9243 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9244
Ryan Hamiltonabad59e2019-06-06 04:02:599245 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:519246 QuicTestPacketMaker client_maker3(
9247 version_,
9248 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9249 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9250 client_headers_include_h2_stream_dependency_);
9251 QuicTestPacketMaker server_maker3(
9252 version_,
9253 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9254 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
9255
Renjie Tangaadb84b2019-08-31 01:00:239256 int packet_num3 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259257 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239258 partitioned_mock_quic_data2.AddWrite(
9259 SYNCHRONOUS,
9260 client_maker3.MakeInitialSettingsPacket(packet_num3++));
9261 }
Matt Menke26e41542019-06-05 01:09:519262
9263 partitioned_mock_quic_data2.AddWrite(
9264 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029265 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239266 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9267 true, true,
Matt Menke26e41542019-06-05 01:09:519268 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029269 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519270 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029271 ASYNC, server_maker3.MakeResponseHeadersPacket(
9272 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9273 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519274 partitioned_mock_quic_data2.AddRead(
9275 ASYNC, server_maker3.MakeDataPacket(
9276 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179277 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519278 partitioned_mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239279 SYNCHRONOUS,
9280 client_maker3.MakeAckPacket(packet_num3++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519281
9282 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9283
9284 if (partition_connections) {
9285 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9286 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9287 } else {
9288 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9289 }
9290
9291 CreateSession();
9292
9293 TestCompletionCallback callback;
9294 HttpRequestInfo request1;
9295 request1.method = "GET";
9296 request1.url = GURL(url1);
9297 request1.traffic_annotation =
9298 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9299 request1.network_isolation_key = network_isolation_key1;
9300 HttpNetworkTransaction trans1(LOWEST, session_.get());
9301 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9302 EXPECT_THAT(callback.GetResult(rv), IsOk());
9303 std::string response_data1;
9304 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9305 EXPECT_EQ("1", response_data1);
9306
9307 HttpRequestInfo request2;
9308 request2.method = "GET";
9309 request2.url = GURL(url2);
9310 request2.traffic_annotation =
9311 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9312 request2.network_isolation_key = network_isolation_key2;
9313 HttpNetworkTransaction trans2(LOWEST, session_.get());
9314 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9315 EXPECT_THAT(callback.GetResult(rv), IsOk());
9316 std::string response_data2;
9317 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9318 EXPECT_EQ("2", response_data2);
9319
9320 HttpRequestInfo request3;
9321 request3.method = "GET";
9322 request3.url = GURL(url3);
9323 request3.traffic_annotation =
9324 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9325 request3.network_isolation_key = network_isolation_key1;
9326 HttpNetworkTransaction trans3(LOWEST, session_.get());
9327 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9328 EXPECT_THAT(callback.GetResult(rv), IsOk());
9329 std::string response_data3;
9330 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9331 EXPECT_EQ("3", response_data3);
9332
9333 if (partition_connections) {
9334 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9335 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9336 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9337 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9338 } else {
9339 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9340 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9341 }
9342 }
9343 }
9344}
9345
9346// Test that two requests to the same origin over QUIC tunnels use different
9347// QUIC sessions if their NetworkIsolationKeys don't match, and
9348// kPartitionConnectionsByNetworkIsolationKey is enabled.
9349TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9350 base::test::ScopedFeatureList feature_list;
9351 feature_list.InitAndEnableFeature(
9352 features::kPartitionConnectionsByNetworkIsolationKey);
9353
9354 session_params_.enable_quic = true;
9355 session_params_.enable_quic_proxies_for_https_urls = true;
9356 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
9357 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9358
9359 const char kGetRequest[] =
9360 "GET / HTTP/1.1\r\n"
9361 "Host: mail.example.org\r\n"
9362 "Connection: keep-alive\r\n\r\n";
9363 const char kGetResponse[] =
9364 "HTTP/1.1 200 OK\r\n"
9365 "Content-Length: 10\r\n\r\n";
9366
Ryan Hamiltonabad59e2019-06-06 04:02:599367 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9368 std::make_unique<MockQuicData>(version_),
9369 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519370
9371 for (int index : {0, 1}) {
9372 QuicTestPacketMaker client_maker(
9373 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9374 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9375 client_headers_include_h2_stream_dependency_);
9376 QuicTestPacketMaker server_maker(
9377 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9378 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
9379
Renjie Tangaadb84b2019-08-31 01:00:239380 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259381 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239382 mock_quic_data[index]->AddWrite(
9383 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
9384 }
Matt Menke26e41542019-06-05 01:09:519385
Ryan Hamiltonabad59e2019-06-06 04:02:599386 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519387 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029388 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239389 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9390 false,
Matt Menke26e41542019-06-05 01:09:519391 ConvertRequestPriorityToQuicPriority(
9392 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:029393 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:599394 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029395 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:519396 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9397 false, GetResponseHeaders("200 OK"), nullptr));
9398
9399 std::string header = ConstructDataHeader(strlen(kGetRequest));
9400 if (version_.transport_version != quic::QUIC_VERSION_99) {
Ryan Hamiltonabad59e2019-06-06 04:02:599401 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239402 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
9403 packet_num++, false,
9404 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
9405 1, false, quic::QuicStringPiece(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:519406 } else {
Ryan Hamiltonabad59e2019-06-06 04:02:599407 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239408 SYNCHRONOUS, client_maker.MakeAckAndMultipleDataFramesPacket(
9409 packet_num++, false,
9410 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
9411 1, false, {header, std::string(kGetRequest)}));
Matt Menke26e41542019-06-05 01:09:519412 }
9413
9414 std::string header2 = ConstructDataHeader(strlen(kGetResponse));
Ryan Hamiltonabad59e2019-06-06 04:02:599415 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519416 ASYNC, server_maker.MakeDataPacket(
9417 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179418 false, header2 + std::string(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599419 mock_quic_data[index]->AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179420 SYNCHRONOUS,
9421 server_maker.MakeDataPacket(
9422 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
9423 ConstructDataHeader(10) + std::string("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599424 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239425 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2, 1, true));
Ryan Hamiltonabad59e2019-06-06 04:02:599426 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9427 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:519428
Ryan Hamiltonabad59e2019-06-06 04:02:599429 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:519430 }
9431
9432 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9433 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9434 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9435
9436 CreateSession();
9437
9438 request_.url = GURL("https://mail.example.org/");
9439 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9440 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9441 RunTransaction(&trans);
9442 CheckResponseData(&trans, "0123456789");
9443
9444 HttpRequestInfo request2;
Shivani Sharma8ae506c2019-07-21 21:08:279445 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9446 request_.network_isolation_key = NetworkIsolationKey(kOrigin1, kOrigin1);
Matt Menke26e41542019-06-05 01:09:519447 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9448 RunTransaction(&trans2);
9449 CheckResponseData(&trans2, "0123456789");
9450
Ryan Hamiltonabad59e2019-06-06 04:02:599451 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9452 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9453 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9454 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:519455}
9456
[email protected]61a527782013-02-21 03:58:009457} // namespace test
9458} // namespace net