blob: da85df7dae004d7f421ab2572be6afe98e18f665 [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
120// Run QuicNetworkTransactionWithDestinationTest instances with all value
121// combinations of version and destination_type.
122struct PoolingTestParams {
123 friend std::ostream& operator<<(std::ostream& os,
124 const PoolingTestParams& p) {
Nick Harper23290b82019-05-02 00:02:56125 os << "{ version: " << ParsedQuicVersionToString(p.version)
bnc359ed2a2016-04-29 20:43:45126 << ", destination_type: ";
127 switch (p.destination_type) {
128 case SAME_AS_FIRST:
129 os << "SAME_AS_FIRST";
130 break;
131 case SAME_AS_SECOND:
132 os << "SAME_AS_SECOND";
133 break;
134 case DIFFERENT:
135 os << "DIFFERENT";
136 break;
137 }
Yixin Wang079ad542018-01-11 04:06:05138 os << ", client_headers_include_h2_stream_dependency: "
139 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45140 os << " }";
141 return os;
142 }
143
Nick Harper23290b82019-05-02 00:02:56144 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45145 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05146 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45147};
148
zhongyie537a002017-06-27 16:48:21149std::string GenerateQuicVersionsListForAltSvcHeader(
Nick Harper23290b82019-05-02 00:02:56150 const quic::ParsedQuicVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21151 std::string result = "";
Nick Harper23290b82019-05-02 00:02:56152 for (const quic::ParsedQuicVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21153 if (!result.empty())
154 result.append(",");
Nick Harper23290b82019-05-02 00:02:56155 result.append(base::NumberToString(version.transport_version));
zhongyie537a002017-06-27 16:48:21156 }
157 return result;
158}
159
bnc359ed2a2016-04-29 20:43:45160std::vector<PoolingTestParams> GetPoolingTestParams() {
161 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56162 quic::ParsedQuicVersionVector all_supported_versions =
Ryan Hamilton93424eb82019-08-23 04:28:40163 quic::AllSupportedVersions();
Nick Harper23290b82019-05-02 00:02:56164 for (const quic::ParsedQuicVersion version : all_supported_versions) {
Ryan Hamiltone940bd12019-06-30 02:46:45165 // TODO(rch): crbug.com/978745 - Make this work with TLS
166 if (version.handshake_protocol != quic::PROTOCOL_TLS1_3) {
167 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
168 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
169 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
170 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
171 params.push_back(PoolingTestParams{version, DIFFERENT, false});
172 params.push_back(PoolingTestParams{version, DIFFERENT, true});
173 }
bnc359ed2a2016-04-29 20:43:45174 }
175 return params;
176}
bncb07c05532015-05-14 19:07:20177
[email protected]61a527782013-02-21 03:58:00178} // namespace
179
ryansturm49a8cb12016-06-15 16:51:09180class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12181 public:
ryansturm49a8cb12016-06-15 16:51:09182 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12183
ryansturm49a8cb12016-06-15 16:51:09184 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12185
ryansturm49a8cb12016-06-15 16:51:09186 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
187 HttpRequestHeaders* request_headers) {
188 if (!proxy_info.is_http() && !proxy_info.is_https() &&
189 !proxy_info.is_quic()) {
190 return;
191 }
192 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12193 }
194
195 private:
ryansturm49a8cb12016-06-15 16:51:09196 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12197};
198
tbansal0f56a39a2016-04-07 22:03:38199class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40200 public:
tbansal180587c2017-02-16 15:13:23201 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
202 bool* rtt_notification_received)
203 : should_notify_updated_rtt_(should_notify_updated_rtt),
204 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38205 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40206
tbansal180587c2017-02-16 15:13:23207 bool ShouldNotifyUpdatedRTT() const override {
208 return *should_notify_updated_rtt_;
209 }
tbansalfdf5665b2015-09-21 22:46:40210
tbansal0f56a39a2016-04-07 22:03:38211 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
212 *rtt_notification_received_ = true;
213 }
214
215 void OnConnectionChanged() override {}
216
217 private:
tbansal180587c2017-02-16 15:13:23218 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38219 bool* rtt_notification_received_;
220
221 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
222};
223
224class TestSocketPerformanceWatcherFactory
225 : public SocketPerformanceWatcherFactory {
226 public:
227 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23228 : watcher_count_(0u),
229 should_notify_updated_rtt_(true),
230 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38231 ~TestSocketPerformanceWatcherFactory() override {}
232
233 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42234 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41235 const Protocol protocol,
236 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51237 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38238 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51239 }
240 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42241 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23242 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
243 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40244 }
245
tbansalc8a94ea2015-11-02 23:58:51246 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40247
tbansalc8a94ea2015-11-02 23:58:51248 bool rtt_notification_received() const { return rtt_notification_received_; }
249
tbansal180587c2017-02-16 15:13:23250 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
251 should_notify_updated_rtt_ = should_notify_updated_rtt;
252 }
253
tbansalc8a94ea2015-11-02 23:58:51254 private:
tbansal0f56a39a2016-04-07 22:03:38255 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23256 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51257 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38258
259 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51260};
261
Ryan Hamilton8d9ee76e2018-05-29 23:52:52262class QuicNetworkTransactionTest
263 : public PlatformTest,
264 public ::testing::WithParamInterface<
Nick Harper23290b82019-05-02 00:02:56265 std::tuple<quic::ParsedQuicVersion, bool>>,
Gabriel Charette694c3c332019-08-19 14:53:05266 public WithTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00267 protected:
[email protected]1c04f9522013-02-21 20:32:43268 QuicNetworkTransactionTest()
Yixin Wang079ad542018-01-11 04:06:05269 : version_(std::get<0>(GetParam())),
270 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Nick Harper23290b82019-05-02 00:02:56271 supported_versions_(quic::test::SupportedVersions(version_)),
David Schinazic8281052019-01-24 06:14:17272 random_generator_(0),
273 client_maker_(
274 version_,
275 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
276 &clock_,
277 kDefaultServerHostName,
278 quic::Perspective::IS_CLIENT,
279 client_headers_include_h2_stream_dependency_),
280 server_maker_(
281 version_,
282 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
283 &clock_,
284 kDefaultServerHostName,
285 quic::Perspective::IS_SERVER,
286 false),
Nick Harpereb483e12019-05-14 00:18:09287 quic_task_runner_(new TestTaskRunner(&clock_)),
rtenneti052774e2015-11-24 21:00:12288 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43289 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59290 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11291 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke3233d8f22019-08-20 21:01:49292 http_server_properties_(std::make_unique<HttpServerProperties>()),
rchf114d982015-10-21 01:34:56293 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19294 request_.method = "GET";
rchf114d982015-10-21 01:34:56295 std::string url("https://");
bncb07c05532015-05-14 19:07:20296 url.append(kDefaultServerHostName);
297 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19298 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10299 request_.traffic_annotation =
300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52301 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56302
303 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29304 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56305 verify_details_.cert_verify_result.verified_cert = cert;
306 verify_details_.cert_verify_result.is_issued_by_known_root = true;
307 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43308 }
[email protected]61a527782013-02-21 03:58:00309
dcheng67be2b1f2014-10-27 21:47:29310 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00311 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55312 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00313 }
314
dcheng67be2b1f2014-10-27 21:47:29315 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00316 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
317 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55318 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00319 PlatformTest::TearDown();
320 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55321 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40322 session_.reset();
[email protected]61a527782013-02-21 03:58:00323 }
324
Ryan Hamilton8d9ee76e2018-05-29 23:52:52325 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23326 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03327 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52328 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30329 }
330
Ryan Hamilton8d9ee76e2018-05-29 23:52:52331 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23332 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03333 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52334 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58335 }
336
Ryan Hamilton8d9ee76e2018-05-29 23:52:52337 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23338 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52339 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20340 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58341 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20342 }
343
Ryan Hamilton8d9ee76e2018-05-29 23:52:52344 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23345 uint64_t packet_number,
346 uint64_t largest_received,
347 uint64_t smallest_received,
348 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37349 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49350 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37351 }
352
Ryan Hamilton8d9ee76e2018-05-29 23:52:52353 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23354 uint64_t packet_number,
355 uint64_t largest_received,
356 uint64_t smallest_received,
357 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52358 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23359 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49360 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23361 ack_delay_time);
362 }
363
Ryan Hamilton8d9ee76e2018-05-29 23:52:52364 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23365 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52366 quic::QuicStreamId stream_id,
367 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23368 uint64_t largest_received,
369 uint64_t smallest_received,
370 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58371 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49372 num, false, stream_id, error_code, largest_received, smallest_received,
373 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20374 }
375
Ryan Hamilton8d9ee76e2018-05-29 23:52:52376 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23377 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52378 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41379 quic::QuicRstStreamErrorCode error_code) {
Yixin Wang46a273ec302018-01-23 17:59:56380 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18381 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56382 }
383
Ryan Hamilton8d9ee76e2018-05-29 23:52:52384 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23385 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
386 uint64_t largest_received,
387 uint64_t smallest_received,
388 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58389 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49390 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20391 }
[email protected]61a527782013-02-21 03:58:00392
Ryan Hamilton8d9ee76e2018-05-29 23:52:52393 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58394 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23395 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52396 quic::QuicTime::Delta delta_time_largest_observed,
Fan Yangac867502019-01-28 21:10:23397 uint64_t largest_received,
398 uint64_t smallest_received,
399 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52400 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29401 const std::string& quic_error_details,
402 uint64_t frame_type) {
alyssar2adf3ac2016-05-03 17:12:58403 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12404 num, false, delta_time_largest_observed, largest_received,
Renjie Tangff0d6372019-08-30 22:03:29405 smallest_received, least_unacked, quic_error, quic_error_details,
406 frame_type);
zhongyica364fbb2015-12-12 03:39:12407 }
408
Ryan Hamilton8d9ee76e2018-05-29 23:52:52409 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23410 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12411 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52412 quic::QuicStreamId stream_id,
413 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58414 return server_maker_.MakeRstPacket(num, include_version, stream_id,
415 error_code);
zhongyica364fbb2015-12-12 03:39:12416 }
417
Ryan Hamilton8d9ee76e2018-05-29 23:52:52418 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02419 uint64_t packet_number) {
420 return client_maker_.MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37421 }
422
Ryan Hamilton8d9ee76e2018-05-29 23:52:52423 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23424 uint64_t packet_number,
425 uint64_t largest_received,
426 uint64_t smallest_received,
427 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37428 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49429 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37430 }
431
Ryan Hamilton8d9ee76e2018-05-29 23:52:52432 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23433 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57434 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52435 quic::QuicStreamId id,
436 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02437 RequestPriority request_priority) {
Yixin Wangb470bc882018-02-15 18:43:57438 return client_maker_.MakePriorityPacket(
439 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02440 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wang385652a2018-02-16 02:37:23441 }
442
Ryan Hamilton8d9ee76e2018-05-29 23:52:52443 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25444 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23445 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23446 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23447 uint64_t largest_received,
448 uint64_t smallest_received,
449 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25450 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
Ryan Hamilton0d65a8c2019-06-07 00:46:02451 priority_frames) {
Yixin Wange7ecc472018-03-06 19:00:25452 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23453 packet_number, should_include_version, largest_received,
Ryan Hamilton0d65a8c2019-06-07 00:46:02454 smallest_received, least_unacked, priority_frames);
Yixin Wangb470bc882018-02-15 18:43:57455 }
456
zhongyi32569c62016-01-08 02:54:30457 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13458 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
459 const std::string& scheme,
460 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58461 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30462 }
463
464 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13465 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
466 const std::string& scheme,
467 const std::string& path,
468 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50469 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00470 }
471
Ryan Hamilton0239aac2018-05-19 00:03:13472 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56473 return client_maker_.ConnectRequestHeaders(host_port);
474 }
475
Ryan Hamilton0239aac2018-05-19 00:03:13476 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58477 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00478 }
479
zhongyi32569c62016-01-08 02:54:30480 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13481 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
482 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58483 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30484 }
485
Ryan Hamilton8d9ee76e2018-05-29 23:52:52486 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23487 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52488 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05489 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00490 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52491 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17492 return server_maker_.MakeDataPacket(packet_number, stream_id,
493 should_include_version, fin, data);
[email protected]61a527782013-02-21 03:58:00494 }
495
Ryan Hamilton8d9ee76e2018-05-29 23:52:52496 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23497 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52498 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36499 bool should_include_version,
500 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52501 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17502 return client_maker_.MakeDataPacket(packet_number, stream_id,
503 should_include_version, fin, data);
ckrasicda193a82016-07-09 00:39:36504 }
505
Renjied172e812019-01-16 05:12:35506 std::unique_ptr<quic::QuicEncryptedPacket>
507 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23508 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35509 quic::QuicStreamId stream_id,
510 bool should_include_version,
511 bool fin,
Renjied172e812019-01-16 05:12:35512 const std::vector<std::string> data_writes) {
Ryan Hamilton7505eb92019-06-08 00:22:17513 return client_maker_.MakeMultipleDataFramesPacket(
514 packet_number, stream_id, should_include_version, fin, data_writes);
Renjied172e812019-01-16 05:12:35515 }
516
Ryan Hamilton8d9ee76e2018-05-29 23:52:52517 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23518 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56519 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52520 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23521 uint64_t largest_received,
522 uint64_t smallest_received,
523 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56524 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52525 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56526 return client_maker_.MakeAckAndDataPacket(
527 packet_number, include_version, stream_id, largest_received,
Ryan Hamilton7505eb92019-06-08 00:22:17528 smallest_received, least_unacked, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56529 }
530
Renjied172e812019-01-16 05:12:35531 std::unique_ptr<quic::QuicEncryptedPacket>
532 ConstructClientAckAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23533 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35534 bool include_version,
535 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23536 uint64_t largest_received,
537 uint64_t smallest_received,
538 uint64_t least_unacked,
Renjied172e812019-01-16 05:12:35539 bool fin,
Renjied172e812019-01-16 05:12:35540 const std::vector<std::string> data_writes) {
541 return client_maker_.MakeAckAndMultipleDataFramesPacket(
542 packet_number, include_version, stream_id, largest_received,
Ryan Hamilton7505eb92019-06-08 00:22:17543 smallest_received, least_unacked, fin, data_writes);
Renjied172e812019-01-16 05:12:35544 }
545
Ryan Hamilton8d9ee76e2018-05-29 23:52:52546 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
Fan Yangac867502019-01-28 21:10:23547 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52548 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36549 bool should_include_version,
550 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52551 quic::QuicStreamOffset* offset,
552 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36553 return client_maker_.MakeForceHolDataPacket(
554 packet_number, stream_id, should_include_version, fin, offset, data);
555 }
556
Ryan Hamilton8d9ee76e2018-05-29 23:52:52557 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23558 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52559 quic::QuicStreamId stream_id,
560 bool should_include_version,
561 bool fin,
562 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56563 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
564 should_include_version, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02565 std::move(headers), 0);
Yixin Wang46a273ec302018-01-23 17:59:56566 }
567
Ryan Hamilton8d9ee76e2018-05-29 23:52:52568 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23569 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52570 quic::QuicStreamId stream_id,
571 bool should_include_version,
572 bool fin,
573 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02574 quic::QuicStreamId parent_stream_id) {
Yixin Wang46a273ec302018-01-23 17:59:56575 return ConstructClientRequestHeadersPacket(
576 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:02577 std::move(headers), parent_stream_id);
zhongyi32569c62016-01-08 02:54:30578 }
579
Ryan Hamilton8d9ee76e2018-05-29 23:52:52580 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23581 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52582 quic::QuicStreamId stream_id,
583 bool should_include_version,
584 bool fin,
585 RequestPriority request_priority,
586 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02587 quic::QuicStreamId parent_stream_id) {
Ryan Hamilton0239aac2018-05-19 00:03:13588 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56589 ConvertRequestPriorityToQuicPriority(request_priority);
Ryan Hamilton0d65a8c2019-06-07 00:46:02590 return client_maker_.MakeRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56591 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02592 std::move(headers), parent_stream_id, nullptr);
[email protected]61a527782013-02-21 03:58:00593 }
594
Ryan Hamilton8d9ee76e2018-05-29 23:52:52595 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25596 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23597 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52598 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25599 bool should_include_version,
600 bool fin,
601 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13602 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52603 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25604 size_t* spdy_headers_frame_length,
605 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13606 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25607 ConvertRequestPriorityToQuicPriority(request_priority);
608 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
609 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02610 std::move(headers), parent_stream_id, spdy_headers_frame_length,
Yixin Wange7ecc472018-03-06 19:00:25611 data_writes);
612 }
613
Ryan Hamilton8d9ee76e2018-05-29 23:52:52614 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23615 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52616 quic::QuicStreamId stream_id,
617 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13618 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13619 spdy::SpdyHeaderBlock headers,
ckrasic769733c2016-06-30 00:42:13620 QuicTestPacketMaker* maker) {
621 return maker->MakePushPromisePacket(
622 packet_number, stream_id, promised_stream_id, should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02623 false, std::move(headers), nullptr);
ckrasic769733c2016-06-30 00:42:13624 }
625
Ryan Hamilton8d9ee76e2018-05-29 23:52:52626 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23627 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52628 quic::QuicStreamId stream_id,
629 bool should_include_version,
630 bool fin,
631 spdy::SpdyHeaderBlock headers) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02632 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
633 should_include_version, fin,
634 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30635 }
636
Victor Vasiliev076657c2019-03-12 02:46:43637 std::string ConstructDataHeader(size_t body_len) {
Nick Harper23290b82019-05-02 00:02:56638 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:41639 return "";
640 }
641 quic::HttpEncoder encoder;
642 std::unique_ptr<char[]> buffer;
643 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43644 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41645 }
646
Nick Harper23290b82019-05-02 00:02:56647 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41648 session_params_.enable_quic = true;
Nick Harper72ade192019-07-17 03:30:42649 session_params_.quic_params.supported_versions = supported_versions;
Bence Béky1ceba552019-07-19 17:11:05650 session_params_.quic_params.max_allowed_push_id = quic::kMaxQuicStreamId;
Nick Harper72ade192019-07-17 03:30:42651 session_params_.quic_params.headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:05652 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00653
mmenke6ddfbea2017-05-31 21:48:41654 session_context_.quic_clock = &clock_;
655 session_context_.quic_random = &random_generator_;
656 session_context_.client_socket_factory = &socket_factory_;
657 session_context_.quic_crypto_client_stream_factory =
658 &crypto_client_stream_factory_;
659 session_context_.host_resolver = &host_resolver_;
660 session_context_.cert_verifier = &cert_verifier_;
661 session_context_.transport_security_state = &transport_security_state_;
662 session_context_.cert_transparency_verifier =
663 cert_transparency_verifier_.get();
664 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
665 session_context_.socket_performance_watcher_factory =
666 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59667 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41668 session_context_.ssl_config_service = ssl_config_service_.get();
669 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49670 session_context_.http_server_properties = http_server_properties_.get();
mmenke6ddfbea2017-05-31 21:48:41671 session_context_.net_log = net_log_.bound().net_log();
672
673 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12674 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56675 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
676 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00677 }
678
zhongyi86838d52017-06-30 01:19:44679 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21680
bnc691fda62016-08-12 00:43:16681 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19682 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42683 ASSERT_TRUE(response != nullptr);
684 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19685 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
686 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52687 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:56688 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
689 version_.transport_version),
[email protected]aa9b14d2013-05-10 23:45:19690 response->connection_info);
691 }
692
bnc691fda62016-08-12 00:43:16693 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41694 const HttpResponseInfo* response = trans->GetResponseInfo();
695 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37696 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41697 }
698
bnc691fda62016-08-12 00:43:16699 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19700 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42701 ASSERT_TRUE(response != nullptr);
702 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19703 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
704 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52705 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52706 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19707 response->connection_info);
708 }
709
Yixin Wang46a273ec302018-01-23 17:59:56710 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
711 const HttpResponseInfo* response = trans->GetResponseInfo();
712 ASSERT_TRUE(response != nullptr);
713 ASSERT_TRUE(response->headers.get() != nullptr);
714 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
715 EXPECT_TRUE(response->was_fetched_via_spdy);
716 EXPECT_TRUE(response->was_alpn_negotiated);
717 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
718 response->connection_info);
719 }
720
bnc691fda62016-08-12 00:43:16721 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19722 const std::string& expected) {
723 std::string response_data;
bnc691fda62016-08-12 00:43:16724 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19725 EXPECT_EQ(expected, response_data);
726 }
727
bnc691fda62016-08-12 00:43:16728 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19729 TestCompletionCallback callback;
730 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01731 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
732 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19733 }
734
735 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16736 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
737 RunTransaction(&trans);
738 CheckWasHttpResponse(&trans);
739 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19740 }
741
tbansalc3308d72016-08-27 10:25:04742 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
743 bool used_proxy,
744 uint16_t port) {
745 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
746 HeadersHandler headers_handler;
747 trans.SetBeforeHeadersSentCallback(
748 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
749 base::Unretained(&headers_handler)));
750 RunTransaction(&trans);
751 CheckWasHttpResponse(&trans);
752 CheckResponsePort(&trans, port);
753 CheckResponseData(&trans, expected);
754 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47755 if (used_proxy) {
756 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
757 } else {
758 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
759 }
tbansalc3308d72016-08-27 10:25:04760 }
761
[email protected]aa9b14d2013-05-10 23:45:19762 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56763 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12764 }
765
bnc62a44f022015-04-02 15:59:41766 void SendRequestAndExpectQuicResponseFromProxyOnPort(
767 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46768 uint16_t port) {
bnc62a44f022015-04-02 15:59:41769 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19770 }
771
772 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27773 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19774 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46775 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21776 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12777 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49778 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07779 server, NetworkIsolationKey(), alternative_service, expiration,
780 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19781 }
782
rchbe69cb902016-02-11 01:10:48783 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27784 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48785 const HostPortPair& alternative) {
786 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46787 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21788 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48789 alternative.port());
790 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49791 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07792 server, NetworkIsolationKey(), alternative_service, expiration,
793 supported_versions_);
rchbe69cb902016-02-11 01:10:48794 }
795
[email protected]aa9b14d2013-05-10 23:45:19796 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46797 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34798 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49799 http_server_properties_->GetAlternativeServiceInfos(
800 server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:34801 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49802 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54803 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19804 }
805
[email protected]4d590c9c2014-05-02 05:14:33806 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46807 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34808 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49809 http_server_properties_->GetAlternativeServiceInfos(
810 server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:34811 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54812 EXPECT_EQ(
813 kProtoQUIC,
814 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49815 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54816 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33817 }
818
[email protected]aa9b14d2013-05-10 23:45:19819 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42820 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30821 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30822 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30823 hanging_data->set_connect_data(hanging_connect);
824 hanging_data_.push_back(std::move(hanging_data));
825 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56826 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19827 }
828
Zhongyi Shia6b68d112018-09-24 07:49:03829 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Nick Harper72ade192019-07-17 03:30:42830 session_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
831 session_params_.quic_params.migrate_sessions_early_v2 = true;
832 session_params_.quic_params.retry_on_alternate_network_before_handshake =
833 true;
Zhongyi Shia6b68d112018-09-24 07:49:03834 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
835 MockNetworkChangeNotifier* mock_ncn =
836 scoped_mock_change_notifier_->mock_network_change_notifier();
837 mock_ncn->ForceNetworkHandlesSupported();
838 mock_ncn->SetConnectedNetworksList(
839 {kDefaultNetworkForTests, kNewNetworkForTests});
840 }
841
tbansalc3308d72016-08-27 10:25:04842 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
843 // alternative proxy. Verifies that if the alternative proxy job returns
844 // |error_code|, the request is fetched successfully by the main job.
845 void TestAlternativeProxy(int error_code) {
846 // Use a non-cryptographic scheme for the request URL since this request
847 // will be fetched via proxy with QUIC as the alternative service.
848 request_.url = GURL("http://example.org/");
849 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27850 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04851 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27852 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04853 };
854
Ryan Sleevib8d7ea02018-05-07 20:01:01855 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04856 socket_factory_.AddSocketDataProvider(&quic_data);
857
858 // Main job succeeds and the alternative job fails.
859 // Add data for two requests that will be read by the main job.
860 MockRead http_reads_1[] = {
861 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
862 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
863 MockRead(ASYNC, OK)};
864
865 MockRead http_reads_2[] = {
866 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
867 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
868 MockRead(ASYNC, OK)};
869
Ryan Sleevib8d7ea02018-05-07 20:01:01870 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
871 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04872 socket_factory_.AddSocketDataProvider(&http_data_1);
873 socket_factory_.AddSocketDataProvider(&http_data_2);
874 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
875 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
876
877 TestProxyDelegate test_proxy_delegate;
878 // Proxy URL is different from the request URL.
879 test_proxy_delegate.set_alternative_proxy_server(
880 ProxyServer::FromPacString("QUIC myproxy.org:443"));
881
Lily Houghton8c2f97d2018-01-22 05:06:59882 proxy_resolution_service_ =
883 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49884 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52885 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04886
887 CreateSession();
888 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
889
890 // The first request should be fetched via the HTTPS proxy.
891 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
892
Reilly Grant89a7e512018-01-20 01:57:16893 // Since the main job succeeded only the alternative proxy server should be
894 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59895 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16896 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04897
898 // Verify that the second request completes successfully, and the
899 // alternative proxy server job is not started.
900 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
901 }
902
Fan Yang32c5a112018-12-10 20:06:33903 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56904 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
905 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36906 }
907
Fan Yang32c5a112018-12-10 20:06:33908 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56909 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
910 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36911 }
912
Bence Béky230ac612017-08-30 19:17:08913 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49914 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08915 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49916 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08917 }
918
Nick Harper23290b82019-05-02 00:02:56919 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05920 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:56921 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01922 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52923 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:17924 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:58925 QuicTestPacketMaker client_maker_;
926 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:09927 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:42928 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00929 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56930 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05931 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43932 MockHostResolver host_resolver_;
933 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11934 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42935 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23936 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38937 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07938 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59939 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42940 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:49941 std::unique_ptr<HttpServerProperties> http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41942 HttpNetworkSession::Params session_params_;
943 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19944 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51945 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42946 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56947 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03948 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12949
950 private:
951 void SendRequestAndExpectQuicResponseMaybeFromProxy(
952 const std::string& expected,
bnc62a44f022015-04-02 15:59:41953 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46954 uint16_t port) {
bnc691fda62016-08-12 00:43:16955 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09956 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16957 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09958 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
959 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16960 RunTransaction(&trans);
961 CheckWasQuicResponse(&trans);
962 CheckResponsePort(&trans, port);
963 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09964 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47965 if (used_proxy) {
966 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
967 } else {
968 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
969 }
tbansal7cec3812015-02-05 21:25:12970 }
[email protected]61a527782013-02-21 03:58:00971};
972
Ryan Hamiltone940bd12019-06-30 02:46:45973quic::ParsedQuicVersionVector AllSupportedVersionsWithoutTls() {
974 quic::ParsedQuicVersionVector versions;
Ryan Hamilton93424eb82019-08-23 04:28:40975 for (auto version : quic::AllSupportedVersions()) {
Ryan Hamiltone940bd12019-06-30 02:46:45976 // TODO(rch): crbug.com/978745 - Make this work with TLS
977 if (version.handshake_protocol != quic::PROTOCOL_TLS1_3) {
978 versions.push_back(version);
979 }
980 }
981 return versions;
982}
983
Victor Costane635086f2019-01-27 05:20:30984INSTANTIATE_TEST_SUITE_P(
Yixin Wang385652a2018-02-16 02:37:23985 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05986 QuicNetworkTransactionTest,
Ryan Hamiltone940bd12019-06-30 02:46:45987 ::testing::Combine(::testing::ValuesIn(AllSupportedVersionsWithoutTls()),
Nick Harper23290b82019-05-02 00:02:56988 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:20989
Shivani Sharma8ae506c2019-07-21 21:08:27990// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
991// kAppendInitiatingFrameOriginToNetworkIsolationKey.
992
Ryan Hamiltona64a5bcf2017-11-30 07:35:28993TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:42994 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:28995 base::HistogramTester histograms;
Nick Harper72ade192019-07-17 03:30:42996 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:28997 HostPortPair::FromString("mail.example.org:443"));
998 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27999 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281000
Ryan Hamiltonabad59e2019-06-06 04:02:591001 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021002 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281003 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1004 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1005 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1006
1007 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1008
1009 CreateSession();
1010
1011 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1012 TestCompletionCallback callback;
1013 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1015 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1016
1017 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1018 -ERR_INTERNET_DISCONNECTED, 1);
1019 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1020 -ERR_INTERNET_DISCONNECTED, 1);
1021}
1022
1023TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Nick Harper72ade192019-07-17 03:30:421024 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281025 base::HistogramTester histograms;
Nick Harper72ade192019-07-17 03:30:421026 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281027 HostPortPair::FromString("mail.example.org:443"));
1028 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271029 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281030
Ryan Hamiltonabad59e2019-06-06 04:02:591031 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021032 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281033 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1034 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1035 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1036
1037 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1038
1039 CreateSession();
1040
1041 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1042 TestCompletionCallback callback;
1043 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1044 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1045 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1046
1047 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1048 -ERR_INTERNET_DISCONNECTED, 1);
1049 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1050 -ERR_INTERNET_DISCONNECTED, 1);
1051}
1052
tbansal180587c2017-02-16 15:13:231053TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Nick Harper72ade192019-07-17 03:30:421054 session_params_.quic_params.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231055 HostPortPair::FromString("mail.example.org:443"));
1056
Ryan Hamiltonabad59e2019-06-06 04:02:591057 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021058 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:361059 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021060 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1061 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1062 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431063 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331064 ASYNC, ConstructServerResponseHeadersPacket(
1065 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1066 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431067 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331068 mock_quic_data.AddRead(
1069 ASYNC, ConstructServerDataPacket(
1070 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171071 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431072 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231073 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1074
1075 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1076
1077 CreateSession();
1078 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1079
1080 EXPECT_FALSE(
1081 test_socket_performance_watcher_factory_.rtt_notification_received());
1082 SendRequestAndExpectQuicResponse("hello!");
1083 EXPECT_TRUE(
1084 test_socket_performance_watcher_factory_.rtt_notification_received());
1085}
1086
1087TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Nick Harper72ade192019-07-17 03:30:421088 session_params_.quic_params.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231089 HostPortPair::FromString("mail.example.org:443"));
1090
Ryan Hamiltonabad59e2019-06-06 04:02:591091 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021092 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:361093 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021094 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1095 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1096 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431097 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331098 ASYNC, ConstructServerResponseHeadersPacket(
1099 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1100 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431101 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331102 mock_quic_data.AddRead(
1103 ASYNC, ConstructServerDataPacket(
1104 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171105 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431106 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231107 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1108
1109 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1110
1111 CreateSession();
1112 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1113
1114 EXPECT_FALSE(
1115 test_socket_performance_watcher_factory_.rtt_notification_received());
1116 SendRequestAndExpectQuicResponse("hello!");
1117 EXPECT_FALSE(
1118 test_socket_performance_watcher_factory_.rtt_notification_received());
1119}
1120
[email protected]1e960032013-12-20 19:00:201121TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Nick Harper72ade192019-07-17 03:30:421122 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571123 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471124
Ryan Hamiltonabad59e2019-06-06 04:02:591125 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021126 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:361127 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021128 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1129 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1130 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431131 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331132 ASYNC, ConstructServerResponseHeadersPacket(
1133 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1134 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431135 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331136 mock_quic_data.AddRead(
1137 ASYNC, ConstructServerDataPacket(
1138 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171139 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431140 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591141 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471142
rcha5399e02015-04-21 19:32:041143 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471144
[email protected]4dca587c2013-03-07 16:54:471145 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471146
[email protected]aa9b14d2013-05-10 23:45:191147 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471148
[email protected]98b20ce2013-05-10 05:55:261149 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:541150 auto entries = net_log_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261151 EXPECT_LT(0u, entries.size());
1152
1153 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291154 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001155 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1156 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261157 EXPECT_LT(0, pos);
1158
rchfd527212015-08-25 00:41:261159 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291160 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261161 entries, 0,
mikecirone8b85c432016-09-08 19:11:001162 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1163 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261164 EXPECT_LT(0, pos);
1165
Eric Roman79cc7552019-07-19 02:17:541166 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261167
rchfd527212015-08-25 00:41:261168 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1169 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001170 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1171 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261172 EXPECT_LT(0, pos);
1173
[email protected]98b20ce2013-05-10 05:55:261174 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291175 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001176 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1177 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261178 EXPECT_LT(0, pos);
1179
Eric Roman79cc7552019-07-19 02:17:541180 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Ryan Hamiltone940bd12019-06-30 02:46:451181 if (quic::VersionUsesQpack(version_.transport_version)) {
1182 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1183 static_cast<quic::QuicStreamId>(log_stream_id));
1184 } else {
1185 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1186 static_cast<quic::QuicStreamId>(log_stream_id));
1187 }
[email protected]4dca587c2013-03-07 16:54:471188}
1189
rchbd089ab2017-05-26 23:05:041190TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Ryan Hamiltone940bd12019-06-30 02:46:451191 // TODO(rch): honor the max header list size. b/136108828
1192 if (quic::VersionUsesQpack(version_.transport_version))
1193 return;
1194
Nick Harper72ade192019-07-17 03:30:421195 session_params_.quic_params.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041196 HostPortPair::FromString("mail.example.org:443"));
1197
Ryan Hamiltonabad59e2019-06-06 04:02:591198 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021199 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rchbd089ab2017-05-26 23:05:041200 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021201 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1202 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1203 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0239aac2018-05-19 00:03:131204 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041205 response_headers["key1"] = std::string(30000, 'A');
1206 response_headers["key2"] = std::string(30000, 'A');
1207 response_headers["key3"] = std::string(30000, 'A');
1208 response_headers["key4"] = std::string(30000, 'A');
1209 response_headers["key5"] = std::string(30000, 'A');
1210 response_headers["key6"] = std::string(30000, 'A');
1211 response_headers["key7"] = std::string(30000, 'A');
1212 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451213 quic::QuicStreamId stream_id;
1214 std::string response_data;
1215 if (quic::VersionUsesQpack(version_.transport_version)) {
1216 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1217 std::vector<std::string> encoded = server_maker_.QpackEncodeHeaders(
1218 stream_id, std::move(response_headers), nullptr);
1219 for (const auto& e : encoded) {
1220 response_data += e;
1221 }
1222 } else {
1223 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1224 spdy::SpdyHeadersIR headers_frame(
1225 GetNthClientInitiatedBidirectionalStreamId(0),
1226 std::move(response_headers));
1227 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1228 spdy::SpdySerializedFrame spdy_frame =
1229 response_framer.SerializeFrame(headers_frame);
1230 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1231 }
rchbd089ab2017-05-26 23:05:041232
Fan Yangac867502019-01-28 21:10:231233 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041234 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451235 for (size_t offset = 0; offset < response_data.length();
1236 offset += chunk_size) {
1237 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431238 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451239 ASYNC, ConstructServerDataPacket(
1240 packet_number++, stream_id, false, false,
1241 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041242 }
1243
Victor Vasiliev076657c2019-03-12 02:46:431244 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041245 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331246 ASYNC, ConstructServerDataPacket(
1247 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171248 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041249 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431250 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1251 mock_quic_data.AddWrite(ASYNC,
1252 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041253
1254 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1255
1256 CreateSession();
1257
1258 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421259 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1260 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041261}
1262
1263TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Nick Harper72ade192019-07-17 03:30:421264 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
1265 session_params_.quic_params.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041266 HostPortPair::FromString("mail.example.org:443"));
1267
Ryan Hamiltonabad59e2019-06-06 04:02:591268 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021269 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rchbd089ab2017-05-26 23:05:041270 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021271 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1272 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1273 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451274
Ryan Hamilton0239aac2018-05-19 00:03:131275 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041276 response_headers["key1"] = std::string(30000, 'A');
1277 response_headers["key2"] = std::string(30000, 'A');
1278 response_headers["key3"] = std::string(30000, 'A');
1279 response_headers["key4"] = std::string(30000, 'A');
1280 response_headers["key5"] = std::string(30000, 'A');
1281 response_headers["key6"] = std::string(30000, 'A');
1282 response_headers["key7"] = std::string(30000, 'A');
1283 response_headers["key8"] = std::string(30000, 'A');
1284 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451285
1286 quic::QuicStreamId stream_id;
1287 std::string response_data;
1288 if (quic::VersionUsesQpack(version_.transport_version)) {
1289 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1290 std::vector<std::string> encoded = server_maker_.QpackEncodeHeaders(
1291 stream_id, std::move(response_headers), nullptr);
1292 for (const auto& e : encoded) {
1293 response_data += e;
1294 }
1295 } else {
1296 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1297 spdy::SpdyHeadersIR headers_frame(
1298 GetNthClientInitiatedBidirectionalStreamId(0),
1299 std::move(response_headers));
1300 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1301 spdy::SpdySerializedFrame spdy_frame =
1302 response_framer.SerializeFrame(headers_frame);
1303 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1304 }
rchbd089ab2017-05-26 23:05:041305
Fan Yangac867502019-01-28 21:10:231306 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041307 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451308 for (size_t offset = 0; offset < response_data.length();
1309 offset += chunk_size) {
1310 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431311 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451312 ASYNC, ConstructServerDataPacket(
1313 packet_number++, stream_id, false, false,
1314 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041315 }
1316
Victor Vasiliev076657c2019-03-12 02:46:431317 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411318
rchbd089ab2017-05-26 23:05:041319 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331320 ASYNC, ConstructServerDataPacket(
1321 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171322 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041323 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431324 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1325 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331326 ASYNC, ConstructClientAckAndRstPacket(
1327 4, GetNthClientInitiatedBidirectionalStreamId(0),
1328 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041329
1330 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1331
1332 CreateSession();
1333
1334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1335 TestCompletionCallback callback;
1336 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1337 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1338 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1339}
1340
rcha2bd44b2016-07-02 00:42:551341TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Nick Harper72ade192019-07-17 03:30:421342 session_params_.quic_params.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551343
Ryan Hamilton9835e662018-08-02 05:36:271344 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551345
Ryan Hamiltonabad59e2019-06-06 04:02:591346 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021347 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:361348 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021349 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1350 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1351 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431352 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331353 ASYNC, ConstructServerResponseHeadersPacket(
1354 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1355 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431356 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331357 mock_quic_data.AddRead(
1358 ASYNC, ConstructServerDataPacket(
1359 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171360 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431361 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551362 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1363
1364 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1365
1366 CreateSession();
1367
1368 SendRequestAndExpectQuicResponse("hello!");
1369 EXPECT_TRUE(
1370 test_socket_performance_watcher_factory_.rtt_notification_received());
1371}
1372
[email protected]cf3e3cd62014-02-05 16:16:161373TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411374 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591375 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491376 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161377
Ryan Hamiltonabad59e2019-06-06 04:02:591378 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021379 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:361380 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021381 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1382 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1383 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431384 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331385 ASYNC, ConstructServerResponseHeadersPacket(
1386 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1387 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431388 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331389 mock_quic_data.AddRead(
1390 ASYNC, ConstructServerDataPacket(
1391 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171392 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431393 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501394 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591395 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161396
rcha5399e02015-04-21 19:32:041397 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161398
tbansal0f56a39a2016-04-07 22:03:381399 EXPECT_FALSE(
1400 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161401 // There is no need to set up an alternate protocol job, because
1402 // no attempt will be made to speak to the proxy over TCP.
1403
rch9ae5b3b2016-02-11 00:36:291404 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161405 CreateSession();
1406
bnc62a44f022015-04-02 15:59:411407 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381408 EXPECT_TRUE(
1409 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161410}
1411
bnc313ba9c2015-06-11 15:42:311412// Regression test for https://crbug.com/492458. Test that for an HTTP
1413// connection through a QUIC proxy, the certificate exhibited by the proxy is
1414// checked against the proxy hostname, not the origin hostname.
1415TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291416 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311417 const std::string proxy_host = "www.example.org";
1418
mmenke6ddfbea2017-05-31 21:48:411419 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591420 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491421 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311422
alyssar2adf3ac2016-05-03 17:12:581423 client_maker_.set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591424 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021425 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:361426 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021427 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1428 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1429 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431430 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331431 ASYNC, ConstructServerResponseHeadersPacket(
1432 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1433 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431434 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331435 mock_quic_data.AddRead(
1436 ASYNC, ConstructServerDataPacket(
1437 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171438 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431439 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501440 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591441 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311442 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1443
1444 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291445 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311446 ASSERT_TRUE(cert.get());
1447 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241448 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1449 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311450 ProofVerifyDetailsChromium verify_details;
1451 verify_details.cert_verify_result.verified_cert = cert;
1452 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561453 ProofVerifyDetailsChromium verify_details2;
1454 verify_details2.cert_verify_result.verified_cert = cert;
1455 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311456
1457 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091458 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321459 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271460 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311461 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1462}
1463
rchbe69cb902016-02-11 01:10:481464TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Nick Harper72ade192019-07-17 03:30:421465 session_params_.quic_params.allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481466 HostPortPair origin("www.example.org", 443);
1467 HostPortPair alternative("mail.example.org", 443);
1468
1469 base::FilePath certs_dir = GetTestCertsDirectory();
1470 scoped_refptr<X509Certificate> cert(
1471 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1472 ASSERT_TRUE(cert.get());
1473 // TODO(rch): the connection should be "to" the origin, so if the cert is
1474 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241475 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1476 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481477 ProofVerifyDetailsChromium verify_details;
1478 verify_details.cert_verify_result.verified_cert = cert;
1479 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1480
alyssar2adf3ac2016-05-03 17:12:581481 client_maker_.set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591482 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021483
1484 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:361485 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021486 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1487 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1488 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431489 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331490 ASYNC, ConstructServerResponseHeadersPacket(
1491 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1492 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431493 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331494 mock_quic_data.AddRead(
1495 ASYNC, ConstructServerDataPacket(
1496 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171497 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431498 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481499 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1500 mock_quic_data.AddRead(ASYNC, 0);
1501 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1502
1503 request_.url = GURL("https://" + origin.host());
1504 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271505 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091506 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321507 CreateSession();
rchbe69cb902016-02-11 01:10:481508
1509 SendRequestAndExpectQuicResponse("hello!");
1510}
1511
zhongyief3f4ce52017-07-05 23:53:281512TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:561513 quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
zhongyief3f4ce52017-07-05 23:53:281514 // Add support for another QUIC version besides |version_|. Also find a
1515 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561516 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281517 if (version == version_)
1518 continue;
1519 if (supported_versions_.size() != 2) {
1520 supported_versions_.push_back(version);
1521 continue;
1522 }
1523 unsupported_version = version;
1524 break;
1525 }
Nick Harper23290b82019-05-02 00:02:561526 DCHECK_NE(unsupported_version, quic::UnsupportedQuicVersion());
zhongyief3f4ce52017-07-05 23:53:281527
1528 // Set up alternative service to use QUIC with a version that is not
1529 // supported.
1530 url::SchemeHostPort server(request_.url);
1531 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1532 443);
1533 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491534 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071535 server, NetworkIsolationKey(), alternative_service, expiration,
1536 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281537
1538 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491539 http_server_properties_->GetAlternativeServiceInfos(
1540 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281541 EXPECT_EQ(1u, alt_svc_info_vector.size());
1542 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1543 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1544 EXPECT_EQ(unsupported_version,
1545 alt_svc_info_vector[0].advertised_versions()[0]);
1546
1547 // First request should still be sent via TCP as the QUIC version advertised
1548 // in the stored AlternativeService is not supported by the client. However,
1549 // the response from the server will advertise new Alt-Svc with supported
1550 // versions.
Ryan Hamilton8380c652019-06-04 02:25:061551 quic::ParsedQuicVersionVector versions;
1552 for (quic::QuicTransportVersion version :
1553 quic::AllSupportedTransportVersions()) {
1554 versions.push_back(
1555 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
1556 }
zhongyief3f4ce52017-07-05 23:53:281557 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:061558 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyief3f4ce52017-07-05 23:53:281559 std::string altsvc_header =
1560 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1561 advertised_versions_list_str.c_str());
1562 MockRead http_reads[] = {
1563 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1564 MockRead("hello world"),
1565 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1566 MockRead(ASYNC, OK)};
1567
Ryan Sleevib8d7ea02018-05-07 20:01:011568 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281569 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081570 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281571 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1572
1573 // Second request should be sent via QUIC as a new list of verions supported
1574 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591575 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021576 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyief3f4ce52017-07-05 23:53:281577 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021578 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1579 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1580 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431581 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331582 ASYNC, ConstructServerResponseHeadersPacket(
1583 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1584 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431585 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331586 mock_quic_data.AddRead(
1587 ASYNC, ConstructServerDataPacket(
1588 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171589 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431590 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281591 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1592 mock_quic_data.AddRead(ASYNC, 0); // EOF
1593
1594 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1595
1596 AddHangingNonAlternateProtocolSocketData();
1597
1598 CreateSession(supported_versions_);
1599
1600 SendRequestAndExpectHttpResponse("hello world");
1601 SendRequestAndExpectQuicResponse("hello!");
1602
1603 // Check alternative service list is updated with new versions.
1604 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491605 session_->http_server_properties()->GetAlternativeServiceInfos(
1606 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281607 EXPECT_EQ(1u, alt_svc_info_vector.size());
1608 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1609 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1610 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:561611 std::sort(
1612 supported_versions_.begin(), supported_versions_.end(),
1613 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
1614 return a.transport_version < b.transport_version;
1615 });
zhongyief3f4ce52017-07-05 23:53:281616 EXPECT_EQ(supported_versions_[0],
1617 alt_svc_info_vector[0].advertised_versions()[0]);
1618 EXPECT_EQ(supported_versions_[1],
1619 alt_svc_info_vector[0].advertised_versions()[1]);
1620}
1621
bncaccd4962017-04-06 21:00:261622// Regression test for https://crbug.com/546991.
1623// The server might not be able to serve a request on an alternative connection,
1624// and might send a 421 Misdirected Request response status to indicate this.
1625// HttpNetworkTransaction should reset the request and retry without using
1626// alternative services.
1627TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1628 // Set up alternative service to use QUIC.
1629 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1630 // that overrides |enable_alternative_services|.
1631 url::SchemeHostPort server(request_.url);
1632 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1633 443);
1634 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491635 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071636 server, NetworkIsolationKey(), alternative_service, expiration,
1637 supported_versions_);
bncaccd4962017-04-06 21:00:261638
davidbena4449722017-05-05 23:30:531639 // First try: The alternative job uses QUIC and reports an HTTP 421
1640 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1641 // paused at Connect(), so it will never exit the socket pool. This ensures
1642 // that the alternate job always wins the race and keeps whether the
1643 // |http_data| exits the socket pool before the main job is aborted
1644 // deterministic. The first main job gets aborted without the socket pool ever
1645 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591646 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021647 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:361648 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021649 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1650 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1651 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331652 mock_quic_data.AddRead(
1653 ASYNC, ConstructServerResponseHeadersPacket(
1654 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021655 GetResponseHeaders("421")));
bncaccd4962017-04-06 21:00:261656 mock_quic_data.AddRead(ASYNC, OK);
1657 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1658
davidbena4449722017-05-05 23:30:531659 // Second try: The main job uses TCP, and there is no alternate job. Once the
1660 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1661 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261662 // Note that if there was an alternative QUIC Job created for the second try,
1663 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1664 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531665 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1666 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1667 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1668 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1669 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1670 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011671 reads, writes);
bncaccd4962017-04-06 21:00:261672 socket_factory_.AddSocketDataProvider(&http_data);
1673 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1674
bncaccd4962017-04-06 21:00:261675 CreateSession();
1676 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531677
1678 // Run until |mock_quic_data| has failed and |http_data| has paused.
1679 TestCompletionCallback callback;
1680 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1681 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1682 base::RunLoop().RunUntilIdle();
1683
1684 // |mock_quic_data| must have run to completion.
1685 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1686 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1687
1688 // Now that the QUIC data has been consumed, unblock |http_data|.
1689 http_data.socket()->OnConnectComplete(MockConnect());
1690
1691 // The retry logic must hide the 421 status. The transaction succeeds on
1692 // |http_data|.
1693 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261694 CheckWasHttpResponse(&trans);
1695 CheckResponsePort(&trans, 443);
1696 CheckResponseData(&trans, "hello!");
1697}
1698
[email protected]1e960032013-12-20 19:00:201699TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Nick Harper72ade192019-07-17 03:30:421700 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571701 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301702
Ryan Hamiltonabad59e2019-06-06 04:02:591703 MockQuicData mock_quic_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021704 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401705 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Ryan Hamilton0d65a8c2019-06-07 00:46:021706 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591707 MockQuicData mock_quic_data2(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021708 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301709 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401710 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431711 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401712
1713 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1714 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301715
1716 CreateSession();
1717
tbansal0f56a39a2016-04-07 22:03:381718 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401719 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161720 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401721 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161722 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011723 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1724 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381725 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531726
1727 NetErrorDetails details;
1728 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521729 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401730 }
[email protected]cebe3282013-05-22 23:49:301731}
1732
tbansalc8a94ea2015-11-02 23:58:511733TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1734 // Attempt to "force" quic on 443, which will not be honored.
Nick Harper72ade192019-07-17 03:30:421735 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571736 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511737
1738 MockRead http_reads[] = {
1739 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1740 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1741 MockRead(ASYNC, OK)};
1742
Ryan Sleevib8d7ea02018-05-07 20:01:011743 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511744 socket_factory_.AddSocketDataProvider(&data);
1745 SSLSocketDataProvider ssl(ASYNC, OK);
1746 socket_factory_.AddSSLSocketDataProvider(&ssl);
1747
1748 CreateSession();
1749
1750 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381751 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511752}
1753
bncc958faa2015-07-31 18:14:521754TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521755 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561756 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1757 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521758 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1759 MockRead(ASYNC, OK)};
1760
Ryan Sleevib8d7ea02018-05-07 20:01:011761 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521762 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081763 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561764 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521765
Ryan Hamiltonabad59e2019-06-06 04:02:591766 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021767 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:361768 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021769 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1770 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1771 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431772 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331773 ASYNC, ConstructServerResponseHeadersPacket(
1774 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1775 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431776 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331777 mock_quic_data.AddRead(
1778 ASYNC, ConstructServerDataPacket(
1779 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171780 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431781 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521782 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591783 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521784
1785 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1786
rtennetib8e80fb2016-05-16 00:12:091787 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321788 CreateSession();
bncc958faa2015-07-31 18:14:521789
1790 SendRequestAndExpectHttpResponse("hello world");
1791 SendRequestAndExpectQuicResponse("hello!");
1792}
1793
Matt Menke3233d8f22019-08-20 21:01:491794// Much like above, but makes sure NetworkIsolationKey is respected.
1795TEST_P(QuicNetworkTransactionTest,
1796 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
1797 base::test::ScopedFeatureList feature_list;
1798 feature_list.InitAndEnableFeature(
1799 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1800 // Since HttpServerProperties caches the feature value, have to create a new
1801 // one.
1802 http_server_properties_ = std::make_unique<HttpServerProperties>();
1803
1804 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
1805 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
1806 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
1807 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
1808
1809 MockRead http_reads[] = {
1810 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1811 MockRead("hello world"),
1812 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1813 MockRead(ASYNC, OK)};
1814
1815 AddCertificate(&ssl_data_);
1816
1817 // Request with empty NetworkIsolationKey.
1818 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
1819 socket_factory_.AddSocketDataProvider(&http_data1);
1820 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1821
1822 // First request with kNetworkIsolationKey1.
1823 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
1824 socket_factory_.AddSocketDataProvider(&http_data2);
1825 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1826
1827 // Request with kNetworkIsolationKey2.
1828 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
1829 socket_factory_.AddSocketDataProvider(&http_data3);
1830 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1831
1832 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
1833 // alternative service infrmation has been received in this context before.
1834 MockQuicData mock_quic_data(version_);
1835 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
1836 mock_quic_data.AddWrite(
1837 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1838 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1839 true, GetRequestHeaders("GET", "https", "/")));
1840 mock_quic_data.AddRead(
1841 ASYNC, ConstructServerResponseHeadersPacket(
1842 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1843 GetResponseHeaders("200 OK")));
1844 std::string header = ConstructDataHeader(6);
1845 mock_quic_data.AddRead(
1846 ASYNC, ConstructServerDataPacket(
1847 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1848 header + "hello!"));
1849 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
1850 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1851 mock_quic_data.AddRead(ASYNC, 0); // EOF
1852
1853 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1854
1855 AddHangingNonAlternateProtocolSocketData();
1856 CreateSession();
1857
1858 // This is first so that the test fails if alternative service info is
1859 // written with the right NetworkIsolationKey, but always queried with an
1860 // empty one.
1861 request_.network_isolation_key = NetworkIsolationKey();
1862 SendRequestAndExpectHttpResponse("hello world");
1863 request_.network_isolation_key = kNetworkIsolationKey1;
1864 SendRequestAndExpectHttpResponse("hello world");
1865 request_.network_isolation_key = kNetworkIsolationKey2;
1866 SendRequestAndExpectHttpResponse("hello world");
1867
1868 // Only use QUIC when using a NetworkIsolationKey which has been used when
1869 // alternative service information was received.
1870 request_.network_isolation_key = kNetworkIsolationKey1;
1871 SendRequestAndExpectQuicResponse("hello!");
1872}
1873
zhongyia00ca012017-07-06 23:36:391874TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1875 // Both server advertises and client supports two QUIC versions.
1876 // Only |version_| is advertised and supported.
1877 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1878 // PacketMakers are using |version_|.
1879
1880 // Add support for another QUIC version besides |version_| on the client side.
1881 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:561882 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
1883 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:391884 if (version == version_)
1885 continue;
1886 if (supported_versions_.size() != 2) {
1887 supported_versions_.push_back(version);
1888 continue;
1889 }
1890 advertised_version_2 = version;
1891 break;
1892 }
Nick Harper23290b82019-05-02 00:02:561893 DCHECK_NE(advertised_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:391894
Nick Harper23290b82019-05-02 00:02:561895 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1896 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1897 advertised_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:391898
1899 MockRead http_reads[] = {
1900 MockRead("HTTP/1.1 200 OK\r\n"),
1901 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1902 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1903 MockRead(ASYNC, OK)};
1904
Ryan Sleevib8d7ea02018-05-07 20:01:011905 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391906 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081907 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391908 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1909
Ryan Hamiltonabad59e2019-06-06 04:02:591910 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021911 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyia00ca012017-07-06 23:36:391912 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021913 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1914 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1915 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431916 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331917 ASYNC, ConstructServerResponseHeadersPacket(
1918 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1919 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431920 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331921 mock_quic_data.AddRead(
1922 ASYNC, ConstructServerDataPacket(
1923 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171924 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431925 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391926 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1927 mock_quic_data.AddRead(ASYNC, 0); // EOF
1928
1929 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1930
1931 AddHangingNonAlternateProtocolSocketData();
1932 CreateSession(supported_versions_);
1933
1934 SendRequestAndExpectHttpResponse("hello world");
1935 SendRequestAndExpectQuicResponse("hello!");
1936}
1937
1938TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1939 // Client and server mutually support more than one QUIC_VERSION.
1940 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1941 // which is verified as the PacketMakers are using |version_|.
1942
Nick Harper23290b82019-05-02 00:02:561943 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
1944 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:391945 if (version == version_)
1946 continue;
1947 common_version_2 = version;
1948 break;
1949 }
Nick Harper23290b82019-05-02 00:02:561950 DCHECK_NE(common_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:391951
1952 supported_versions_.push_back(
1953 common_version_2); // Supported but unpreferred.
1954
1955 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:561956 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1957 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:391958
1959 MockRead http_reads[] = {
1960 MockRead("HTTP/1.1 200 OK\r\n"),
1961 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1962 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1963 MockRead(ASYNC, OK)};
1964
Ryan Sleevib8d7ea02018-05-07 20:01:011965 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391966 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081967 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391968 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1969
Ryan Hamiltonabad59e2019-06-06 04:02:591970 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021971 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyia00ca012017-07-06 23:36:391972 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:021973 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
1974 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
1975 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431976 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331977 ASYNC, ConstructServerResponseHeadersPacket(
1978 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1979 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431980 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331981 mock_quic_data.AddRead(
1982 ASYNC, ConstructServerDataPacket(
1983 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171984 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431985 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391986 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1987 mock_quic_data.AddRead(ASYNC, 0); // EOF
1988
1989 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1990
1991 AddHangingNonAlternateProtocolSocketData();
1992 CreateSession(supported_versions_);
1993
1994 SendRequestAndExpectHttpResponse("hello world");
1995 SendRequestAndExpectQuicResponse("hello!");
1996}
1997
rchf47265dc2016-03-21 21:33:121998TEST_P(QuicNetworkTransactionTest,
1999 UseAlternativeServiceWithProbabilityForQuic) {
2000 MockRead http_reads[] = {
2001 MockRead("HTTP/1.1 200 OK\r\n"),
2002 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
2003 MockRead("hello world"),
2004 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2005 MockRead(ASYNC, OK)};
2006
Ryan Sleevib8d7ea02018-05-07 20:01:012007 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:122008 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082009 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:122010 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2011
Ryan Hamiltonabad59e2019-06-06 04:02:592012 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:022013 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:362014 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022015 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
2016 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
2017 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432018 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332019 ASYNC, ConstructServerResponseHeadersPacket(
2020 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2021 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432022 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332023 mock_quic_data.AddRead(
2024 ASYNC, ConstructServerDataPacket(
2025 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172026 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432027 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:122028 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2029 mock_quic_data.AddRead(ASYNC, 0); // EOF
2030
2031 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2032
rtennetib8e80fb2016-05-16 00:12:092033 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:122034 CreateSession();
2035
2036 SendRequestAndExpectHttpResponse("hello world");
2037 SendRequestAndExpectQuicResponse("hello!");
2038}
2039
zhongyi3d4a55e72016-04-22 20:36:462040TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2041 MockRead http_reads[] = {
2042 MockRead("HTTP/1.1 200 OK\r\n"),
2043 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2044 MockRead("hello world"),
2045 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2046 MockRead(ASYNC, OK)};
2047
Ryan Sleevib8d7ea02018-05-07 20:01:012048 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462049 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082050 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462051 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2052
2053 CreateSession();
bncb26024382016-06-29 02:39:452054 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462055 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452056 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462057 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402058 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462059 session_->http_server_properties();
2060 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2061 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2062 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462063 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492064 2u, http_server_properties
2065 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2066 .size());
bncb26024382016-06-29 02:39:452067 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492068 http_server_properties
2069 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2070 .empty());
zhongyi3d4a55e72016-04-22 20:36:462071}
2072
2073TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2074 MockRead http_reads[] = {
2075 MockRead("HTTP/1.1 200 OK\r\n"),
2076 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2077 MockRead("hello world"),
2078 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2079 MockRead(ASYNC, OK)};
2080
Ryan Sleevib8d7ea02018-05-07 20:01:012081 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082082 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462083
2084 socket_factory_.AddSocketDataProvider(&http_data);
2085 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2086 socket_factory_.AddSocketDataProvider(&http_data);
2087 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2088
2089 CreateSession();
2090
2091 // Send https request and set alternative services if response header
2092 // advertises alternative service for mail.example.org.
2093 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402094 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462095 session_->http_server_properties();
2096
2097 const url::SchemeHostPort https_server(request_.url);
2098 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342099 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492100 2u, http_server_properties
2101 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2102 .size());
zhongyi3d4a55e72016-04-22 20:36:462103
2104 // Send http request to the same origin but with diffrent scheme, should not
2105 // use QUIC.
2106 request_.url = GURL("http://mail.example.org:443");
2107 SendRequestAndExpectHttpResponse("hello world");
2108}
2109
zhongyie537a002017-06-27 16:48:212110TEST_P(QuicNetworkTransactionTest,
2111 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442112 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562113 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyi86838d52017-06-30 01:19:442114 if (version == version_)
2115 continue;
2116 supported_versions_.push_back(version);
2117 break;
2118 }
2119
Ryan Hamilton8380c652019-06-04 02:25:062120 quic::ParsedQuicVersionVector versions;
2121 for (quic::QuicTransportVersion version :
2122 quic::AllSupportedTransportVersions()) {
2123 versions.push_back(
2124 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
2125 }
zhongyie537a002017-06-27 16:48:212126 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:062127 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyie537a002017-06-27 16:48:212128 std::string altsvc_header =
2129 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2130 advertised_versions_list_str.c_str());
2131 MockRead http_reads[] = {
2132 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2133 MockRead("hello world"),
2134 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2135 MockRead(ASYNC, OK)};
2136
Ryan Sleevib8d7ea02018-05-07 20:01:012137 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212138 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082139 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212140 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2141
Ryan Hamiltonabad59e2019-06-06 04:02:592142 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:022143 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyie537a002017-06-27 16:48:212144 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022145 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
2146 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
2147 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432148 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332149 ASYNC, ConstructServerResponseHeadersPacket(
2150 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2151 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432152 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332153 mock_quic_data.AddRead(
2154 ASYNC, ConstructServerDataPacket(
2155 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172156 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432157 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212158 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2159 mock_quic_data.AddRead(ASYNC, 0); // EOF
2160
2161 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2162
2163 AddHangingNonAlternateProtocolSocketData();
2164
zhongyi86838d52017-06-30 01:19:442165 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212166
2167 SendRequestAndExpectHttpResponse("hello world");
2168 SendRequestAndExpectQuicResponse("hello!");
2169
2170 // Check alternative service is set with only mutually supported versions.
2171 const url::SchemeHostPort https_server(request_.url);
2172 const AlternativeServiceInfoVector alt_svc_info_vector =
2173 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492174 https_server, NetworkIsolationKey());
zhongyie537a002017-06-27 16:48:212175 EXPECT_EQ(1u, alt_svc_info_vector.size());
2176 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2177 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2178 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:562179 std::sort(
2180 supported_versions_.begin(), supported_versions_.end(),
2181 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
2182 return a.transport_version < b.transport_version;
2183 });
zhongyi86838d52017-06-30 01:19:442184 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212185 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442186 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212187 alt_svc_info_vector[0].advertised_versions()[1]);
2188}
2189
danzh3134c2562016-08-12 14:07:522190TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562191 std::string altsvc_header = base::StringPrintf(
2192 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_.transport_version);
bnc8be55ebb2015-10-30 14:12:072193 MockRead http_reads[] = {
2194 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2195 MockRead("hello world"),
2196 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2197 MockRead(ASYNC, OK)};
2198
Ryan Sleevib8d7ea02018-05-07 20:01:012199 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072200 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082201 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072202 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2203
Ryan Hamiltonabad59e2019-06-06 04:02:592204 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:022205 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:362206 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022207 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
2208 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
2209 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432210 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332211 ASYNC, ConstructServerResponseHeadersPacket(
2212 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2213 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432214 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332215 mock_quic_data.AddRead(
2216 ASYNC, ConstructServerDataPacket(
2217 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172218 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432219 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072220 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592221 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072222
2223 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2224
rtennetib8e80fb2016-05-16 00:12:092225 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322226 CreateSession();
bnc8be55ebb2015-10-30 14:12:072227
2228 SendRequestAndExpectHttpResponse("hello world");
2229 SendRequestAndExpectQuicResponse("hello!");
2230}
2231
zhongyi6b5a3892016-03-12 04:46:202232TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562233 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz6e4c5382018-06-21 23:00:092234 // Not available under version 99
2235 return;
2236 }
Ryan Hamiltonabad59e2019-06-06 04:02:592237 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:022238 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:362239 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022240 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
2241 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
2242 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332243 mock_quic_data.AddRead(
2244 ASYNC, ConstructServerResponseHeadersPacket(
2245 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2246 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202247 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522248 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432249 mock_quic_data.AddRead(SYNCHRONOUS,
2250 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522251 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432252 "connection migration with port change only"));
2253 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432254 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332255 mock_quic_data.AddRead(
2256 SYNCHRONOUS, ConstructServerDataPacket(
2257 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:172258 true, header + "hello!"));
Fan Yang32c5a112018-12-10 20:06:332259 mock_quic_data.AddWrite(SYNCHRONOUS,
2260 ConstructClientAckAndRstPacket(
2261 4, GetNthClientInitiatedBidirectionalStreamId(0),
2262 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202263 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
2268 // The non-alternate protocol job needs to hang in order to guarantee that
2269 // the alternate-protocol job will "win".
2270 AddHangingNonAlternateProtocolSocketData();
2271
2272 // In order for a new QUIC session to be established via alternate-protocol
2273 // without racing an HTTP connection, we need the host resolution to happen
2274 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2275 // connection to the the server, in this test we require confirmation
2276 // before encrypting so the HTTP job will still start.
2277 host_resolver_.set_synchronous_mode(true);
2278 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2279 "");
zhongyi6b5a3892016-03-12 04:46:202280
2281 CreateSession();
2282 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272283 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202284
bnc691fda62016-08-12 00:43:162285 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202286 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362287 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012288 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202289
2290 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522291 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012292 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202293
2294 // Check whether this transaction is correctly marked as received a go-away
2295 // because of migrating port.
2296 NetErrorDetails details;
2297 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162298 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202299 EXPECT_TRUE(details.quic_port_migration_detected);
2300}
2301
Zhongyi Shia6b68d112018-09-24 07:49:032302// This test verifies that a new QUIC connection will be attempted on the
2303// alternate network if the original QUIC connection fails with idle timeout
2304// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2305// alternate network as well, QUIC is marked as broken and the brokenness will
2306// not expire when default network changes.
2307TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2308 SetUpTestForRetryConnectionOnAlternateNetwork();
2309
Michael Warres167db3e2019-03-01 21:38:032310 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032311
2312 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592313 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032314 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2315 int packet_num = 1;
2316 quic_data.AddWrite(SYNCHRONOUS,
2317 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2318 // Retranmit the handshake messages.
2319 quic_data.AddWrite(SYNCHRONOUS,
2320 client_maker_.MakeDummyCHLOPacket(packet_num++));
2321 quic_data.AddWrite(SYNCHRONOUS,
2322 client_maker_.MakeDummyCHLOPacket(packet_num++));
2323 quic_data.AddWrite(SYNCHRONOUS,
2324 client_maker_.MakeDummyCHLOPacket(packet_num++));
2325 quic_data.AddWrite(SYNCHRONOUS,
2326 client_maker_.MakeDummyCHLOPacket(packet_num++));
2327 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562328 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032329 quic_data.AddWrite(SYNCHRONOUS,
2330 client_maker_.MakeDummyCHLOPacket(packet_num++));
2331 }
2332 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2333 quic_data.AddWrite(SYNCHRONOUS,
2334 client_maker_.MakeConnectionClosePacket(
2335 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2336 "No recent network activity."));
2337 quic_data.AddSocketDataToFactory(&socket_factory_);
2338
2339 // Add successful TCP data so that TCP job will succeed.
2340 MockWrite http_writes[] = {
2341 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2342 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2343 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2344
2345 MockRead http_reads[] = {
2346 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2347 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2348 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2349 SequencedSocketData http_data(http_reads, http_writes);
2350 socket_factory_.AddSocketDataProvider(&http_data);
2351 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2352
2353 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592354 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032355 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2356 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2357 quic_data2.AddSocketDataToFactory(&socket_factory_);
2358
2359 // Resolve the host resolution synchronously.
2360 host_resolver_.set_synchronous_mode(true);
2361 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2362 "");
Zhongyi Shia6b68d112018-09-24 07:49:032363
2364 CreateSession();
2365 session_->quic_stream_factory()->set_require_confirmation(true);
2366 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032367 QuicStreamFactoryPeer::SetAlarmFactory(
2368 session_->quic_stream_factory(),
2369 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2370 &clock_));
2371 // Add alternate protocol mapping to race QUIC and TCP.
2372 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2373 // peer.
2374 AddQuicAlternateProtocolMapping(
2375 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2376
2377 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2378 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362379 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032380 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2381
2382 // Pump the message loop to get the request started.
2383 // Request will be served with TCP job.
2384 base::RunLoop().RunUntilIdle();
2385 EXPECT_THAT(callback.WaitForResult(), IsOk());
2386 CheckResponseData(&trans, "TCP succeeds");
2387
Zhongyi Shia6b68d112018-09-24 07:49:032388 // Fast forward to idle timeout the original connection. A new connection will
2389 // be kicked off on the alternate network.
2390 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2391 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2392 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2393
2394 // Run the message loop to execute posted tasks, which will report job status.
2395 base::RunLoop().RunUntilIdle();
2396
2397 // Verify that QUIC is marked as broken.
2398 ExpectBrokenAlternateProtocolMapping();
2399
2400 // Deliver a message to notify the new network becomes default, the brokenness
2401 // will not expire as QUIC is broken on both networks.
2402 scoped_mock_change_notifier_->mock_network_change_notifier()
2403 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2404 ExpectBrokenAlternateProtocolMapping();
2405
2406 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2407 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2408}
2409
2410// This test verifies that a new QUIC connection will be attempted on the
2411// alternate network if the original QUIC connection fails with idle timeout
2412// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2413// alternate network, QUIC is marked as broken. The brokenness will expire when
2414// the default network changes.
2415TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2416 SetUpTestForRetryConnectionOnAlternateNetwork();
2417
Michael Warres167db3e2019-03-01 21:38:032418 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032419
2420 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592421 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032422 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2423 int packet_num = 1;
2424 quic_data.AddWrite(SYNCHRONOUS,
2425 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2426 // Retranmit the handshake messages.
2427 quic_data.AddWrite(SYNCHRONOUS,
2428 client_maker_.MakeDummyCHLOPacket(packet_num++));
2429 quic_data.AddWrite(SYNCHRONOUS,
2430 client_maker_.MakeDummyCHLOPacket(packet_num++));
2431 quic_data.AddWrite(SYNCHRONOUS,
2432 client_maker_.MakeDummyCHLOPacket(packet_num++));
2433 quic_data.AddWrite(SYNCHRONOUS,
2434 client_maker_.MakeDummyCHLOPacket(packet_num++));
2435 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562436 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032437 quic_data.AddWrite(SYNCHRONOUS,
2438 client_maker_.MakeDummyCHLOPacket(packet_num++));
2439 }
2440 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2441 quic_data.AddWrite(SYNCHRONOUS,
2442 client_maker_.MakeConnectionClosePacket(
2443 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2444 "No recent network activity."));
2445 quic_data.AddSocketDataToFactory(&socket_factory_);
2446
2447 // Add successful TCP data so that TCP job will succeed.
2448 MockWrite http_writes[] = {
2449 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2450 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2451 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2452
2453 MockRead http_reads[] = {
2454 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2455 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2456 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2457 SequencedSocketData http_data(http_reads, http_writes);
2458 socket_factory_.AddSocketDataProvider(&http_data);
2459 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2460
2461 // Quic connection will be retried on the alternate network after the initial
2462 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592463 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032464 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2465 quic_data2.AddWrite(SYNCHRONOUS,
2466 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2467
2468 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton0d65a8c2019-06-07 00:46:022469 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032470 quic_data2.AddSocketDataToFactory(&socket_factory_);
2471
2472 // Resolve the host resolution synchronously.
2473 host_resolver_.set_synchronous_mode(true);
2474 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2475 "");
Zhongyi Shia6b68d112018-09-24 07:49:032476
2477 CreateSession();
2478 session_->quic_stream_factory()->set_require_confirmation(true);
2479 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032480 QuicStreamFactoryPeer::SetAlarmFactory(
2481 session_->quic_stream_factory(),
2482 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2483 &clock_));
2484 // Add alternate protocol mapping to race QUIC and TCP.
2485 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2486 // peer.
2487 AddQuicAlternateProtocolMapping(
2488 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2489
2490 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2491 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362492 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032493 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2494
2495 // Pump the message loop to get the request started.
2496 // Request will be served with TCP job.
2497 base::RunLoop().RunUntilIdle();
2498 EXPECT_THAT(callback.WaitForResult(), IsOk());
2499 CheckResponseData(&trans, "TCP succeeds");
2500
Zhongyi Shia6b68d112018-09-24 07:49:032501 // Fast forward to idle timeout the original connection. A new connection will
2502 // be kicked off on the alternate network.
2503 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2504 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2505 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2506
2507 // The second connection hasn't finish handshake, verify that QUIC is not
2508 // marked as broken.
2509 ExpectQuicAlternateProtocolMapping();
2510 // Explicitly confirm the handshake on the second connection.
2511 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2512 quic::QuicSession::HANDSHAKE_CONFIRMED);
2513 // Run message loop to execute posted tasks, which will notify JoController
2514 // about the orphaned job status.
2515 base::RunLoop().RunUntilIdle();
2516
2517 // Verify that QUIC is marked as broken.
2518 ExpectBrokenAlternateProtocolMapping();
2519
2520 // Deliver a message to notify the new network becomes default, the previous
2521 // brokenness will be clear as the brokenness is bond with old default
2522 // network.
2523 scoped_mock_change_notifier_->mock_network_change_notifier()
2524 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2525 ExpectQuicAlternateProtocolMapping();
2526
2527 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2528 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2529}
2530
2531// This test verifies that a new QUIC connection will be attempted on the
2532// alternate network if the original QUIC connection fails with idle timeout
2533// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2534// alternative network succeeds, QUIC is not marked as broken.
2535TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2536 SetUpTestForRetryConnectionOnAlternateNetwork();
2537
Michael Warres167db3e2019-03-01 21:38:032538 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032539
2540 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592541 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032542 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2543 int packet_num = 1;
2544 quic_data.AddWrite(SYNCHRONOUS,
2545 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2546 // Retranmit the handshake messages.
2547 quic_data.AddWrite(SYNCHRONOUS,
2548 client_maker_.MakeDummyCHLOPacket(packet_num++));
2549 quic_data.AddWrite(SYNCHRONOUS,
2550 client_maker_.MakeDummyCHLOPacket(packet_num++));
2551 quic_data.AddWrite(SYNCHRONOUS,
2552 client_maker_.MakeDummyCHLOPacket(packet_num++));
2553 quic_data.AddWrite(SYNCHRONOUS,
2554 client_maker_.MakeDummyCHLOPacket(packet_num++));
2555 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2556 // quic_fix_has_pending_crypto_data is introduced and enabled.
Nick Harper23290b82019-05-02 00:02:562557 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032558 quic_data.AddWrite(SYNCHRONOUS,
2559 client_maker_.MakeDummyCHLOPacket(packet_num++));
2560 }
2561 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2562 quic_data.AddWrite(SYNCHRONOUS,
2563 client_maker_.MakeConnectionClosePacket(
2564 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2565 "No recent network activity."));
2566 quic_data.AddSocketDataToFactory(&socket_factory_);
2567
2568 // Add hanging TCP data so that TCP job will never succeeded.
2569 AddHangingNonAlternateProtocolSocketData();
2570
2571 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:592572 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032573 quic_data2.AddWrite(SYNCHRONOUS,
2574 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2575
Victor Vasiliev076657c2019-03-12 02:46:432576 const std::string body = "hello!";
2577 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:412578
Zhongyi Shia6b68d112018-09-24 07:49:032579 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton0d65a8c2019-06-07 00:46:022580 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032581 quic_data2.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022582 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
2583 3, GetNthClientInitiatedBidirectionalStreamId(0), true,
2584 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:032585 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332586 ASYNC, ConstructServerResponseHeadersPacket(
2587 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2588 GetResponseHeaders("200 OK")));
2589 quic_data2.AddRead(
2590 ASYNC, ConstructServerDataPacket(
2591 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172592 header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032593 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2594 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2595 quic_data2.AddSocketDataToFactory(&socket_factory_);
2596
2597 // Resolve the host resolution synchronously.
2598 host_resolver_.set_synchronous_mode(true);
2599 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2600 "");
Zhongyi Shia6b68d112018-09-24 07:49:032601
2602 CreateSession();
2603 session_->quic_stream_factory()->set_require_confirmation(true);
2604 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032605 QuicStreamFactoryPeer::SetAlarmFactory(
2606 session_->quic_stream_factory(),
2607 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2608 &clock_));
2609 // Add alternate protocol mapping to race QUIC and TCP.
2610 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2611 // peer.
2612 AddQuicAlternateProtocolMapping(
2613 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2614
2615 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2616 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362617 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032618 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2619
2620 // Pump the message loop to get the request started.
2621 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:032622
2623 // Fast forward to idle timeout the original connection. A new connection will
2624 // be kicked off on the alternate network.
2625 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2626 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2627 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2628
2629 // Verify that QUIC is not marked as broken.
2630 ExpectQuicAlternateProtocolMapping();
2631 // Explicitly confirm the handshake on the second connection.
2632 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2633 quic::QuicSession::HANDSHAKE_CONFIRMED);
2634
2635 // Read the response.
2636 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412637 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032638 // Verify that QUIC is not marked as broken.
2639 ExpectQuicAlternateProtocolMapping();
2640
2641 // Deliver a message to notify the new network becomes default.
2642 scoped_mock_change_notifier_->mock_network_change_notifier()
2643 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2644 ExpectQuicAlternateProtocolMapping();
2645 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2646 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2647}
2648
rch9ecde09b2017-04-08 00:18:232649// Verify that if a QUIC connection times out, the QuicHttpStream will
2650// return QUIC_PROTOCOL_ERROR.
2651TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:422652 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Sleevi2e8255b2019-07-17 21:02:212653 session_params_.quic_params.idle_connection_timeout =
2654 base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:232655
2656 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592657 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:132658 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232659 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2660
Ryan Hamiltone940bd12019-06-30 02:46:452661 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:032662 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:022663 quic_data.AddWrite(
2664 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:452665 client_maker_.MakeRequestHeadersPacket(
2666 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
2667 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
2668
2669 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton3cc2c152019-07-09 19:36:012670 if (version_.transport_version != quic::QUIC_VERSION_99) {
2671 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(2));
2672 // TLP 1
2673 quic_data.AddWrite(SYNCHRONOUS,
2674 client_maker_.MakeRetransmissionPacket(1, 3, true));
2675 // TLP 2
2676 quic_data.AddWrite(SYNCHRONOUS,
2677 client_maker_.MakeRetransmissionPacket(2, 4, true));
2678 // RTO 1
2679 quic_data.AddWrite(SYNCHRONOUS,
2680 client_maker_.MakeRetransmissionPacket(1, 5, true));
2681 quic_data.AddWrite(SYNCHRONOUS,
2682 client_maker_.MakeRetransmissionPacket(2, 6, true));
2683 // RTO 2
2684 quic_data.AddWrite(SYNCHRONOUS,
2685 client_maker_.MakeRetransmissionPacket(1, 7, true));
2686 quic_data.AddWrite(SYNCHRONOUS,
2687 client_maker_.MakeRetransmissionPacket(2, 8, true));
2688 // RTO 3
2689 quic_data.AddWrite(SYNCHRONOUS,
2690 client_maker_.MakeRetransmissionPacket(1, 9, true));
2691 quic_data.AddWrite(SYNCHRONOUS,
2692 client_maker_.MakeRetransmissionPacket(2, 10, true));
rch9ecde09b2017-04-08 00:18:232693
Ryan Hamilton3cc2c152019-07-09 19:36:012694 quic_data.AddWrite(SYNCHRONOUS,
2695 client_maker_.MakeConnectionClosePacket(
2696 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2697 "No recent network activity."));
2698 } else {
2699 // Settings were sent in the request packet so there is only 1 packet to
2700 // retransmit.
2701 // TLP 1
2702 quic_data.AddWrite(SYNCHRONOUS,
2703 client_maker_.MakeRetransmissionPacket(1, 2, true));
2704 // TLP 2
2705 quic_data.AddWrite(SYNCHRONOUS,
2706 client_maker_.MakeRetransmissionPacket(1, 3, true));
2707 // RTO 1
2708 quic_data.AddWrite(SYNCHRONOUS,
2709 client_maker_.MakeRetransmissionPacket(1, 4, true));
2710 // RTO 2
2711 quic_data.AddWrite(SYNCHRONOUS,
2712 client_maker_.MakeRetransmissionPacket(1, 5, true));
2713 // RTO 3
2714 quic_data.AddWrite(SYNCHRONOUS,
2715 client_maker_.MakeRetransmissionPacket(1, 6, true));
2716
2717 quic_data.AddWrite(SYNCHRONOUS,
2718 client_maker_.MakeConnectionClosePacket(
2719 7, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2720 "No recent network activity."));
2721 }
Fan Yang928f1632017-12-14 18:55:222722
rch9ecde09b2017-04-08 00:18:232723 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2724 quic_data.AddRead(ASYNC, OK);
2725 quic_data.AddSocketDataToFactory(&socket_factory_);
2726
2727 // In order for a new QUIC session to be established via alternate-protocol
2728 // without racing an HTTP connection, we need the host resolution to happen
2729 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2730 // connection to the the server, in this test we require confirmation
2731 // before encrypting so the HTTP job will still start.
2732 host_resolver_.set_synchronous_mode(true);
2733 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2734 "");
rch9ecde09b2017-04-08 00:18:232735
2736 CreateSession();
2737 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232738 QuicStreamFactoryPeer::SetAlarmFactory(
2739 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192740 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552741 &clock_));
rch9ecde09b2017-04-08 00:18:232742
Ryan Hamilton9835e662018-08-02 05:36:272743 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232744
2745 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2746 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362747 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232748 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2749
2750 // Pump the message loop to get the request started.
2751 base::RunLoop().RunUntilIdle();
2752 // Explicitly confirm the handshake.
2753 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522754 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232755
2756 // Run the QUIC session to completion.
2757 quic_task_runner_->RunUntilIdle();
2758
2759 ExpectQuicAlternateProtocolMapping();
2760 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2761 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2762}
2763
2764// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2765// return QUIC_PROTOCOL_ERROR.
2766TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:422767 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
2768 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232769
2770 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592771 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:132772 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232773 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2774
Ryan Hamiltone940bd12019-06-30 02:46:452775 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:032776 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:022777 quic_data.AddWrite(
2778 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:452779 client_maker_.MakeRequestHeadersPacket(
2780 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
2781 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
2782
2783 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:552784 if (version_.transport_version != quic::QUIC_VERSION_99) {
2785 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(2));
2786 // TLP 1
2787 quic_data.AddWrite(SYNCHRONOUS,
2788 client_maker_.MakeRetransmissionPacket(1, 3, true));
2789 // TLP 2
2790 quic_data.AddWrite(SYNCHRONOUS,
2791 client_maker_.MakeRetransmissionPacket(2, 4, true));
2792 // RTO 1
2793 quic_data.AddWrite(SYNCHRONOUS,
2794 client_maker_.MakeRetransmissionPacket(1, 5, true));
2795 quic_data.AddWrite(SYNCHRONOUS,
2796 client_maker_.MakeRetransmissionPacket(2, 6, true));
2797 // RTO 2
2798 quic_data.AddWrite(SYNCHRONOUS,
2799 client_maker_.MakeRetransmissionPacket(1, 7, true));
2800 quic_data.AddWrite(SYNCHRONOUS,
2801 client_maker_.MakeRetransmissionPacket(2, 8, true));
2802 // RTO 3
2803 quic_data.AddWrite(SYNCHRONOUS,
2804 client_maker_.MakeRetransmissionPacket(1, 9, true));
2805 quic_data.AddWrite(SYNCHRONOUS,
2806 client_maker_.MakeRetransmissionPacket(2, 10, true));
2807 // RTO 4
2808 quic_data.AddWrite(SYNCHRONOUS,
2809 client_maker_.MakeRetransmissionPacket(1, 11, true));
2810 quic_data.AddWrite(SYNCHRONOUS,
2811 client_maker_.MakeRetransmissionPacket(2, 12, true));
2812 // RTO 5
2813 quic_data.AddWrite(SYNCHRONOUS,
2814 client_maker_.MakeConnectionClosePacket(
2815 13, true, quic::QUIC_TOO_MANY_RTOS,
2816 "5 consecutive retransmission timeouts"));
2817 } else {
2818 // TLP 1
2819 quic_data.AddWrite(SYNCHRONOUS,
2820 client_maker_.MakeRetransmissionPacket(1, 2, true));
2821 // TLP 2
2822 quic_data.AddWrite(SYNCHRONOUS,
2823 client_maker_.MakeRetransmissionPacket(1, 3, true));
2824 // RTO 1
2825 quic_data.AddWrite(SYNCHRONOUS,
2826 client_maker_.MakeRetransmissionPacket(1, 4, true));
2827 // RTO 2
2828 quic_data.AddWrite(SYNCHRONOUS,
2829 client_maker_.MakeRetransmissionPacket(1, 5, true));
2830 // RTO 3
2831 quic_data.AddWrite(SYNCHRONOUS,
2832 client_maker_.MakeRetransmissionPacket(1, 6, true));
2833 // RTO 4
2834 quic_data.AddWrite(SYNCHRONOUS,
2835 client_maker_.MakeRetransmissionPacket(1, 7, true));
2836 // RTO 5
2837 quic_data.AddWrite(SYNCHRONOUS,
2838 client_maker_.MakeConnectionClosePacket(
2839 8, true, quic::QUIC_TOO_MANY_RTOS,
2840 "5 consecutive retransmission timeouts"));
2841 }
rch9ecde09b2017-04-08 00:18:232842
2843 quic_data.AddRead(ASYNC, OK);
2844 quic_data.AddSocketDataToFactory(&socket_factory_);
2845
2846 // In order for a new QUIC session to be established via alternate-protocol
2847 // without racing an HTTP connection, we need the host resolution to happen
2848 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2849 // connection to the the server, in this test we require confirmation
2850 // before encrypting so the HTTP job will still start.
2851 host_resolver_.set_synchronous_mode(true);
2852 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2853 "");
rch9ecde09b2017-04-08 00:18:232854
2855 CreateSession();
2856 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232857 QuicStreamFactoryPeer::SetAlarmFactory(
2858 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192859 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552860 &clock_));
rch9ecde09b2017-04-08 00:18:232861
Ryan Hamilton9835e662018-08-02 05:36:272862 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232863
2864 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2865 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362866 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232867 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2868
2869 // Pump the message loop to get the request started.
2870 base::RunLoop().RunUntilIdle();
2871 // Explicitly confirm the handshake.
2872 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522873 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232874
2875 // Run the QUIC session to completion.
2876 quic_task_runner_->RunUntilIdle();
2877
2878 ExpectQuicAlternateProtocolMapping();
2879 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2880 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2881}
2882
2883// Verify that if a QUIC connection RTOs, while there are no active streams
2884// QUIC will not be marked as broken.
2885TEST_P(QuicNetworkTransactionTest,
2886 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Nick Harper72ade192019-07-17 03:30:422887 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232888
2889 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592890 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:132891 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232892 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2893
Ryan Hamiltone940bd12019-06-30 02:46:452894 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:032895 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:022896 quic_data.AddWrite(
2897 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:452898 client_maker_.MakeRequestHeadersPacket(
2899 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
2900 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
2901
2902 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:552903 if (version_.transport_version != quic::QUIC_VERSION_99) {
2904 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(2));
2905 }
rch9ecde09b2017-04-08 00:18:232906
Ryan Hamiltone940bd12019-06-30 02:46:452907 if (quic::VersionUsesQpack(version_.transport_version)) {
Ryan Hamiltonb01f886f2019-07-10 02:25:552908 quic_data.AddWrite(
2909 SYNCHRONOUS, client_maker_.MakeRstPacket(
2910 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2911 quic::QUIC_STREAM_CANCELLED));
Ryan Hamiltone940bd12019-06-30 02:46:452912 // Since the headers are sent on the data stream, when the stream is reset
2913 // the headers are no longer retransmitted.
Ryan Hamiltonb01f886f2019-07-10 02:25:552914 client_maker_.RemoveSavedStreamFrames(
2915 GetNthClientInitiatedBidirectionalStreamId(0));
Ryan Hamiltone940bd12019-06-30 02:46:452916 // TLP 1
2917 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:552918 client_maker_.MakeRetransmissionPacket(1, 3, true));
Ryan Hamiltone940bd12019-06-30 02:46:452919 // TLP 2
2920 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:552921 client_maker_.MakeRetransmissionPacket(2, 4, true));
Ryan Hamiltone940bd12019-06-30 02:46:452922 // RTO 1
2923 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:552924 client_maker_.MakeRetransmissionPacket(1, 5, true));
Ryan Hamiltone940bd12019-06-30 02:46:452925 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:552926 client_maker_.MakeRetransmissionPacket(2, 6, true));
Ryan Hamiltone940bd12019-06-30 02:46:452927 // RTO 2
2928 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:552929 client_maker_.MakeRetransmissionPacket(1, 7, true));
Ryan Hamiltone940bd12019-06-30 02:46:452930 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:552931 client_maker_.MakeRetransmissionPacket(2, 8, true));
Ryan Hamiltone940bd12019-06-30 02:46:452932 // RTO 3
2933 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:552934 client_maker_.MakeRetransmissionPacket(1, 9, true));
Ryan Hamiltone940bd12019-06-30 02:46:452935 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:552936 client_maker_.MakeRetransmissionPacket(2, 10, true));
Ryan Hamiltone940bd12019-06-30 02:46:452937 // RTO 4
2938 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:552939 client_maker_.MakeRetransmissionPacket(1, 11, true));
Ryan Hamiltone940bd12019-06-30 02:46:452940 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:552941 client_maker_.MakeRetransmissionPacket(2, 12, true));
2942 // RTO 5
2943 quic_data.AddWrite(SYNCHRONOUS,
2944 client_maker_.MakeConnectionClosePacket(
2945 13, true, quic::QUIC_TOO_MANY_RTOS,
2946 "5 consecutive retransmission timeouts"));
Ryan Hamiltone940bd12019-06-30 02:46:452947 } else {
Ryan Hamiltonb01f886f2019-07-10 02:25:552948 quic_data.AddWrite(
2949 SYNCHRONOUS, client_maker_.MakeRstPacket(
2950 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2951 quic::QUIC_STREAM_CANCELLED));
Ryan Hamiltone940bd12019-06-30 02:46:452952 // TLP 1
2953 quic_data.AddWrite(SYNCHRONOUS,
2954 client_maker_.MakeRetransmissionPacket(1, 4, true));
2955 // TLP 2
2956 quic_data.AddWrite(SYNCHRONOUS,
2957 client_maker_.MakeRetransmissionPacket(2, 5, true));
2958 // RTO 1
2959 quic_data.AddWrite(SYNCHRONOUS,
2960 client_maker_.MakeRetransmissionPacket(3, 6, true));
2961 quic_data.AddWrite(SYNCHRONOUS,
2962 client_maker_.MakeRetransmissionPacket(1, 7, true));
2963 // RTO 2
2964 quic_data.AddWrite(SYNCHRONOUS,
2965 client_maker_.MakeRetransmissionPacket(2, 8, true));
2966 quic_data.AddWrite(SYNCHRONOUS,
2967 client_maker_.MakeRetransmissionPacket(3, 9, true));
2968 // RTO 3
2969 quic_data.AddWrite(SYNCHRONOUS,
2970 client_maker_.MakeRetransmissionPacket(1, 10, true));
2971 quic_data.AddWrite(SYNCHRONOUS,
2972 client_maker_.MakeRetransmissionPacket(2, 11, true));
2973 // RTO 4
2974 quic_data.AddWrite(SYNCHRONOUS,
2975 client_maker_.MakeRetransmissionPacket(3, 12, true));
2976 quic_data.AddWrite(SYNCHRONOUS,
2977 client_maker_.MakeRetransmissionPacket(1, 13, true));
rch9ecde09b2017-04-08 00:18:232978 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432979 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522980 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432981 "5 consecutive retransmission timeouts"));
Ryan Hamiltonb01f886f2019-07-10 02:25:552982 }
rch9ecde09b2017-04-08 00:18:232983
2984 quic_data.AddRead(ASYNC, OK);
2985 quic_data.AddSocketDataToFactory(&socket_factory_);
2986
2987 // In order for a new QUIC session to be established via alternate-protocol
2988 // without racing an HTTP connection, we need the host resolution to happen
2989 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2990 // connection to the the server, in this test we require confirmation
2991 // before encrypting so the HTTP job will still start.
2992 host_resolver_.set_synchronous_mode(true);
2993 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2994 "");
rch9ecde09b2017-04-08 00:18:232995
2996 CreateSession();
2997 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232998 QuicStreamFactoryPeer::SetAlarmFactory(
2999 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193000 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553001 &clock_));
rch9ecde09b2017-04-08 00:18:233002
Ryan Hamilton9835e662018-08-02 05:36:273003 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233004
Jeremy Roman0579ed62017-08-29 15:56:193005 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233006 session_.get());
3007 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363008 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233009 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3010
3011 // Pump the message loop to get the request started.
3012 base::RunLoop().RunUntilIdle();
3013 // Explicitly confirm the handshake.
3014 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523015 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233016
3017 // Now cancel the request.
3018 trans.reset();
3019
3020 // Run the QUIC session to completion.
3021 quic_task_runner_->RunUntilIdle();
3022
3023 ExpectQuicAlternateProtocolMapping();
3024
3025 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3026}
3027
rch2f2991c2017-04-13 19:28:173028// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3029// the request fails with QUIC_PROTOCOL_ERROR.
3030TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:423031 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173032 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593033 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033034 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433035 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:023036 ConstructClientRequestHeadersPacket(
3037 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3038 true, GetRequestHeaders("GET", "https", "/")));
3039 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton3cc2c152019-07-09 19:36:013040 uint64_t packet_number = 2;
3041 if (version_.transport_version != quic::QUIC_VERSION_99) {
3042 quic_data.AddWrite(SYNCHRONOUS,
3043 ConstructInitialSettingsPacket(packet_number++));
3044 }
Ryan Hamiltonb01f886f2019-07-10 02:25:553045 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173046 // Peer sending data from an non-existing stream causes this end to raise
3047 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333048 quic_data.AddRead(
3049 ASYNC, ConstructServerRstPacket(
3050 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3051 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173052 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton3cc2c152019-07-09 19:36:013053 quic_data.AddWrite(
3054 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
3055 packet_number++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
Renjie Tangff0d6372019-08-30 22:03:293056 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3057 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173058 quic_data.AddSocketDataToFactory(&socket_factory_);
3059
3060 // In order for a new QUIC session to be established via alternate-protocol
3061 // without racing an HTTP connection, we need the host resolution to happen
3062 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3063 // connection to the the server, in this test we require confirmation
3064 // before encrypting so the HTTP job will still start.
3065 host_resolver_.set_synchronous_mode(true);
3066 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3067 "");
rch2f2991c2017-04-13 19:28:173068
3069 CreateSession();
3070
Ryan Hamilton9835e662018-08-02 05:36:273071 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173072
3073 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3074 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363075 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173076 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3077
3078 // Pump the message loop to get the request started.
3079 base::RunLoop().RunUntilIdle();
3080 // Explicitly confirm the handshake.
3081 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523082 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173083
3084 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553085 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173086
3087 // Run the QUIC session to completion.
3088 base::RunLoop().RunUntilIdle();
3089 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3090 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3091
3092 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3093 ExpectQuicAlternateProtocolMapping();
3094 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3095}
3096
rch9ecde09b2017-04-08 00:18:233097// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3098// connection times out, then QUIC will be marked as broken and the request
3099// retried over TCP.
3100TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
Nick Harper72ade192019-07-17 03:30:423101 session_params_.quic_params.mark_quic_broken_when_network_blackholes = true;
Ryan Sleevi2e8255b2019-07-17 21:02:213102 session_params_.quic_params.idle_connection_timeout =
3103 base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:233104
3105 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593106 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133107 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233108 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3109
Ryan Hamiltone940bd12019-06-30 02:46:453110 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033111 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023112 quic_data.AddWrite(
3113 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453114 client_maker_.MakeRequestHeadersPacket(
3115 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3116 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3117
3118 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton3cc2c152019-07-09 19:36:013119 if (version_.transport_version != quic::QUIC_VERSION_99) {
3120 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(2));
3121 // TLP 1
3122 quic_data.AddWrite(SYNCHRONOUS,
3123 client_maker_.MakeRetransmissionPacket(1, 3, true));
3124 // TLP 2
3125 quic_data.AddWrite(SYNCHRONOUS,
3126 client_maker_.MakeRetransmissionPacket(2, 4, true));
3127 // RTO 1
3128 quic_data.AddWrite(SYNCHRONOUS,
3129 client_maker_.MakeRetransmissionPacket(1, 5, true));
3130 quic_data.AddWrite(SYNCHRONOUS,
3131 client_maker_.MakeRetransmissionPacket(2, 6, true));
3132 // RTO 2
3133 quic_data.AddWrite(SYNCHRONOUS,
3134 client_maker_.MakeRetransmissionPacket(1, 7, true));
3135 quic_data.AddWrite(SYNCHRONOUS,
3136 client_maker_.MakeRetransmissionPacket(2, 8, true));
3137 // RTO 3
3138 quic_data.AddWrite(SYNCHRONOUS,
3139 client_maker_.MakeRetransmissionPacket(1, 9, true));
3140 quic_data.AddWrite(SYNCHRONOUS,
3141 client_maker_.MakeRetransmissionPacket(2, 10, true));
rch9ecde09b2017-04-08 00:18:233142
Ryan Hamilton3cc2c152019-07-09 19:36:013143 quic_data.AddWrite(SYNCHRONOUS,
3144 client_maker_.MakeConnectionClosePacket(
3145 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3146 "No recent network activity."));
3147 } else {
3148 // Settings were sent in the request packet so there is only 1 packet to
3149 // retransmit.
3150 // TLP 1
3151 quic_data.AddWrite(SYNCHRONOUS,
3152 client_maker_.MakeRetransmissionPacket(1, 2, true));
3153 // TLP 2
3154 quic_data.AddWrite(SYNCHRONOUS,
3155 client_maker_.MakeRetransmissionPacket(1, 3, true));
3156 // RTO 1
3157 quic_data.AddWrite(SYNCHRONOUS,
3158 client_maker_.MakeRetransmissionPacket(1, 4, true));
3159 // RTO 2
3160 quic_data.AddWrite(SYNCHRONOUS,
3161 client_maker_.MakeRetransmissionPacket(1, 5, true));
3162 // RTO 3
3163 quic_data.AddWrite(SYNCHRONOUS,
3164 client_maker_.MakeRetransmissionPacket(1, 6, true));
3165
3166 quic_data.AddWrite(SYNCHRONOUS,
3167 client_maker_.MakeConnectionClosePacket(
3168 7, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3169 "No recent network activity."));
3170 }
Fan Yang928f1632017-12-14 18:55:223171
rch9ecde09b2017-04-08 00:18:233172 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3173 quic_data.AddRead(ASYNC, OK);
3174 quic_data.AddSocketDataToFactory(&socket_factory_);
3175
3176 // After that fails, it will be resent via TCP.
3177 MockWrite http_writes[] = {
3178 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3179 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3180 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3181
3182 MockRead http_reads[] = {
3183 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3184 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3185 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013186 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233187 socket_factory_.AddSocketDataProvider(&http_data);
3188 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3189
3190 // In order for a new QUIC session to be established via alternate-protocol
3191 // without racing an HTTP connection, we need the host resolution to happen
3192 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3193 // connection to the the server, in this test we require confirmation
3194 // before encrypting so the HTTP job will still start.
3195 host_resolver_.set_synchronous_mode(true);
3196 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3197 "");
rch9ecde09b2017-04-08 00:18:233198
3199 CreateSession();
3200 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233201 QuicStreamFactoryPeer::SetAlarmFactory(
3202 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193203 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553204 &clock_));
rch9ecde09b2017-04-08 00:18:233205
Ryan Hamilton9835e662018-08-02 05:36:273206 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233207
3208 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3209 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363210 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233211 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3212
3213 // Pump the message loop to get the request started.
3214 base::RunLoop().RunUntilIdle();
3215 // Explicitly confirm the handshake.
3216 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523217 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233218
3219 // Run the QUIC session to completion.
3220 quic_task_runner_->RunUntilIdle();
3221 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3222
3223 // Let the transaction proceed which will result in QUIC being marked
3224 // as broken and the request falling back to TCP.
3225 EXPECT_THAT(callback.WaitForResult(), IsOk());
3226
3227 ExpectBrokenAlternateProtocolMapping();
3228 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3229 ASSERT_FALSE(http_data.AllReadDataConsumed());
3230
3231 // Read the response body over TCP.
3232 CheckResponseData(&trans, "hello world");
3233 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3234 ASSERT_TRUE(http_data.AllReadDataConsumed());
3235}
3236
rch2f2991c2017-04-13 19:28:173237// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3238// connection times out, then QUIC will be marked as broken and the request
3239// retried over TCP.
3240TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Ryan Sleevi2e8255b2019-07-17 21:02:213241 session_params_.quic_params.idle_connection_timeout =
3242 base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173243
3244 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593245 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133246 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173247 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3248
Ryan Hamiltone940bd12019-06-30 02:46:453249 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033250 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023251 quic_data.AddWrite(
3252 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453253 client_maker_.MakeRequestHeadersPacket(
3254 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3255 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3256
3257 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton3cc2c152019-07-09 19:36:013258 if (version_.transport_version != quic::QUIC_VERSION_99) {
3259 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(2));
3260 // TLP 1
3261 quic_data.AddWrite(SYNCHRONOUS,
3262 client_maker_.MakeRetransmissionPacket(1, 3, true));
3263 // TLP 2
3264 quic_data.AddWrite(SYNCHRONOUS,
3265 client_maker_.MakeRetransmissionPacket(2, 4, true));
3266 // RTO 1
3267 quic_data.AddWrite(SYNCHRONOUS,
3268 client_maker_.MakeRetransmissionPacket(1, 5, true));
3269 quic_data.AddWrite(SYNCHRONOUS,
3270 client_maker_.MakeRetransmissionPacket(2, 6, true));
3271 // RTO 2
3272 quic_data.AddWrite(SYNCHRONOUS,
3273 client_maker_.MakeRetransmissionPacket(1, 7, true));
3274 quic_data.AddWrite(SYNCHRONOUS,
3275 client_maker_.MakeRetransmissionPacket(2, 8, true));
3276 // RTO 3
3277 quic_data.AddWrite(SYNCHRONOUS,
3278 client_maker_.MakeRetransmissionPacket(1, 9, true));
3279 quic_data.AddWrite(SYNCHRONOUS,
3280 client_maker_.MakeRetransmissionPacket(2, 10, true));
rch2f2991c2017-04-13 19:28:173281
Ryan Hamilton3cc2c152019-07-09 19:36:013282 quic_data.AddWrite(SYNCHRONOUS,
3283 client_maker_.MakeConnectionClosePacket(
3284 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3285 "No recent network activity."));
3286 } else {
3287 // Settings were sent in the request packet so there is only 1 packet to
3288 // retransmit.
3289 // TLP 1
3290 quic_data.AddWrite(SYNCHRONOUS,
3291 client_maker_.MakeRetransmissionPacket(1, 2, true));
3292 // TLP 2
3293 quic_data.AddWrite(SYNCHRONOUS,
3294 client_maker_.MakeRetransmissionPacket(1, 3, true));
3295 // RTO 1
3296 quic_data.AddWrite(SYNCHRONOUS,
3297 client_maker_.MakeRetransmissionPacket(1, 4, true));
3298 // RTO 2
3299 quic_data.AddWrite(SYNCHRONOUS,
3300 client_maker_.MakeRetransmissionPacket(1, 5, true));
3301 // RTO 3
3302 quic_data.AddWrite(SYNCHRONOUS,
3303 client_maker_.MakeRetransmissionPacket(1, 6, true));
3304
3305 quic_data.AddWrite(SYNCHRONOUS,
3306 client_maker_.MakeConnectionClosePacket(
3307 7, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3308 "No recent network activity."));
3309 }
Fan Yang928f1632017-12-14 18:55:223310
rch2f2991c2017-04-13 19:28:173311 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3312 quic_data.AddRead(ASYNC, OK);
3313 quic_data.AddSocketDataToFactory(&socket_factory_);
3314
3315 // After that fails, it will be resent via TCP.
3316 MockWrite http_writes[] = {
3317 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3318 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3319 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3320
3321 MockRead http_reads[] = {
3322 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3323 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3324 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013325 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173326 socket_factory_.AddSocketDataProvider(&http_data);
3327 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3328
3329 // In order for a new QUIC session to be established via alternate-protocol
3330 // without racing an HTTP connection, we need the host resolution to happen
3331 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3332 // connection to the the server, in this test we require confirmation
3333 // before encrypting so the HTTP job will still start.
3334 host_resolver_.set_synchronous_mode(true);
3335 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3336 "");
rch2f2991c2017-04-13 19:28:173337
3338 CreateSession();
3339 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173340 QuicStreamFactoryPeer::SetAlarmFactory(
3341 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193342 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553343 &clock_));
rch2f2991c2017-04-13 19:28:173344
Ryan Hamilton9835e662018-08-02 05:36:273345 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173346
3347 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3348 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363349 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173350 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3351
3352 // Pump the message loop to get the request started.
3353 base::RunLoop().RunUntilIdle();
3354 // Explicitly confirm the handshake.
3355 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523356 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173357
3358 // Run the QUIC session to completion.
3359 quic_task_runner_->RunUntilIdle();
3360 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3361
3362 ExpectQuicAlternateProtocolMapping();
3363
3364 // Let the transaction proceed which will result in QUIC being marked
3365 // as broken and the request falling back to TCP.
3366 EXPECT_THAT(callback.WaitForResult(), IsOk());
3367
3368 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3369 ASSERT_FALSE(http_data.AllReadDataConsumed());
3370
3371 // Read the response body over TCP.
3372 CheckResponseData(&trans, "hello world");
3373 ExpectBrokenAlternateProtocolMapping();
3374 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3375 ASSERT_TRUE(http_data.AllReadDataConsumed());
3376}
3377
rch9ecde09b2017-04-08 00:18:233378// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3379// connection times out, then QUIC will be marked as broken but the request
3380// will not be retried over TCP.
3381TEST_P(QuicNetworkTransactionTest,
3382 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
Nick Harper72ade192019-07-17 03:30:423383 session_params_.quic_params.mark_quic_broken_when_network_blackholes = true;
Ryan Sleevi2e8255b2019-07-17 21:02:213384 session_params_.quic_params.idle_connection_timeout =
3385 base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:233386
3387 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593388 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133389 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233390 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3391
Ryan Hamiltone940bd12019-06-30 02:46:453392 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033393 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023394 quic_data.AddWrite(
3395 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453396 client_maker_.MakeRequestHeadersPacket(
3397 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3398 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3399
3400 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton3cc2c152019-07-09 19:36:013401 if (version_.transport_version != quic::QUIC_VERSION_99) {
3402 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(2));
rch9ecde09b2017-04-08 00:18:233403
Ryan Hamilton3cc2c152019-07-09 19:36:013404 quic_data.AddRead(
3405 ASYNC, ConstructServerResponseHeadersPacket(
3406 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
3407 false, GetResponseHeaders("200 OK")));
3408 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
3409 quic_data.AddWrite(
3410 SYNCHRONOUS,
3411 ConstructClientAckPacket(3, 1, 1, 1,
3412 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233413
Ryan Hamilton3cc2c152019-07-09 19:36:013414 // TLP 1
3415 quic_data.AddWrite(SYNCHRONOUS,
3416 client_maker_.MakeRetransmissionPacket(1, 4, false));
3417 // TLP 2
3418 quic_data.AddWrite(SYNCHRONOUS,
3419 client_maker_.MakeRetransmissionPacket(2, 5, false));
3420 // RTO 1
3421 quic_data.AddWrite(SYNCHRONOUS,
3422 client_maker_.MakeRetransmissionPacket(1, 6, false));
3423 quic_data.AddWrite(SYNCHRONOUS,
3424 client_maker_.MakeRetransmissionPacket(2, 7, false));
3425 // RTO 2
3426 quic_data.AddWrite(SYNCHRONOUS,
3427 client_maker_.MakeRetransmissionPacket(1, 8, false));
3428 quic_data.AddWrite(SYNCHRONOUS,
3429 client_maker_.MakeRetransmissionPacket(2, 9, false));
3430 // RTO 3
3431 quic_data.AddWrite(SYNCHRONOUS,
3432 client_maker_.MakeRetransmissionPacket(1, 10, false));
3433 quic_data.AddWrite(SYNCHRONOUS,
3434 client_maker_.MakeRetransmissionPacket(2, 11, false));
rch9ecde09b2017-04-08 00:18:233435
Ryan Hamilton3cc2c152019-07-09 19:36:013436 quic_data.AddWrite(
3437 SYNCHRONOUS,
3438 client_maker_.MakeAckAndConnectionClosePacket(
3439 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
Renjie Tangff0d6372019-08-30 22:03:293440 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity.", 0));
Ryan Hamilton3cc2c152019-07-09 19:36:013441 } else {
3442 // Settings were sent in the request packet so there is only 1 packet to
3443 // retransmit.
3444 quic_data.AddRead(
3445 ASYNC, ConstructServerResponseHeadersPacket(
3446 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
3447 false, GetResponseHeaders("200 OK")));
3448 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
3449 quic_data.AddWrite(
3450 SYNCHRONOUS,
3451 ConstructClientAckPacket(2, 1, 1, 1,
3452 quic::QuicTime::Delta::FromMilliseconds(25)));
3453
3454 // TLP 1
3455 quic_data.AddWrite(SYNCHRONOUS,
3456 client_maker_.MakeRetransmissionPacket(1, 3, false));
3457 // TLP 2
3458 quic_data.AddWrite(SYNCHRONOUS,
3459 client_maker_.MakeRetransmissionPacket(1, 4, false));
3460 // RTO 1
3461 quic_data.AddWrite(SYNCHRONOUS,
3462 client_maker_.MakeRetransmissionPacket(1, 5, false));
3463 // RTO 2
3464 quic_data.AddWrite(SYNCHRONOUS,
3465 client_maker_.MakeRetransmissionPacket(1, 6, false));
3466 // RTO 3
3467 quic_data.AddWrite(SYNCHRONOUS,
3468 client_maker_.MakeRetransmissionPacket(1, 7, false));
3469
3470 quic_data.AddWrite(
3471 SYNCHRONOUS,
3472 client_maker_.MakeAckAndConnectionClosePacket(
3473 8, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
Renjie Tangff0d6372019-08-30 22:03:293474 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity.", 0));
Ryan Hamilton3cc2c152019-07-09 19:36:013475 }
Zhongyi Shia15736c2018-09-25 00:31:183476
rch9ecde09b2017-04-08 00:18:233477 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3478 quic_data.AddRead(ASYNC, OK);
3479 quic_data.AddSocketDataToFactory(&socket_factory_);
3480
3481 // In order for a new QUIC session to be established via alternate-protocol
3482 // without racing an HTTP connection, we need the host resolution to happen
3483 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3484 // connection to the the server, in this test we require confirmation
3485 // before encrypting so the HTTP job will still start.
3486 host_resolver_.set_synchronous_mode(true);
3487 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3488 "");
rch9ecde09b2017-04-08 00:18:233489
3490 CreateSession();
3491 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233492 QuicStreamFactoryPeer::SetAlarmFactory(
3493 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193494 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553495 &clock_));
rch9ecde09b2017-04-08 00:18:233496
Ryan Hamilton9835e662018-08-02 05:36:273497 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233498
3499 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3500 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363501 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233502 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3503
3504 // Pump the message loop to get the request started.
3505 base::RunLoop().RunUntilIdle();
3506 // Explicitly confirm the handshake.
3507 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523508 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233509
3510 // Pump the message loop to get the request started.
3511 base::RunLoop().RunUntilIdle();
3512
3513 // Run the QUIC session to completion.
3514 quic_task_runner_->RunUntilIdle();
3515 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3516
3517 // Let the transaction proceed which will result in QUIC being marked
3518 // as broken and the request falling back to TCP.
3519 EXPECT_THAT(callback.WaitForResult(), IsOk());
3520
3521 ExpectBrokenAlternateProtocolMapping();
3522 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3523
3524 std::string response_data;
3525 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3526 IsError(ERR_QUIC_PROTOCOL_ERROR));
3527}
3528
3529// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3530// connection RTOs, then QUIC will be marked as broken and the request retried
3531// over TCP.
3532TEST_P(QuicNetworkTransactionTest,
3533 TooManyRtosAfterHandshakeConfirmedThenBroken) {
Nick Harper72ade192019-07-17 03:30:423534 session_params_.quic_params.mark_quic_broken_when_network_blackholes = true;
3535 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233536
3537 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593538 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133539 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233540 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3541
Ryan Hamiltone940bd12019-06-30 02:46:453542 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033543 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023544 quic_data.AddWrite(
3545 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453546 client_maker_.MakeRequestHeadersPacket(
3547 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3548 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3549
3550 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton3cc2c152019-07-09 19:36:013551 if (version_.transport_version != quic::QUIC_VERSION_99) {
3552 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(2));
Ryan Hamiltone940bd12019-06-30 02:46:453553
Ryan Hamilton3cc2c152019-07-09 19:36:013554 // TLP 1
3555 quic_data.AddWrite(SYNCHRONOUS,
3556 client_maker_.MakeRetransmissionPacket(1, 3, true));
3557 // TLP 2
3558 quic_data.AddWrite(SYNCHRONOUS,
3559 client_maker_.MakeRetransmissionPacket(2, 4, true));
3560 // RTO 1
3561 quic_data.AddWrite(SYNCHRONOUS,
3562 client_maker_.MakeRetransmissionPacket(1, 5, true));
3563 quic_data.AddWrite(SYNCHRONOUS,
3564 client_maker_.MakeRetransmissionPacket(2, 6, true));
3565 // RTO 2
3566 quic_data.AddWrite(SYNCHRONOUS,
3567 client_maker_.MakeRetransmissionPacket(1, 7, true));
3568 quic_data.AddWrite(SYNCHRONOUS,
3569 client_maker_.MakeRetransmissionPacket(2, 8, true));
3570 // RTO 3
3571 quic_data.AddWrite(SYNCHRONOUS,
3572 client_maker_.MakeRetransmissionPacket(1, 9, true));
3573 quic_data.AddWrite(SYNCHRONOUS,
3574 client_maker_.MakeRetransmissionPacket(2, 10, true));
3575 // RTO 4
3576 quic_data.AddWrite(SYNCHRONOUS,
3577 client_maker_.MakeRetransmissionPacket(1, 11, true));
3578 quic_data.AddWrite(SYNCHRONOUS,
3579 client_maker_.MakeRetransmissionPacket(2, 12, true));
rch9ecde09b2017-04-08 00:18:233580
Ryan Hamilton3cc2c152019-07-09 19:36:013581 quic_data.AddWrite(SYNCHRONOUS,
3582 client_maker_.MakeConnectionClosePacket(
3583 13, true, quic::QUIC_TOO_MANY_RTOS,
3584 "5 consecutive retransmission timeouts"));
3585 } else {
3586 // Settings were sent in the request packet so there is only 1 packet to
3587 // retransmit.
3588 // TLP 1
3589 quic_data.AddWrite(SYNCHRONOUS,
3590 client_maker_.MakeRetransmissionPacket(1, 2, true));
3591 // TLP 2
3592 quic_data.AddWrite(SYNCHRONOUS,
3593 client_maker_.MakeRetransmissionPacket(1, 3, true));
3594 // RTO 1
3595 quic_data.AddWrite(SYNCHRONOUS,
3596 client_maker_.MakeRetransmissionPacket(1, 4, true));
3597 // RTO 2
3598 quic_data.AddWrite(SYNCHRONOUS,
3599 client_maker_.MakeRetransmissionPacket(1, 5, true));
3600 // RTO 3
3601 quic_data.AddWrite(SYNCHRONOUS,
3602 client_maker_.MakeRetransmissionPacket(1, 6, true));
3603 // RTO 4
3604 quic_data.AddWrite(SYNCHRONOUS,
3605 client_maker_.MakeRetransmissionPacket(1, 7, true));
rch9ecde09b2017-04-08 00:18:233606
Ryan Hamilton3cc2c152019-07-09 19:36:013607 quic_data.AddWrite(SYNCHRONOUS,
3608 client_maker_.MakeConnectionClosePacket(
3609 8, true, quic::QUIC_TOO_MANY_RTOS,
3610 "5 consecutive retransmission timeouts"));
3611 }
rch9ecde09b2017-04-08 00:18:233612 quic_data.AddRead(ASYNC, OK);
3613 quic_data.AddSocketDataToFactory(&socket_factory_);
3614
3615 // After that fails, it will be resent via TCP.
3616 MockWrite http_writes[] = {
3617 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3618 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3619 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3620
3621 MockRead http_reads[] = {
3622 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3623 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3624 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013625 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233626 socket_factory_.AddSocketDataProvider(&http_data);
3627 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3628
3629 // In order for a new QUIC session to be established via alternate-protocol
3630 // without racing an HTTP connection, we need the host resolution to happen
3631 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3632 // connection to the the server, in this test we require confirmation
3633 // before encrypting so the HTTP job will still start.
3634 host_resolver_.set_synchronous_mode(true);
3635 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3636 "");
rch9ecde09b2017-04-08 00:18:233637
3638 CreateSession();
3639 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233640 QuicStreamFactoryPeer::SetAlarmFactory(
3641 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193642 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553643 &clock_));
rch9ecde09b2017-04-08 00:18:233644
Ryan Hamilton9835e662018-08-02 05:36:273645 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233646
3647 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3648 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363649 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3651
3652 // Pump the message loop to get the request started.
3653 base::RunLoop().RunUntilIdle();
3654 // Explicitly confirm the handshake.
3655 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523656 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233657
3658 // Run the QUIC session to completion.
3659 quic_task_runner_->RunUntilIdle();
3660 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3661
3662 // Let the transaction proceed which will result in QUIC being marked
3663 // as broken and the request falling back to TCP.
3664 EXPECT_THAT(callback.WaitForResult(), IsOk());
3665
3666 ExpectBrokenAlternateProtocolMapping();
3667 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3668 ASSERT_FALSE(http_data.AllReadDataConsumed());
3669
3670 // Read the response body over TCP.
3671 CheckResponseData(&trans, "hello world");
3672 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3673 ASSERT_TRUE(http_data.AllReadDataConsumed());
3674}
3675
3676// Verify that if a QUIC connection RTOs, while there are no active streams
3677// QUIC will be marked as broken.
3678TEST_P(QuicNetworkTransactionTest,
3679 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
Nick Harper72ade192019-07-17 03:30:423680 session_params_.quic_params.mark_quic_broken_when_network_blackholes = true;
3681 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233682
3683 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593684 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133685 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233686 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3687
Ryan Hamiltone940bd12019-06-30 02:46:453688 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033689 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023690 quic_data.AddWrite(
3691 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453692 client_maker_.MakeRequestHeadersPacket(
3693 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3694 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3695
3696 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton3cc2c152019-07-09 19:36:013697
Ryan Hamiltone940bd12019-06-30 02:46:453698 if (quic::VersionUsesQpack(version_.transport_version)) {
Ryan Hamiltonb01f886f2019-07-10 02:25:553699 quic_data.AddWrite(
3700 SYNCHRONOUS, client_maker_.MakeRstPacket(
3701 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
3702 quic::QUIC_STREAM_CANCELLED));
Ryan Hamiltone940bd12019-06-30 02:46:453703 // Since the headers are sent on the data stream, when the stream is reset
3704 // the headers are no longer retransmitted.
Ryan Hamiltonb01f886f2019-07-10 02:25:553705 client_maker_.RemoveSavedStreamFrames(
3706 GetNthClientInitiatedBidirectionalStreamId(0));
Ryan Hamiltone940bd12019-06-30 02:46:453707 // TLP 1
3708 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:553709 client_maker_.MakeRetransmissionPacket(1, 3, true));
Ryan Hamiltone940bd12019-06-30 02:46:453710 // TLP 2
3711 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:553712 client_maker_.MakeRetransmissionPacket(2, 4, true));
Ryan Hamiltone940bd12019-06-30 02:46:453713 // RTO 1
3714 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:553715 client_maker_.MakeRetransmissionPacket(1, 5, true));
Ryan Hamiltone940bd12019-06-30 02:46:453716 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:553717 client_maker_.MakeRetransmissionPacket(2, 6, true));
Ryan Hamiltone940bd12019-06-30 02:46:453718 // RTO 2
3719 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:553720 client_maker_.MakeRetransmissionPacket(1, 7, true));
Ryan Hamiltone940bd12019-06-30 02:46:453721 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:553722 client_maker_.MakeRetransmissionPacket(2, 8, true));
Ryan Hamiltone940bd12019-06-30 02:46:453723 // RTO 3
3724 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:553725 client_maker_.MakeRetransmissionPacket(1, 9, true));
Ryan Hamiltone940bd12019-06-30 02:46:453726 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:553727 client_maker_.MakeRetransmissionPacket(2, 10, true));
Ryan Hamiltone940bd12019-06-30 02:46:453728 // RTO 4
3729 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:553730 client_maker_.MakeRetransmissionPacket(1, 11, true));
Ryan Hamiltone940bd12019-06-30 02:46:453731 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamiltonb01f886f2019-07-10 02:25:553732 client_maker_.MakeRetransmissionPacket(2, 12, true));
3733 // RTO 5
3734 quic_data.AddWrite(SYNCHRONOUS,
3735 client_maker_.MakeConnectionClosePacket(
3736 13, true, quic::QUIC_TOO_MANY_RTOS,
3737 "5 consecutive retransmission timeouts"));
Ryan Hamiltone940bd12019-06-30 02:46:453738 } else {
Ryan Hamiltonb01f886f2019-07-10 02:25:553739 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(2));
3740 quic_data.AddWrite(
3741 SYNCHRONOUS, client_maker_.MakeRstPacket(
3742 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3743 quic::QUIC_STREAM_CANCELLED));
Ryan Hamiltone940bd12019-06-30 02:46:453744 // TLP 1
3745 quic_data.AddWrite(SYNCHRONOUS,
3746 client_maker_.MakeRetransmissionPacket(1, 4, true));
3747 // TLP 2
3748 quic_data.AddWrite(SYNCHRONOUS,
3749 client_maker_.MakeRetransmissionPacket(2, 5, true));
3750 // RTO 1
3751 quic_data.AddWrite(SYNCHRONOUS,
3752 client_maker_.MakeRetransmissionPacket(3, 6, true));
3753 quic_data.AddWrite(SYNCHRONOUS,
3754 client_maker_.MakeRetransmissionPacket(1, 7, true));
3755 // RTO 2
3756 quic_data.AddWrite(SYNCHRONOUS,
3757 client_maker_.MakeRetransmissionPacket(2, 8, true));
3758 quic_data.AddWrite(SYNCHRONOUS,
3759 client_maker_.MakeRetransmissionPacket(3, 9, true));
3760 // RTO 3
3761 quic_data.AddWrite(SYNCHRONOUS,
3762 client_maker_.MakeRetransmissionPacket(1, 10, true));
3763 quic_data.AddWrite(SYNCHRONOUS,
3764 client_maker_.MakeRetransmissionPacket(2, 11, true));
3765 // RTO 4
3766 quic_data.AddWrite(SYNCHRONOUS,
3767 client_maker_.MakeRetransmissionPacket(3, 12, true));
3768 quic_data.AddWrite(SYNCHRONOUS,
3769 client_maker_.MakeRetransmissionPacket(1, 13, true));
rch9ecde09b2017-04-08 00:18:233770 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433771 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523772 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433773 "5 consecutive retransmission timeouts"));
Ryan Hamiltonb01f886f2019-07-10 02:25:553774 }
rch9ecde09b2017-04-08 00:18:233775
3776 quic_data.AddRead(ASYNC, OK);
3777 quic_data.AddSocketDataToFactory(&socket_factory_);
3778
3779 // In order for a new QUIC session to be established via alternate-protocol
3780 // without racing an HTTP connection, we need the host resolution to happen
3781 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3782 // connection to the the server, in this test we require confirmation
3783 // before encrypting so the HTTP job will still start.
3784 host_resolver_.set_synchronous_mode(true);
3785 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3786 "");
rch9ecde09b2017-04-08 00:18:233787
3788 CreateSession();
3789 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233790 QuicStreamFactoryPeer::SetAlarmFactory(
3791 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193792 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553793 &clock_));
rch9ecde09b2017-04-08 00:18:233794
Ryan Hamilton9835e662018-08-02 05:36:273795 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233796
Jeremy Roman0579ed62017-08-29 15:56:193797 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233798 session_.get());
3799 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363800 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3802
3803 // Pump the message loop to get the request started.
3804 base::RunLoop().RunUntilIdle();
3805 // Explicitly confirm the handshake.
3806 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523807 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233808
3809 // Now cancel the request.
3810 trans.reset();
3811
3812 // Run the QUIC session to completion.
3813 quic_task_runner_->RunUntilIdle();
3814
3815 ExpectBrokenAlternateProtocolMapping();
3816
3817 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3818}
3819
rch2f2991c2017-04-13 19:28:173820// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3821// protocol error occurs after the handshake is confirmed, the request
3822// retried over TCP and the QUIC will be marked as broken.
3823TEST_P(QuicNetworkTransactionTest,
3824 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Ryan Sleevi2e8255b2019-07-17 21:02:213825 session_params_.quic_params.idle_connection_timeout =
3826 base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173827
3828 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593829 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033830 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433831 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:023832 ConstructClientRequestHeadersPacket(
3833 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3834 true, GetRequestHeaders("GET", "https", "/")));
3835 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553836 uint64_t packet_number = 2;
3837 if (version_.transport_version != quic::QUIC_VERSION_99) {
3838 quic_data.AddWrite(SYNCHRONOUS,
3839 ConstructInitialSettingsPacket(packet_number++));
3840 }
3841 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3842
rch2f2991c2017-04-13 19:28:173843 // Peer sending data from an non-existing stream causes this end to raise
3844 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333845 quic_data.AddRead(
3846 ASYNC, ConstructServerRstPacket(
3847 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3848 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173849 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamiltonb01f886f2019-07-10 02:25:553850 quic_data.AddWrite(
3851 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
3852 packet_number++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
Renjie Tangff0d6372019-08-30 22:03:293853 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3854 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173855 quic_data.AddSocketDataToFactory(&socket_factory_);
3856
3857 // After that fails, it will be resent via TCP.
3858 MockWrite http_writes[] = {
3859 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3860 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3861 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3862
3863 MockRead http_reads[] = {
3864 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3865 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3866 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013867 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173868 socket_factory_.AddSocketDataProvider(&http_data);
3869 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3870
3871 // In order for a new QUIC session to be established via alternate-protocol
3872 // without racing an HTTP connection, we need the host resolution to happen
3873 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3874 // connection to the the server, in this test we require confirmation
3875 // before encrypting so the HTTP job will still start.
3876 host_resolver_.set_synchronous_mode(true);
3877 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3878 "");
rch2f2991c2017-04-13 19:28:173879
3880 CreateSession();
3881
Ryan Hamilton9835e662018-08-02 05:36:273882 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173883
3884 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3885 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363886 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173887 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3888
3889 // Pump the message loop to get the request started.
3890 base::RunLoop().RunUntilIdle();
3891 // Explicitly confirm the handshake.
3892 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523893 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553894 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173895
3896 // Run the QUIC session to completion.
3897 base::RunLoop().RunUntilIdle();
3898 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3899
3900 ExpectQuicAlternateProtocolMapping();
3901
3902 // Let the transaction proceed which will result in QUIC being marked
3903 // as broken and the request falling back to TCP.
3904 EXPECT_THAT(callback.WaitForResult(), IsOk());
3905
3906 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3907 ASSERT_FALSE(http_data.AllReadDataConsumed());
3908
3909 // Read the response body over TCP.
3910 CheckResponseData(&trans, "hello world");
3911 ExpectBrokenAlternateProtocolMapping();
3912 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3913 ASSERT_TRUE(http_data.AllReadDataConsumed());
3914}
3915
rch30943ee2017-06-12 21:28:443916// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3917// request is reset from, then QUIC will be marked as broken and the request
3918// retried over TCP.
3919TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443920 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593921 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133922 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443923 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3924
Michael Warres167db3e2019-03-01 21:38:033925 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023926 quic_data.AddWrite(
3927 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453928 client_maker_.MakeRequestHeadersPacket(
3929 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3930 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3931
3932 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553933 if (version_.transport_version != quic::QUIC_VERSION_99) {
3934 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(2));
3935 }
3936 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443937
Fan Yang32c5a112018-12-10 20:06:333938 quic_data.AddRead(ASYNC,
3939 ConstructServerRstPacket(
3940 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3941 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443942
3943 quic_data.AddRead(ASYNC, OK);
3944 quic_data.AddSocketDataToFactory(&socket_factory_);
3945
3946 // After that fails, it will be resent via TCP.
3947 MockWrite http_writes[] = {
3948 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3949 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3950 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3951
3952 MockRead http_reads[] = {
3953 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3954 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3955 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013956 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443957 socket_factory_.AddSocketDataProvider(&http_data);
3958 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3959
3960 // In order for a new QUIC session to be established via alternate-protocol
3961 // without racing an HTTP connection, we need the host resolution to happen
3962 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3963 // connection to the the server, in this test we require confirmation
3964 // before encrypting so the HTTP job will still start.
3965 host_resolver_.set_synchronous_mode(true);
3966 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3967 "");
rch30943ee2017-06-12 21:28:443968
3969 CreateSession();
3970
Ryan Hamilton9835e662018-08-02 05:36:273971 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443972
3973 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3974 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363975 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3977
3978 // Pump the message loop to get the request started.
3979 base::RunLoop().RunUntilIdle();
3980 // Explicitly confirm the handshake.
3981 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523982 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553983 quic_data.Resume();
rch30943ee2017-06-12 21:28:443984
3985 // Run the QUIC session to completion.
3986 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3987
3988 ExpectQuicAlternateProtocolMapping();
3989
3990 // Let the transaction proceed which will result in QUIC being marked
3991 // as broken and the request falling back to TCP.
3992 EXPECT_THAT(callback.WaitForResult(), IsOk());
3993
3994 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3995 ASSERT_FALSE(http_data.AllReadDataConsumed());
3996
3997 // Read the response body over TCP.
3998 CheckResponseData(&trans, "hello world");
3999 ExpectBrokenAlternateProtocolMapping();
4000 ASSERT_TRUE(http_data.AllWriteDataConsumed());
4001 ASSERT_TRUE(http_data.AllReadDataConsumed());
4002}
4003
Ryan Hamilton6c2a2a82017-12-15 02:06:284004// Verify that when an origin has two alt-svc advertisements, one local and one
4005// remote, that when the local is broken the request will go over QUIC via
4006// the remote Alt-Svc.
4007// This is a regression test for crbug/825646.
4008TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Nick Harper72ade192019-07-17 03:30:424009 session_params_.quic_params.allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:284010
4011 GURL origin1 = request_.url; // mail.example.org
4012 GURL origin2("https://www.example.org/");
4013 ASSERT_NE(origin1.host(), origin2.host());
4014
4015 scoped_refptr<X509Certificate> cert(
4016 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244017 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4018 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:284019
4020 ProofVerifyDetailsChromium verify_details;
4021 verify_details.cert_verify_result.verified_cert = cert;
4022 verify_details.cert_verify_result.is_issued_by_known_root = true;
4023 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4024
Ryan Hamiltonabad59e2019-06-06 04:02:594025 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024026 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284027 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024028 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4029 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4030 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434031 mock_quic_data.AddRead(
4032 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334033 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024034 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434035 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434036 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334037 ASYNC, ConstructServerDataPacket(
4038 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174039 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434040 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284041 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4042 mock_quic_data.AddRead(ASYNC, 0); // EOF
4043
4044 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:594045 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:284046 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4047 AddHangingNonAlternateProtocolSocketData();
4048
4049 CreateSession();
4050
4051 // Set up alternative service for |origin1|.
4052 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4053 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4054 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4055 AlternativeServiceInfoVector alternative_services;
4056 alternative_services.push_back(
4057 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4058 local_alternative, expiration,
Nick Harper72ade192019-07-17 03:30:424059 session_->params().quic_params.supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:284060 alternative_services.push_back(
4061 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4062 remote_alternative, expiration,
Nick Harper72ade192019-07-17 03:30:424063 session_->params().quic_params.supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494064 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4065 NetworkIsolationKey(),
4066 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:284067
Matt Menke3233d8f22019-08-20 21:01:494068 http_server_properties_->MarkAlternativeServiceBroken(local_alternative);
Ryan Hamilton6c2a2a82017-12-15 02:06:284069
4070 SendRequestAndExpectQuicResponse("hello!");
4071}
4072
rch30943ee2017-06-12 21:28:444073// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4074// request is reset from, then QUIC will be marked as broken and the request
4075// retried over TCP. Then, subsequent requests will go over a new QUIC
4076// connection instead of going back to the broken QUIC connection.
4077// This is a regression tests for crbug/731303.
4078TEST_P(QuicNetworkTransactionTest,
4079 ResetPooledAfterHandshakeConfirmedThenBroken) {
Nick Harper72ade192019-07-17 03:30:424080 session_params_.quic_params.allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444081
4082 GURL origin1 = request_.url;
4083 GURL origin2("https://www.example.org/");
4084 ASSERT_NE(origin1.host(), origin2.host());
4085
Ryan Hamiltonabad59e2019-06-06 04:02:594086 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:444087
4088 scoped_refptr<X509Certificate> cert(
4089 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244090 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4091 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444092
4093 ProofVerifyDetailsChromium verify_details;
4094 verify_details.cert_verify_result.verified_cert = cert;
4095 verify_details.cert_verify_result.is_issued_by_known_root = true;
4096 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4097
Ryan Hamilton0d65a8c2019-06-07 00:46:024098 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch30943ee2017-06-12 21:28:444099 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434100 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024101 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4102 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4103 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434104 mock_quic_data.AddRead(
4105 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334106 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024107 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434108 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434109 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334110 ASYNC, ConstructServerDataPacket(
4111 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174112 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434113 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444114
4115 // Second request will go over the pooled QUIC connection, but will be
4116 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054117 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174118 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4119 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054120 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174121 QuicTestPacketMaker server_maker2(
4122 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4123 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434124 mock_quic_data.AddWrite(
4125 SYNCHRONOUS,
4126 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334127 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434128 GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024129 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334130 mock_quic_data.AddRead(
4131 ASYNC, ConstructServerRstPacket(
4132 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4133 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444134 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4135 mock_quic_data.AddRead(ASYNC, 0); // EOF
4136
4137 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4138
4139 // After that fails, it will be resent via TCP.
4140 MockWrite http_writes[] = {
4141 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4142 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4143 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4144
4145 MockRead http_reads[] = {
4146 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4147 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4148 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014149 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444150 socket_factory_.AddSocketDataProvider(&http_data);
4151 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4152
Ryan Hamilton6c2a2a82017-12-15 02:06:284153 // Then the next request to the second origin will be sent over TCP.
4154 socket_factory_.AddSocketDataProvider(&http_data);
4155 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444156
4157 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564158 QuicStreamFactoryPeer::SetAlarmFactory(
4159 session_->quic_stream_factory(),
4160 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4161 &clock_));
rch30943ee2017-06-12 21:28:444162
4163 // Set up alternative service for |origin1|.
4164 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244165 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494166 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074167 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4168 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:444169
4170 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244171 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494172 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074173 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4174 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344175
rch30943ee2017-06-12 21:28:444176 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524177 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444178 SendRequestAndExpectQuicResponse("hello!");
4179
4180 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524181 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444182 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4183 request_.url = origin2;
4184 SendRequestAndExpectHttpResponse("hello world");
Matt Menke3233d8f22019-08-20 21:01:494185 EXPECT_FALSE(
4186 http_server_properties_->IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244187 << alternative1.ToString();
Matt Menke3233d8f22019-08-20 21:01:494188 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244189 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444190
4191 // The third request should use a new QUIC connection, not the broken
4192 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284193 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444194}
4195
bnc8be55ebb2015-10-30 14:12:074196TEST_P(QuicNetworkTransactionTest,
4197 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564198 std::string altsvc_header =
4199 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4200 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074201 MockRead http_reads[] = {
4202 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4203 MockRead("hello world"),
4204 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4205 MockRead(ASYNC, OK)};
4206
Ryan Sleevib8d7ea02018-05-07 20:01:014207 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074208 socket_factory_.AddSocketDataProvider(&http_data);
4209 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4210 socket_factory_.AddSocketDataProvider(&http_data);
4211 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4212
rch3f4b8452016-02-23 16:59:324213 CreateSession();
bnc8be55ebb2015-10-30 14:12:074214
4215 SendRequestAndExpectHttpResponse("hello world");
4216 SendRequestAndExpectHttpResponse("hello world");
4217}
4218
Xida Chen9bfe0b62018-04-24 19:52:214219// When multiple alternative services are advertised, HttpStreamFactory should
4220// select the alternative service which uses existing QUIC session if available.
4221// If no existing QUIC session can be used, use the first alternative service
4222// from the list.
zhongyi32569c62016-01-08 02:54:304223TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Nick Harper72ade192019-07-17 03:30:424224 session_params_.quic_params.allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524225 MockRead http_reads[] = {
4226 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294227 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524228 MockRead("hello world"),
4229 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4230 MockRead(ASYNC, OK)};
4231
Ryan Sleevib8d7ea02018-05-07 20:01:014232 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524233 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084234 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564235 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524236
zhongyi32569c62016-01-08 02:54:304237 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294238 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304239 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594240 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024241 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:364242 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024243 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4244 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4245 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304246
4247 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294248 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4249 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434250 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024251 ASYNC, ConstructServerResponseHeadersPacket(
4252 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4253 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434254 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434255 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334256 ASYNC, ConstructServerDataPacket(
4257 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174258 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434259 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304260
4261 // Second QUIC request data.
4262 // Connection pooling, using existing session, no need to include version
4263 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584264 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334265 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4266 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4267 true, GetRequestHeaders("GET", "https", "/"),
Ryan Hamilton0d65a8c2019-06-07 00:46:024268 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434269 mock_quic_data.AddRead(
4270 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334271 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024272 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434273 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334274 ASYNC, ConstructServerDataPacket(
4275 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174276 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434277 mock_quic_data.AddWrite(
4278 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524279 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594280 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524281
4282 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4283
rtennetib8e80fb2016-05-16 00:12:094284 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324285 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564286 QuicStreamFactoryPeer::SetAlarmFactory(
4287 session_->quic_stream_factory(),
4288 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4289 &clock_));
bncc958faa2015-07-31 18:14:524290
4291 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304292
bnc359ed2a2016-04-29 20:43:454293 SendRequestAndExpectQuicResponse("hello!");
4294 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304295}
4296
tbansal6490783c2016-09-20 17:55:274297// Check that an existing QUIC connection to an alternative proxy server is
4298// used.
4299TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4300 base::HistogramTester histogram_tester;
4301
tbansal6490783c2016-09-20 17:55:274302 // First QUIC request data.
4303 // Open a session to foo.example.org:443 using the first entry of the
4304 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594305 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024306 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:364307 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024308 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4309 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4310 true, GetRequestHeaders("GET", "http", "/")));
tbansal6490783c2016-09-20 17:55:274311
4312 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434313 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024314 ASYNC, ConstructServerResponseHeadersPacket(
4315 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4316 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434317 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434318 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334319 ASYNC, ConstructServerDataPacket(
4320 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174321 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434322 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274323
4324 // Second QUIC request data.
4325 // Connection pooling, using existing session, no need to include version
4326 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274327 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334328 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4329 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4330 true, GetRequestHeaders("GET", "http", "/"),
Ryan Hamilton0d65a8c2019-06-07 00:46:024331 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434332 mock_quic_data.AddRead(
4333 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334334 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024335 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434336 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334337 ASYNC, ConstructServerDataPacket(
4338 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174339 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434340 mock_quic_data.AddWrite(
4341 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274342 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4343 mock_quic_data.AddRead(ASYNC, 0); // EOF
4344
4345 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4346
4347 AddHangingNonAlternateProtocolSocketData();
4348
4349 TestProxyDelegate test_proxy_delegate;
4350
Lily Houghton8c2f97d2018-01-22 05:06:594351 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494352 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274353
4354 test_proxy_delegate.set_alternative_proxy_server(
4355 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524356 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274357
4358 request_.url = GURL("http://mail.example.org/");
4359
4360 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564361 QuicStreamFactoryPeer::SetAlarmFactory(
4362 session_->quic_stream_factory(),
4363 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4364 &clock_));
tbansal6490783c2016-09-20 17:55:274365
4366 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4367 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4368 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4369 1);
4370
4371 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4372 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4373 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4374 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4375 1);
4376}
4377
Ryan Hamilton8d9ee76e2018-05-29 23:52:524378// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454379// even if alternative service destination is different.
4380TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Nick Harper72ade192019-07-17 03:30:424381 session_params_.quic_params.allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594382 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454383
Ryan Hamilton0d65a8c2019-06-07 00:46:024384 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
bnc359ed2a2016-04-29 20:43:454385 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434386 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024387 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4388 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4389 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434390 mock_quic_data.AddRead(
4391 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334392 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024393 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434394 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434395 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334396 ASYNC, ConstructServerDataPacket(
4397 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174398 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434399 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304400
bnc359ed2a2016-04-29 20:43:454401 // Second request.
alyssar2adf3ac2016-05-03 17:12:584402 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334403 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4404 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4405 true, GetRequestHeaders("GET", "https", "/"),
Ryan Hamilton0d65a8c2019-06-07 00:46:024406 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434407 mock_quic_data.AddRead(
4408 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334409 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024410 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434411 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334412 ASYNC, ConstructServerDataPacket(
4413 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174414 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434415 mock_quic_data.AddWrite(
4416 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304417 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4418 mock_quic_data.AddRead(ASYNC, 0); // EOF
4419
4420 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454421
4422 AddHangingNonAlternateProtocolSocketData();
4423 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304424
rch3f4b8452016-02-23 16:59:324425 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564426 QuicStreamFactoryPeer::SetAlarmFactory(
4427 session_->quic_stream_factory(),
4428 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4429 &clock_));
zhongyi32569c62016-01-08 02:54:304430
bnc359ed2a2016-04-29 20:43:454431 const char destination1[] = "first.example.com";
4432 const char destination2[] = "second.example.com";
4433
4434 // Set up alternative service entry to destination1.
4435 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214436 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454437 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494438 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074439 server, NetworkIsolationKey(), alternative_service, expiration,
4440 supported_versions_);
bnc359ed2a2016-04-29 20:43:454441 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524442 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454443 SendRequestAndExpectQuicResponse("hello!");
4444
4445 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214446 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494447 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074448 server, NetworkIsolationKey(), alternative_service, expiration,
4449 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524450 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454451 // even though alternative service destination is different.
4452 SendRequestAndExpectQuicResponse("hello!");
4453}
4454
4455// Pool to existing session with matching destination and matching certificate
4456// even if origin is different, and even if the alternative service with
4457// matching destination is not the first one on the list.
4458TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Nick Harper72ade192019-07-17 03:30:424459 session_params_.quic_params.allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454460 GURL origin1 = request_.url;
4461 GURL origin2("https://www.example.org/");
4462 ASSERT_NE(origin1.host(), origin2.host());
4463
Ryan Hamiltonabad59e2019-06-06 04:02:594464 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454465
Ryan Hamilton0d65a8c2019-06-07 00:46:024466 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
bnc359ed2a2016-04-29 20:43:454467 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434468 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024469 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4470 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4471 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434472 mock_quic_data.AddRead(
4473 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334474 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024475 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434476 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434477 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334478 ASYNC, ConstructServerDataPacket(
4479 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174480 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434481 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454482
4483 // Second request.
Yixin Wang079ad542018-01-11 04:06:054484 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174485 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4486 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054487 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174488 QuicTestPacketMaker server_maker2(
4489 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4490 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584491 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434492 SYNCHRONOUS,
4493 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334494 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434495 GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024496 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434497 mock_quic_data.AddRead(
4498 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334499 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024500 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434501 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334502 ASYNC, ConstructServerDataPacket(
4503 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174504 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434505 mock_quic_data.AddWrite(
4506 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454507 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4508 mock_quic_data.AddRead(ASYNC, 0); // EOF
4509
4510 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4511
4512 AddHangingNonAlternateProtocolSocketData();
4513 AddHangingNonAlternateProtocolSocketData();
4514
4515 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564516 QuicStreamFactoryPeer::SetAlarmFactory(
4517 session_->quic_stream_factory(),
4518 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4519 &clock_));
bnc359ed2a2016-04-29 20:43:454520
4521 const char destination1[] = "first.example.com";
4522 const char destination2[] = "second.example.com";
4523
4524 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214525 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454526 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494527 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074528 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4529 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454530
4531 // Set up multiple alternative service entries for |origin2|,
4532 // the first one with a different destination as for |origin1|,
4533 // the second one with the same. The second one should be used,
4534 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214535 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454536 AlternativeServiceInfoVector alternative_services;
4537 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214538 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4539 alternative_service2, expiration,
Nick Harper72ade192019-07-17 03:30:424540 session_->params().quic_params.supported_versions));
bnc359ed2a2016-04-29 20:43:454541 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214542 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4543 alternative_service1, expiration,
Nick Harper72ade192019-07-17 03:30:424544 session_->params().quic_params.supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494545 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4546 NetworkIsolationKey(),
4547 alternative_services);
bnc359ed2a2016-04-29 20:43:454548 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524549 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454550 SendRequestAndExpectQuicResponse("hello!");
4551
4552 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524553 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454554 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584555
bnc359ed2a2016-04-29 20:43:454556 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304557}
4558
4559// Multiple origins have listed the same alternative services. When there's a
4560// existing QUIC session opened by a request to other origin,
4561// if the cert is valid, should select this QUIC session to make the request
4562// if this is also the first existing QUIC session.
4563TEST_P(QuicNetworkTransactionTest,
4564 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Nick Harper72ade192019-07-17 03:30:424565 session_params_.quic_params.allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294566 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304567
rch9ae5b3b2016-02-11 00:36:294568 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304569 MockRead http_reads[] = {
4570 MockRead("HTTP/1.1 200 OK\r\n"),
4571 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294572 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304573 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4574 MockRead(ASYNC, OK)};
4575
Ryan Sleevib8d7ea02018-05-07 20:01:014576 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304577 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084578 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304579 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4580
4581 // HTTP data for request to mail.example.org.
4582 MockRead http_reads2[] = {
4583 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294584 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304585 MockRead("hello world from mail.example.org"),
4586 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4587 MockRead(ASYNC, OK)};
4588
Ryan Sleevib8d7ea02018-05-07 20:01:014589 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304590 socket_factory_.AddSocketDataProvider(&http_data2);
4591 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4592
Yixin Wang079ad542018-01-11 04:06:054593 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174594 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4595 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054596 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584597 server_maker_.set_hostname("www.example.org");
4598 client_maker_.set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594599 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024600 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:304601 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584602 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024603 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4604 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4605 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434606
4607 mock_quic_data.AddRead(
4608 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334609 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024610 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434611 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334612 mock_quic_data.AddRead(
4613 ASYNC, ConstructServerDataPacket(
4614 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174615 header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434616 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4617 // Second QUIC request data.
4618 mock_quic_data.AddWrite(
4619 SYNCHRONOUS,
4620 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334621 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434622 GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024623 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434624 mock_quic_data.AddRead(
4625 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334626 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024627 GetResponseHeaders("200 OK")));
Fan Yang32c5a112018-12-10 20:06:334628 mock_quic_data.AddRead(
4629 ASYNC, ConstructServerDataPacket(
4630 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174631 header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434632 mock_quic_data.AddWrite(
4633 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304634 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4635 mock_quic_data.AddRead(ASYNC, 0); // EOF
4636
4637 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304638
rtennetib8e80fb2016-05-16 00:12:094639 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324640 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564641 QuicStreamFactoryPeer::SetAlarmFactory(
4642 session_->quic_stream_factory(),
4643 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4644 &clock_));
zhongyi32569c62016-01-08 02:54:304645
4646 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294647 request_.url = GURL("https://www.example.org/");
4648 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304649 request_.url = GURL("https://mail.example.org/");
4650 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4651
rch9ae5b3b2016-02-11 00:36:294652 // Open a QUIC session to mail.example.org:443 when making request
4653 // to mail.example.org.
4654 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454655 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304656
rch9ae5b3b2016-02-11 00:36:294657 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304658 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454659 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524660}
4661
4662TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524663 MockRead http_reads[] = {
4664 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564665 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524666 MockRead("hello world"),
4667 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4668 MockRead(ASYNC, OK)};
4669
Ryan Sleevib8d7ea02018-05-07 20:01:014670 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524671 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084672 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564673 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524674
rtennetib8e80fb2016-05-16 00:12:094675 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324676 CreateSession();
bncc958faa2015-07-31 18:14:524677
4678 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454679
4680 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344681 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494682 http_server_properties_->GetAlternativeServiceInfos(
4683 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344684 ASSERT_EQ(1u, alternative_service_info_vector.size());
4685 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544686 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344687 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4688 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4689 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524690}
4691
4692TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524693 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564694 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4695 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524696 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4697 MockRead(ASYNC, OK)};
4698
Ryan Sleevib8d7ea02018-05-07 20:01:014699 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524700 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084701 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564702 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524703
Ryan Hamiltonabad59e2019-06-06 04:02:594704 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024705 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:364706 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024707 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4708 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4709 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434710 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334711 ASYNC, ConstructServerResponseHeadersPacket(
4712 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4713 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434714 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334715 mock_quic_data.AddRead(
4716 ASYNC, ConstructServerDataPacket(
4717 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174718 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434719 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524720 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4721 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524722
4723 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4724
rtennetib8e80fb2016-05-16 00:12:094725 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324726 CreateSession();
bncc958faa2015-07-31 18:14:524727
bnc3472afd2016-11-17 15:27:214728 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524729 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494730 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
bncc958faa2015-07-31 18:14:524731 alternative_service);
Matt Menke3233d8f22019-08-20 21:01:494732 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
bncc958faa2015-07-31 18:14:524733 alternative_service));
4734
4735 SendRequestAndExpectHttpResponse("hello world");
4736 SendRequestAndExpectQuicResponse("hello!");
4737
mmenkee24011922015-12-17 22:12:594738 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524739
Matt Menke3233d8f22019-08-20 21:01:494740 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
bncc958faa2015-07-31 18:14:524741 alternative_service));
Matt Menke19475f72019-08-21 18:57:444742 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4743 url::SchemeHostPort("https", request_.url.host(), 443),
4744 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524745}
4746
bncc958faa2015-07-31 18:14:524747TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524748 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564749 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4750 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524751 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4752 MockRead(ASYNC, OK)};
4753
Ryan Sleevib8d7ea02018-05-07 20:01:014754 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524755 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564756 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524757
Ryan Hamiltonabad59e2019-06-06 04:02:594758 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024759 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:364760 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024761 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4762 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4763 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434764 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334765 ASYNC, ConstructServerResponseHeadersPacket(
4766 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4767 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434768 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334769 mock_quic_data.AddRead(
4770 ASYNC, ConstructServerDataPacket(
4771 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174772 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434773 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524774 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4775
4776 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4777
4778 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324779 CreateSession();
bncc958faa2015-07-31 18:14:524780
4781 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4782 SendRequestAndExpectHttpResponse("hello world");
4783}
4784
tbansalc3308d72016-08-27 10:25:044785// Tests that the connection to an HTTPS proxy is raced with an available
4786// alternative proxy server.
4787TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274788 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594789 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494790 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044791
Ryan Hamiltonabad59e2019-06-06 04:02:594792 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024793 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:364794 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024795 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4796 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4797 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434798 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334799 ASYNC, ConstructServerResponseHeadersPacket(
4800 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4801 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434802 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334803 mock_quic_data.AddRead(
4804 ASYNC, ConstructServerDataPacket(
4805 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174806 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434807 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044808 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4809 mock_quic_data.AddRead(ASYNC, 0); // EOF
4810
4811 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4812
4813 // There is no need to set up main job, because no attempt will be made to
4814 // speak to the proxy over TCP.
4815 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044816 TestProxyDelegate test_proxy_delegate;
4817 const HostPortPair host_port_pair("mail.example.org", 443);
4818
4819 test_proxy_delegate.set_alternative_proxy_server(
4820 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524821 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044822 CreateSession();
4823 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4824
4825 // The main job needs to hang in order to guarantee that the alternative
4826 // proxy server job will "win".
4827 AddHangingNonAlternateProtocolSocketData();
4828
4829 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4830
4831 // Verify that the alternative proxy server is not marked as broken.
4832 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4833
4834 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594835 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274836
4837 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4838 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4839 1);
tbansalc3308d72016-08-27 10:25:044840}
4841
bnc1c196c6e2016-05-28 13:51:484842TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304843 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274844 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304845
4846 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564847 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294848 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564849 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304850
4851 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564852 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484853 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564854 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304855
Ryan Sleevib8d7ea02018-05-07 20:01:014856 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504857 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084858 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504859 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304860
4861 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454862 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304863 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454864 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304865 };
Ryan Sleevib8d7ea02018-05-07 20:01:014866 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504867 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304868
4869 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014870 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504871 socket_factory_.AddSocketDataProvider(&http_data2);
4872 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304873
bnc912a04b2016-04-20 14:19:504874 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304875
4876 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304877 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174878 ASSERT_TRUE(http_data.AllReadDataConsumed());
4879 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304880
4881 // Now run the second request in which the QUIC socket hangs,
4882 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304883 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454884 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304885
rch37de576c2015-05-17 20:28:174886 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4887 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454888 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304889}
4890
[email protected]1e960032013-12-20 19:00:204891TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594892 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:034893 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:434894 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024895 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4896 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4897 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434898 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334899 ASYNC, ConstructServerResponseHeadersPacket(
4900 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4901 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434902 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334903 mock_quic_data.AddRead(
4904 ASYNC, ConstructServerDataPacket(
4905 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174906 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434907 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504908 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594909 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484910
rcha5399e02015-04-21 19:32:044911 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484912
rtennetib8e80fb2016-05-16 00:12:094913 // The non-alternate protocol job needs to hang in order to guarantee that
4914 // the alternate-protocol job will "win".
4915 AddHangingNonAlternateProtocolSocketData();
4916
rch3f4b8452016-02-23 16:59:324917 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274918 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194919 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304920
Matt Menke19475f72019-08-21 18:57:444921 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4922 url::SchemeHostPort("https", request_.url.host(), 443),
4923 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:484924}
4925
[email protected]1e960032013-12-20 19:00:204926TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594927 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:034928 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Fan Yang32c5a112018-12-10 20:06:334929 mock_quic_data.AddWrite(
4930 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4931 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4932 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434933 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334934 ASYNC, ConstructServerResponseHeadersPacket(
4935 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4936 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434937 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334938 mock_quic_data.AddRead(
4939 ASYNC, ConstructServerDataPacket(
4940 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174941 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434942 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504943 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594944 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044945 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274946
4947 // In order for a new QUIC session to be established via alternate-protocol
4948 // without racing an HTTP connection, we need the host resolution to happen
4949 // synchronously.
4950 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294951 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564952 "");
[email protected]3a120a6b2013-06-25 01:08:274953
rtennetib8e80fb2016-05-16 00:12:094954 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324955 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274956 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274957 SendRequestAndExpectQuicResponse("hello!");
4958}
4959
[email protected]0fc924b2014-03-31 04:34:154960TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494961 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4962 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154963
4964 // Since we are using a proxy, the QUIC job will not succeed.
4965 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294966 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4967 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564968 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154969
4970 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564971 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484972 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564973 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154974
Ryan Sleevib8d7ea02018-05-07 20:01:014975 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154976 socket_factory_.AddSocketDataProvider(&http_data);
4977
4978 // In order for a new QUIC session to be established via alternate-protocol
4979 // without racing an HTTP connection, we need the host resolution to happen
4980 // synchronously.
4981 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294982 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564983 "");
[email protected]0fc924b2014-03-31 04:34:154984
rch9ae5b3b2016-02-11 00:36:294985 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324986 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274987 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154988 SendRequestAndExpectHttpResponse("hello world");
4989}
4990
[email protected]1e960032013-12-20 19:00:204991TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:594992 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024993 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:364994 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024995 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4996 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4997 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434998 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334999 ASYNC, ConstructServerResponseHeadersPacket(
5000 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5001 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435002 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335003 mock_quic_data.AddRead(
5004 ASYNC, ConstructServerDataPacket(
5005 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175006 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435007 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595008 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045009 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125010
rtennetib8e80fb2016-05-16 00:12:095011 // The non-alternate protocol job needs to hang in order to guarantee that
5012 // the alternate-protocol job will "win".
5013 AddHangingNonAlternateProtocolSocketData();
5014
[email protected]11c05872013-08-20 02:04:125015 // In order for a new QUIC session to be established via alternate-protocol
5016 // without racing an HTTP connection, we need the host resolution to happen
5017 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5018 // connection to the the server, in this test we require confirmation
5019 // before encrypting so the HTTP job will still start.
5020 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295021 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565022 "");
[email protected]11c05872013-08-20 02:04:125023
rch3f4b8452016-02-23 16:59:325024 CreateSession();
[email protected]11c05872013-08-20 02:04:125025 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275026 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125027
bnc691fda62016-08-12 00:43:165028 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125029 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365030 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015031 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125032
5033 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525034 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015035 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505036
bnc691fda62016-08-12 00:43:165037 CheckWasQuicResponse(&trans);
5038 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125039}
5040
Steven Valdez58097ec32018-07-16 18:29:045041TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015042 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595043 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035044 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045045 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015046 SYNCHRONOUS,
5047 ConstructClientRequestHeadersPacket(
5048 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5049 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335050 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025051 ASYNC, ConstructServerResponseHeadersPacket(
5052 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5053 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015054 mock_quic_data.AddWrite(
5055 SYNCHRONOUS,
5056 ConstructClientAckAndRstPacket(
5057 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5058 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045059
5060 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5061
Ryan Hamilton3cc2c152019-07-09 19:36:015062 if (version_.transport_version != quic::QUIC_VERSION_99) {
5063 mock_quic_data.AddWrite(
5064 SYNCHRONOUS, client_maker_.MakeSettingsPacket(packet_number++, false));
5065 }
Steven Valdez58097ec32018-07-16 18:29:045066
5067 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015068 SYNCHRONOUS,
5069 ConstructClientRequestHeadersPacket(
5070 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5071 true, GetRequestHeaders("GET", "https", "/"),
5072 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045073 mock_quic_data.AddRead(
5074 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335075 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025076 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435077 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045078 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335079 ASYNC, ConstructServerDataPacket(
5080 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175081 header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045082 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015083 SYNCHRONOUS,
5084 ConstructClientAckAndConnectionClosePacket(packet_number++, 3, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045085 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5086 mock_quic_data.AddRead(ASYNC, 0); // EOF
5087
5088 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5089
5090 // In order for a new QUIC session to be established via alternate-protocol
5091 // without racing an HTTP connection, we need the host resolution to happen
5092 // synchronously.
5093 host_resolver_.set_synchronous_mode(true);
5094 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5095 "");
Steven Valdez58097ec32018-07-16 18:29:045096
5097 AddHangingNonAlternateProtocolSocketData();
5098 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275099 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565100 QuicStreamFactoryPeer::SetAlarmFactory(
5101 session_->quic_stream_factory(),
5102 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5103 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045104
5105 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5106 TestCompletionCallback callback;
5107 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5108 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5109
5110 // Confirm the handshake after the 425 Too Early.
5111 base::RunLoop().RunUntilIdle();
5112
5113 // The handshake hasn't been confirmed yet, so the retry should not have
5114 // succeeded.
5115 EXPECT_FALSE(callback.have_result());
5116
5117 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5118 quic::QuicSession::HANDSHAKE_CONFIRMED);
5119
5120 EXPECT_THAT(callback.WaitForResult(), IsOk());
5121 CheckWasQuicResponse(&trans);
5122 CheckResponseData(&trans, "hello!");
5123}
5124
5125TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015126 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595127 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035128 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045129 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015130 SYNCHRONOUS,
5131 ConstructClientRequestHeadersPacket(
5132 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5133 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335134 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025135 ASYNC, ConstructServerResponseHeadersPacket(
5136 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5137 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015138 mock_quic_data.AddWrite(
5139 SYNCHRONOUS,
5140 ConstructClientAckAndRstPacket(
5141 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5142 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045143
5144 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5145
Ryan Hamilton3cc2c152019-07-09 19:36:015146 if (version_.transport_version != quic::QUIC_VERSION_99) {
5147 mock_quic_data.AddWrite(
5148 SYNCHRONOUS, client_maker_.MakeSettingsPacket(packet_number++, false));
5149 }
Steven Valdez58097ec32018-07-16 18:29:045150
5151 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015152 SYNCHRONOUS,
5153 ConstructClientRequestHeadersPacket(
5154 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5155 true, GetRequestHeaders("GET", "https", "/"),
5156 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335157 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025158 ASYNC, ConstructServerResponseHeadersPacket(
5159 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5160 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015161 mock_quic_data.AddWrite(
5162 SYNCHRONOUS,
5163 ConstructClientAckAndRstPacket(
5164 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
5165 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045166 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5167 mock_quic_data.AddRead(ASYNC, 0); // EOF
5168
5169 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5170
5171 // In order for a new QUIC session to be established via alternate-protocol
5172 // without racing an HTTP connection, we need the host resolution to happen
5173 // synchronously.
5174 host_resolver_.set_synchronous_mode(true);
5175 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5176 "");
Steven Valdez58097ec32018-07-16 18:29:045177
5178 AddHangingNonAlternateProtocolSocketData();
5179 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275180 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565181 QuicStreamFactoryPeer::SetAlarmFactory(
5182 session_->quic_stream_factory(),
5183 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5184 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045185
5186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5187 TestCompletionCallback callback;
5188 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5189 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5190
5191 // Confirm the handshake after the 425 Too Early.
5192 base::RunLoop().RunUntilIdle();
5193
5194 // The handshake hasn't been confirmed yet, so the retry should not have
5195 // succeeded.
5196 EXPECT_FALSE(callback.have_result());
5197
5198 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5199 quic::QuicSession::HANDSHAKE_CONFIRMED);
5200
5201 EXPECT_THAT(callback.WaitForResult(), IsOk());
5202 const HttpResponseInfo* response = trans.GetResponseInfo();
5203 ASSERT_TRUE(response != nullptr);
5204 ASSERT_TRUE(response->headers.get() != nullptr);
5205 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5206 EXPECT_TRUE(response->was_fetched_via_spdy);
5207 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565208 EXPECT_EQ(
5209 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5210 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045211}
5212
zhongyica364fbb2015-12-12 03:39:125213TEST_P(QuicNetworkTransactionTest,
5214 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Nick Harper72ade192019-07-17 03:30:425215 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595216 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:025217 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:365218 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025219 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5220 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
5221 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125222 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525223 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435224 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125225 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5226
5227 // The non-alternate protocol job needs to hang in order to guarantee that
5228 // the alternate-protocol job will "win".
5229 AddHangingNonAlternateProtocolSocketData();
5230
5231 // In order for a new QUIC session to be established via alternate-protocol
5232 // without racing an HTTP connection, we need the host resolution to happen
5233 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5234 // connection to the the server, in this test we require confirmation
5235 // before encrypting so the HTTP job will still start.
5236 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295237 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125238 "");
zhongyica364fbb2015-12-12 03:39:125239
rch3f4b8452016-02-23 16:59:325240 CreateSession();
zhongyica364fbb2015-12-12 03:39:125241 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275242 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125243
bnc691fda62016-08-12 00:43:165244 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125245 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365246 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015247 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125248
5249 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525250 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015251 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125252
5253 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525254 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125255
bnc691fda62016-08-12 00:43:165256 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125257 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525258 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5259 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125260}
5261
5262TEST_P(QuicNetworkTransactionTest,
5263 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Nick Harper72ade192019-07-17 03:30:425264 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595265 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:025266 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:365267 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025268 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5269 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
5270 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215271 // Peer sending data from an non-existing stream causes this end to raise
5272 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335273 mock_quic_data.AddRead(
5274 ASYNC, ConstructServerRstPacket(
5275 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5276 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215277 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tangff0d6372019-08-30 22:03:295278 mock_quic_data.AddWrite(SYNCHRONOUS,
5279 ConstructClientAckAndConnectionClosePacket(
5280 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5281 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
5282 quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125283 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5284
5285 // The non-alternate protocol job needs to hang in order to guarantee that
5286 // the alternate-protocol job will "win".
5287 AddHangingNonAlternateProtocolSocketData();
5288
5289 // In order for a new QUIC session to be established via alternate-protocol
5290 // without racing an HTTP connection, we need the host resolution to happen
5291 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5292 // connection to the the server, in this test we require confirmation
5293 // before encrypting so the HTTP job will still start.
5294 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295295 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125296 "");
zhongyica364fbb2015-12-12 03:39:125297
rch3f4b8452016-02-23 16:59:325298 CreateSession();
zhongyica364fbb2015-12-12 03:39:125299 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275300 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125301
bnc691fda62016-08-12 00:43:165302 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125303 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365304 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015305 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125306
5307 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525308 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015309 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125310 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525311 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125312
bnc691fda62016-08-12 00:43:165313 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525314 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125315}
5316
rchcd5f1c62016-06-23 02:43:485317TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:595318 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:025319 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:365320 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025321 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5322 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
5323 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485324 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335325 mock_quic_data.AddRead(
5326 ASYNC, ConstructServerResponseHeadersPacket(
5327 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5328 GetResponseHeaders("200 OK")));
5329 mock_quic_data.AddRead(
5330 ASYNC, ConstructServerRstPacket(
5331 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5332 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435333 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485334 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5335 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5336
5337 // The non-alternate protocol job needs to hang in order to guarantee that
5338 // the alternate-protocol job will "win".
5339 AddHangingNonAlternateProtocolSocketData();
5340
5341 // In order for a new QUIC session to be established via alternate-protocol
5342 // without racing an HTTP connection, we need the host resolution to happen
5343 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5344 // connection to the the server, in this test we require confirmation
5345 // before encrypting so the HTTP job will still start.
5346 host_resolver_.set_synchronous_mode(true);
5347 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5348 "");
rchcd5f1c62016-06-23 02:43:485349
5350 CreateSession();
5351 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275352 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485353
bnc691fda62016-08-12 00:43:165354 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485355 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365356 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015357 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485358
5359 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525360 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485361 // Read the headers.
robpercival214763f2016-07-01 23:27:015362 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485363
bnc691fda62016-08-12 00:43:165364 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485365 ASSERT_TRUE(response != nullptr);
5366 ASSERT_TRUE(response->headers.get() != nullptr);
5367 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5368 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525369 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565370 EXPECT_EQ(
5371 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5372 response->connection_info);
rchcd5f1c62016-06-23 02:43:485373
5374 std::string response_data;
bnc691fda62016-08-12 00:43:165375 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485376}
5377
5378TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Nick Harper72ade192019-07-17 03:30:425379 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595380 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:025381 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:365382 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025383 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5384 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
5385 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335386 mock_quic_data.AddRead(
5387 ASYNC, ConstructServerRstPacket(
5388 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5389 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485390 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5391 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5392
5393 // The non-alternate protocol job needs to hang in order to guarantee that
5394 // the alternate-protocol job will "win".
5395 AddHangingNonAlternateProtocolSocketData();
5396
5397 // In order for a new QUIC session to be established via alternate-protocol
5398 // without racing an HTTP connection, we need the host resolution to happen
5399 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5400 // connection to the the server, in this test we require confirmation
5401 // before encrypting so the HTTP job will still start.
5402 host_resolver_.set_synchronous_mode(true);
5403 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5404 "");
rchcd5f1c62016-06-23 02:43:485405
5406 CreateSession();
5407 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275408 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485409
bnc691fda62016-08-12 00:43:165410 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485411 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365412 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015413 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485414
5415 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525416 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485417 // Read the headers.
robpercival214763f2016-07-01 23:27:015418 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485419}
5420
[email protected]1e960032013-12-20 19:00:205421TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305422 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525423 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585424 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305425 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505426 MockRead(ASYNC, close->data(), close->length()),
5427 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5428 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305429 };
Ryan Sleevib8d7ea02018-05-07 20:01:015430 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305431 socket_factory_.AddSocketDataProvider(&quic_data);
5432
5433 // Main job which will succeed even though the alternate job fails.
5434 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025435 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5436 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5437 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305438
Ryan Sleevib8d7ea02018-05-07 20:01:015439 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305440 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565441 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305442
rch3f4b8452016-02-23 16:59:325443 CreateSession();
David Schinazic8281052019-01-24 06:14:175444 AddQuicAlternateProtocolMapping(
5445 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195446 SendRequestAndExpectHttpResponse("hello from http");
5447 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305448}
5449
[email protected]1e960032013-12-20 19:00:205450TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595451 // Alternate-protocol job
5452 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025453 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595454 };
Ryan Sleevib8d7ea02018-05-07 20:01:015455 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595456 socket_factory_.AddSocketDataProvider(&quic_data);
5457
5458 // Main job which will succeed even though the alternate job fails.
5459 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025460 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5461 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5462 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595463
Ryan Sleevib8d7ea02018-05-07 20:01:015464 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595465 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565466 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595467
rch3f4b8452016-02-23 16:59:325468 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595469
Ryan Hamilton9835e662018-08-02 05:36:275470 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195471 SendRequestAndExpectHttpResponse("hello from http");
5472 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595473}
5474
[email protected]00c159f2014-05-21 22:38:165475TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535476 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165477 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025478 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165479 };
Ryan Sleevib8d7ea02018-05-07 20:01:015480 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165481 socket_factory_.AddSocketDataProvider(&quic_data);
5482
[email protected]eb71ab62014-05-23 07:57:535483 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165484 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025485 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165486 };
5487
Ryan Sleevib8d7ea02018-05-07 20:01:015488 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165489 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5490 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565491 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165492
rtennetib8e80fb2016-05-16 00:12:095493 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325494 CreateSession();
[email protected]00c159f2014-05-21 22:38:165495
Ryan Hamilton9835e662018-08-02 05:36:275496 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165497 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165498 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165499 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015500 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5501 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165502 ExpectQuicAlternateProtocolMapping();
5503}
5504
Zhongyi Shia0cef1082017-08-25 01:49:505505TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5506 // Tests that TCP job is delayed and QUIC job does not require confirmation
5507 // if QUIC was recently supported on the same IP on start.
5508
5509 // Set QUIC support on the last IP address, which is same with the local IP
5510 // address. Require confirmation mode will be turned off immediately when
5511 // local IP address is sorted out after we configure the UDP socket.
Matt Menke3233d8f22019-08-20 21:01:495512 http_server_properties_->SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:505513
Ryan Hamiltonabad59e2019-06-06 04:02:595514 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035515 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:435516 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025517 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5518 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5519 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435520 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335521 ASYNC, ConstructServerResponseHeadersPacket(
5522 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5523 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435524 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335525 mock_quic_data.AddRead(
5526 ASYNC, ConstructServerDataPacket(
5527 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175528 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435529 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505530 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5531 mock_quic_data.AddRead(ASYNC, 0); // EOF
5532
5533 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5534 // No HTTP data is mocked as TCP job never starts in this case.
5535
5536 CreateSession();
5537 // QuicStreamFactory by default requires confirmation on construction.
5538 session_->quic_stream_factory()->set_require_confirmation(true);
5539
Ryan Hamilton9835e662018-08-02 05:36:275540 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505541
5542 // Stall host resolution so that QUIC job will not succeed synchronously.
5543 // Socket will not be configured immediately and QUIC support is not sorted
5544 // out, TCP job will still be delayed as server properties indicates QUIC
5545 // support on last IP address.
5546 host_resolver_.set_synchronous_mode(false);
5547
5548 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5549 TestCompletionCallback callback;
5550 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5551 IsError(ERR_IO_PENDING));
5552 // Complete host resolution in next message loop so that QUIC job could
5553 // proceed.
5554 base::RunLoop().RunUntilIdle();
5555 EXPECT_THAT(callback.WaitForResult(), IsOk());
5556
5557 CheckWasQuicResponse(&trans);
5558 CheckResponseData(&trans, "hello!");
5559}
5560
5561TEST_P(QuicNetworkTransactionTest,
5562 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5563 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5564 // was recently supported on a different IP address on start.
5565
5566 // Set QUIC support on the last IP address, which is different with the local
5567 // IP address. Require confirmation mode will remain when local IP address is
5568 // sorted out after we configure the UDP socket.
Matt Menke3233d8f22019-08-20 21:01:495569 http_server_properties_->SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:505570
Ryan Hamiltonabad59e2019-06-06 04:02:595571 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:025572 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Zhongyi Shia0cef1082017-08-25 01:49:505573 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025574 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5575 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
5576 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435577 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335578 ASYNC, ConstructServerResponseHeadersPacket(
5579 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5580 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435581 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335582 mock_quic_data.AddRead(
5583 ASYNC, ConstructServerDataPacket(
5584 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175585 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435586 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505587 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5588 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5589 // No HTTP data is mocked as TCP job will be delayed and never starts.
5590
5591 CreateSession();
5592 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275593 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505594
5595 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5596 // Socket will not be configured immediately and QUIC support is not sorted
5597 // out, TCP job will still be delayed as server properties indicates QUIC
5598 // support on last IP address.
5599 host_resolver_.set_synchronous_mode(false);
5600
5601 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5602 TestCompletionCallback callback;
5603 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5604 IsError(ERR_IO_PENDING));
5605
5606 // Complete host resolution in next message loop so that QUIC job could
5607 // proceed.
5608 base::RunLoop().RunUntilIdle();
5609 // Explicitly confirm the handshake so that QUIC job could succeed.
5610 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525611 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505612 EXPECT_THAT(callback.WaitForResult(), IsOk());
5613
5614 CheckWasQuicResponse(&trans);
5615 CheckResponseData(&trans, "hello!");
5616}
5617
Ryan Hamilton75f197262017-08-17 14:00:075618TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5619 // Test that NetErrorDetails is correctly populated, even if the
5620 // handshake has not yet been confirmed and no stream has been created.
5621
5622 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595623 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075624 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5625 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5626 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5627
5628 // Main job will also fail.
5629 MockRead http_reads[] = {
5630 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5631 };
5632
Ryan Sleevib8d7ea02018-05-07 20:01:015633 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075634 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5635 socket_factory_.AddSocketDataProvider(&http_data);
5636 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5637
5638 AddHangingNonAlternateProtocolSocketData();
5639 CreateSession();
5640 // Require handshake confirmation to ensure that no QUIC streams are
5641 // created, and to ensure that the TCP job does not wait for the QUIC
5642 // job to fail before it starts.
5643 session_->quic_stream_factory()->set_require_confirmation(true);
5644
Ryan Hamilton9835e662018-08-02 05:36:275645 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5647 TestCompletionCallback callback;
5648 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5649 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5650 // Allow the TCP job to fail.
5651 base::RunLoop().RunUntilIdle();
5652 // Now let the QUIC job fail.
5653 mock_quic_data.Resume();
5654 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5655 ExpectQuicAlternateProtocolMapping();
5656 NetErrorDetails details;
5657 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525658 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075659}
5660
[email protected]1e960032013-12-20 19:00:205661TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455662 // Alternate-protocol job
5663 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025664 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455665 };
Ryan Sleevib8d7ea02018-05-07 20:01:015666 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455667 socket_factory_.AddSocketDataProvider(&quic_data);
5668
[email protected]c92c1b52014-05-31 04:16:065669 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015670 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065671 socket_factory_.AddSocketDataProvider(&quic_data2);
5672
[email protected]4d283b32013-10-17 12:57:275673 // Final job that will proceed when the QUIC job fails.
5674 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025675 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5676 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5677 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275678
Ryan Sleevib8d7ea02018-05-07 20:01:015679 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275680 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565681 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275682
rtennetiafccbc062016-05-16 18:21:145683 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325684 CreateSession();
[email protected]77c6c162013-08-17 02:57:455685
Ryan Hamilton9835e662018-08-02 05:36:275686 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455687
[email protected]4d283b32013-10-17 12:57:275688 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455689
5690 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275691
rch37de576c2015-05-17 20:28:175692 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5693 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455694}
5695
[email protected]93b31772014-06-19 08:03:355696TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035697 // Alternate-protocol job
5698 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595699 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035700 };
Ryan Sleevib8d7ea02018-05-07 20:01:015701 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035702 socket_factory_.AddSocketDataProvider(&quic_data);
5703
5704 // Main job that will proceed when the QUIC job fails.
5705 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025706 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5707 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5708 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035709
Ryan Sleevib8d7ea02018-05-07 20:01:015710 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035711 socket_factory_.AddSocketDataProvider(&http_data);
5712
rtennetib8e80fb2016-05-16 00:12:095713 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325714 CreateSession();
[email protected]65768442014-06-06 23:37:035715
Ryan Hamilton9835e662018-08-02 05:36:275716 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035717
5718 SendRequestAndExpectHttpResponse("hello from http");
5719}
5720
[email protected]eb71ab62014-05-23 07:57:535721TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335722 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015723 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495724 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335725 socket_factory_.AddSocketDataProvider(&quic_data);
5726
5727 // Main job which will succeed even though the alternate job fails.
5728 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025729 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5730 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5731 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335732
Ryan Sleevib8d7ea02018-05-07 20:01:015733 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335734 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565735 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335736
rch3f4b8452016-02-23 16:59:325737 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275738 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335739 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535740
5741 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335742}
5743
[email protected]4fee9672014-01-08 14:47:155744TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltonabad59e2019-06-06 04:02:595745 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:175746 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5747 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045748 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155749
5750 // When the QUIC connection fails, we will try the request again over HTTP.
5751 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485752 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565753 MockRead("hello world"),
5754 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5755 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155756
Ryan Sleevib8d7ea02018-05-07 20:01:015757 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155758 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565759 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155760
5761 // In order for a new QUIC session to be established via alternate-protocol
5762 // without racing an HTTP connection, we need the host resolution to happen
5763 // synchronously.
5764 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295765 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565766 "");
[email protected]4fee9672014-01-08 14:47:155767
rch3f4b8452016-02-23 16:59:325768 CreateSession();
David Schinazic8281052019-01-24 06:14:175769 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5770 AddQuicAlternateProtocolMapping(
5771 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155772 SendRequestAndExpectHttpResponse("hello world");
5773}
5774
tbansalc3308d72016-08-27 10:25:045775// For an alternative proxy that supports QUIC, test that the request is
5776// successfully fetched by the main job when the alternate proxy job encounters
5777// an error.
5778TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5779 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5780}
5781TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5782 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5783}
5784TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5785 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5786}
5787TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5788 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5789}
5790TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5791 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5792}
5793TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5794 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5795}
5796TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5797 TestAlternativeProxy(ERR_IO_PENDING);
5798}
5799TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5800 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5801}
5802
5803TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltonabad59e2019-06-06 04:02:595804 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:175805 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5806 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335807 mock_quic_data.AddWrite(
5808 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5809 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5810 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435811 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045812 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5813
5814 // When the QUIC connection fails, we will try the request again over HTTP.
5815 MockRead http_reads[] = {
5816 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5817 MockRead("hello world"),
5818 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5819 MockRead(ASYNC, OK)};
5820
Ryan Sleevib8d7ea02018-05-07 20:01:015821 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045822 socket_factory_.AddSocketDataProvider(&http_data);
5823 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5824
5825 TestProxyDelegate test_proxy_delegate;
5826 const HostPortPair host_port_pair("myproxy.org", 443);
5827 test_proxy_delegate.set_alternative_proxy_server(
5828 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5829 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5830
Ramin Halavatica8d5252018-03-12 05:33:495831 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5832 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525833 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045834 request_.url = GURL("http://mail.example.org/");
5835
5836 // In order for a new QUIC session to be established via alternate-protocol
5837 // without racing an HTTP connection, we need the host resolution to happen
5838 // synchronously.
5839 host_resolver_.set_synchronous_mode(true);
5840 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045841
5842 CreateSession();
David Schinazic8281052019-01-24 06:14:175843 crypto_client_stream_factory_.set_handshake_mode(
5844 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045845 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595846 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165847 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045848}
5849
bnc508835902015-05-12 20:10:295850TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585851 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385852 EXPECT_FALSE(
5853 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:595854 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:025855 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
rch5cb522462017-04-25 20:18:365856 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025857 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5858 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
5859 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435860 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335861 ASYNC, ConstructServerResponseHeadersPacket(
5862 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5863 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435864 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335865 mock_quic_data.AddRead(
5866 ASYNC, ConstructServerDataPacket(
5867 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175868 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435869 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505870 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295871 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5872
bncb07c05532015-05-14 19:07:205873 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095874 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325875 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275876 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295877 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385878 EXPECT_TRUE(
5879 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295880}
5881
zhongyi363c91c2017-03-23 23:16:085882// TODO(zhongyi): disabled this broken test as it was not testing the correct
5883// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5884TEST_P(QuicNetworkTransactionTest,
5885 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275886 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595887 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495888 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045889
5890 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045891
5892 test_proxy_delegate.set_alternative_proxy_server(
5893 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525894 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045895
5896 request_.url = GURL("http://mail.example.org/");
5897
5898 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5899 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015900 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045901 socket_factory_.AddSocketDataProvider(&socket_data);
5902
5903 // The non-alternate protocol job needs to hang in order to guarantee that
5904 // the alternate-protocol job will "win".
5905 AddHangingNonAlternateProtocolSocketData();
5906
5907 CreateSession();
5908 request_.method = "POST";
5909 ChunkedUploadDataStream upload_data(0);
5910 upload_data.AppendData("1", 1, true);
5911
5912 request_.upload_data_stream = &upload_data;
5913
5914 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5915 TestCompletionCallback callback;
5916 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5917 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5918 EXPECT_NE(OK, callback.WaitForResult());
5919
5920 // Verify that the alternative proxy server is not marked as broken.
5921 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5922
5923 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595924 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275925
5926 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5927 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5928 1);
tbansalc3308d72016-08-27 10:25:045929}
5930
rtenneti56977812016-01-15 19:26:565931TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Nick Harper72ade192019-07-17 03:30:425932 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575933 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565934
5935 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5936 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015937 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:565938 socket_factory_.AddSocketDataProvider(&socket_data);
5939
rtennetib8e80fb2016-05-16 00:12:095940 // The non-alternate protocol job needs to hang in order to guarantee that
5941 // the alternate-protocol job will "win".
5942 AddHangingNonAlternateProtocolSocketData();
5943
rtenneti56977812016-01-15 19:26:565944 CreateSession();
5945 request_.method = "POST";
5946 ChunkedUploadDataStream upload_data(0);
5947 upload_data.AppendData("1", 1, true);
5948
5949 request_.upload_data_stream = &upload_data;
5950
bnc691fda62016-08-12 00:43:165951 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:565952 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165953 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015954 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:565955 EXPECT_NE(OK, callback.WaitForResult());
5956}
5957
rche11300ef2016-09-02 01:44:285958TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Nick Harper72ade192019-07-17 03:30:425959 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:285960 ScopedMockNetworkChangeNotifier network_change_notifier;
5961 MockNetworkChangeNotifier* mock_ncn =
5962 network_change_notifier.mock_network_change_notifier();
5963 mock_ncn->ForceNetworkHandlesSupported();
5964 mock_ncn->SetConnectedNetworksList(
5965 {kDefaultNetworkForTests, kNewNetworkForTests});
5966
Nick Harper72ade192019-07-17 03:30:425967 session_params_.quic_params.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:285968 HostPortPair::FromString("mail.example.org:443"));
Nick Harper72ade192019-07-17 03:30:425969 session_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:285970
Ryan Hamiltonabad59e2019-06-06 04:02:595971 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:285972 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:025973 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Fan Yang32c5a112018-12-10 20:06:335974 socket_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025975 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5976 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
5977 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:285978 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5979 socket_data.AddSocketDataToFactory(&socket_factory_);
5980
Ryan Hamiltonabad59e2019-06-06 04:02:595981 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:285982 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
5983 socket_data2.AddSocketDataToFactory(&socket_factory_);
5984
5985 // The non-alternate protocol job needs to hang in order to guarantee that
5986 // the alternate-protocol job will "win".
5987 AddHangingNonAlternateProtocolSocketData();
5988
5989 CreateSession();
5990 request_.method = "POST";
5991 ChunkedUploadDataStream upload_data(0);
5992
5993 request_.upload_data_stream = &upload_data;
5994
rdsmith1d343be52016-10-21 20:37:505995 std::unique_ptr<HttpNetworkTransaction> trans(
5996 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:285997 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:505998 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:285999 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6000
6001 base::RunLoop().RunUntilIdle();
6002 upload_data.AppendData("1", 1, true);
6003 base::RunLoop().RunUntilIdle();
6004
6005 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506006 trans.reset();
rche11300ef2016-09-02 01:44:286007 session_.reset();
6008}
6009
Ryan Hamilton4b3574532017-10-30 20:17:256010TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426011 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256012 HostPortPair::FromString("mail.example.org:443"));
6013
Ryan Hamiltonabad59e2019-06-06 04:02:596014 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:026015 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton4b3574532017-10-30 20:17:256016 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336017 socket_data.AddWrite(
6018 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6019 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Ryan Hamilton0d65a8c2019-06-07 00:46:026020 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436021 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336022 ASYNC, ConstructServerResponseHeadersPacket(
6023 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6024 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436025 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336026 socket_data.AddRead(
6027 ASYNC, ConstructServerDataPacket(
6028 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176029 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436030 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256031 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166032 socket_data.AddWrite(
6033 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6034 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
Renjie Tangff0d6372019-08-30 22:03:296035 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256036
6037 socket_data.AddSocketDataToFactory(&socket_factory_);
6038
6039 CreateSession();
6040
6041 SendRequestAndExpectQuicResponse("hello!");
6042 session_.reset();
6043}
6044
6045TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426046 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256047 HostPortPair::FromString("mail.example.org:443"));
6048
Ryan Hamiltonabad59e2019-06-06 04:02:596049 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:026050 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton4b3574532017-10-30 20:17:256051 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336052 socket_data.AddWrite(
6053 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6054 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Ryan Hamilton0d65a8c2019-06-07 00:46:026055 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436056 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336057 ASYNC, ConstructServerResponseHeadersPacket(
6058 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6059 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436060 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336061 socket_data.AddRead(
6062 ASYNC, ConstructServerDataPacket(
6063 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176064 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436065 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256066 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166067 socket_data.AddWrite(
6068 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6069 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
Renjie Tangff0d6372019-08-30 22:03:296070 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256071
6072 socket_data.AddSocketDataToFactory(&socket_factory_);
6073
6074 CreateSession();
6075
6076 SendRequestAndExpectQuicResponse("hello!");
6077 session_.reset();
6078}
6079
Ryan Hamilton9edcf1a2017-11-22 05:55:176080TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426081 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6082 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256083 HostPortPair::FromString("mail.example.org:443"));
6084
Ryan Hamiltonabad59e2019-06-06 04:02:596085 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256086 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Ryan Hamilton0d65a8c2019-06-07 00:46:026087 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176088 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256089 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6090 }
6091 socket_data.AddSocketDataToFactory(&socket_factory_);
6092
6093 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176094 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176095 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6096 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256097
Ryan Hamilton8d9ee76e2018-05-29 23:52:526098 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256099 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6100 TestCompletionCallback callback;
6101 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6102 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176103 while (!callback.have_result()) {
6104 base::RunLoop().RunUntilIdle();
6105 quic_task_runner_->RunUntilIdle();
6106 }
6107 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256108 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176109 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6110 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6111 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526112 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6113 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256114}
6115
Ryan Hamilton9edcf1a2017-11-22 05:55:176116TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426117 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6118 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256119 HostPortPair::FromString("mail.example.org:443"));
6120
Ryan Hamiltonabad59e2019-06-06 04:02:596121 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256122 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Ryan Hamilton0d65a8c2019-06-07 00:46:026123 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176124 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256125 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6126 }
6127 socket_data.AddSocketDataToFactory(&socket_factory_);
6128
6129 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176130 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176131 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6132 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256133
Ryan Hamilton8d9ee76e2018-05-29 23:52:526134 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256135 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6136 TestCompletionCallback callback;
6137 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6138 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176139 while (!callback.have_result()) {
6140 base::RunLoop().RunUntilIdle();
6141 quic_task_runner_->RunUntilIdle();
6142 }
6143 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256144 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176145 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6146 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6147 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526148 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6149 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256150}
6151
Cherie Shi7596de632018-02-22 07:28:186152TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Nick Harper72ade192019-07-17 03:30:426153 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6154 session_params_.quic_params.origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186155 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436156 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:526157 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6158 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186159
Ryan Hamiltonabad59e2019-06-06 04:02:596160 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186161 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:026162 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Cherie Shi7596de632018-02-22 07:28:186163 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6164 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526165 socket_data.AddWrite(
6166 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6167 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186168 socket_data.AddSocketDataToFactory(&socket_factory_);
6169
6170 CreateSession();
6171
6172 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6173 TestCompletionCallback callback;
6174 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6175 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6176 base::RunLoop().RunUntilIdle();
6177 ASSERT_TRUE(callback.have_result());
6178 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6179 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6180 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6181}
6182
ckrasic769733c2016-06-30 00:42:136183// Adds coverage to catch regression such as https://crbug.com/622043
6184TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Nick Harper72ade192019-07-17 03:30:426185 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136186 HostPortPair::FromString("mail.example.org:443"));
6187
Ryan Hamiltonabad59e2019-06-06 04:02:596188 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236189 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436190 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026191 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:436192 mock_quic_data.AddWrite(
6193 SYNCHRONOUS,
6194 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336195 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026196 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436197 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026198 ASYNC,
6199 ConstructServerPushPromisePacket(
6200 1, GetNthClientInitiatedBidirectionalStreamId(0),
6201 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6202 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316203 if ((client_headers_include_h2_stream_dependency_ &&
6204 version_.transport_version >= quic::QUIC_VERSION_43) ||
6205 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026206 mock_quic_data.AddWrite(
6207 SYNCHRONOUS,
6208 ConstructClientPriorityPacket(
6209 client_packet_number++, false,
6210 GetNthServerInitiatedUnidirectionalStreamId(0),
6211 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576212 }
Zhongyi Shi32f2fd02018-04-16 18:23:436213 mock_quic_data.AddRead(
6214 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336215 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026216 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:576217 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436218 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6219 mock_quic_data.AddRead(
6220 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336221 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026222 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436223 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436224 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336225 ASYNC, ConstructServerDataPacket(
6226 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176227 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576228 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436229 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436230 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436231 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336232 ASYNC, ConstructServerDataPacket(
6233 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176234 header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336235 mock_quic_data.AddWrite(SYNCHRONOUS,
6236 ConstructClientAckAndRstPacket(
6237 client_packet_number++,
6238 GetNthServerInitiatedUnidirectionalStreamId(0),
6239 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136240 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6241 mock_quic_data.AddRead(ASYNC, 0); // EOF
6242 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
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
6250 // PUSH_PROMISE handling in the http layer gets exercised here.
6251 SendRequestAndExpectQuicResponse("hello!");
6252
6253 request_.url = GURL("https://mail.example.org/pushed.jpg");
6254 SendRequestAndExpectQuicResponse("and hello!");
6255
6256 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:546257 auto entries = net_log_.GetEntries();
ckrasic769733c2016-06-30 00:42:136258 EXPECT_LT(0u, entries.size());
6259
6260 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6261 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006262 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6263 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136264 EXPECT_LT(0, pos);
6265}
6266
rch56ec40a2017-06-23 14:48:446267// Regression test for http://crbug.com/719461 in which a promised stream
6268// is closed before the pushed headers arrive, but after the connection
6269// is closed and before the callbacks are executed.
6270TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Nick Harper72ade192019-07-17 03:30:426271 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6272 session_params_.quic_params.origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446273 HostPortPair::FromString("mail.example.org:443"));
6274
Ryan Hamiltonabad59e2019-06-06 04:02:596275 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236276 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446277 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436278 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026279 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
rch56ec40a2017-06-23 14:48:446280 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436281 mock_quic_data.AddWrite(
6282 SYNCHRONOUS,
6283 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336284 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026285 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446286 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436287 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026288 ASYNC,
6289 ConstructServerPushPromisePacket(
6290 1, GetNthClientInitiatedBidirectionalStreamId(0),
6291 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6292 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316293 if ((client_headers_include_h2_stream_dependency_ &&
6294 version_.transport_version >= quic::QUIC_VERSION_43) ||
6295 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026296 mock_quic_data.AddWrite(
6297 SYNCHRONOUS,
6298 ConstructClientPriorityPacket(
6299 client_packet_number++, false,
6300 GetNthServerInitiatedUnidirectionalStreamId(0),
6301 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576302 }
rch56ec40a2017-06-23 14:48:446303 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436304 mock_quic_data.AddRead(
6305 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336306 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026307 GetResponseHeaders("200 OK")));
rch56ec40a2017-06-23 14:48:446308 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576309 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436310 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446311 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:436312 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436313 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336314 ASYNC, ConstructServerDataPacket(
6315 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176316 header + "hello!"));
rch56ec40a2017-06-23 14:48:446317 // Write error for the third request.
6318 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6319 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6320 mock_quic_data.AddRead(ASYNC, 0); // EOF
6321 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6322
6323 CreateSession();
6324
6325 // Send a request which triggers a push promise from the server.
6326 SendRequestAndExpectQuicResponse("hello!");
6327
6328 // Start a push transaction that will be cancelled after the connection
6329 // is closed, but before the callback is executed.
6330 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196331 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446332 session_.get());
6333 TestCompletionCallback callback2;
6334 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6335 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6336 base::RunLoop().RunUntilIdle();
6337
6338 // Cause the connection to close on a write error.
6339 HttpRequestInfo request3;
6340 request3.method = "GET";
6341 request3.url = GURL("https://mail.example.org/");
6342 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106343 request3.traffic_annotation =
6344 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446345 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6346 TestCompletionCallback callback3;
6347 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6348 IsError(ERR_IO_PENDING));
6349
6350 base::RunLoop().RunUntilIdle();
6351
6352 // When |trans2| is destroyed, the underlying stream will be closed.
6353 EXPECT_FALSE(callback2.have_result());
6354 trans2 = nullptr;
6355
6356 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6357}
6358
ckrasicda193a82016-07-09 00:39:366359TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Nick Harper72ade192019-07-17 03:30:426360 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366361 HostPortPair::FromString("mail.example.org:443"));
6362
Ryan Hamiltonabad59e2019-06-06 04:02:596363 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:366364
Renjief49758b2019-01-11 23:32:416365 int write_packet_index = 1;
Ryan Hamilton0d65a8c2019-06-07 00:46:026366 mock_quic_data.AddWrite(SYNCHRONOUS,
6367 ConstructInitialSettingsPacket(write_packet_index++));
ckrasicda193a82016-07-09 00:39:366368
Victor Vasiliev076657c2019-03-12 02:46:436369 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:566370 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416371 mock_quic_data.AddWrite(
6372 SYNCHRONOUS,
6373 ConstructClientRequestHeadersAndDataFramesPacket(
6374 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6375 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:026376 GetRequestHeaders("POST", "https", "/"), 0, nullptr, {"1"}));
Renjief49758b2019-01-11 23:32:416377 } else {
6378 mock_quic_data.AddWrite(
6379 SYNCHRONOUS,
6380 ConstructClientRequestHeadersAndDataFramesPacket(
6381 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6382 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:026383 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
Renjief49758b2019-01-11 23:32:416384 {header, "1"}));
6385 }
ckrasicda193a82016-07-09 00:39:366386
Zhongyi Shi32f2fd02018-04-16 18:23:436387 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336388 ASYNC, ConstructServerResponseHeadersPacket(
6389 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6390 GetResponseHeaders("200 OK")));
6391
Victor Vasiliev076657c2019-03-12 02:46:436392 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336393 mock_quic_data.AddRead(
6394 ASYNC, ConstructServerDataPacket(
6395 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176396 header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366397
Renjief49758b2019-01-11 23:32:416398 mock_quic_data.AddWrite(
6399 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366400
6401 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6402 mock_quic_data.AddRead(ASYNC, 0); // EOF
6403 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6404
6405 // The non-alternate protocol job needs to hang in order to guarantee that
6406 // the alternate-protocol job will "win".
6407 AddHangingNonAlternateProtocolSocketData();
6408
6409 CreateSession();
6410 request_.method = "POST";
6411 ChunkedUploadDataStream upload_data(0);
6412 upload_data.AppendData("1", 1, true);
6413
6414 request_.upload_data_stream = &upload_data;
6415
6416 SendRequestAndExpectQuicResponse("hello!");
6417}
6418
allada71b2efb2016-09-09 04:57:486419class QuicURLRequestContext : public URLRequestContext {
6420 public:
6421 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6422 MockClientSocketFactory* socket_factory)
6423 : storage_(this) {
6424 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076425 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046426 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486427 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046428 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596429 storage_.set_proxy_resolution_service(
6430 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076431 storage_.set_ssl_config_service(
6432 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486433 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:116434 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:486435 storage_.set_http_server_properties(
Matt Menke609160742019-08-02 18:47:266436 std::make_unique<HttpServerProperties>());
Bence Béky8f9d7d3952017-10-09 19:58:046437 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486438 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046439 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6440 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6441 false));
allada71b2efb2016-09-09 04:57:486442 }
6443
6444 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6445
6446 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6447
6448 private:
6449 MockClientSocketFactory* socket_factory_;
6450 URLRequestContextStorage storage_;
6451};
6452
6453TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
Nick Harper72ade192019-07-17 03:30:426454 session_params_.quic_params.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486455 HostPortPair::FromString("mail.example.org:443"));
6456
Ryan Hamiltonabad59e2019-06-06 04:02:596457 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:026458 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton0239aac2018-05-19 00:03:136459 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486460 headers["user-agent"] = "";
6461 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336462 mock_quic_data.AddWrite(
6463 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6464 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Ryan Hamilton0d65a8c2019-06-07 00:46:026465 true, std::move(headers)));
allada71b2efb2016-09-09 04:57:486466
Fan Yang32c5a112018-12-10 20:06:336467 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026468 ASYNC, ConstructServerResponseHeadersPacket(
6469 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6470 GetResponseHeaders("200 OK")));
6471 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:456472 server_maker_.stream_offset(
6473 quic::VersionUsesQpack(version_.transport_version)
6474 ? GetNthClientInitiatedBidirectionalStreamId(0)
6475 : quic::QuicUtils::GetHeadersStreamId(
6476 version_.transport_version));
allada71b2efb2016-09-09 04:57:486477
Victor Vasiliev076657c2019-03-12 02:46:436478 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366479 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336480 ASYNC, ConstructServerDataPacket(
6481 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176482 "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436483 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486484
6485 mock_quic_data.AddRead(ASYNC, 0); // EOF
6486
6487 CreateSession();
6488
6489 TestDelegate delegate;
6490 QuicURLRequestContext quic_url_request_context(std::move(session_),
6491 &socket_factory_);
6492
6493 mock_quic_data.AddSocketDataToFactory(
6494 &quic_url_request_context.socket_factory());
6495 TestNetworkDelegate network_delegate;
6496 quic_url_request_context.set_network_delegate(&network_delegate);
6497
6498 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296499 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6500 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486501 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6502 &ssl_data_);
6503
6504 request->Start();
Wez2a31b222018-06-07 22:07:156505 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486506
6507 EXPECT_LT(0, request->GetTotalSentBytes());
6508 EXPECT_LT(0, request->GetTotalReceivedBytes());
6509 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6510 request->GetTotalSentBytes());
6511 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6512 request->GetTotalReceivedBytes());
6513 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6514 request->raw_header_size());
Wez0e717112018-06-18 23:09:226515
6516 // Pump the message loop to allow all data to be consumed.
6517 base::RunLoop().RunUntilIdle();
6518
allada71b2efb2016-09-09 04:57:486519 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6520 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6521}
6522
6523TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
Nick Harper72ade192019-07-17 03:30:426524 session_params_.quic_params.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486525 HostPortPair::FromString("mail.example.org:443"));
6526
Ryan Hamiltonabad59e2019-06-06 04:02:596527 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236528 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436529 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026530 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
Ryan Hamilton0239aac2018-05-19 00:03:136531 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486532 headers["user-agent"] = "";
6533 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436534 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336535 SYNCHRONOUS,
6536 ConstructClientRequestHeadersPacket(
6537 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026538 true, true, std::move(headers)));
allada71b2efb2016-09-09 04:57:486539
Fan Yang2330d182019-08-05 14:50:506540 const quic::QuicStreamOffset initial = server_maker_.stream_offset(
6541 GetNthClientInitiatedBidirectionalStreamId(0));
Zhongyi Shi32f2fd02018-04-16 18:23:436542 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026543 ASYNC,
6544 ConstructServerPushPromisePacket(
6545 1, GetNthClientInitiatedBidirectionalStreamId(0),
6546 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6547 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Fan Yang2330d182019-08-05 14:50:506548 quic::QuicStreamOffset push_promise_offset = 0;
6549 if (VersionUsesQpack(version_.transport_version)) {
6550 push_promise_offset = server_maker_.stream_offset(
6551 GetNthClientInitiatedBidirectionalStreamId(0)) -
6552 initial;
6553 }
allada71b2efb2016-09-09 04:57:486554
Renjie Tang703fea92019-07-23 21:08:316555 if ((client_headers_include_h2_stream_dependency_ &&
6556 version_.transport_version >= quic::QUIC_VERSION_43) ||
6557 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026558 mock_quic_data.AddWrite(
6559 SYNCHRONOUS,
6560 ConstructClientPriorityPacket(
6561 client_packet_number++, false,
6562 GetNthServerInitiatedUnidirectionalStreamId(0),
6563 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576564 }
6565
Ryan Hamiltone940bd12019-06-30 02:46:456566 const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
6567 quic::VersionUsesQpack(version_.transport_version)
6568 ? GetNthClientInitiatedBidirectionalStreamId(0)
6569 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Zhongyi Shi32f2fd02018-04-16 18:23:436570 mock_quic_data.AddRead(
6571 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336572 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026573 GetResponseHeaders("200 OK")));
Ryan Hamiltone940bd12019-06-30 02:46:456574 const quic::QuicStreamOffset final_offset = server_maker_.stream_offset(
6575 quic::VersionUsesQpack(version_.transport_version)
6576 ? GetNthClientInitiatedBidirectionalStreamId(0)
6577 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Ryan Hamilton0d65a8c2019-06-07 00:46:026578 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:456579 final_offset - initial_offset;
allada71b2efb2016-09-09 04:57:486580
Yixin Wangb470bc882018-02-15 18:43:576581 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436582 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486583
ckrasicbf2f59c2017-05-04 23:54:366584 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436585 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336586 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026587 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436588 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436589 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336590 ASYNC, ConstructServerDataPacket(
6591 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176592 header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486593
Yixin Wangb470bc882018-02-15 18:43:576594 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436595 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436596 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366597 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336598 ASYNC, ConstructServerDataPacket(
6599 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176600 header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486601
Zhongyi Shi32f2fd02018-04-16 18:23:436602 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486603
6604 CreateSession();
6605
6606 TestDelegate delegate;
6607 QuicURLRequestContext quic_url_request_context(std::move(session_),
6608 &socket_factory_);
6609
6610 mock_quic_data.AddSocketDataToFactory(
6611 &quic_url_request_context.socket_factory());
6612 TestNetworkDelegate network_delegate;
6613 quic_url_request_context.set_network_delegate(&network_delegate);
6614
6615 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296616 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6617 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486618 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6619 &ssl_data_);
6620
6621 request->Start();
Wez2a31b222018-06-07 22:07:156622 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486623
6624 EXPECT_LT(0, request->GetTotalSentBytes());
6625 EXPECT_LT(0, request->GetTotalReceivedBytes());
6626 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6627 request->GetTotalSentBytes());
6628 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6629 request->GetTotalReceivedBytes());
Fan Yang2330d182019-08-05 14:50:506630 EXPECT_EQ(
6631 static_cast<int>(expected_raw_header_response_size + push_promise_offset),
6632 request->raw_header_size());
Wez0e717112018-06-18 23:09:226633
6634 // Pump the message loop to allow all data to be consumed.
6635 base::RunLoop().RunUntilIdle();
6636
allada71b2efb2016-09-09 04:57:486637 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6638 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6639}
6640
Ryan Sleevia9d6aa62019-07-26 13:32:186641TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
6642 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:206643
6644 MockRead http_reads[] = {
6645 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6646 MockRead("hello world"),
6647 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6648 MockRead(ASYNC, OK)};
6649
Ryan Sleevib8d7ea02018-05-07 20:01:016650 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206651 socket_factory_.AddSocketDataProvider(&http_data);
6652 AddCertificate(&ssl_data_);
6653 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6654
Ryan Hamiltonabad59e2019-06-06 04:02:596655 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:026656 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Yixin Wang10f477ed2017-11-21 04:20:206657 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026658 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6659 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6660 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436661 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336662 ASYNC, ConstructServerResponseHeadersPacket(
6663 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6664 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436665 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336666 mock_quic_data.AddRead(
6667 ASYNC, ConstructServerDataPacket(
6668 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176669 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436670 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206671 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6672 mock_quic_data.AddRead(ASYNC, 0); // EOF
6673
6674 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6675
6676 AddHangingNonAlternateProtocolSocketData();
6677 CreateSession();
6678
6679 SendRequestAndExpectHttpResponse("hello world");
6680 SendRequestAndExpectQuicResponse("hello!");
6681}
6682
Ryan Sleevia9d6aa62019-07-26 13:32:186683TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
6684 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:206685
6686 MockRead http_reads[] = {
6687 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6688 MockRead("hello world"),
6689 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6690 MockRead(ASYNC, OK)};
6691
Ryan Sleevib8d7ea02018-05-07 20:01:016692 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206693 socket_factory_.AddSocketDataProvider(&http_data);
6694 AddCertificate(&ssl_data_);
6695 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6696 socket_factory_.AddSocketDataProvider(&http_data);
6697 AddCertificate(&ssl_data_);
6698 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6699
6700 AddHangingNonAlternateProtocolSocketData();
6701 CreateSession();
6702
6703 SendRequestAndExpectHttpResponse("hello world");
6704 SendRequestAndExpectHttpResponse("hello world");
6705}
6706
bnc359ed2a2016-04-29 20:43:456707class QuicNetworkTransactionWithDestinationTest
6708 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016709 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:056710 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456711 protected:
6712 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556713 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056714 client_headers_include_h2_stream_dependency_(
6715 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:566716 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:456717 destination_type_(GetParam().destination_type),
6718 cert_transparency_verifier_(new MultiLogCTVerifier()),
6719 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596720 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:116721 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:456722 random_generator_(0),
6723 ssl_data_(ASYNC, OK) {}
6724
6725 void SetUp() override {
6726 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556727 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456728
mmenke6ddfbea2017-05-31 21:48:416729 HttpNetworkSession::Params session_params;
6730 session_params.enable_quic = true;
Nick Harper72ade192019-07-17 03:30:426731 session_params.quic_params.allow_remote_alt_svc = true;
6732 session_params.quic_params.supported_versions = supported_versions_;
6733 session_params.quic_params.headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:056734 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416735
6736 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456737
Ryan Hamilton8d9ee76e2018-05-29 23:52:526738 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416739 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456740
6741 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276742 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416743 session_context.quic_crypto_client_stream_factory =
6744 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456745
mmenke6ddfbea2017-05-31 21:48:416746 session_context.quic_random = &random_generator_;
6747 session_context.client_socket_factory = &socket_factory_;
6748 session_context.host_resolver = &host_resolver_;
6749 session_context.cert_verifier = &cert_verifier_;
6750 session_context.transport_security_state = &transport_security_state_;
6751 session_context.cert_transparency_verifier =
6752 cert_transparency_verifier_.get();
6753 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6754 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456755 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416756 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596757 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416758 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6759 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456760
mmenke6ddfbea2017-05-31 21:48:416761 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456762 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456763 }
6764
6765 void TearDown() override {
6766 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6767 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556768 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456769 PlatformTest::TearDown();
6770 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556771 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406772 session_.reset();
bnc359ed2a2016-04-29 20:43:456773 }
6774
zhongyie537a002017-06-27 16:48:216775 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456776 HostPortPair destination;
6777 switch (destination_type_) {
6778 case SAME_AS_FIRST:
6779 destination = HostPortPair(origin1_, 443);
6780 break;
6781 case SAME_AS_SECOND:
6782 destination = HostPortPair(origin2_, 443);
6783 break;
6784 case DIFFERENT:
6785 destination = HostPortPair(kDifferentHostname, 443);
6786 break;
6787 }
bnc3472afd2016-11-17 15:27:216788 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456789 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216790 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:076791 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
6792 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456793 }
6794
Ryan Hamilton8d9ee76e2018-05-29 23:52:526795 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236796 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526797 quic::QuicStreamId stream_id,
6798 bool should_include_version,
6799 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526800 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136801 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456802 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136803 spdy::SpdyHeaderBlock headers(
6804 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:026805 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456806 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:026807 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:456808 }
6809
Ryan Hamilton8d9ee76e2018-05-29 23:52:526810 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236811 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526812 quic::QuicStreamId stream_id,
6813 bool should_include_version,
6814 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586815 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:026816 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:456817 }
6818
Ryan Hamilton8d9ee76e2018-05-29 23:52:526819 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236820 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526821 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526822 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136823 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
Ryan Hamilton0d65a8c2019-06-07 00:46:026824 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
6825 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:456826 }
6827
Ryan Hamilton8d9ee76e2018-05-29 23:52:526828 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:236829 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526830 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456831 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:436832 std::string header = "";
Nick Harper23290b82019-05-02 00:02:566833 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416834 quic::HttpEncoder encoder;
6835 std::unique_ptr<char[]> buffer;
6836 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:436837 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:416838 }
Ryan Hamilton7505eb92019-06-08 00:22:176839 return maker->MakeDataPacket(packet_number, stream_id, false, true,
Renjief49758b2019-01-11 23:32:416840 header + "hello");
bnc359ed2a2016-04-29 20:43:456841 }
6842
Ryan Hamilton8d9ee76e2018-05-29 23:52:526843 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:236844 uint64_t packet_number,
6845 uint64_t largest_received,
6846 uint64_t smallest_received,
6847 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:456848 QuicTestPacketMaker* maker) {
6849 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496850 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456851 }
6852
Ryan Hamilton8d9ee76e2018-05-29 23:52:526853 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:236854 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:376855 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026856 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:376857 }
6858
bnc359ed2a2016-04-29 20:43:456859 void AddRefusedSocketData() {
6860 std::unique_ptr<StaticSocketDataProvider> refused_data(
6861 new StaticSocketDataProvider());
6862 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6863 refused_data->set_connect_data(refused_connect);
6864 socket_factory_.AddSocketDataProvider(refused_data.get());
6865 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6866 }
6867
6868 void AddHangingSocketData() {
6869 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6870 new StaticSocketDataProvider());
6871 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6872 hanging_data->set_connect_data(hanging_connect);
6873 socket_factory_.AddSocketDataProvider(hanging_data.get());
6874 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6875 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6876 }
6877
6878 bool AllDataConsumed() {
6879 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6880 if (!socket_data_ptr->AllReadDataConsumed() ||
6881 !socket_data_ptr->AllWriteDataConsumed()) {
6882 return false;
6883 }
6884 }
6885 return true;
6886 }
6887
6888 void SendRequestAndExpectQuicResponse(const std::string& host) {
6889 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6890 HttpRequestInfo request;
6891 std::string url("https://");
6892 url.append(host);
6893 request.url = GURL(url);
6894 request.load_flags = 0;
6895 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106896 request.traffic_annotation =
6897 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456898 TestCompletionCallback callback;
6899 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016900 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456901
6902 std::string response_data;
robpercival214763f2016-07-01 23:27:016903 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456904 EXPECT_EQ("hello", response_data);
6905
6906 const HttpResponseInfo* response = trans.GetResponseInfo();
6907 ASSERT_TRUE(response != nullptr);
6908 ASSERT_TRUE(response->headers.get() != nullptr);
6909 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6910 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526911 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:566912 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
6913 version_.transport_version),
bnc359ed2a2016-04-29 20:43:456914 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:376915 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:456916 }
6917
Fan Yang32c5a112018-12-10 20:06:336918 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:566919 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
6920 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:366921 }
6922
Ryan Hamilton8d9ee76e2018-05-29 23:52:526923 quic::MockClock clock_;
Nick Harper23290b82019-05-02 00:02:566924 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:056925 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:566926 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:456927 DestinationType destination_type_;
6928 std::string origin1_;
6929 std::string origin2_;
6930 std::unique_ptr<HttpNetworkSession> session_;
6931 MockClientSocketFactory socket_factory_;
6932 MockHostResolver host_resolver_;
6933 MockCertVerifier cert_verifier_;
6934 TransportSecurityState transport_security_state_;
6935 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:236936 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:456937 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:076938 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:596939 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:456940 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526941 quic::test::MockRandom random_generator_;
Matt Menke609160742019-08-02 18:47:266942 HttpServerProperties http_server_properties_;
bnc359ed2a2016-04-29 20:43:456943 BoundTestNetLog net_log_;
6944 MockCryptoClientStreamFactory crypto_client_stream_factory_;
6945 std::vector<std::unique_ptr<StaticSocketDataProvider>>
6946 static_socket_data_provider_vector_;
6947 SSLSocketDataProvider ssl_data_;
6948};
6949
Victor Costane635086f2019-01-27 05:20:306950INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
6951 QuicNetworkTransactionWithDestinationTest,
6952 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:456953
6954// A single QUIC request fails because the certificate does not match the origin
6955// hostname, regardless of whether it matches the alternative service hostname.
6956TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
6957 if (destination_type_ == DIFFERENT)
6958 return;
6959
6960 GURL url("https://mail.example.com/");
6961 origin1_ = url.host();
6962
6963 // Not used for requests, but this provides a test case where the certificate
6964 // is valid for the hostname of the alternative service.
6965 origin2_ = "mail.example.org";
6966
zhongyie537a002017-06-27 16:48:216967 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:456968
6969 scoped_refptr<X509Certificate> cert(
6970 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246971 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
6972 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:456973
6974 ProofVerifyDetailsChromium verify_details;
6975 verify_details.cert_verify_result.verified_cert = cert;
6976 verify_details.cert_verify_result.is_issued_by_known_root = true;
6977 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6978
Ryan Hamiltonabad59e2019-06-06 04:02:596979 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:456980 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
6981 mock_quic_data.AddRead(ASYNC, 0);
6982
6983 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6984
6985 AddRefusedSocketData();
6986
6987 HttpRequestInfo request;
6988 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:106989 request.traffic_annotation =
6990 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456991
6992 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6993 TestCompletionCallback callback;
6994 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016995 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:456996
6997 EXPECT_TRUE(AllDataConsumed());
6998}
6999
7000// First request opens QUIC session to alternative service. Second request
7001// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527002// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457003TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7004 origin1_ = "mail.example.org";
7005 origin2_ = "news.example.org";
7006
zhongyie537a002017-06-27 16:48:217007 SetQuicAlternativeService(origin1_);
7008 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457009
7010 scoped_refptr<X509Certificate> cert(
7011 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247012 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7013 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7014 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457015
7016 ProofVerifyDetailsChromium verify_details;
7017 verify_details.cert_verify_result.verified_cert = cert;
7018 verify_details.cert_verify_result.is_issued_by_known_root = true;
7019 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7020
Yixin Wang079ad542018-01-11 04:06:057021 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177022 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7023 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057024 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177025 QuicTestPacketMaker server_maker(
7026 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7027 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457028
Ryan Hamiltonabad59e2019-06-06 04:02:597029 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027030 mock_quic_data.AddWrite(SYNCHRONOUS,
7031 ConstructInitialSettingsPacket(1, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337032 mock_quic_data.AddWrite(
7033 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7034 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Ryan Hamilton0d65a8c2019-06-07 00:46:027035 &client_maker));
7036 mock_quic_data.AddRead(
7037 ASYNC,
7038 ConstructServerResponseHeadersPacket(
7039 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437040 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337041 ASYNC,
7042 ConstructServerDataPacket(
7043 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437044 mock_quic_data.AddWrite(SYNCHRONOUS,
7045 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457046
Yixin Wang079ad542018-01-11 04:06:057047 client_maker.set_hostname(origin2_);
7048 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457049
Zhongyi Shi32f2fd02018-04-16 18:23:437050 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027051 SYNCHRONOUS,
7052 ConstructClientRequestHeadersPacket(
7053 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7054 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7055 mock_quic_data.AddRead(
7056 ASYNC,
7057 ConstructServerResponseHeadersPacket(
7058 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437059 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337060 ASYNC,
7061 ConstructServerDataPacket(
7062 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437063 mock_quic_data.AddWrite(SYNCHRONOUS,
7064 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457065 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 AddHangingSocketData();
7071 AddHangingSocketData();
7072
Nick Harpereb483e12019-05-14 00:18:097073 scoped_refptr<TestTaskRunner> quic_task_runner(new TestTaskRunner(&clock_));
Fan Yangc9e00dc2018-10-09 14:17:567074 QuicStreamFactoryPeer::SetAlarmFactory(
7075 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097076 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Fan Yangc9e00dc2018-10-09 14:17:567077 &clock_));
7078
bnc359ed2a2016-04-29 20:43:457079 SendRequestAndExpectQuicResponse(origin1_);
7080 SendRequestAndExpectQuicResponse(origin2_);
7081
7082 EXPECT_TRUE(AllDataConsumed());
7083}
7084
7085// First request opens QUIC session to alternative service. Second request does
7086// not pool to it, even though destination matches, because certificate is not
7087// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527088// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457089TEST_P(QuicNetworkTransactionWithDestinationTest,
7090 DoNotPoolIfCertificateInvalid) {
7091 origin1_ = "news.example.org";
7092 origin2_ = "mail.example.com";
7093
zhongyie537a002017-06-27 16:48:217094 SetQuicAlternativeService(origin1_);
7095 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457096
7097 scoped_refptr<X509Certificate> cert1(
7098 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247099 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7100 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7101 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457102
7103 scoped_refptr<X509Certificate> cert2(
7104 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247105 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7106 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457107
7108 ProofVerifyDetailsChromium verify_details1;
7109 verify_details1.cert_verify_result.verified_cert = cert1;
7110 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7111 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7112
7113 ProofVerifyDetailsChromium verify_details2;
7114 verify_details2.cert_verify_result.verified_cert = cert2;
7115 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7116 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7117
Yixin Wang079ad542018-01-11 04:06:057118 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177119 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7120 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057121 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177122 QuicTestPacketMaker server_maker1(
7123 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7124 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457125
Ryan Hamiltonabad59e2019-06-06 04:02:597126 MockQuicData mock_quic_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027127 mock_quic_data1.AddWrite(SYNCHRONOUS,
7128 ConstructInitialSettingsPacket(1, &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337129 mock_quic_data1.AddWrite(
7130 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7131 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Ryan Hamilton0d65a8c2019-06-07 00:46:027132 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437133 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337134 ASYNC,
7135 ConstructServerResponseHeadersPacket(
7136 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437137 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337138 ASYNC,
7139 ConstructServerDataPacket(
7140 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437141 mock_quic_data1.AddWrite(
7142 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457143 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7144 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7145
7146 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7147
Yixin Wang079ad542018-01-11 04:06:057148 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177149 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7150 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057151 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177152 QuicTestPacketMaker server_maker2(
7153 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7154 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457155
Ryan Hamiltonabad59e2019-06-06 04:02:597156 MockQuicData mock_quic_data2(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027157 mock_quic_data2.AddWrite(SYNCHRONOUS,
7158 ConstructInitialSettingsPacket(1, &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337159 mock_quic_data2.AddWrite(
7160 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7161 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Ryan Hamilton0d65a8c2019-06-07 00:46:027162 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437163 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337164 ASYNC,
7165 ConstructServerResponseHeadersPacket(
7166 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437167 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337168 ASYNC,
7169 ConstructServerDataPacket(
7170 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437171 mock_quic_data2.AddWrite(
7172 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457173 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7174 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7175
7176 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7177
bnc359ed2a2016-04-29 20:43:457178 SendRequestAndExpectQuicResponse(origin1_);
7179 SendRequestAndExpectQuicResponse(origin2_);
7180
7181 EXPECT_TRUE(AllDataConsumed());
7182}
7183
ckrasicdee37572017-04-06 22:42:277184// crbug.com/705109 - this confirms that matching request with a body
7185// triggers a crash (pre-fix).
7186TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Nick Harper72ade192019-07-17 03:30:427187 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277188 HostPortPair::FromString("mail.example.org:443"));
7189
Ryan Hamiltonabad59e2019-06-06 04:02:597190 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237191 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437192 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027193 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
Zhongyi Shi32f2fd02018-04-16 18:23:437194 mock_quic_data.AddWrite(
7195 SYNCHRONOUS,
7196 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337197 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027198 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437199 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027200 ASYNC,
7201 ConstructServerPushPromisePacket(
7202 1, GetNthClientInitiatedBidirectionalStreamId(0),
7203 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7204 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:317205
7206 if ((client_headers_include_h2_stream_dependency_ &&
7207 version_.transport_version >= quic::QUIC_VERSION_43) ||
7208 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027209 mock_quic_data.AddWrite(
7210 SYNCHRONOUS,
7211 ConstructClientPriorityPacket(
7212 client_packet_number++, false,
7213 GetNthServerInitiatedUnidirectionalStreamId(0),
7214 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577215 }
Zhongyi Shi32f2fd02018-04-16 18:23:437216 mock_quic_data.AddRead(
7217 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337218 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027219 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:577220 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437221 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7222 mock_quic_data.AddRead(
7223 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337224 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027225 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437226 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437227 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337228 ASYNC, ConstructServerDataPacket(
7229 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177230 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577231 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437232 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417233
Victor Vasiliev076657c2019-03-12 02:46:437234 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437235 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337236 ASYNC, ConstructServerDataPacket(
7237 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177238 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277239
7240 // Because the matching request has a body, we will see the push
7241 // stream get cancelled, and the matching request go out on the
7242 // wire.
Fan Yang32c5a112018-12-10 20:06:337243 mock_quic_data.AddWrite(SYNCHRONOUS,
7244 ConstructClientAckAndRstPacket(
7245 client_packet_number++,
7246 GetNthServerInitiatedUnidirectionalStreamId(0),
7247 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277248 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437249 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567250 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417251 mock_quic_data.AddWrite(
7252 SYNCHRONOUS,
7253 ConstructClientRequestHeadersAndDataFramesPacket(
7254 client_packet_number++,
7255 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7256 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027257 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, {kBody}));
Renjief49758b2019-01-11 23:32:417258 } else {
7259 mock_quic_data.AddWrite(
7260 SYNCHRONOUS,
7261 ConstructClientRequestHeadersAndDataFramesPacket(
7262 client_packet_number++,
7263 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7264 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027265 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7266 {header3, kBody}));
Renjief49758b2019-01-11 23:32:417267 }
ckrasicdee37572017-04-06 22:42:277268
7269 // We see the same response as for the earlier pushed and cancelled
7270 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437271 mock_quic_data.AddRead(
7272 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337273 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027274 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:437275 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337276 ASYNC, ConstructServerDataPacket(
7277 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177278 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277279
Yixin Wangb470bc882018-02-15 18:43:577280 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437281 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277282 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7283 mock_quic_data.AddRead(ASYNC, 0); // EOF
7284 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7285
7286 // The non-alternate protocol job needs to hang in order to guarantee that
7287 // the alternate-protocol job will "win".
7288 AddHangingNonAlternateProtocolSocketData();
7289
7290 CreateSession();
7291
7292 // PUSH_PROMISE handling in the http layer gets exercised here.
7293 SendRequestAndExpectQuicResponse("hello!");
7294
7295 request_.url = GURL("https://mail.example.org/pushed.jpg");
7296 ChunkedUploadDataStream upload_data(0);
7297 upload_data.AppendData("1", 1, true);
7298 request_.upload_data_stream = &upload_data;
7299 SendRequestAndExpectQuicResponse("and hello!");
7300}
7301
Bence Béky7538a952018-02-01 16:59:527302// Regression test for https://crbug.com/797825: If pushed headers describe a
7303// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7304// not be called (otherwise a DCHECK fails).
7305TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137306 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527307 pushed_request_headers[":authority"] = "";
7308 pushed_request_headers[":method"] = "GET";
7309 pushed_request_headers[":path"] = "/";
7310 pushed_request_headers[":scheme"] = "nosuchscheme";
7311
Nick Harper72ade192019-07-17 03:30:427312 session_params_.quic_params.origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:527313 HostPortPair::FromString("mail.example.org:443"));
7314
Ryan Hamiltonabad59e2019-06-06 04:02:597315 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:527316
Ryan Hamilton0d65a8c2019-06-07 00:46:027317 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Bence Béky7538a952018-02-01 16:59:527318 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027319 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7320 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7321 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:527322
Fan Yang32c5a112018-12-10 20:06:337323 mock_quic_data.AddRead(
7324 ASYNC, ConstructServerPushPromisePacket(
7325 1, GetNthClientInitiatedBidirectionalStreamId(0),
7326 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027327 std::move(pushed_request_headers), &server_maker_));
Fan Yang32c5a112018-12-10 20:06:337328 mock_quic_data.AddWrite(SYNCHRONOUS,
7329 ConstructClientRstPacket(
7330 3, GetNthServerInitiatedUnidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417331 quic::QUIC_INVALID_PROMISE_URL));
Bence Béky7538a952018-02-01 16:59:527332
Zhongyi Shi32f2fd02018-04-16 18:23:437333 mock_quic_data.AddRead(
7334 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337335 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027336 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:437337 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527338
Zhongyi Shi32f2fd02018-04-16 18:23:437339 mock_quic_data.AddRead(
7340 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337341 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027342 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437343 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437344 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337345 ASYNC, ConstructServerDataPacket(
7346 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177347 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437348 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527349
7350 mock_quic_data.AddRead(ASYNC, 0);
7351 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7352
7353 // The non-alternate protocol job needs to hang in order to guarantee that
7354 // the alternate-protocol job will "win".
7355 AddHangingNonAlternateProtocolSocketData();
7356
7357 CreateSession();
7358
7359 // PUSH_PROMISE handling in the http layer gets exercised here.
7360 SendRequestAndExpectQuicResponse("hello!");
7361
7362 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7363 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7364}
7365
Yixin Wang46a273ec302018-01-23 17:59:567366// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147367TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567368 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147369 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567370 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497371 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567372
Ryan Hamiltonabad59e2019-06-06 04:02:597373 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027374 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Fan Yang32c5a112018-12-10 20:06:337375 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357376 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7377 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047378 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027379 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337380 mock_quic_data.AddRead(
7381 ASYNC, ConstructServerResponseHeadersPacket(
7382 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7383 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567384
7385 const char get_request[] =
7386 "GET / HTTP/1.1\r\n"
7387 "Host: mail.example.org\r\n"
7388 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437389 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567390 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417391 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357392 SYNCHRONOUS,
7393 ConstructClientAckAndDataPacket(
7394 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Ryan Hamilton7505eb92019-06-08 00:22:177395 false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417396 } else {
7397 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417398 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357399 ConstructClientAckAndMultipleDataFramesPacket(
7400 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Ryan Hamilton7505eb92019-06-08 00:22:177401 false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417402 }
7403
Yixin Wang46a273ec302018-01-23 17:59:567404 const char get_response[] =
7405 "HTTP/1.1 200 OK\r\n"
7406 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437407 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437408 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337409 ASYNC, ConstructServerDataPacket(
7410 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177411 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:437412 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337413 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417414 SYNCHRONOUS, ConstructServerDataPacket(
7415 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:177416 false, header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357417 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567418 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7419
7420 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417421 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357422 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417423 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567424
7425 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7426
7427 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7428
7429 CreateSession();
7430
7431 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097432 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567433 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7434 HeadersHandler headers_handler;
7435 trans.SetBeforeHeadersSentCallback(
7436 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7437 base::Unretained(&headers_handler)));
7438 RunTransaction(&trans);
7439 CheckWasHttpResponse(&trans);
7440 CheckResponsePort(&trans, 70);
7441 CheckResponseData(&trans, "0123456789");
7442 EXPECT_TRUE(headers_handler.was_proxied());
7443 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7444
7445 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7446 // proxy socket to disconnect.
7447 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7448
7449 base::RunLoop().RunUntilIdle();
7450 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7451 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7452}
7453
7454// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147455TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567456 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147457 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567458 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497459 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567460
Ryan Hamiltonabad59e2019-06-06 04:02:597461 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027462 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Fan Yang32c5a112018-12-10 20:06:337463 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357464 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7465 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047466 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027467 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337468 mock_quic_data.AddRead(
7469 ASYNC, ConstructServerResponseHeadersPacket(
7470 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7471 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567472
7473 SpdyTestUtil spdy_util;
7474
Ryan Hamilton0239aac2018-05-19 00:03:137475 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567476 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437477 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567478 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417479 mock_quic_data.AddWrite(
7480 SYNCHRONOUS,
7481 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357482 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Ryan Hamilton7505eb92019-06-08 00:22:177483 false, quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:417484 } else {
7485 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417486 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357487 ConstructClientAckAndMultipleDataFramesPacket(
7488 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Ryan Hamilton7505eb92019-06-08 00:22:177489 false, {header, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417490 }
Ryan Hamilton0239aac2018-05-19 00:03:137491 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567492 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437493 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437494 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177495 ASYNC, ConstructServerDataPacket(
7496 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7497 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567498
Ryan Hamilton0239aac2018-05-19 00:03:137499 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197500 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:437501 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437502 mock_quic_data.AddRead(
7503 SYNCHRONOUS,
7504 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337505 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437506 header3 + std::string(data_frame.data(), data_frame.size())));
Renjied172e812019-01-16 05:12:357507 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567508 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7509
7510 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437511 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357512 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417513 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567514
7515 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7516
7517 SSLSocketDataProvider ssl_data(ASYNC, OK);
7518 ssl_data.next_proto = kProtoHTTP2;
7519 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7520
7521 CreateSession();
7522
7523 request_.url = GURL("https://mail.example.org/");
7524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7525 HeadersHandler headers_handler;
7526 trans.SetBeforeHeadersSentCallback(
7527 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7528 base::Unretained(&headers_handler)));
7529 RunTransaction(&trans);
7530 CheckWasSpdyResponse(&trans);
7531 CheckResponsePort(&trans, 70);
7532 CheckResponseData(&trans, "0123456789");
7533 EXPECT_TRUE(headers_handler.was_proxied());
7534 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7535
Wez0e717112018-06-18 23:09:227536 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7537 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567538 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7539
7540 base::RunLoop().RunUntilIdle();
7541 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7542 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7543}
7544
7545// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7546// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147547TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567548 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147549 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567550 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497551 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567552
Ryan Hamiltonabad59e2019-06-06 04:02:597553 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:417554 int write_packet_index = 1;
Ryan Hamilton0d65a8c2019-06-07 00:46:027555 mock_quic_data.AddWrite(SYNCHRONOUS,
7556 ConstructInitialSettingsPacket(write_packet_index++));
Fan Yang32c5a112018-12-10 20:06:337557 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417558 SYNCHRONOUS,
7559 ConstructClientRequestHeadersPacket(
7560 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:047561 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027562 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337563 mock_quic_data.AddRead(
7564 ASYNC, ConstructServerResponseHeadersPacket(
7565 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7566 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567567
Ryan Hamilton8d9ee76e2018-05-29 23:52:527568 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567569 const char get_request_1[] =
7570 "GET / HTTP/1.1\r\n"
7571 "Host: mail.example.org\r\n"
7572 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437573 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:567574 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417575 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:177576 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7577 write_packet_index++, false,
7578 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7579 false, quic::QuicStringPiece(get_request_1)));
Renjief49758b2019-01-11 23:32:417580 } else {
7581 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:177582 SYNCHRONOUS, ConstructClientAckAndMultipleDataFramesPacket(
7583 write_packet_index++, false,
7584 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7585 false, {header, std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:417586 }
7587
Yixin Wang46a273ec302018-01-23 17:59:567588 const char get_response_1[] =
7589 "HTTP/1.1 200 OK\r\n"
7590 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437591 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437592 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437593 ASYNC, ConstructServerDataPacket(
7594 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177595 header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:417596 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567597
Victor Vasiliev076657c2019-03-12 02:46:437598 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337599 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177600 SYNCHRONOUS, ConstructServerDataPacket(
7601 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7602 false, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:417603 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567604
Renjief49758b2019-01-11 23:32:417605 mock_quic_data.AddWrite(
7606 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567607
7608 const char get_request_2[] =
7609 "GET /2 HTTP/1.1\r\n"
7610 "Host: mail.example.org\r\n"
7611 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437612 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:567613 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417614 mock_quic_data.AddWrite(
7615 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357616 ConstructClientMultipleDataFramesPacket(
7617 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:177618 false, false, {header4, std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:357619 } else {
7620 mock_quic_data.AddWrite(
7621 SYNCHRONOUS,
Ryan Hamilton7505eb92019-06-08 00:22:177622 ConstructClientDataPacket(
7623 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7624 false, false, quic::QuicStringPiece(get_request_2)));
Renjief49758b2019-01-11 23:32:417625 }
Yixin Wang46a273ec302018-01-23 17:59:567626
7627 const char get_response_2[] =
7628 "HTTP/1.1 200 OK\r\n"
7629 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437630 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437631 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437632 ASYNC, ConstructServerDataPacket(
7633 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177634 header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:417635 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567636
Victor Vasiliev076657c2019-03-12 02:46:437637 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527638 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177639 SYNCHRONOUS, ConstructServerDataPacket(
7640 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
7641 false, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:417642 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567643
Renjief49758b2019-01-11 23:32:417644 mock_quic_data.AddWrite(
7645 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567646 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7647
Renjief49758b2019-01-11 23:32:417648 mock_quic_data.AddWrite(
7649 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417650 ConstructClientRstPacket(write_packet_index++,
7651 GetNthClientInitiatedBidirectionalStreamId(0),
7652 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567653
7654 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7655
7656 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7657
7658 CreateSession();
7659
7660 request_.url = GURL("https://mail.example.org/");
7661 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7662 HeadersHandler headers_handler_1;
7663 trans_1.SetBeforeHeadersSentCallback(
7664 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7665 base::Unretained(&headers_handler_1)));
7666 RunTransaction(&trans_1);
7667 CheckWasHttpResponse(&trans_1);
7668 CheckResponsePort(&trans_1, 70);
7669 CheckResponseData(&trans_1, "0123456789");
7670 EXPECT_TRUE(headers_handler_1.was_proxied());
7671 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7672
7673 request_.url = GURL("https://mail.example.org/2");
7674 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7675 HeadersHandler headers_handler_2;
7676 trans_2.SetBeforeHeadersSentCallback(
7677 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7678 base::Unretained(&headers_handler_2)));
7679 RunTransaction(&trans_2);
7680 CheckWasHttpResponse(&trans_2);
7681 CheckResponsePort(&trans_2, 70);
7682 CheckResponseData(&trans_2, "0123456");
7683 EXPECT_TRUE(headers_handler_2.was_proxied());
7684 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7685
7686 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7687 // proxy socket to disconnect.
7688 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7689
7690 base::RunLoop().RunUntilIdle();
7691 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7692 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7693}
7694
7695// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7696// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7697// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147698TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567699 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147700 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567701 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497702 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567703
Ryan Hamiltonabad59e2019-06-06 04:02:597704 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027705 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Yixin Wang46a273ec302018-01-23 17:59:567706
7707 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337708 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357709 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7710 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047711 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027712 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:437713 mock_quic_data.AddRead(
7714 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337715 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027716 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567717
7718 // GET request, response, and data over QUIC tunnel for first request
7719 const char get_request[] =
7720 "GET / HTTP/1.1\r\n"
7721 "Host: mail.example.org\r\n"
7722 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437723 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567724 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417725 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357726 SYNCHRONOUS,
7727 ConstructClientAckAndDataPacket(
7728 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Ryan Hamilton7505eb92019-06-08 00:22:177729 false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417730 } else {
7731 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417732 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357733 ConstructClientAckAndMultipleDataFramesPacket(
7734 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Ryan Hamilton7505eb92019-06-08 00:22:177735 false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417736 }
7737
Yixin Wang46a273ec302018-01-23 17:59:567738 const char get_response[] =
7739 "HTTP/1.1 200 OK\r\n"
7740 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437741 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567742 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337743 ASYNC, ConstructServerDataPacket(
7744 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177745 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:437746 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337747 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417748 SYNCHRONOUS, ConstructServerDataPacket(
7749 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:177750 false, header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357751 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567752
7753 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437754 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:047755 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7756 5, GetNthClientInitiatedBidirectionalStreamId(1), false,
7757 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7758 ConnectRequestHeaders("different.example.org:443"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027759 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:437760 mock_quic_data.AddRead(
7761 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337762 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027763 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567764
7765 // GET request, response, and data over QUIC tunnel for second request
7766 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137767 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567768 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437769 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567770 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417771 mock_quic_data.AddWrite(
7772 SYNCHRONOUS,
7773 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357774 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
Ryan Hamilton7505eb92019-06-08 00:22:177775 false, quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:417776 } else {
7777 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417778 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357779 ConstructClientAckAndMultipleDataFramesPacket(
7780 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
Ryan Hamilton7505eb92019-06-08 00:22:177781 false, {header4, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417782 }
Yixin Wang46a273ec302018-01-23 17:59:567783
Ryan Hamilton0239aac2018-05-19 00:03:137784 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567785 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437786 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437787 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177788 ASYNC, ConstructServerDataPacket(
7789 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7790 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567791
Ryan Hamilton0239aac2018-05-19 00:03:137792 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197793 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:437794 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437795 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437796 ASYNC, ConstructServerDataPacket(
7797 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437798 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567799
Renjied172e812019-01-16 05:12:357800 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567801 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7802
7803 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417804 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357805 ConstructClientRstPacket(8, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417806 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567807 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437808 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357809 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417810 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567811
7812 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7813
7814 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7815
7816 SSLSocketDataProvider ssl_data(ASYNC, OK);
7817 ssl_data.next_proto = kProtoHTTP2;
7818 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7819
7820 CreateSession();
7821
7822 request_.url = GURL("https://mail.example.org/");
7823 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7824 HeadersHandler headers_handler_1;
7825 trans_1.SetBeforeHeadersSentCallback(
7826 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7827 base::Unretained(&headers_handler_1)));
7828 RunTransaction(&trans_1);
7829 CheckWasHttpResponse(&trans_1);
7830 CheckResponsePort(&trans_1, 70);
7831 CheckResponseData(&trans_1, "0123456789");
7832 EXPECT_TRUE(headers_handler_1.was_proxied());
7833 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7834
7835 request_.url = GURL("https://different.example.org/");
7836 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7837 HeadersHandler headers_handler_2;
7838 trans_2.SetBeforeHeadersSentCallback(
7839 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7840 base::Unretained(&headers_handler_2)));
7841 RunTransaction(&trans_2);
7842 CheckWasSpdyResponse(&trans_2);
7843 CheckResponsePort(&trans_2, 70);
7844 CheckResponseData(&trans_2, "0123456");
7845 EXPECT_TRUE(headers_handler_2.was_proxied());
7846 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7847
7848 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7849 // proxy socket to disconnect.
7850 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7851
7852 base::RunLoop().RunUntilIdle();
7853 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7854 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7855}
7856
7857// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:147858TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:567859 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147860 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567861 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497862 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567863
Ryan Hamiltonabad59e2019-06-06 04:02:597864 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027865 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527866 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337867 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7868 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047869 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027870 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337871 mock_quic_data.AddRead(
7872 ASYNC, ConstructServerResponseHeadersPacket(
7873 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7874 GetResponseHeaders("500")));
7875 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7876 mock_quic_data.AddWrite(SYNCHRONOUS,
7877 ConstructClientAckAndRstPacket(
7878 3, GetNthClientInitiatedBidirectionalStreamId(0),
7879 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567880
7881 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7882
7883 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7884
7885 CreateSession();
7886
7887 request_.url = GURL("https://mail.example.org/");
7888 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7889 HeadersHandler headers_handler;
7890 trans.SetBeforeHeadersSentCallback(
7891 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7892 base::Unretained(&headers_handler)));
7893 TestCompletionCallback callback;
7894 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7895 EXPECT_EQ(ERR_IO_PENDING, rv);
7896 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
7897 EXPECT_EQ(false, headers_handler.was_proxied());
7898
7899 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7900 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7901}
7902
7903// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:147904TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:567905 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147906 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567907 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497908 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567909
Ryan Hamiltonabad59e2019-06-06 04:02:597910 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027911 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Fan Yang32c5a112018-12-10 20:06:337912 mock_quic_data.AddWrite(
7913 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7914 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047915 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027916 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:567917 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7918
7919 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7920
7921 CreateSession();
7922
7923 request_.url = GURL("https://mail.example.org/");
7924 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7925 HeadersHandler headers_handler;
7926 trans.SetBeforeHeadersSentCallback(
7927 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7928 base::Unretained(&headers_handler)));
7929 TestCompletionCallback callback;
7930 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7931 EXPECT_EQ(ERR_IO_PENDING, rv);
7932 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7933
7934 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7935 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7936}
7937
7938// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
7939// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:147940TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:567941 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147942 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567943 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497944 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567945
Ryan Hamiltonabad59e2019-06-06 04:02:597946 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027947 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Fan Yang32c5a112018-12-10 20:06:337948 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357949 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7950 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047951 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027952 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:437953 mock_quic_data.AddRead(
7954 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337955 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027956 GetResponseHeaders("200 OK")));
Renjied172e812019-01-16 05:12:357957 mock_quic_data.AddWrite(SYNCHRONOUS,
7958 ConstructClientAckAndRstPacket(
7959 3, GetNthClientInitiatedBidirectionalStreamId(0),
7960 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567961
Zhongyi Shi32f2fd02018-04-16 18:23:437962 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357963 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7964 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Matt Menke6e879bd2019-03-18 17:26:047965 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7966 ConnectRequestHeaders("mail.example.org:443"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027967 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:437968 mock_quic_data.AddRead(
7969 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337970 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027971 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567972
7973 const char get_request[] =
7974 "GET / HTTP/1.1\r\n"
7975 "Host: mail.example.org\r\n"
7976 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437977 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567978 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417979 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357980 SYNCHRONOUS,
7981 ConstructClientAckAndDataPacket(
7982 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
Ryan Hamilton7505eb92019-06-08 00:22:177983 false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417984 } else {
7985 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417986 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357987 ConstructClientAckAndMultipleDataFramesPacket(
7988 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
Ryan Hamilton7505eb92019-06-08 00:22:177989 false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417990 }
Yixin Wang46a273ec302018-01-23 17:59:567991 const char get_response[] =
7992 "HTTP/1.1 200 OK\r\n"
7993 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437994 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437995 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337996 ASYNC, ConstructServerDataPacket(
7997 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177998 header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527999
Victor Vasiliev076657c2019-03-12 02:46:438000 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338001 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418002 SYNCHRONOUS, ConstructServerDataPacket(
8003 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178004 false, header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:358005 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568006 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8007
8008 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418009 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358010 ConstructClientRstPacket(7, GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418011 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568012
8013 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8014
8015 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8016 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8017
8018 SSLSocketDataProvider ssl_data(ASYNC, OK);
8019 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8020
8021 CreateSession();
8022
8023 request_.url = GURL("https://mail.example.org/");
8024 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8025 HeadersHandler headers_handler;
8026 trans.SetBeforeHeadersSentCallback(
8027 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8028 base::Unretained(&headers_handler)));
8029 TestCompletionCallback callback;
8030 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8031 EXPECT_EQ(ERR_IO_PENDING, rv);
8032 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8033
8034 rv = trans.RestartIgnoringLastError(callback.callback());
8035 EXPECT_EQ(ERR_IO_PENDING, rv);
8036 EXPECT_EQ(OK, callback.WaitForResult());
8037
8038 CheckWasHttpResponse(&trans);
8039 CheckResponsePort(&trans, 70);
8040 CheckResponseData(&trans, "0123456789");
8041 EXPECT_EQ(true, headers_handler.was_proxied());
8042 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8043
8044 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8045 // proxy socket to disconnect.
8046 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8047
8048 base::RunLoop().RunUntilIdle();
8049 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8050 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8051}
8052
8053// Checks if a request's specified "user-agent" header shows up correctly in the
8054// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148055TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008056 const char kConfiguredUserAgent[] = "Configured User-Agent";
8057 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568058 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148059 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568060 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498061 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568062
Ryan Hamiltonabad59e2019-06-06 04:02:598063 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:028064 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Yixin Wang46a273ec302018-01-23 17:59:568065
Ryan Hamilton0239aac2018-05-19 00:03:138066 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008067 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338068 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028069 SYNCHRONOUS,
8070 ConstructClientRequestHeadersPacket(
8071 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8072 HttpProxyConnectJob::kH2QuicTunnelPriority, std::move(headers), 0));
Yixin Wang46a273ec302018-01-23 17:59:568073 // Return an error, so the transaction stops here (this test isn't interested
8074 // in the rest).
8075 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8076
8077 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8078
Matt Menked732ea42019-03-08 12:05:008079 StaticHttpUserAgentSettings http_user_agent_settings(
8080 std::string() /* accept_language */, kConfiguredUserAgent);
8081 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568082 CreateSession();
8083
8084 request_.url = GURL("https://mail.example.org/");
8085 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008086 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568087 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8088 HeadersHandler headers_handler;
8089 trans.SetBeforeHeadersSentCallback(
8090 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8091 base::Unretained(&headers_handler)));
8092 TestCompletionCallback callback;
8093 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8094 EXPECT_EQ(ERR_IO_PENDING, rv);
8095 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8096
8097 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8098 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8099}
8100
Yixin Wang00fc44c2018-01-23 21:12:208101// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8102// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148103TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208104 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148105 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208106 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498107 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208108
8109 const RequestPriority request_priority = MEDIUM;
8110
Ryan Hamiltonabad59e2019-06-06 04:02:598111 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:028112 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Zhongyi Shi32f2fd02018-04-16 18:23:438113 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048114 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8115 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8116 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:028117 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:208118 // Return an error, so the transaction stops here (this test isn't interested
8119 // in the rest).
8120 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8121
8122 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8123
8124 CreateSession();
8125
8126 request_.url = GURL("https://mail.example.org/");
8127 HttpNetworkTransaction trans(request_priority, session_.get());
8128 TestCompletionCallback callback;
8129 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8130 EXPECT_EQ(ERR_IO_PENDING, rv);
8131 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8132
8133 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8134 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8135}
8136
Matt Menkeedaf3b82019-03-14 21:39:448137// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8138// HTTP/2 stream dependency and weights given the request priority.
8139TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8140 session_params_.enable_quic = true;
8141 session_params_.enable_quic_proxies_for_https_urls = true;
8142 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8143 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8144
8145 const RequestPriority kRequestPriority = MEDIUM;
8146 const RequestPriority kRequestPriority2 = LOWEST;
8147
Ryan Hamiltonabad59e2019-06-06 04:02:598148 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:028149 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
Matt Menkeedaf3b82019-03-14 21:39:448150 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8151 // This should never be reached.
8152 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8153 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8154
8155 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:598156 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:448157 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8158 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8159
8160 int original_max_sockets_per_group =
8161 ClientSocketPoolManager::max_sockets_per_group(
8162 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8163 ClientSocketPoolManager::set_max_sockets_per_group(
8164 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8165 int original_max_sockets_per_pool =
8166 ClientSocketPoolManager::max_sockets_per_pool(
8167 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8168 ClientSocketPoolManager::set_max_sockets_per_pool(
8169 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8170 CreateSession();
8171
8172 request_.url = GURL("https://mail.example.org/");
8173 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8174 TestCompletionCallback callback;
8175 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8176 EXPECT_EQ(ERR_IO_PENDING, rv);
8177
8178 HttpRequestInfo request2;
8179 request2.url = GURL("https://mail.example.org/some/other/path/");
8180 request2.traffic_annotation =
8181 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8182
8183 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8184 TestCompletionCallback callback2;
8185 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8186 EXPECT_EQ(ERR_IO_PENDING, rv2);
8187
8188 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8189 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8190
8191 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8192
8193 ClientSocketPoolManager::set_max_sockets_per_pool(
8194 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8195 original_max_sockets_per_pool);
8196 ClientSocketPoolManager::set_max_sockets_per_group(
8197 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8198 original_max_sockets_per_group);
8199}
8200
Yixin Wang46a273ec302018-01-23 17:59:568201// Test the request-challenge-retry sequence for basic auth, over a QUIC
8202// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148203TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568204 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8205 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:568206
8207 std::unique_ptr<QuicTestPacketMaker> client_maker;
8208 std::unique_ptr<QuicTestPacketMaker> server_maker;
8209
8210 // On the second pass, the body read of the auth challenge is synchronous, so
8211 // IsConnectedAndIdle returns false. The socket should still be drained and
8212 // reused. See http://crbug.com/544255.
8213 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338214 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178215 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8216 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338217 client_headers_include_h2_stream_dependency_));
8218 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178219 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8220 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568221
8222 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148223 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568224 proxy_resolution_service_ =
8225 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498226 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568227
Ryan Hamiltonabad59e2019-06-06 04:02:598228 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528229 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568230
Zhongyi Shi32f2fd02018-04-16 18:23:438231 mock_quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028232 client_maker->MakeInitialSettingsPacket(1));
Yixin Wang46a273ec302018-01-23 17:59:568233
8234 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438235 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028236 client_maker->MakeRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338237 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
Matt Menke6e879bd2019-03-18 17:26:048238 ConvertRequestPriorityToQuicPriority(
8239 HttpProxyConnectJob::kH2QuicTunnelPriority),
Yixin Wang46a273ec302018-01-23 17:59:568240 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028241 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568242
Ryan Hamilton0239aac2018-05-19 00:03:138243 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568244 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8245 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8246 headers["content-length"] = "10";
8247 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028248 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338249 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028250 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568251
8252 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438253 mock_quic_data.AddRead(
8254 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338255 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178256 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568257 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438258 mock_quic_data.AddRead(
8259 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338260 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:178261 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568262 }
8263 server_data_offset += 10;
8264
Zhongyi Shi32f2fd02018-04-16 18:23:438265 mock_quic_data.AddWrite(SYNCHRONOUS,
8266 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568267
8268 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338269 SYNCHRONOUS,
8270 client_maker->MakeRstPacket(
8271 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418272 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:188273 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568274
8275 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8276 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8277 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048278 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028279 client_maker->MakeRequestHeadersPacket(
Matt Menke6e879bd2019-03-18 17:26:048280 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8281 ConvertRequestPriorityToQuicPriority(
8282 HttpProxyConnectJob::kH2QuicTunnelPriority),
8283 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:028284 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568285
8286 // Response to wrong password
8287 headers =
8288 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8289 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8290 headers["content-length"] = "10";
8291 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028292 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338293 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028294 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568295 mock_quic_data.AddRead(SYNCHRONOUS,
8296 ERR_IO_PENDING); // No more data to read
8297
Fan Yang32c5a112018-12-10 20:06:338298 mock_quic_data.AddWrite(
8299 SYNCHRONOUS,
8300 client_maker->MakeAckAndRstPacket(
8301 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8302 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568303
8304 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8305 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8306
8307 CreateSession();
8308
8309 request_.url = GURL("https://mail.example.org/");
8310 // Ensure that proxy authentication is attempted even
8311 // when the no authentication data flag is set.
8312 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8313 {
8314 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8315 HeadersHandler headers_handler;
8316 trans.SetBeforeHeadersSentCallback(
8317 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8318 base::Unretained(&headers_handler)));
8319 RunTransaction(&trans);
8320
8321 const HttpResponseInfo* response = trans.GetResponseInfo();
8322 ASSERT_TRUE(response != nullptr);
8323 ASSERT_TRUE(response->headers.get() != nullptr);
8324 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8325 response->headers->GetStatusLine());
8326 EXPECT_TRUE(response->headers->IsKeepAlive());
8327 EXPECT_EQ(407, response->headers->response_code());
8328 EXPECT_EQ(10, response->headers->GetContentLength());
8329 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588330 base::Optional<AuthChallengeInfo> auth_challenge =
8331 response->auth_challenge;
8332 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568333 EXPECT_TRUE(auth_challenge->is_proxy);
8334 EXPECT_EQ("https://proxy.example.org:70",
8335 auth_challenge->challenger.Serialize());
8336 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8337 EXPECT_EQ("basic", auth_challenge->scheme);
8338
8339 TestCompletionCallback callback;
8340 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8341 callback.callback());
8342 EXPECT_EQ(ERR_IO_PENDING, rv);
8343 EXPECT_EQ(OK, callback.WaitForResult());
8344
8345 response = trans.GetResponseInfo();
8346 ASSERT_TRUE(response != nullptr);
8347 ASSERT_TRUE(response->headers.get() != nullptr);
8348 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8349 response->headers->GetStatusLine());
8350 EXPECT_TRUE(response->headers->IsKeepAlive());
8351 EXPECT_EQ(407, response->headers->response_code());
8352 EXPECT_EQ(10, response->headers->GetContentLength());
8353 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588354 auth_challenge = response->auth_challenge;
8355 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568356 EXPECT_TRUE(auth_challenge->is_proxy);
8357 EXPECT_EQ("https://proxy.example.org:70",
8358 auth_challenge->challenger.Serialize());
8359 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8360 EXPECT_EQ("basic", auth_challenge->scheme);
8361 }
8362 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8363 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8364 // reused because it's not connected).
8365 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8366 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8367 }
8368}
8369
Yixin Wang385652a2018-02-16 02:37:238370TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8371 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8372 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:568373 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238374 !client_headers_include_h2_stream_dependency_) {
8375 return;
8376 }
8377
Ryan Hamiltone940bd12019-06-30 02:46:458378 if (quic::VersionUsesQpack(version_.transport_version)) {
8379 // TODO(rch): both stream_dependencies and priority frames need to be
8380 // supported in IETF QUIC.
8381 return;
8382 }
8383
Nick Harper72ade192019-07-17 03:30:428384 session_params_.quic_params.origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:238385 HostPortPair::FromString("mail.example.org:443"));
8386
Fan Yang32c5a112018-12-10 20:06:338387 const quic::QuicStreamId client_stream_0 =
8388 GetNthClientInitiatedBidirectionalStreamId(0);
8389 const quic::QuicStreamId client_stream_1 =
8390 GetNthClientInitiatedBidirectionalStreamId(1);
8391 const quic::QuicStreamId client_stream_2 =
8392 GetNthClientInitiatedBidirectionalStreamId(2);
8393 const quic::QuicStreamId push_stream_0 =
8394 GetNthServerInitiatedUnidirectionalStreamId(0);
8395 const quic::QuicStreamId push_stream_1 =
8396 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238397
Ryan Hamiltonabad59e2019-06-06 04:02:598398 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:028399 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Yixin Wang385652a2018-02-16 02:37:238400
8401 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438402 mock_quic_data.AddWrite(SYNCHRONOUS,
8403 ConstructClientRequestHeadersPacket(
8404 2, client_stream_0, true, true, HIGHEST,
Ryan Hamilton0d65a8c2019-06-07 00:46:028405 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
8406 mock_quic_data.AddWrite(
8407 SYNCHRONOUS,
8408 ConstructClientRequestHeadersPacket(
8409 3, client_stream_1, true, true, MEDIUM,
8410 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
8411 mock_quic_data.AddWrite(
8412 SYNCHRONOUS,
8413 ConstructClientRequestHeadersPacket(
8414 4, client_stream_2, true, true, MEDIUM,
8415 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:238416
8417 // Server replies "OK" for the three requests.
Ryan Hamilton0d65a8c2019-06-07 00:46:028418 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8419 1, client_stream_0, false, false,
8420 GetResponseHeaders("200 OK")));
8421 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8422 2, client_stream_1, false, false,
8423 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:438424 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
Ryan Hamilton0d65a8c2019-06-07 00:46:028425 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8426 3, client_stream_2, false, false,
8427 GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:238428
8429 // Server sends two push promises associated with |client_stream_0|; client
8430 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8431 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:028432 mock_quic_data.AddRead(
8433 ASYNC,
8434 ConstructServerPushPromisePacket(
8435 4, client_stream_0, push_stream_0, false,
8436 GetRequestHeaders("GET", "https", "/pushed_0.jpg"), &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238437 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438438 SYNCHRONOUS,
8439 ConstructClientAckAndPriorityFramesPacket(
8440 6, false, 4, 3, 1,
8441 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:028442 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
8443 mock_quic_data.AddRead(
8444 ASYNC,
8445 ConstructServerPushPromisePacket(
8446 5, client_stream_0, push_stream_1, false,
8447 GetRequestHeaders("GET", "https", "/pushed_1.jpg"), &server_maker_));
8448 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientPriorityPacket(
8449 7, false, push_stream_1,
8450 push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:238451
8452 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438453 mock_quic_data.AddRead(
8454 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:028455 6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:438456 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8457 mock_quic_data.AddRead(
8458 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:028459 7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:238460
8461 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8462 // priority updates to match the request's priority. Client sends PRIORITY
8463 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438464 mock_quic_data.AddWrite(
8465 SYNCHRONOUS,
8466 ConstructClientAckAndPriorityFramesPacket(
8467 9, false, 7, 7, 1,
8468 {{push_stream_1, client_stream_2,
8469 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8470 {push_stream_0, client_stream_0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028471 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:238472
8473 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:438474 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438475 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178476 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Renjief49758b2019-01-11 23:32:418477 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438478 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178479 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Renjief49758b2019-01-11 23:32:418480 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438481 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8482 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178483 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Renjief49758b2019-01-11 23:32:418484 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:438485 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438486 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178487 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true,
Renjief49758b2019-01-11 23:32:418488 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438489 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8490 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178491 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Renjief49758b2019-01-11 23:32:418492 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238493
Yixin Wang385652a2018-02-16 02:37:238494 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8495 mock_quic_data.AddRead(ASYNC, 0); // EOF
8496 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8497
8498 // The non-alternate protocol job needs to hang in order to guarantee that
8499 // the alternate-protocol job will "win".
8500 AddHangingNonAlternateProtocolSocketData();
8501
8502 CreateSession();
8503
8504 request_.url = GURL("https://mail.example.org/0.jpg");
8505 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8506 TestCompletionCallback callback_0;
8507 EXPECT_EQ(ERR_IO_PENDING,
8508 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8509 base::RunLoop().RunUntilIdle();
8510
8511 request_.url = GURL("https://mail.example.org/1.jpg");
8512 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8513 TestCompletionCallback callback_1;
8514 EXPECT_EQ(ERR_IO_PENDING,
8515 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8516 base::RunLoop().RunUntilIdle();
8517
8518 request_.url = GURL("https://mail.example.org/2.jpg");
8519 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8520 TestCompletionCallback callback_2;
8521 EXPECT_EQ(ERR_IO_PENDING,
8522 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8523 base::RunLoop().RunUntilIdle();
8524
8525 // Client makes request that matches resource pushed in |pushed_stream_0|.
8526 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8527 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8528 TestCompletionCallback callback_3;
8529 EXPECT_EQ(ERR_IO_PENDING,
8530 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8531 base::RunLoop().RunUntilIdle();
8532
8533 EXPECT_TRUE(callback_0.have_result());
8534 EXPECT_EQ(OK, callback_0.WaitForResult());
8535 EXPECT_TRUE(callback_1.have_result());
8536 EXPECT_EQ(OK, callback_1.WaitForResult());
8537 EXPECT_TRUE(callback_2.have_result());
8538 EXPECT_EQ(OK, callback_2.WaitForResult());
8539
8540 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8541 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8542 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8543 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8544
8545 mock_quic_data.Resume();
8546 base::RunLoop().RunUntilIdle();
8547 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8548 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8549}
8550
Matt Menke26e41542019-06-05 01:09:518551// Test that NetworkIsolationKey is respected by QUIC connections, when
8552// kPartitionConnectionsByNetworkIsolationKey is enabled.
8553TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Shivani Sharma8ae506c2019-07-21 21:08:278554 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
8555 const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
8556 NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
8557 NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
Matt Menke26e41542019-06-05 01:09:518558
Nick Harper72ade192019-07-17 03:30:428559 session_params_.quic_params.origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:518560 HostPortPair::FromString("mail.example.org:443"));
8561
8562 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
8563 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
8564 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
8565 // the same way as the HTTP over H2 proxy case.
8566 for (bool use_proxy : {false, true}) {
8567 SCOPED_TRACE(use_proxy);
8568
8569 if (use_proxy) {
8570 proxy_resolution_service_ =
8571 ProxyResolutionService::CreateFixedFromPacResult(
8572 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
8573 } else {
8574 proxy_resolution_service_ = ProxyResolutionService::CreateDirect();
8575 }
8576
8577 GURL url1;
8578 GURL url2;
8579 GURL url3;
8580 if (use_proxy) {
8581 url1 = GURL("http://mail.example.org/1");
8582 url2 = GURL("http://mail.example.org/2");
8583 url3 = GURL("http://mail.example.org/3");
8584 } else {
8585 url1 = GURL("https://mail.example.org/1");
8586 url2 = GURL("https://mail.example.org/2");
8587 url3 = GURL("https://mail.example.org/3");
8588 }
8589
8590 for (bool partition_connections : {false, true}) {
8591 SCOPED_TRACE(partition_connections);
8592
8593 base::test::ScopedFeatureList feature_list;
8594 if (partition_connections) {
8595 feature_list.InitAndEnableFeature(
8596 features::kPartitionConnectionsByNetworkIsolationKey);
8597 } else {
8598 feature_list.InitAndDisableFeature(
8599 features::kPartitionConnectionsByNetworkIsolationKey);
8600 }
8601
8602 // Reads and writes for the unpartitioned case, where only one socket is
8603 // used.
8604
Nick Harper72ade192019-07-17 03:30:428605 session_params_.quic_params.origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:518606 HostPortPair::FromString("mail.example.org:443"));
8607
Ryan Hamiltonabad59e2019-06-06 04:02:598608 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:518609 QuicTestPacketMaker client_maker1(
8610 version_,
8611 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8612 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8613 client_headers_include_h2_stream_dependency_);
8614 QuicTestPacketMaker server_maker1(
8615 version_,
8616 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8617 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8618
8619 unpartitioned_mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028620 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(1));
Matt Menke26e41542019-06-05 01:09:518621
8622 unpartitioned_mock_quic_data.AddWrite(
8623 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028624 client_maker1.MakeRequestHeadersPacket(
Matt Menke26e41542019-06-05 01:09:518625 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
8626 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028627 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518628 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028629 ASYNC, server_maker1.MakeResponseHeadersPacket(
8630 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8631 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518632 unpartitioned_mock_quic_data.AddRead(
8633 ASYNC, server_maker1.MakeDataPacket(
8634 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178635 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:518636 unpartitioned_mock_quic_data.AddWrite(
8637 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
8638
8639 unpartitioned_mock_quic_data.AddWrite(
8640 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028641 client_maker1.MakeRequestHeadersPacket(
Matt Menke26e41542019-06-05 01:09:518642 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
8643 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028644 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518645 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028646 ASYNC, server_maker1.MakeResponseHeadersPacket(
8647 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8648 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518649 unpartitioned_mock_quic_data.AddRead(
8650 ASYNC, server_maker1.MakeDataPacket(
8651 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178652 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:518653 unpartitioned_mock_quic_data.AddWrite(
8654 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
8655
8656 unpartitioned_mock_quic_data.AddWrite(
8657 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028658 client_maker1.MakeRequestHeadersPacket(
Matt Menke26e41542019-06-05 01:09:518659 6, GetNthClientInitiatedBidirectionalStreamId(2), false, true,
8660 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028661 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518662 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028663 ASYNC, server_maker1.MakeResponseHeadersPacket(
8664 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
8665 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518666 unpartitioned_mock_quic_data.AddRead(
8667 ASYNC, server_maker1.MakeDataPacket(
8668 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Ryan Hamilton7505eb92019-06-08 00:22:178669 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:518670 unpartitioned_mock_quic_data.AddWrite(
8671 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(7, 6, 5, 1));
8672
8673 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8674
8675 // Reads and writes for the partitioned case, where two sockets are used.
8676
Ryan Hamiltonabad59e2019-06-06 04:02:598677 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:518678 QuicTestPacketMaker client_maker2(
8679 version_,
8680 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8681 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8682 client_headers_include_h2_stream_dependency_);
8683 QuicTestPacketMaker server_maker2(
8684 version_,
8685 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8686 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8687
8688 partitioned_mock_quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028689 SYNCHRONOUS, client_maker2.MakeInitialSettingsPacket(1));
Matt Menke26e41542019-06-05 01:09:518690
8691 partitioned_mock_quic_data1.AddWrite(
8692 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028693 client_maker2.MakeRequestHeadersPacket(
Matt Menke26e41542019-06-05 01:09:518694 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
8695 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028696 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518697 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028698 ASYNC, server_maker2.MakeResponseHeadersPacket(
8699 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8700 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518701 partitioned_mock_quic_data1.AddRead(
8702 ASYNC, server_maker2.MakeDataPacket(
8703 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178704 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:518705 partitioned_mock_quic_data1.AddWrite(
8706 SYNCHRONOUS, client_maker2.MakeAckPacket(3, 2, 1, 1, true));
8707
8708 partitioned_mock_quic_data1.AddWrite(
8709 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028710 client_maker2.MakeRequestHeadersPacket(
Matt Menke26e41542019-06-05 01:09:518711 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
8712 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028713 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518714 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028715 ASYNC, server_maker2.MakeResponseHeadersPacket(
8716 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8717 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518718 partitioned_mock_quic_data1.AddRead(
8719 ASYNC, server_maker2.MakeDataPacket(
8720 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178721 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:518722 partitioned_mock_quic_data1.AddWrite(
8723 SYNCHRONOUS, client_maker2.MakeAckPacket(5, 4, 3, 1, true));
8724
8725 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8726
Ryan Hamiltonabad59e2019-06-06 04:02:598727 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:518728 QuicTestPacketMaker client_maker3(
8729 version_,
8730 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8731 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8732 client_headers_include_h2_stream_dependency_);
8733 QuicTestPacketMaker server_maker3(
8734 version_,
8735 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8736 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8737
8738 partitioned_mock_quic_data2.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028739 SYNCHRONOUS, client_maker3.MakeInitialSettingsPacket(1));
Matt Menke26e41542019-06-05 01:09:518740
8741 partitioned_mock_quic_data2.AddWrite(
8742 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028743 client_maker3.MakeRequestHeadersPacket(
Matt Menke26e41542019-06-05 01:09:518744 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
8745 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028746 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518747 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028748 ASYNC, server_maker3.MakeResponseHeadersPacket(
8749 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8750 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518751 partitioned_mock_quic_data2.AddRead(
8752 ASYNC, server_maker3.MakeDataPacket(
8753 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178754 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:518755 partitioned_mock_quic_data2.AddWrite(
8756 SYNCHRONOUS, client_maker3.MakeAckPacket(3, 2, 1, 1, true));
8757
8758 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8759
8760 if (partition_connections) {
8761 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
8762 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8763 } else {
8764 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8765 }
8766
8767 CreateSession();
8768
8769 TestCompletionCallback callback;
8770 HttpRequestInfo request1;
8771 request1.method = "GET";
8772 request1.url = GURL(url1);
8773 request1.traffic_annotation =
8774 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8775 request1.network_isolation_key = network_isolation_key1;
8776 HttpNetworkTransaction trans1(LOWEST, session_.get());
8777 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
8778 EXPECT_THAT(callback.GetResult(rv), IsOk());
8779 std::string response_data1;
8780 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
8781 EXPECT_EQ("1", response_data1);
8782
8783 HttpRequestInfo request2;
8784 request2.method = "GET";
8785 request2.url = GURL(url2);
8786 request2.traffic_annotation =
8787 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8788 request2.network_isolation_key = network_isolation_key2;
8789 HttpNetworkTransaction trans2(LOWEST, session_.get());
8790 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
8791 EXPECT_THAT(callback.GetResult(rv), IsOk());
8792 std::string response_data2;
8793 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
8794 EXPECT_EQ("2", response_data2);
8795
8796 HttpRequestInfo request3;
8797 request3.method = "GET";
8798 request3.url = GURL(url3);
8799 request3.traffic_annotation =
8800 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8801 request3.network_isolation_key = network_isolation_key1;
8802 HttpNetworkTransaction trans3(LOWEST, session_.get());
8803 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
8804 EXPECT_THAT(callback.GetResult(rv), IsOk());
8805 std::string response_data3;
8806 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
8807 EXPECT_EQ("3", response_data3);
8808
8809 if (partition_connections) {
8810 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
8811 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
8812 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
8813 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
8814 } else {
8815 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
8816 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
8817 }
8818 }
8819 }
8820}
8821
8822// Test that two requests to the same origin over QUIC tunnels use different
8823// QUIC sessions if their NetworkIsolationKeys don't match, and
8824// kPartitionConnectionsByNetworkIsolationKey is enabled.
8825TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
8826 base::test::ScopedFeatureList feature_list;
8827 feature_list.InitAndEnableFeature(
8828 features::kPartitionConnectionsByNetworkIsolationKey);
8829
8830 session_params_.enable_quic = true;
8831 session_params_.enable_quic_proxies_for_https_urls = true;
8832 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8833 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8834
8835 const char kGetRequest[] =
8836 "GET / HTTP/1.1\r\n"
8837 "Host: mail.example.org\r\n"
8838 "Connection: keep-alive\r\n\r\n";
8839 const char kGetResponse[] =
8840 "HTTP/1.1 200 OK\r\n"
8841 "Content-Length: 10\r\n\r\n";
8842
Ryan Hamiltonabad59e2019-06-06 04:02:598843 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
8844 std::make_unique<MockQuicData>(version_),
8845 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:518846
8847 for (int index : {0, 1}) {
8848 QuicTestPacketMaker client_maker(
8849 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8850 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8851 client_headers_include_h2_stream_dependency_);
8852 QuicTestPacketMaker server_maker(
8853 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8854 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8855
Ryan Hamilton0d65a8c2019-06-07 00:46:028856 mock_quic_data[index]->AddWrite(SYNCHRONOUS,
8857 client_maker.MakeInitialSettingsPacket(1));
Matt Menke26e41542019-06-05 01:09:518858
Ryan Hamiltonabad59e2019-06-06 04:02:598859 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:518860 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028861 client_maker.MakeRequestHeadersPacket(
Matt Menke26e41542019-06-05 01:09:518862 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8863 ConvertRequestPriorityToQuicPriority(
8864 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:028865 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:598866 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028867 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:518868 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8869 false, GetResponseHeaders("200 OK"), nullptr));
8870
8871 std::string header = ConstructDataHeader(strlen(kGetRequest));
8872 if (version_.transport_version != quic::QUIC_VERSION_99) {
Ryan Hamiltonabad59e2019-06-06 04:02:598873 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:518874 SYNCHRONOUS,
8875 client_maker.MakeAckAndDataPacket(
8876 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Ryan Hamilton7505eb92019-06-08 00:22:178877 false, quic::QuicStringPiece(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:518878 } else {
Ryan Hamiltonabad59e2019-06-06 04:02:598879 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:518880 SYNCHRONOUS,
8881 client_maker.MakeAckAndMultipleDataFramesPacket(
8882 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Ryan Hamilton7505eb92019-06-08 00:22:178883 false, {header, std::string(kGetRequest)}));
Matt Menke26e41542019-06-05 01:09:518884 }
8885
8886 std::string header2 = ConstructDataHeader(strlen(kGetResponse));
Ryan Hamiltonabad59e2019-06-06 04:02:598887 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:518888 ASYNC, server_maker.MakeDataPacket(
8889 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178890 false, header2 + std::string(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:598891 mock_quic_data[index]->AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178892 SYNCHRONOUS,
8893 server_maker.MakeDataPacket(
8894 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8895 ConstructDataHeader(10) + std::string("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:598896 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:518897 SYNCHRONOUS, client_maker.MakeAckPacket(4, 3, 2, 1, true));
Ryan Hamiltonabad59e2019-06-06 04:02:598898 mock_quic_data[index]->AddRead(SYNCHRONOUS,
8899 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:518900
Ryan Hamiltonabad59e2019-06-06 04:02:598901 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:518902 }
8903
8904 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8905 SSLSocketDataProvider ssl_data2(ASYNC, OK);
8906 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
8907
8908 CreateSession();
8909
8910 request_.url = GURL("https://mail.example.org/");
8911 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
8912 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8913 RunTransaction(&trans);
8914 CheckResponseData(&trans, "0123456789");
8915
8916 HttpRequestInfo request2;
Shivani Sharma8ae506c2019-07-21 21:08:278917 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
8918 request_.network_isolation_key = NetworkIsolationKey(kOrigin1, kOrigin1);
Matt Menke26e41542019-06-05 01:09:518919 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8920 RunTransaction(&trans2);
8921 CheckResponseData(&trans2, "0123456789");
8922
Ryan Hamiltonabad59e2019-06-06 04:02:598923 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
8924 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
8925 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
8926 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:518927}
8928
[email protected]61a527782013-02-21 03:58:008929} // namespace test
8930} // namespace net