blob: c435912a4d90af4afbacf310c12cd61349995689 [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(
Matt Menkeb32ba5122019-09-10 19:17:05773 MockCryptoClientStream::HandshakeMode handshake_mode,
774 const NetworkIsolationKey& network_isolation_key =
775 NetworkIsolationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19776 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46777 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21778 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12779 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49780 http_server_properties_->SetQuicAlternativeService(
Matt Menkeb32ba5122019-09-10 19:17:05781 server, network_isolation_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07782 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19783 }
784
rchbe69cb902016-02-11 01:10:48785 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27786 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48787 const HostPortPair& alternative) {
788 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46789 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21790 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48791 alternative.port());
792 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49793 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07794 server, NetworkIsolationKey(), alternative_service, expiration,
795 supported_versions_);
rchbe69cb902016-02-11 01:10:48796 }
797
Matt Menkeb32ba5122019-09-10 19:17:05798 void ExpectBrokenAlternateProtocolMapping(
799 const NetworkIsolationKey& network_isolation_key =
800 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46801 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34802 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49803 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05804 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34805 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49806 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05807 alternative_service_info_vector[0].alternative_service(),
808 network_isolation_key));
[email protected]aa9b14d2013-05-10 23:45:19809 }
810
Matt Menkeb32ba5122019-09-10 19:17:05811 void ExpectQuicAlternateProtocolMapping(
812 const NetworkIsolationKey& network_isolation_key =
813 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46814 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34815 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49816 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05817 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34818 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54819 EXPECT_EQ(
820 kProtoQUIC,
821 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49822 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05823 alternative_service_info_vector[0].alternative_service(),
824 network_isolation_key));
[email protected]4d590c9c2014-05-02 05:14:33825 }
826
[email protected]aa9b14d2013-05-10 23:45:19827 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42828 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30829 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30830 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30831 hanging_data->set_connect_data(hanging_connect);
832 hanging_data_.push_back(std::move(hanging_data));
833 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56834 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19835 }
836
Zhongyi Shia6b68d112018-09-24 07:49:03837 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Nick Harper72ade192019-07-17 03:30:42838 session_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
839 session_params_.quic_params.migrate_sessions_early_v2 = true;
840 session_params_.quic_params.retry_on_alternate_network_before_handshake =
841 true;
Zhongyi Shia6b68d112018-09-24 07:49:03842 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
843 MockNetworkChangeNotifier* mock_ncn =
844 scoped_mock_change_notifier_->mock_network_change_notifier();
845 mock_ncn->ForceNetworkHandlesSupported();
846 mock_ncn->SetConnectedNetworksList(
847 {kDefaultNetworkForTests, kNewNetworkForTests});
848 }
849
tbansalc3308d72016-08-27 10:25:04850 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
851 // alternative proxy. Verifies that if the alternative proxy job returns
852 // |error_code|, the request is fetched successfully by the main job.
853 void TestAlternativeProxy(int error_code) {
854 // Use a non-cryptographic scheme for the request URL since this request
855 // will be fetched via proxy with QUIC as the alternative service.
856 request_.url = GURL("http://example.org/");
857 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27858 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04859 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27860 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04861 };
862
Ryan Sleevib8d7ea02018-05-07 20:01:01863 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04864 socket_factory_.AddSocketDataProvider(&quic_data);
865
866 // Main job succeeds and the alternative job fails.
867 // Add data for two requests that will be read by the main job.
868 MockRead http_reads_1[] = {
869 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
870 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
871 MockRead(ASYNC, OK)};
872
873 MockRead http_reads_2[] = {
874 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
875 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
876 MockRead(ASYNC, OK)};
877
Ryan Sleevib8d7ea02018-05-07 20:01:01878 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
879 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04880 socket_factory_.AddSocketDataProvider(&http_data_1);
881 socket_factory_.AddSocketDataProvider(&http_data_2);
882 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
883 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
884
885 TestProxyDelegate test_proxy_delegate;
886 // Proxy URL is different from the request URL.
887 test_proxy_delegate.set_alternative_proxy_server(
888 ProxyServer::FromPacString("QUIC myproxy.org:443"));
889
Lily Houghton8c2f97d2018-01-22 05:06:59890 proxy_resolution_service_ =
891 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49892 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52893 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04894
895 CreateSession();
896 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
897
898 // The first request should be fetched via the HTTPS proxy.
899 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
900
Reilly Grant89a7e512018-01-20 01:57:16901 // Since the main job succeeded only the alternative proxy server should be
902 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59903 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16904 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04905
906 // Verify that the second request completes successfully, and the
907 // alternative proxy server job is not started.
908 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
909 }
910
Matt Menkeb32ba5122019-09-10 19:17:05911 // Adds a new socket data provider for an HTTP request, and runs a request,
912 // expecting it to be used.
913 void AddHttpDataAndRunRequest() {
914 MockWrite http_writes[] = {
915 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
916 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
917 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
918
919 MockRead http_reads[] = {
920 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
921 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
922 MockRead(SYNCHRONOUS, 5, "http used"),
923 // Connection closed.
924 MockRead(SYNCHRONOUS, OK, 6)};
925 SequencedSocketData http_data(http_reads, http_writes);
926 socket_factory_.AddSocketDataProvider(&http_data);
927 SSLSocketDataProvider ssl_data(ASYNC, OK);
928 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
929 SendRequestAndExpectHttpResponse("http used");
930 EXPECT_TRUE(http_data.AllWriteDataConsumed());
931 EXPECT_TRUE(http_data.AllReadDataConsumed());
932 }
933
934 // Adds a new socket data provider for a QUIC request, and runs a request,
935 // expecting it to be used. The new QUIC session is not closed.
936 void AddQuicDataAndRunRequest() {
937 QuicTestPacketMaker client_maker(
938 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
939 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
940 client_headers_include_h2_stream_dependency_);
941 QuicTestPacketMaker server_maker(
942 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
943 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
944 MockQuicData quic_data(version_);
945 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
946 quic_data.AddWrite(
947 SYNCHRONOUS,
948 client_maker.MakeRequestHeadersPacket(
949 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
950 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
951 GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
952 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
953 quic_data.AddRead(
954 ASYNC, server_maker.MakeResponseHeadersPacket(
955 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
956 false, server_maker.GetResponseHeaders("200 OK"), nullptr));
957 std::string header = ConstructDataHeader(9);
958 quic_data.AddRead(
959 ASYNC, server_maker.MakeDataPacket(
960 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
961 true, header + "quic used"));
962 // Don't care about the final ack.
963 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
964 // No more data to read.
965 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
966 quic_data.AddSocketDataToFactory(&socket_factory_);
967 SendRequestAndExpectQuicResponse("quic used");
968
969 EXPECT_TRUE(quic_data.AllReadDataConsumed());
970 }
971
Fan Yang32c5a112018-12-10 20:06:33972 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56973 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
974 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36975 }
976
Fan Yang32c5a112018-12-10 20:06:33977 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56978 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
979 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36980 }
981
Bence Béky230ac612017-08-30 19:17:08982 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49983 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08984 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49985 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08986 }
987
Nick Harper23290b82019-05-02 00:02:56988 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05989 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:56990 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01991 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52992 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:17993 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:58994 QuicTestPacketMaker client_maker_;
995 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:09996 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:42997 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00998 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56999 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:051000 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:431001 MockHostResolver host_resolver_;
1002 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:111003 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:421004 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:231005 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:381006 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:071007 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:591008 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:421009 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:491010 std::unique_ptr<HttpServerProperties> http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:411011 HttpNetworkSession::Params session_params_;
1012 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:191013 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:511014 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:421015 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:561016 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:031017 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:121018
1019 private:
1020 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1021 const std::string& expected,
bnc62a44f022015-04-02 15:59:411022 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:461023 uint16_t port) {
bnc691fda62016-08-12 00:43:161024 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:091025 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:161026 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091027 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
1028 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:161029 RunTransaction(&trans);
1030 CheckWasQuicResponse(&trans);
1031 CheckResponsePort(&trans, port);
1032 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:091033 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:471034 if (used_proxy) {
1035 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
1036 } else {
1037 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1038 }
tbansal7cec3812015-02-05 21:25:121039 }
[email protected]61a527782013-02-21 03:58:001040};
1041
Ryan Hamiltone940bd12019-06-30 02:46:451042quic::ParsedQuicVersionVector AllSupportedVersionsWithoutTls() {
1043 quic::ParsedQuicVersionVector versions;
Ryan Hamilton93424eb82019-08-23 04:28:401044 for (auto version : quic::AllSupportedVersions()) {
Ryan Hamiltone940bd12019-06-30 02:46:451045 // TODO(rch): crbug.com/978745 - Make this work with TLS
1046 if (version.handshake_protocol != quic::PROTOCOL_TLS1_3) {
1047 versions.push_back(version);
1048 }
1049 }
1050 return versions;
1051}
1052
Victor Costane635086f2019-01-27 05:20:301053INSTANTIATE_TEST_SUITE_P(
Yixin Wang385652a2018-02-16 02:37:231054 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051055 QuicNetworkTransactionTest,
Ryan Hamiltone940bd12019-06-30 02:46:451056 ::testing::Combine(::testing::ValuesIn(AllSupportedVersionsWithoutTls()),
Nick Harper23290b82019-05-02 00:02:561057 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:201058
Shivani Sharma8ae506c2019-07-21 21:08:271059// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
1060// kAppendInitiatingFrameOriginToNetworkIsolationKey.
1061
Ryan Hamiltona64a5bcf2017-11-30 07:35:281062TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:421063 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281064 base::HistogramTester histograms;
Nick Harper72ade192019-07-17 03:30:421065 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281066 HostPortPair::FromString("mail.example.org:443"));
1067 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271068 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281069
Ryan Hamiltonabad59e2019-06-06 04:02:591070 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231071 if (VersionUsesQpack(version_.transport_version))
1072 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281073 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1074 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1075 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1076
1077 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1078
1079 CreateSession();
1080
1081 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1082 TestCompletionCallback callback;
1083 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1085 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1086
1087 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1088 -ERR_INTERNET_DISCONNECTED, 1);
1089 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1090 -ERR_INTERNET_DISCONNECTED, 1);
1091}
1092
1093TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Nick Harper72ade192019-07-17 03:30:421094 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281095 base::HistogramTester histograms;
Nick Harper72ade192019-07-17 03:30:421096 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281097 HostPortPair::FromString("mail.example.org:443"));
1098 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271099 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281100
Ryan Hamiltonabad59e2019-06-06 04:02:591101 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231102 if (VersionUsesQpack(version_.transport_version))
1103 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281104 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1105 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1106 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1107
1108 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1109
1110 CreateSession();
1111
1112 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1113 TestCompletionCallback callback;
1114 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1115 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1116 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1117
1118 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1119 -ERR_INTERNET_DISCONNECTED, 1);
1120 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1121 -ERR_INTERNET_DISCONNECTED, 1);
1122}
1123
tbansal180587c2017-02-16 15:13:231124TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Nick Harper72ade192019-07-17 03:30:421125 session_params_.quic_params.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231126 HostPortPair::FromString("mail.example.org:443"));
1127
Ryan Hamiltonabad59e2019-06-06 04:02:591128 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231129 int packet_num = 1;
1130 if (VersionUsesQpack(version_.transport_version)) {
1131 mock_quic_data.AddWrite(SYNCHRONOUS,
1132 ConstructInitialSettingsPacket(packet_num++));
1133 }
rch5cb522462017-04-25 20:18:361134 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231135 SYNCHRONOUS,
1136 ConstructClientRequestHeadersPacket(
1137 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1138 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431139 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331140 ASYNC, ConstructServerResponseHeadersPacket(
1141 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1142 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431143 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331144 mock_quic_data.AddRead(
1145 ASYNC, ConstructServerDataPacket(
1146 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171147 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231148 mock_quic_data.AddWrite(SYNCHRONOUS,
1149 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231150 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1151
1152 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1153
1154 CreateSession();
1155 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1156
1157 EXPECT_FALSE(
1158 test_socket_performance_watcher_factory_.rtt_notification_received());
1159 SendRequestAndExpectQuicResponse("hello!");
1160 EXPECT_TRUE(
1161 test_socket_performance_watcher_factory_.rtt_notification_received());
1162}
1163
1164TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Nick Harper72ade192019-07-17 03:30:421165 session_params_.quic_params.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231166 HostPortPair::FromString("mail.example.org:443"));
1167
Ryan Hamiltonabad59e2019-06-06 04:02:591168 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231169 int packet_num = 1;
1170 if (VersionUsesQpack(version_.transport_version)) {
1171 mock_quic_data.AddWrite(SYNCHRONOUS,
1172 ConstructInitialSettingsPacket(packet_num++));
1173 }
rch5cb522462017-04-25 20:18:361174 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231175 SYNCHRONOUS,
1176 ConstructClientRequestHeadersPacket(
1177 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1178 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431179 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331180 ASYNC, ConstructServerResponseHeadersPacket(
1181 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1182 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431183 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331184 mock_quic_data.AddRead(
1185 ASYNC, ConstructServerDataPacket(
1186 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171187 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231188 mock_quic_data.AddWrite(SYNCHRONOUS,
1189 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231190 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1191
1192 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1193
1194 CreateSession();
1195 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1196
1197 EXPECT_FALSE(
1198 test_socket_performance_watcher_factory_.rtt_notification_received());
1199 SendRequestAndExpectQuicResponse("hello!");
1200 EXPECT_FALSE(
1201 test_socket_performance_watcher_factory_.rtt_notification_received());
1202}
1203
[email protected]1e960032013-12-20 19:00:201204TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Nick Harper72ade192019-07-17 03:30:421205 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571206 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471207
Ryan Hamiltonabad59e2019-06-06 04:02:591208 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231209 int packet_num = 1;
1210 if (VersionUsesQpack(version_.transport_version)) {
1211 mock_quic_data.AddWrite(SYNCHRONOUS,
1212 ConstructInitialSettingsPacket(packet_num++));
1213 }
rch5cb522462017-04-25 20:18:361214 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231215 SYNCHRONOUS,
1216 ConstructClientRequestHeadersPacket(
1217 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1218 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431219 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331220 ASYNC, ConstructServerResponseHeadersPacket(
1221 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1222 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431223 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331224 mock_quic_data.AddRead(
1225 ASYNC, ConstructServerDataPacket(
1226 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171227 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231228 mock_quic_data.AddWrite(SYNCHRONOUS,
1229 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591230 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471231
rcha5399e02015-04-21 19:32:041232 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471233
[email protected]4dca587c2013-03-07 16:54:471234 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471235
[email protected]aa9b14d2013-05-10 23:45:191236 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471237
[email protected]98b20ce2013-05-10 05:55:261238 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:541239 auto entries = net_log_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261240 EXPECT_LT(0u, entries.size());
1241
1242 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291243 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001244 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1245 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261246 EXPECT_LT(0, pos);
1247
rchfd527212015-08-25 00:41:261248 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291249 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261250 entries, 0,
mikecirone8b85c432016-09-08 19:11:001251 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1252 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261253 EXPECT_LT(0, pos);
1254
Eric Roman79cc7552019-07-19 02:17:541255 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261256
rchfd527212015-08-25 00:41:261257 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1258 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001259 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1260 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261261 EXPECT_LT(0, pos);
1262
[email protected]98b20ce2013-05-10 05:55:261263 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291264 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001265 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1266 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261267 EXPECT_LT(0, pos);
1268
Eric Roman79cc7552019-07-19 02:17:541269 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Ryan Hamiltone940bd12019-06-30 02:46:451270 if (quic::VersionUsesQpack(version_.transport_version)) {
1271 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1272 static_cast<quic::QuicStreamId>(log_stream_id));
1273 } else {
1274 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1275 static_cast<quic::QuicStreamId>(log_stream_id));
1276 }
[email protected]4dca587c2013-03-07 16:54:471277}
1278
rchbd089ab2017-05-26 23:05:041279TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Ryan Hamiltone940bd12019-06-30 02:46:451280 // TODO(rch): honor the max header list size. b/136108828
1281 if (quic::VersionUsesQpack(version_.transport_version))
1282 return;
1283
Nick Harper72ade192019-07-17 03:30:421284 session_params_.quic_params.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041285 HostPortPair::FromString("mail.example.org:443"));
1286
Ryan Hamiltonabad59e2019-06-06 04:02:591287 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231288 int packet_num = 1;
1289 if (VersionUsesQpack(version_.transport_version)) {
1290 mock_quic_data.AddWrite(SYNCHRONOUS,
1291 ConstructInitialSettingsPacket(packet_num++));
1292 }
rchbd089ab2017-05-26 23:05:041293 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231294 SYNCHRONOUS,
1295 ConstructClientRequestHeadersPacket(
1296 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1297 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0239aac2018-05-19 00:03:131298 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041299 response_headers["key1"] = std::string(30000, 'A');
1300 response_headers["key2"] = std::string(30000, 'A');
1301 response_headers["key3"] = std::string(30000, 'A');
1302 response_headers["key4"] = std::string(30000, 'A');
1303 response_headers["key5"] = std::string(30000, 'A');
1304 response_headers["key6"] = std::string(30000, 'A');
1305 response_headers["key7"] = std::string(30000, 'A');
1306 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451307 quic::QuicStreamId stream_id;
1308 std::string response_data;
1309 if (quic::VersionUsesQpack(version_.transport_version)) {
1310 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1311 std::vector<std::string> encoded = server_maker_.QpackEncodeHeaders(
1312 stream_id, std::move(response_headers), nullptr);
1313 for (const auto& e : encoded) {
1314 response_data += e;
1315 }
1316 } else {
1317 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1318 spdy::SpdyHeadersIR headers_frame(
1319 GetNthClientInitiatedBidirectionalStreamId(0),
1320 std::move(response_headers));
1321 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1322 spdy::SpdySerializedFrame spdy_frame =
1323 response_framer.SerializeFrame(headers_frame);
1324 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1325 }
rchbd089ab2017-05-26 23:05:041326
Fan Yangac867502019-01-28 21:10:231327 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041328 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451329 for (size_t offset = 0; offset < response_data.length();
1330 offset += chunk_size) {
1331 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431332 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451333 ASYNC, ConstructServerDataPacket(
1334 packet_number++, stream_id, false, false,
1335 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041336 }
1337
Victor Vasiliev076657c2019-03-12 02:46:431338 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041339 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331340 ASYNC, ConstructServerDataPacket(
1341 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171342 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041343 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431344 mock_quic_data.AddWrite(ASYNC,
Renjie Tangaadb84b2019-08-31 01:00:231345 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1346 mock_quic_data.AddWrite(
1347 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041348
1349 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1350
1351 CreateSession();
1352
1353 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421354 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1355 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041356}
1357
1358TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Nick Harper72ade192019-07-17 03:30:421359 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
1360 session_params_.quic_params.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041361 HostPortPair::FromString("mail.example.org:443"));
1362
Ryan Hamiltonabad59e2019-06-06 04:02:591363 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231364 int packet_num = 1;
1365 if (VersionUsesQpack(version_.transport_version)) {
1366 mock_quic_data.AddWrite(SYNCHRONOUS,
1367 ConstructInitialSettingsPacket(packet_num++));
1368 }
rchbd089ab2017-05-26 23:05:041369 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231370 SYNCHRONOUS,
1371 ConstructClientRequestHeadersPacket(
1372 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1373 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451374
Ryan Hamilton0239aac2018-05-19 00:03:131375 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041376 response_headers["key1"] = std::string(30000, 'A');
1377 response_headers["key2"] = std::string(30000, 'A');
1378 response_headers["key3"] = std::string(30000, 'A');
1379 response_headers["key4"] = std::string(30000, 'A');
1380 response_headers["key5"] = std::string(30000, 'A');
1381 response_headers["key6"] = std::string(30000, 'A');
1382 response_headers["key7"] = std::string(30000, 'A');
1383 response_headers["key8"] = std::string(30000, 'A');
1384 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451385
1386 quic::QuicStreamId stream_id;
1387 std::string response_data;
1388 if (quic::VersionUsesQpack(version_.transport_version)) {
1389 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1390 std::vector<std::string> encoded = server_maker_.QpackEncodeHeaders(
1391 stream_id, std::move(response_headers), nullptr);
1392 for (const auto& e : encoded) {
1393 response_data += e;
1394 }
1395 } else {
1396 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1397 spdy::SpdyHeadersIR headers_frame(
1398 GetNthClientInitiatedBidirectionalStreamId(0),
1399 std::move(response_headers));
1400 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1401 spdy::SpdySerializedFrame spdy_frame =
1402 response_framer.SerializeFrame(headers_frame);
1403 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1404 }
rchbd089ab2017-05-26 23:05:041405
Fan Yangac867502019-01-28 21:10:231406 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041407 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451408 for (size_t offset = 0; offset < response_data.length();
1409 offset += chunk_size) {
1410 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431411 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451412 ASYNC, ConstructServerDataPacket(
1413 packet_number++, stream_id, false, false,
1414 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041415 }
1416
Victor Vasiliev076657c2019-03-12 02:46:431417 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411418
rchbd089ab2017-05-26 23:05:041419 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331420 ASYNC, ConstructServerDataPacket(
1421 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171422 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041423 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:231424 mock_quic_data.AddWrite(ASYNC,
1425 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431426 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331427 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231428 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:331429 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041430
1431 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1432
1433 CreateSession();
1434
1435 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1436 TestCompletionCallback callback;
1437 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1438 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1439 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1440}
1441
rcha2bd44b2016-07-02 00:42:551442TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Nick Harper72ade192019-07-17 03:30:421443 session_params_.quic_params.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551444
Ryan Hamilton9835e662018-08-02 05:36:271445 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551446
Ryan Hamiltonabad59e2019-06-06 04:02:591447 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231448 int packet_num = 1;
1449 if (VersionUsesQpack(version_.transport_version)) {
1450 mock_quic_data.AddWrite(SYNCHRONOUS,
1451 ConstructInitialSettingsPacket(packet_num++));
1452 }
rch5cb522462017-04-25 20:18:361453 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231454 SYNCHRONOUS,
1455 ConstructClientRequestHeadersPacket(
1456 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1457 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431458 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331459 ASYNC, ConstructServerResponseHeadersPacket(
1460 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1461 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431462 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331463 mock_quic_data.AddRead(
1464 ASYNC, ConstructServerDataPacket(
1465 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171466 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231467 mock_quic_data.AddWrite(SYNCHRONOUS,
1468 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551469 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1470
1471 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1472
1473 CreateSession();
1474
1475 SendRequestAndExpectQuicResponse("hello!");
1476 EXPECT_TRUE(
1477 test_socket_performance_watcher_factory_.rtt_notification_received());
1478}
1479
[email protected]cf3e3cd62014-02-05 16:16:161480TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411481 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591482 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491483 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161484
Ryan Hamiltonabad59e2019-06-06 04:02:591485 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231486 int packet_num = 1;
1487 if (VersionUsesQpack(version_.transport_version)) {
1488 mock_quic_data.AddWrite(SYNCHRONOUS,
1489 ConstructInitialSettingsPacket(packet_num++));
1490 }
rch5cb522462017-04-25 20:18:361491 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231492 SYNCHRONOUS,
1493 ConstructClientRequestHeadersPacket(
1494 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1495 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431496 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331497 ASYNC, ConstructServerResponseHeadersPacket(
1498 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1499 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431500 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331501 mock_quic_data.AddRead(
1502 ASYNC, ConstructServerDataPacket(
1503 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171504 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231505 mock_quic_data.AddWrite(SYNCHRONOUS,
1506 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501507 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591508 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161509
rcha5399e02015-04-21 19:32:041510 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161511
tbansal0f56a39a2016-04-07 22:03:381512 EXPECT_FALSE(
1513 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161514 // There is no need to set up an alternate protocol job, because
1515 // no attempt will be made to speak to the proxy over TCP.
1516
rch9ae5b3b2016-02-11 00:36:291517 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161518 CreateSession();
1519
bnc62a44f022015-04-02 15:59:411520 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381521 EXPECT_TRUE(
1522 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161523}
1524
bnc313ba9c2015-06-11 15:42:311525// Regression test for https://crbug.com/492458. Test that for an HTTP
1526// connection through a QUIC proxy, the certificate exhibited by the proxy is
1527// checked against the proxy hostname, not the origin hostname.
1528TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291529 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311530 const std::string proxy_host = "www.example.org";
1531
mmenke6ddfbea2017-05-31 21:48:411532 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591533 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491534 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311535
alyssar2adf3ac2016-05-03 17:12:581536 client_maker_.set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591537 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231538 int packet_num = 1;
1539 if (VersionUsesQpack(version_.transport_version)) {
1540 mock_quic_data.AddWrite(SYNCHRONOUS,
1541 ConstructInitialSettingsPacket(packet_num++));
1542 }
rch5cb522462017-04-25 20:18:361543 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231544 SYNCHRONOUS,
1545 ConstructClientRequestHeadersPacket(
1546 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1547 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431548 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331549 ASYNC, ConstructServerResponseHeadersPacket(
1550 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1551 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431552 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331553 mock_quic_data.AddRead(
1554 ASYNC, ConstructServerDataPacket(
1555 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171556 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231557 mock_quic_data.AddWrite(SYNCHRONOUS,
1558 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501559 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591560 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311561 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1562
1563 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291564 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311565 ASSERT_TRUE(cert.get());
1566 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241567 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1568 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311569 ProofVerifyDetailsChromium verify_details;
1570 verify_details.cert_verify_result.verified_cert = cert;
1571 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561572 ProofVerifyDetailsChromium verify_details2;
1573 verify_details2.cert_verify_result.verified_cert = cert;
1574 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311575
1576 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091577 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321578 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271579 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311580 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1581}
1582
rchbe69cb902016-02-11 01:10:481583TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Nick Harper72ade192019-07-17 03:30:421584 session_params_.quic_params.allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481585 HostPortPair origin("www.example.org", 443);
1586 HostPortPair alternative("mail.example.org", 443);
1587
1588 base::FilePath certs_dir = GetTestCertsDirectory();
1589 scoped_refptr<X509Certificate> cert(
1590 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1591 ASSERT_TRUE(cert.get());
1592 // TODO(rch): the connection should be "to" the origin, so if the cert is
1593 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241594 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1595 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481596 ProofVerifyDetailsChromium verify_details;
1597 verify_details.cert_verify_result.verified_cert = cert;
1598 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1599
alyssar2adf3ac2016-05-03 17:12:581600 client_maker_.set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591601 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021602
Renjie Tangaadb84b2019-08-31 01:00:231603 int packet_num = 1;
1604 if (VersionUsesQpack(version_.transport_version)) {
1605 mock_quic_data.AddWrite(SYNCHRONOUS,
1606 ConstructInitialSettingsPacket(packet_num++));
1607 }
rch5cb522462017-04-25 20:18:361608 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231609 SYNCHRONOUS,
1610 ConstructClientRequestHeadersPacket(
1611 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1612 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431613 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331614 ASYNC, ConstructServerResponseHeadersPacket(
1615 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1616 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431617 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331618 mock_quic_data.AddRead(
1619 ASYNC, ConstructServerDataPacket(
1620 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171621 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231622 mock_quic_data.AddWrite(SYNCHRONOUS,
1623 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481624 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1625 mock_quic_data.AddRead(ASYNC, 0);
1626 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1627
1628 request_.url = GURL("https://" + origin.host());
1629 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271630 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091631 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321632 CreateSession();
rchbe69cb902016-02-11 01:10:481633
1634 SendRequestAndExpectQuicResponse("hello!");
1635}
1636
zhongyief3f4ce52017-07-05 23:53:281637TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:561638 quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
zhongyief3f4ce52017-07-05 23:53:281639 // Add support for another QUIC version besides |version_|. Also find a
1640 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561641 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281642 if (version == version_)
1643 continue;
1644 if (supported_versions_.size() != 2) {
1645 supported_versions_.push_back(version);
1646 continue;
1647 }
1648 unsupported_version = version;
1649 break;
1650 }
Nick Harper23290b82019-05-02 00:02:561651 DCHECK_NE(unsupported_version, quic::UnsupportedQuicVersion());
zhongyief3f4ce52017-07-05 23:53:281652
1653 // Set up alternative service to use QUIC with a version that is not
1654 // supported.
1655 url::SchemeHostPort server(request_.url);
1656 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1657 443);
1658 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491659 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071660 server, NetworkIsolationKey(), alternative_service, expiration,
1661 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281662
1663 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491664 http_server_properties_->GetAlternativeServiceInfos(
1665 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281666 EXPECT_EQ(1u, alt_svc_info_vector.size());
1667 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1668 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1669 EXPECT_EQ(unsupported_version,
1670 alt_svc_info_vector[0].advertised_versions()[0]);
1671
1672 // First request should still be sent via TCP as the QUIC version advertised
1673 // in the stored AlternativeService is not supported by the client. However,
1674 // the response from the server will advertise new Alt-Svc with supported
1675 // versions.
Ryan Hamilton8380c652019-06-04 02:25:061676 quic::ParsedQuicVersionVector versions;
1677 for (quic::QuicTransportVersion version :
1678 quic::AllSupportedTransportVersions()) {
1679 versions.push_back(
1680 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
1681 }
zhongyief3f4ce52017-07-05 23:53:281682 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:061683 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyief3f4ce52017-07-05 23:53:281684 std::string altsvc_header =
1685 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1686 advertised_versions_list_str.c_str());
1687 MockRead http_reads[] = {
1688 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1689 MockRead("hello world"),
1690 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1691 MockRead(ASYNC, OK)};
1692
Ryan Sleevib8d7ea02018-05-07 20:01:011693 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281694 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081695 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281696 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1697
1698 // Second request should be sent via QUIC as a new list of verions supported
1699 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591700 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231701 int packet_num = 1;
1702 if (VersionUsesQpack(version_.transport_version)) {
1703 mock_quic_data.AddWrite(SYNCHRONOUS,
1704 ConstructInitialSettingsPacket(packet_num++));
1705 }
zhongyief3f4ce52017-07-05 23:53:281706 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231707 SYNCHRONOUS,
1708 ConstructClientRequestHeadersPacket(
1709 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1710 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431711 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331712 ASYNC, ConstructServerResponseHeadersPacket(
1713 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1714 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431715 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331716 mock_quic_data.AddRead(
1717 ASYNC, ConstructServerDataPacket(
1718 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171719 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231720 mock_quic_data.AddWrite(SYNCHRONOUS,
1721 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281722 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1723 mock_quic_data.AddRead(ASYNC, 0); // EOF
1724
1725 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1726
1727 AddHangingNonAlternateProtocolSocketData();
1728
1729 CreateSession(supported_versions_);
1730
1731 SendRequestAndExpectHttpResponse("hello world");
1732 SendRequestAndExpectQuicResponse("hello!");
1733
1734 // Check alternative service list is updated with new versions.
1735 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491736 session_->http_server_properties()->GetAlternativeServiceInfos(
1737 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281738 EXPECT_EQ(1u, alt_svc_info_vector.size());
1739 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1740 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1741 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:561742 std::sort(
1743 supported_versions_.begin(), supported_versions_.end(),
1744 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
1745 return a.transport_version < b.transport_version;
1746 });
zhongyief3f4ce52017-07-05 23:53:281747 EXPECT_EQ(supported_versions_[0],
1748 alt_svc_info_vector[0].advertised_versions()[0]);
1749 EXPECT_EQ(supported_versions_[1],
1750 alt_svc_info_vector[0].advertised_versions()[1]);
1751}
1752
bncaccd4962017-04-06 21:00:261753// Regression test for https://crbug.com/546991.
1754// The server might not be able to serve a request on an alternative connection,
1755// and might send a 421 Misdirected Request response status to indicate this.
1756// HttpNetworkTransaction should reset the request and retry without using
1757// alternative services.
1758TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1759 // Set up alternative service to use QUIC.
1760 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1761 // that overrides |enable_alternative_services|.
1762 url::SchemeHostPort server(request_.url);
1763 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1764 443);
1765 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491766 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071767 server, NetworkIsolationKey(), alternative_service, expiration,
1768 supported_versions_);
bncaccd4962017-04-06 21:00:261769
davidbena4449722017-05-05 23:30:531770 // First try: The alternative job uses QUIC and reports an HTTP 421
1771 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1772 // paused at Connect(), so it will never exit the socket pool. This ensures
1773 // that the alternate job always wins the race and keeps whether the
1774 // |http_data| exits the socket pool before the main job is aborted
1775 // deterministic. The first main job gets aborted without the socket pool ever
1776 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591777 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231778 int packet_num = 1;
1779 if (VersionUsesQpack(version_.transport_version)) {
1780 mock_quic_data.AddWrite(SYNCHRONOUS,
1781 ConstructInitialSettingsPacket(packet_num++));
1782 }
rch5cb522462017-04-25 20:18:361783 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231784 SYNCHRONOUS,
1785 ConstructClientRequestHeadersPacket(
1786 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1787 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331788 mock_quic_data.AddRead(
1789 ASYNC, ConstructServerResponseHeadersPacket(
1790 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021791 GetResponseHeaders("421")));
bncaccd4962017-04-06 21:00:261792 mock_quic_data.AddRead(ASYNC, OK);
1793 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1794
davidbena4449722017-05-05 23:30:531795 // Second try: The main job uses TCP, and there is no alternate job. Once the
1796 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1797 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261798 // Note that if there was an alternative QUIC Job created for the second try,
1799 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1800 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531801 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1802 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1803 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1804 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1805 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1806 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011807 reads, writes);
bncaccd4962017-04-06 21:00:261808 socket_factory_.AddSocketDataProvider(&http_data);
1809 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1810
bncaccd4962017-04-06 21:00:261811 CreateSession();
1812 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531813
1814 // Run until |mock_quic_data| has failed and |http_data| has paused.
1815 TestCompletionCallback callback;
1816 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1818 base::RunLoop().RunUntilIdle();
1819
1820 // |mock_quic_data| must have run to completion.
1821 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1822 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1823
1824 // Now that the QUIC data has been consumed, unblock |http_data|.
1825 http_data.socket()->OnConnectComplete(MockConnect());
1826
1827 // The retry logic must hide the 421 status. The transaction succeeds on
1828 // |http_data|.
1829 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261830 CheckWasHttpResponse(&trans);
1831 CheckResponsePort(&trans, 443);
1832 CheckResponseData(&trans, "hello!");
1833}
1834
[email protected]1e960032013-12-20 19:00:201835TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Nick Harper72ade192019-07-17 03:30:421836 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571837 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301838
Ryan Hamiltonabad59e2019-06-06 04:02:591839 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:231840 if (VersionUsesQpack(version_.transport_version))
1841 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401842 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Ryan Hamilton0d65a8c2019-06-07 00:46:021843 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591844 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:231845 if (VersionUsesQpack(version_.transport_version))
1846 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301847 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401848 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431849 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401850
1851 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1852 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301853
1854 CreateSession();
1855
tbansal0f56a39a2016-04-07 22:03:381856 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401857 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161858 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401859 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161860 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011861 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1862 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381863 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531864
1865 NetErrorDetails details;
1866 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521867 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401868 }
[email protected]cebe3282013-05-22 23:49:301869}
1870
tbansalc8a94ea2015-11-02 23:58:511871TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1872 // Attempt to "force" quic on 443, which will not be honored.
Nick Harper72ade192019-07-17 03:30:421873 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571874 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511875
1876 MockRead http_reads[] = {
1877 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1878 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1879 MockRead(ASYNC, OK)};
1880
Ryan Sleevib8d7ea02018-05-07 20:01:011881 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511882 socket_factory_.AddSocketDataProvider(&data);
1883 SSLSocketDataProvider ssl(ASYNC, OK);
1884 socket_factory_.AddSSLSocketDataProvider(&ssl);
1885
1886 CreateSession();
1887
1888 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381889 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511890}
1891
bncc958faa2015-07-31 18:14:521892TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521893 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561894 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1895 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521896 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1897 MockRead(ASYNC, OK)};
1898
Ryan Sleevib8d7ea02018-05-07 20:01:011899 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521900 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081901 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561902 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521903
Ryan Hamiltonabad59e2019-06-06 04:02:591904 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231905 int packet_num = 1;
1906 if (VersionUsesQpack(version_.transport_version)) {
1907 mock_quic_data.AddWrite(SYNCHRONOUS,
1908 ConstructInitialSettingsPacket(packet_num++));
1909 }
rch5cb522462017-04-25 20:18:361910 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231911 SYNCHRONOUS,
1912 ConstructClientRequestHeadersPacket(
1913 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1914 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431915 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331916 ASYNC, ConstructServerResponseHeadersPacket(
1917 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1918 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431919 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331920 mock_quic_data.AddRead(
1921 ASYNC, ConstructServerDataPacket(
1922 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171923 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231924 mock_quic_data.AddWrite(SYNCHRONOUS,
1925 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:521926 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591927 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521928
1929 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1930
rtennetib8e80fb2016-05-16 00:12:091931 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321932 CreateSession();
bncc958faa2015-07-31 18:14:521933
1934 SendRequestAndExpectHttpResponse("hello world");
1935 SendRequestAndExpectQuicResponse("hello!");
1936}
1937
Ryan Hamilton64f21d52019-08-31 07:10:511938TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
1939 std::string alt_svc_header =
1940 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
1941 MockRead http_reads[] = {
1942 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
1943 MockRead("hello world"),
1944 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1945 MockRead(ASYNC, OK)};
1946
1947 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
1948 socket_factory_.AddSocketDataProvider(&http_data);
1949 AddCertificate(&ssl_data_);
1950 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1951
1952 MockQuicData mock_quic_data(version_);
1953 int packet_num = 1;
1954 if (VersionUsesQpack(version_.transport_version)) {
1955 mock_quic_data.AddWrite(SYNCHRONOUS,
1956 ConstructInitialSettingsPacket(packet_num++));
1957 }
1958 mock_quic_data.AddWrite(
1959 SYNCHRONOUS,
1960 ConstructClientRequestHeadersPacket(
1961 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1962 true, GetRequestHeaders("GET", "https", "/")));
1963 mock_quic_data.AddRead(
1964 ASYNC, ConstructServerResponseHeadersPacket(
1965 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1966 GetResponseHeaders("200 OK")));
1967 std::string header = ConstructDataHeader(6);
1968 mock_quic_data.AddRead(
1969 ASYNC, ConstructServerDataPacket(
1970 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1971 header + "hello!"));
1972 mock_quic_data.AddWrite(SYNCHRONOUS,
1973 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1974 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1975 mock_quic_data.AddRead(ASYNC, 0); // EOF
1976
1977 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1978
1979 AddHangingNonAlternateProtocolSocketData();
1980 CreateSession();
1981
1982 SendRequestAndExpectHttpResponse("hello world");
1983 SendRequestAndExpectQuicResponse("hello!");
1984}
1985
Matt Menke3233d8f22019-08-20 21:01:491986// Much like above, but makes sure NetworkIsolationKey is respected.
1987TEST_P(QuicNetworkTransactionTest,
1988 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
1989 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:051990 feature_list.InitWithFeatures(
1991 // enabled_features
1992 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
1993 features::kPartitionConnectionsByNetworkIsolationKey},
1994 // disabled_features
1995 {});
Matt Menke3233d8f22019-08-20 21:01:491996 // Since HttpServerProperties caches the feature value, have to create a new
1997 // one.
1998 http_server_properties_ = std::make_unique<HttpServerProperties>();
1999
2000 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2001 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2002 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2003 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2004
2005 MockRead http_reads[] = {
2006 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
2007 MockRead("hello world"),
2008 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2009 MockRead(ASYNC, OK)};
2010
2011 AddCertificate(&ssl_data_);
2012
2013 // Request with empty NetworkIsolationKey.
2014 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2015 socket_factory_.AddSocketDataProvider(&http_data1);
2016 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2017
2018 // First request with kNetworkIsolationKey1.
2019 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2020 socket_factory_.AddSocketDataProvider(&http_data2);
2021 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2022
2023 // Request with kNetworkIsolationKey2.
2024 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2025 socket_factory_.AddSocketDataProvider(&http_data3);
2026 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2027
2028 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2029 // alternative service infrmation has been received in this context before.
2030 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232031 int packet_num = 1;
2032 if (VersionUsesQpack(version_.transport_version)) {
2033 mock_quic_data.AddWrite(SYNCHRONOUS,
2034 ConstructInitialSettingsPacket(packet_num++));
2035 }
Matt Menke3233d8f22019-08-20 21:01:492036 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232037 SYNCHRONOUS,
2038 ConstructClientRequestHeadersPacket(
2039 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2040 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492041 mock_quic_data.AddRead(
2042 ASYNC, ConstructServerResponseHeadersPacket(
2043 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2044 GetResponseHeaders("200 OK")));
2045 std::string header = ConstructDataHeader(6);
2046 mock_quic_data.AddRead(
2047 ASYNC, ConstructServerDataPacket(
2048 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2049 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232050 mock_quic_data.AddWrite(SYNCHRONOUS,
2051 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke3233d8f22019-08-20 21:01:492052 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2053 mock_quic_data.AddRead(ASYNC, 0); // EOF
2054
2055 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2056
2057 AddHangingNonAlternateProtocolSocketData();
2058 CreateSession();
2059
2060 // This is first so that the test fails if alternative service info is
2061 // written with the right NetworkIsolationKey, but always queried with an
2062 // empty one.
2063 request_.network_isolation_key = NetworkIsolationKey();
2064 SendRequestAndExpectHttpResponse("hello world");
2065 request_.network_isolation_key = kNetworkIsolationKey1;
2066 SendRequestAndExpectHttpResponse("hello world");
2067 request_.network_isolation_key = kNetworkIsolationKey2;
2068 SendRequestAndExpectHttpResponse("hello world");
2069
2070 // Only use QUIC when using a NetworkIsolationKey which has been used when
2071 // alternative service information was received.
2072 request_.network_isolation_key = kNetworkIsolationKey1;
2073 SendRequestAndExpectQuicResponse("hello!");
2074}
2075
zhongyia00ca012017-07-06 23:36:392076TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
2077 // Both server advertises and client supports two QUIC versions.
2078 // Only |version_| is advertised and supported.
2079 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2080 // PacketMakers are using |version_|.
2081
2082 // Add support for another QUIC version besides |version_| on the client side.
2083 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:562084 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
2085 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392086 if (version == version_)
2087 continue;
2088 if (supported_versions_.size() != 2) {
2089 supported_versions_.push_back(version);
2090 continue;
2091 }
2092 advertised_version_2 = version;
2093 break;
2094 }
Nick Harper23290b82019-05-02 00:02:562095 DCHECK_NE(advertised_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392096
Nick Harper23290b82019-05-02 00:02:562097 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
2098 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2099 advertised_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392100
2101 MockRead http_reads[] = {
2102 MockRead("HTTP/1.1 200 OK\r\n"),
2103 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2104 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2105 MockRead(ASYNC, OK)};
2106
Ryan Sleevib8d7ea02018-05-07 20:01:012107 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392108 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082109 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392110 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2111
Ryan Hamiltonabad59e2019-06-06 04:02:592112 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232113 int packet_num = 1;
2114 if (VersionUsesQpack(version_.transport_version)) {
2115 mock_quic_data.AddWrite(SYNCHRONOUS,
2116 ConstructInitialSettingsPacket(packet_num++));
2117 }
zhongyia00ca012017-07-06 23:36:392118 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232119 SYNCHRONOUS,
2120 ConstructClientRequestHeadersPacket(
2121 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2122 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432123 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332124 ASYNC, ConstructServerResponseHeadersPacket(
2125 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2126 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432127 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332128 mock_quic_data.AddRead(
2129 ASYNC, ConstructServerDataPacket(
2130 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172131 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232132 mock_quic_data.AddWrite(SYNCHRONOUS,
2133 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392134 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2135 mock_quic_data.AddRead(ASYNC, 0); // EOF
2136
2137 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2138
2139 AddHangingNonAlternateProtocolSocketData();
2140 CreateSession(supported_versions_);
2141
2142 SendRequestAndExpectHttpResponse("hello world");
2143 SendRequestAndExpectQuicResponse("hello!");
2144}
2145
2146TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
2147 // Client and server mutually support more than one QUIC_VERSION.
2148 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
2149 // which is verified as the PacketMakers are using |version_|.
2150
Nick Harper23290b82019-05-02 00:02:562151 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
2152 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392153 if (version == version_)
2154 continue;
2155 common_version_2 = version;
2156 break;
2157 }
Nick Harper23290b82019-05-02 00:02:562158 DCHECK_NE(common_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392159
2160 supported_versions_.push_back(
2161 common_version_2); // Supported but unpreferred.
2162
2163 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:562164 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2165 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392166
2167 MockRead http_reads[] = {
2168 MockRead("HTTP/1.1 200 OK\r\n"),
2169 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2170 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2171 MockRead(ASYNC, OK)};
2172
Ryan Sleevib8d7ea02018-05-07 20:01:012173 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392174 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082175 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392176 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2177
Ryan Hamiltonabad59e2019-06-06 04:02:592178 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232179 int packet_num = 1;
2180 if (VersionUsesQpack(version_.transport_version)) {
2181 mock_quic_data.AddWrite(SYNCHRONOUS,
2182 ConstructInitialSettingsPacket(packet_num++));
2183 }
zhongyia00ca012017-07-06 23:36:392184 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232185 SYNCHRONOUS,
2186 ConstructClientRequestHeadersPacket(
2187 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2188 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432189 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332190 ASYNC, ConstructServerResponseHeadersPacket(
2191 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2192 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432193 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332194 mock_quic_data.AddRead(
2195 ASYNC, ConstructServerDataPacket(
2196 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172197 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232198 mock_quic_data.AddWrite(SYNCHRONOUS,
2199 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392200 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2201 mock_quic_data.AddRead(ASYNC, 0); // EOF
2202
2203 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2204
2205 AddHangingNonAlternateProtocolSocketData();
2206 CreateSession(supported_versions_);
2207
2208 SendRequestAndExpectHttpResponse("hello world");
2209 SendRequestAndExpectQuicResponse("hello!");
2210}
2211
rchf47265dc2016-03-21 21:33:122212TEST_P(QuicNetworkTransactionTest,
2213 UseAlternativeServiceWithProbabilityForQuic) {
2214 MockRead http_reads[] = {
2215 MockRead("HTTP/1.1 200 OK\r\n"),
2216 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
2217 MockRead("hello world"),
2218 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2219 MockRead(ASYNC, OK)};
2220
Ryan Sleevib8d7ea02018-05-07 20:01:012221 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:122222 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082223 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:122224 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2225
Ryan Hamiltonabad59e2019-06-06 04:02:592226 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232227 int packet_num = 1;
2228 if (VersionUsesQpack(version_.transport_version)) {
2229 mock_quic_data.AddWrite(SYNCHRONOUS,
2230 ConstructInitialSettingsPacket(packet_num++));
2231 }
rch5cb522462017-04-25 20:18:362232 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232233 SYNCHRONOUS,
2234 ConstructClientRequestHeadersPacket(
2235 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2236 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432237 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332238 ASYNC, ConstructServerResponseHeadersPacket(
2239 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2240 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432241 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332242 mock_quic_data.AddRead(
2243 ASYNC, ConstructServerDataPacket(
2244 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172245 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232246 mock_quic_data.AddWrite(SYNCHRONOUS,
2247 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchf47265dc2016-03-21 21:33:122248 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2249 mock_quic_data.AddRead(ASYNC, 0); // EOF
2250
2251 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2252
rtennetib8e80fb2016-05-16 00:12:092253 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:122254 CreateSession();
2255
2256 SendRequestAndExpectHttpResponse("hello world");
2257 SendRequestAndExpectQuicResponse("hello!");
2258}
2259
zhongyi3d4a55e72016-04-22 20:36:462260TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2261 MockRead http_reads[] = {
2262 MockRead("HTTP/1.1 200 OK\r\n"),
2263 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2264 MockRead("hello world"),
2265 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2266 MockRead(ASYNC, OK)};
2267
Ryan Sleevib8d7ea02018-05-07 20:01:012268 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462269 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082270 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462271 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2272
2273 CreateSession();
bncb26024382016-06-29 02:39:452274 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462275 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452276 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462277 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402278 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462279 session_->http_server_properties();
2280 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2281 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2282 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462283 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492284 2u, http_server_properties
2285 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2286 .size());
bncb26024382016-06-29 02:39:452287 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492288 http_server_properties
2289 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2290 .empty());
zhongyi3d4a55e72016-04-22 20:36:462291}
2292
2293TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2294 MockRead http_reads[] = {
2295 MockRead("HTTP/1.1 200 OK\r\n"),
2296 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2297 MockRead("hello world"),
2298 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2299 MockRead(ASYNC, OK)};
2300
Ryan Sleevib8d7ea02018-05-07 20:01:012301 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082302 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462303
2304 socket_factory_.AddSocketDataProvider(&http_data);
2305 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2306 socket_factory_.AddSocketDataProvider(&http_data);
2307 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2308
2309 CreateSession();
2310
2311 // Send https request and set alternative services if response header
2312 // advertises alternative service for mail.example.org.
2313 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402314 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462315 session_->http_server_properties();
2316
2317 const url::SchemeHostPort https_server(request_.url);
2318 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342319 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492320 2u, http_server_properties
2321 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2322 .size());
zhongyi3d4a55e72016-04-22 20:36:462323
2324 // Send http request to the same origin but with diffrent scheme, should not
2325 // use QUIC.
2326 request_.url = GURL("http://mail.example.org:443");
2327 SendRequestAndExpectHttpResponse("hello world");
2328}
2329
zhongyie537a002017-06-27 16:48:212330TEST_P(QuicNetworkTransactionTest,
2331 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442332 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562333 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyi86838d52017-06-30 01:19:442334 if (version == version_)
2335 continue;
2336 supported_versions_.push_back(version);
2337 break;
2338 }
2339
Ryan Hamilton8380c652019-06-04 02:25:062340 quic::ParsedQuicVersionVector versions;
2341 for (quic::QuicTransportVersion version :
2342 quic::AllSupportedTransportVersions()) {
2343 versions.push_back(
2344 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
2345 }
zhongyie537a002017-06-27 16:48:212346 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:062347 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyie537a002017-06-27 16:48:212348 std::string altsvc_header =
2349 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2350 advertised_versions_list_str.c_str());
2351 MockRead http_reads[] = {
2352 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2353 MockRead("hello world"),
2354 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2355 MockRead(ASYNC, OK)};
2356
Ryan Sleevib8d7ea02018-05-07 20:01:012357 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212358 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082359 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212360 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2361
Ryan Hamiltonabad59e2019-06-06 04:02:592362 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232363 int packet_num = 1;
2364 if (VersionUsesQpack(version_.transport_version)) {
2365 mock_quic_data.AddWrite(SYNCHRONOUS,
2366 ConstructInitialSettingsPacket(packet_num++));
2367 }
zhongyie537a002017-06-27 16:48:212368 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232369 SYNCHRONOUS,
2370 ConstructClientRequestHeadersPacket(
2371 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2372 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432373 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332374 ASYNC, ConstructServerResponseHeadersPacket(
2375 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2376 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432377 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332378 mock_quic_data.AddRead(
2379 ASYNC, ConstructServerDataPacket(
2380 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172381 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232382 mock_quic_data.AddWrite(SYNCHRONOUS,
2383 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212384 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2385 mock_quic_data.AddRead(ASYNC, 0); // EOF
2386
2387 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2388
2389 AddHangingNonAlternateProtocolSocketData();
2390
zhongyi86838d52017-06-30 01:19:442391 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212392
2393 SendRequestAndExpectHttpResponse("hello world");
2394 SendRequestAndExpectQuicResponse("hello!");
2395
2396 // Check alternative service is set with only mutually supported versions.
2397 const url::SchemeHostPort https_server(request_.url);
2398 const AlternativeServiceInfoVector alt_svc_info_vector =
2399 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492400 https_server, NetworkIsolationKey());
zhongyie537a002017-06-27 16:48:212401 EXPECT_EQ(1u, alt_svc_info_vector.size());
2402 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2403 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2404 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:562405 std::sort(
2406 supported_versions_.begin(), supported_versions_.end(),
2407 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
2408 return a.transport_version < b.transport_version;
2409 });
zhongyi86838d52017-06-30 01:19:442410 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212411 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442412 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212413 alt_svc_info_vector[0].advertised_versions()[1]);
2414}
2415
danzh3134c2562016-08-12 14:07:522416TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562417 std::string altsvc_header = base::StringPrintf(
2418 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_.transport_version);
bnc8be55ebb2015-10-30 14:12:072419 MockRead http_reads[] = {
2420 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2421 MockRead("hello world"),
2422 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2423 MockRead(ASYNC, OK)};
2424
Ryan Sleevib8d7ea02018-05-07 20:01:012425 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072426 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082427 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072428 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2429
Ryan Hamiltonabad59e2019-06-06 04:02:592430 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232431 int packet_num = 1;
2432 if (VersionUsesQpack(version_.transport_version)) {
2433 mock_quic_data.AddWrite(SYNCHRONOUS,
2434 ConstructInitialSettingsPacket(packet_num++));
2435 }
rch5cb522462017-04-25 20:18:362436 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232437 SYNCHRONOUS,
2438 ConstructClientRequestHeadersPacket(
2439 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2440 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432441 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332442 ASYNC, ConstructServerResponseHeadersPacket(
2443 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2444 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432445 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332446 mock_quic_data.AddRead(
2447 ASYNC, ConstructServerDataPacket(
2448 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172449 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232450 mock_quic_data.AddWrite(SYNCHRONOUS,
2451 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072452 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592453 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072454
2455 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2456
rtennetib8e80fb2016-05-16 00:12:092457 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322458 CreateSession();
bnc8be55ebb2015-10-30 14:12:072459
2460 SendRequestAndExpectHttpResponse("hello world");
2461 SendRequestAndExpectQuicResponse("hello!");
2462}
2463
zhongyi6b5a3892016-03-12 04:46:202464TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562465 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz6e4c5382018-06-21 23:00:092466 // Not available under version 99
2467 return;
2468 }
Ryan Hamiltonabad59e2019-06-06 04:02:592469 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232470 int packet_num = 1;
2471 if (VersionUsesQpack(version_.transport_version)) {
2472 mock_quic_data.AddWrite(SYNCHRONOUS,
2473 ConstructInitialSettingsPacket(packet_num++));
2474 }
rch5cb522462017-04-25 20:18:362475 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232476 SYNCHRONOUS,
2477 ConstructClientRequestHeadersPacket(
2478 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2479 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332480 mock_quic_data.AddRead(
2481 ASYNC, ConstructServerResponseHeadersPacket(
2482 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2483 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202484 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522485 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432486 mock_quic_data.AddRead(SYNCHRONOUS,
2487 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522488 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432489 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232490 mock_quic_data.AddWrite(SYNCHRONOUS,
2491 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432492 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332493 mock_quic_data.AddRead(
2494 SYNCHRONOUS, ConstructServerDataPacket(
2495 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:172496 true, header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232497 mock_quic_data.AddWrite(
2498 SYNCHRONOUS,
2499 ConstructClientAckAndRstPacket(
2500 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2501 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202502 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2503 mock_quic_data.AddRead(ASYNC, 0); // EOF
2504
2505 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2506
2507 // The non-alternate protocol job needs to hang in order to guarantee that
2508 // the alternate-protocol job will "win".
2509 AddHangingNonAlternateProtocolSocketData();
2510
2511 // In order for a new QUIC session to be established via alternate-protocol
2512 // without racing an HTTP connection, we need the host resolution to happen
2513 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2514 // connection to the the server, in this test we require confirmation
2515 // before encrypting so the HTTP job will still start.
2516 host_resolver_.set_synchronous_mode(true);
2517 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2518 "");
zhongyi6b5a3892016-03-12 04:46:202519
2520 CreateSession();
2521 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272522 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202523
bnc691fda62016-08-12 00:43:162524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202525 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362526 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012527 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202528
2529 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522530 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012531 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202532
2533 // Check whether this transaction is correctly marked as received a go-away
2534 // because of migrating port.
2535 NetErrorDetails details;
2536 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162537 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202538 EXPECT_TRUE(details.quic_port_migration_detected);
2539}
2540
Zhongyi Shia6b68d112018-09-24 07:49:032541// This test verifies that a new QUIC connection will be attempted on the
2542// alternate network if the original QUIC connection fails with idle timeout
2543// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2544// alternate network as well, QUIC is marked as broken and the brokenness will
2545// not expire when default network changes.
2546TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2547 SetUpTestForRetryConnectionOnAlternateNetwork();
2548
Michael Warres167db3e2019-03-01 21:38:032549 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032550
2551 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592552 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032553 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2554 int packet_num = 1;
2555 quic_data.AddWrite(SYNCHRONOUS,
2556 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2557 // Retranmit the handshake messages.
2558 quic_data.AddWrite(SYNCHRONOUS,
2559 client_maker_.MakeDummyCHLOPacket(packet_num++));
2560 quic_data.AddWrite(SYNCHRONOUS,
2561 client_maker_.MakeDummyCHLOPacket(packet_num++));
2562 quic_data.AddWrite(SYNCHRONOUS,
2563 client_maker_.MakeDummyCHLOPacket(packet_num++));
2564 quic_data.AddWrite(SYNCHRONOUS,
2565 client_maker_.MakeDummyCHLOPacket(packet_num++));
2566 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562567 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032568 quic_data.AddWrite(SYNCHRONOUS,
2569 client_maker_.MakeDummyCHLOPacket(packet_num++));
2570 }
2571 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2572 quic_data.AddWrite(SYNCHRONOUS,
2573 client_maker_.MakeConnectionClosePacket(
2574 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2575 "No recent network activity."));
2576 quic_data.AddSocketDataToFactory(&socket_factory_);
2577
2578 // Add successful TCP data so that TCP job will succeed.
2579 MockWrite http_writes[] = {
2580 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2581 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2582 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2583
2584 MockRead http_reads[] = {
2585 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2586 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2587 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2588 SequencedSocketData http_data(http_reads, http_writes);
2589 socket_factory_.AddSocketDataProvider(&http_data);
2590 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2591
2592 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592593 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032594 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2595 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2596 quic_data2.AddSocketDataToFactory(&socket_factory_);
2597
2598 // Resolve the host resolution synchronously.
2599 host_resolver_.set_synchronous_mode(true);
2600 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2601 "");
Zhongyi Shia6b68d112018-09-24 07:49:032602
2603 CreateSession();
2604 session_->quic_stream_factory()->set_require_confirmation(true);
2605 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032606 QuicStreamFactoryPeer::SetAlarmFactory(
2607 session_->quic_stream_factory(),
2608 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2609 &clock_));
2610 // Add alternate protocol mapping to race QUIC and TCP.
2611 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2612 // peer.
2613 AddQuicAlternateProtocolMapping(
2614 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2615
2616 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2617 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362618 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2620
2621 // Pump the message loop to get the request started.
2622 // Request will be served with TCP job.
2623 base::RunLoop().RunUntilIdle();
2624 EXPECT_THAT(callback.WaitForResult(), IsOk());
2625 CheckResponseData(&trans, "TCP succeeds");
2626
Zhongyi Shia6b68d112018-09-24 07:49:032627 // Fast forward to idle timeout the original connection. A new connection will
2628 // be kicked off on the alternate network.
2629 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2630 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2631 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2632
2633 // Run the message loop to execute posted tasks, which will report job status.
2634 base::RunLoop().RunUntilIdle();
2635
2636 // Verify that QUIC is marked as broken.
2637 ExpectBrokenAlternateProtocolMapping();
2638
2639 // Deliver a message to notify the new network becomes default, the brokenness
2640 // will not expire as QUIC is broken on both networks.
2641 scoped_mock_change_notifier_->mock_network_change_notifier()
2642 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2643 ExpectBrokenAlternateProtocolMapping();
2644
2645 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2646 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2647}
2648
2649// This test verifies that a new QUIC connection will be attempted on the
2650// alternate network if the original QUIC connection fails with idle timeout
2651// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2652// alternate network, QUIC is marked as broken. The brokenness will expire when
2653// the default network changes.
2654TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2655 SetUpTestForRetryConnectionOnAlternateNetwork();
2656
Michael Warres167db3e2019-03-01 21:38:032657 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032658
2659 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592660 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032661 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2662 int packet_num = 1;
2663 quic_data.AddWrite(SYNCHRONOUS,
2664 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2665 // Retranmit the handshake messages.
2666 quic_data.AddWrite(SYNCHRONOUS,
2667 client_maker_.MakeDummyCHLOPacket(packet_num++));
2668 quic_data.AddWrite(SYNCHRONOUS,
2669 client_maker_.MakeDummyCHLOPacket(packet_num++));
2670 quic_data.AddWrite(SYNCHRONOUS,
2671 client_maker_.MakeDummyCHLOPacket(packet_num++));
2672 quic_data.AddWrite(SYNCHRONOUS,
2673 client_maker_.MakeDummyCHLOPacket(packet_num++));
2674 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562675 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032676 quic_data.AddWrite(SYNCHRONOUS,
2677 client_maker_.MakeDummyCHLOPacket(packet_num++));
2678 }
2679 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2680 quic_data.AddWrite(SYNCHRONOUS,
2681 client_maker_.MakeConnectionClosePacket(
2682 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2683 "No recent network activity."));
2684 quic_data.AddSocketDataToFactory(&socket_factory_);
2685
2686 // Add successful TCP data so that TCP job will succeed.
2687 MockWrite http_writes[] = {
2688 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2689 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2690 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2691
2692 MockRead http_reads[] = {
2693 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2694 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2695 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2696 SequencedSocketData http_data(http_reads, http_writes);
2697 socket_factory_.AddSocketDataProvider(&http_data);
2698 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2699
2700 // Quic connection will be retried on the alternate network after the initial
2701 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592702 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032703 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2704 quic_data2.AddWrite(SYNCHRONOUS,
2705 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2706
2707 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Renjie Tangaadb84b2019-08-31 01:00:232708 if (VersionUsesQpack(version_.transport_version))
2709 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032710 quic_data2.AddSocketDataToFactory(&socket_factory_);
2711
2712 // Resolve the host resolution synchronously.
2713 host_resolver_.set_synchronous_mode(true);
2714 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2715 "");
Zhongyi Shia6b68d112018-09-24 07:49:032716
2717 CreateSession();
2718 session_->quic_stream_factory()->set_require_confirmation(true);
2719 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032720 QuicStreamFactoryPeer::SetAlarmFactory(
2721 session_->quic_stream_factory(),
2722 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2723 &clock_));
2724 // Add alternate protocol mapping to race QUIC and TCP.
2725 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2726 // peer.
2727 AddQuicAlternateProtocolMapping(
2728 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2729
2730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2731 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362732 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2734
2735 // Pump the message loop to get the request started.
2736 // Request will be served with TCP job.
2737 base::RunLoop().RunUntilIdle();
2738 EXPECT_THAT(callback.WaitForResult(), IsOk());
2739 CheckResponseData(&trans, "TCP succeeds");
2740
Zhongyi Shia6b68d112018-09-24 07:49:032741 // Fast forward to idle timeout the original connection. A new connection will
2742 // be kicked off on the alternate network.
2743 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2744 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2745 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2746
2747 // The second connection hasn't finish handshake, verify that QUIC is not
2748 // marked as broken.
2749 ExpectQuicAlternateProtocolMapping();
2750 // Explicitly confirm the handshake on the second connection.
2751 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2752 quic::QuicSession::HANDSHAKE_CONFIRMED);
2753 // Run message loop to execute posted tasks, which will notify JoController
2754 // about the orphaned job status.
2755 base::RunLoop().RunUntilIdle();
2756
2757 // Verify that QUIC is marked as broken.
2758 ExpectBrokenAlternateProtocolMapping();
2759
2760 // Deliver a message to notify the new network becomes default, the previous
2761 // brokenness will be clear as the brokenness is bond with old default
2762 // network.
2763 scoped_mock_change_notifier_->mock_network_change_notifier()
2764 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2765 ExpectQuicAlternateProtocolMapping();
2766
2767 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2768 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2769}
2770
Matt Menkeb32ba5122019-09-10 19:17:052771// Much like above test, but verifies NetworkIsolationKeys are respected.
2772TEST_P(QuicNetworkTransactionTest,
2773 RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
2774 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2775 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2776 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2777 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2778
2779 base::test::ScopedFeatureList feature_list;
2780 feature_list.InitWithFeatures(
2781 // enabled_features
2782 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2783 // Need to partition connections by NetworkIsolationKey for
2784 // QuicSessionAliasKey to include NetworkIsolationKeys.
2785 features::kPartitionConnectionsByNetworkIsolationKey},
2786 // disabled_features
2787 {});
2788 // Since HttpServerProperties caches the feature value, have to create a new
2789 // one.
2790 http_server_properties_ = std::make_unique<HttpServerProperties>();
2791
2792 SetUpTestForRetryConnectionOnAlternateNetwork();
2793
2794 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
2795
2796 // The request will initially go out over QUIC.
2797 MockQuicData quic_data(version_);
2798 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2799 int packet_num = 1;
2800 quic_data.AddWrite(SYNCHRONOUS,
2801 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2802 // Retranmit the handshake messages.
2803 quic_data.AddWrite(SYNCHRONOUS,
2804 client_maker_.MakeDummyCHLOPacket(packet_num++));
2805 quic_data.AddWrite(SYNCHRONOUS,
2806 client_maker_.MakeDummyCHLOPacket(packet_num++));
2807 quic_data.AddWrite(SYNCHRONOUS,
2808 client_maker_.MakeDummyCHLOPacket(packet_num++));
2809 quic_data.AddWrite(SYNCHRONOUS,
2810 client_maker_.MakeDummyCHLOPacket(packet_num++));
2811 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2812 if (version_.transport_version <= quic::QUIC_VERSION_39) {
2813 quic_data.AddWrite(SYNCHRONOUS,
2814 client_maker_.MakeDummyCHLOPacket(packet_num++));
2815 }
2816 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2817 quic_data.AddWrite(SYNCHRONOUS,
2818 client_maker_.MakeConnectionClosePacket(
2819 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2820 "No recent network activity."));
2821 quic_data.AddSocketDataToFactory(&socket_factory_);
2822
2823 // Add successful TCP data so that TCP job will succeed.
2824 MockWrite http_writes[] = {
2825 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2826 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2827 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2828
2829 MockRead http_reads[] = {
2830 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2831 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2832 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2833 SequencedSocketData http_data(http_reads, http_writes);
2834 socket_factory_.AddSocketDataProvider(&http_data);
2835 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2836
2837 // Quic connection will be retried on the alternate network after the initial
2838 // one fails on the default network.
2839 MockQuicData quic_data2(version_);
2840 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2841 quic_data2.AddWrite(SYNCHRONOUS,
2842 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2843
2844 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2845 if (VersionUsesQpack(version_.transport_version))
2846 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
2847 quic_data2.AddSocketDataToFactory(&socket_factory_);
2848
2849 // Resolve the host resolution synchronously.
2850 host_resolver_.set_synchronous_mode(true);
2851 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2852 "");
2853
2854 CreateSession();
2855 session_->quic_stream_factory()->set_require_confirmation(true);
2856 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2857 QuicStreamFactoryPeer::SetAlarmFactory(
2858 session_->quic_stream_factory(),
2859 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2860 &clock_));
2861 // Add alternate protocol mapping to race QUIC and TCP.
2862 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2863 // peer.
2864 AddQuicAlternateProtocolMapping(
2865 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
2866 AddQuicAlternateProtocolMapping(
2867 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
2868
2869 request_.network_isolation_key = kNetworkIsolationKey1;
2870 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2871 TestCompletionCallback callback;
2872 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2873 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2874
2875 // Pump the message loop to get the request started.
2876 // Request will be served with TCP job.
2877 base::RunLoop().RunUntilIdle();
2878 EXPECT_THAT(callback.WaitForResult(), IsOk());
2879 CheckResponseData(&trans, "TCP succeeds");
2880
2881 // Fast forward to idle timeout the original connection. A new connection will
2882 // be kicked off on the alternate network.
2883 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2884 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2885 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2886
2887 // The second connection hasn't finish handshake, verify that QUIC is not
2888 // marked as broken.
2889 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2890 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2891 // Explicitly confirm the handshake on the second connection.
2892 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2893 quic::QuicSession::HANDSHAKE_CONFIRMED);
2894 // Run message loop to execute posted tasks, which will notify JoController
2895 // about the orphaned job status.
2896 base::RunLoop().RunUntilIdle();
2897
2898 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
2899 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
2900 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2901
2902 // Deliver a message to notify the new network becomes default, the previous
2903 // brokenness will be clear as the brokenness is bond with old default
2904 // network.
2905 scoped_mock_change_notifier_->mock_network_change_notifier()
2906 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2907 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2908 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2909
2910 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2911 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2912}
2913
Zhongyi Shia6b68d112018-09-24 07:49:032914// This test verifies that a new QUIC connection will be attempted on the
2915// alternate network if the original QUIC connection fails with idle timeout
2916// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2917// alternative network succeeds, QUIC is not marked as broken.
2918TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2919 SetUpTestForRetryConnectionOnAlternateNetwork();
2920
Michael Warres167db3e2019-03-01 21:38:032921 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032922
2923 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592924 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032925 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2926 int packet_num = 1;
2927 quic_data.AddWrite(SYNCHRONOUS,
2928 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2929 // Retranmit the handshake messages.
2930 quic_data.AddWrite(SYNCHRONOUS,
2931 client_maker_.MakeDummyCHLOPacket(packet_num++));
2932 quic_data.AddWrite(SYNCHRONOUS,
2933 client_maker_.MakeDummyCHLOPacket(packet_num++));
2934 quic_data.AddWrite(SYNCHRONOUS,
2935 client_maker_.MakeDummyCHLOPacket(packet_num++));
2936 quic_data.AddWrite(SYNCHRONOUS,
2937 client_maker_.MakeDummyCHLOPacket(packet_num++));
2938 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2939 // quic_fix_has_pending_crypto_data is introduced and enabled.
Nick Harper23290b82019-05-02 00:02:562940 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032941 quic_data.AddWrite(SYNCHRONOUS,
2942 client_maker_.MakeDummyCHLOPacket(packet_num++));
2943 }
2944 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2945 quic_data.AddWrite(SYNCHRONOUS,
2946 client_maker_.MakeConnectionClosePacket(
2947 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2948 "No recent network activity."));
2949 quic_data.AddSocketDataToFactory(&socket_factory_);
2950
2951 // Add hanging TCP data so that TCP job will never succeeded.
2952 AddHangingNonAlternateProtocolSocketData();
2953
2954 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:592955 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:232956 packet_num = 1;
Zhongyi Shia6b68d112018-09-24 07:49:032957 quic_data2.AddWrite(SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:232958 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:032959
Victor Vasiliev076657c2019-03-12 02:46:432960 const std::string body = "hello!";
2961 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:412962
Zhongyi Shia6b68d112018-09-24 07:49:032963 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Renjie Tangaadb84b2019-08-31 01:00:232964 if (VersionUsesQpack(version_.transport_version)) {
2965 quic_data2.AddWrite(SYNCHRONOUS,
2966 ConstructInitialSettingsPacket(packet_num++));
2967 }
Zhongyi Shia6b68d112018-09-24 07:49:032968 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232969 SYNCHRONOUS,
2970 ConstructClientRequestHeadersPacket(
2971 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2972 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:032973 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332974 ASYNC, ConstructServerResponseHeadersPacket(
2975 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2976 GetResponseHeaders("200 OK")));
2977 quic_data2.AddRead(
2978 ASYNC, ConstructServerDataPacket(
2979 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172980 header + body));
Renjie Tangaadb84b2019-08-31 01:00:232981 quic_data2.AddWrite(SYNCHRONOUS,
2982 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia6b68d112018-09-24 07:49:032983 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2984 quic_data2.AddSocketDataToFactory(&socket_factory_);
2985
2986 // Resolve the host resolution synchronously.
2987 host_resolver_.set_synchronous_mode(true);
2988 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2989 "");
Zhongyi Shia6b68d112018-09-24 07:49:032990
2991 CreateSession();
2992 session_->quic_stream_factory()->set_require_confirmation(true);
2993 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032994 QuicStreamFactoryPeer::SetAlarmFactory(
2995 session_->quic_stream_factory(),
2996 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2997 &clock_));
2998 // Add alternate protocol mapping to race QUIC and TCP.
2999 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3000 // peer.
3001 AddQuicAlternateProtocolMapping(
3002 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3003
3004 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3005 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363006 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:033007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3008
3009 // Pump the message loop to get the request started.
3010 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:033011
3012 // Fast forward to idle timeout the original connection. A new connection will
3013 // be kicked off on the alternate network.
3014 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3015 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3016 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3017
3018 // Verify that QUIC is not marked as broken.
3019 ExpectQuicAlternateProtocolMapping();
3020 // Explicitly confirm the handshake on the second connection.
3021 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
3022 quic::QuicSession::HANDSHAKE_CONFIRMED);
3023
3024 // Read the response.
3025 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:413026 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:033027 // Verify that QUIC is not marked as broken.
3028 ExpectQuicAlternateProtocolMapping();
3029
3030 // Deliver a message to notify the new network becomes default.
3031 scoped_mock_change_notifier_->mock_network_change_notifier()
3032 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3033 ExpectQuicAlternateProtocolMapping();
3034 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3035 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3036}
3037
rch9ecde09b2017-04-08 00:18:233038// Verify that if a QUIC connection times out, the QuicHttpStream will
3039// return QUIC_PROTOCOL_ERROR.
3040TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:423041 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Sleevi2e8255b2019-07-17 21:02:213042 session_params_.quic_params.idle_connection_timeout =
3043 base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:233044
3045 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593046 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133047 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233048 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3049
Ryan Hamiltone940bd12019-06-30 02:46:453050 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033051 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023052 quic_data.AddWrite(
3053 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453054 client_maker_.MakeRequestHeadersPacket(
3055 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3056 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3057
3058 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233059
Renjie Tangaadb84b2019-08-31 01:00:233060 // TLP 1
3061 quic_data.AddWrite(SYNCHRONOUS,
3062 client_maker_.MakeRetransmissionPacket(1, 2, true));
3063 // TLP 2
3064 quic_data.AddWrite(SYNCHRONOUS,
3065 client_maker_.MakeRetransmissionPacket(1, 3, true));
3066 // RTO 1
3067 quic_data.AddWrite(SYNCHRONOUS,
3068 client_maker_.MakeRetransmissionPacket(1, 4, true));
3069 // RTO 2
3070 quic_data.AddWrite(SYNCHRONOUS,
3071 client_maker_.MakeRetransmissionPacket(1, 5, true));
3072 // RTO 3
3073 quic_data.AddWrite(SYNCHRONOUS,
3074 client_maker_.MakeRetransmissionPacket(1, 6, true));
Ryan Hamilton3cc2c152019-07-09 19:36:013075
Renjie Tangaadb84b2019-08-31 01:00:233076 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
3077 7, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3078 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223079
rch9ecde09b2017-04-08 00:18:233080 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3081 quic_data.AddRead(ASYNC, OK);
3082 quic_data.AddSocketDataToFactory(&socket_factory_);
3083
3084 // In order for a new QUIC session to be established via alternate-protocol
3085 // without racing an HTTP connection, we need the host resolution to happen
3086 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3087 // connection to the the server, in this test we require confirmation
3088 // before encrypting so the HTTP job will still start.
3089 host_resolver_.set_synchronous_mode(true);
3090 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3091 "");
rch9ecde09b2017-04-08 00:18:233092
3093 CreateSession();
3094 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233095 QuicStreamFactoryPeer::SetAlarmFactory(
3096 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193097 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553098 &clock_));
rch9ecde09b2017-04-08 00:18:233099
Ryan Hamilton9835e662018-08-02 05:36:273100 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233101
3102 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3103 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363104 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233105 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3106
3107 // Pump the message loop to get the request started.
3108 base::RunLoop().RunUntilIdle();
3109 // Explicitly confirm the handshake.
3110 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523111 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233112
3113 // Run the QUIC session to completion.
3114 quic_task_runner_->RunUntilIdle();
3115
3116 ExpectQuicAlternateProtocolMapping();
3117 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3118 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3119}
3120
3121// Verify that if a QUIC connection RTOs, the QuicHttpStream will
3122// return QUIC_PROTOCOL_ERROR.
3123TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:423124 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
3125 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233126
3127 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593128 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133129 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233130 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3131
Ryan Hamiltone940bd12019-06-30 02:46:453132 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033133 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023134 quic_data.AddWrite(
3135 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453136 client_maker_.MakeRequestHeadersPacket(
3137 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3138 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3139
3140 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Renjie Tangaadb84b2019-08-31 01:00:233141 // TLP 1
3142 quic_data.AddWrite(SYNCHRONOUS,
3143 client_maker_.MakeRetransmissionPacket(1, 2, true));
3144 // TLP 2
3145 quic_data.AddWrite(SYNCHRONOUS,
3146 client_maker_.MakeRetransmissionPacket(1, 3, true));
3147 // RTO 1
3148 quic_data.AddWrite(SYNCHRONOUS,
3149 client_maker_.MakeRetransmissionPacket(1, 4, true));
3150 // RTO 2
3151 quic_data.AddWrite(SYNCHRONOUS,
3152 client_maker_.MakeRetransmissionPacket(1, 5, true));
3153 // RTO 3
3154 quic_data.AddWrite(SYNCHRONOUS,
3155 client_maker_.MakeRetransmissionPacket(1, 6, true));
3156 // RTO 4
3157 quic_data.AddWrite(SYNCHRONOUS,
3158 client_maker_.MakeRetransmissionPacket(1, 7, true));
3159 // RTO 5
3160 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
3161 8, true, quic::QUIC_TOO_MANY_RTOS,
3162 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233163
3164 quic_data.AddRead(ASYNC, OK);
3165 quic_data.AddSocketDataToFactory(&socket_factory_);
3166
3167 // In order for a new QUIC session to be established via alternate-protocol
3168 // without racing an HTTP connection, we need the host resolution to happen
3169 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3170 // connection to the the server, in this test we require confirmation
3171 // before encrypting so the HTTP job will still start.
3172 host_resolver_.set_synchronous_mode(true);
3173 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3174 "");
rch9ecde09b2017-04-08 00:18:233175
3176 CreateSession();
3177 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233178 QuicStreamFactoryPeer::SetAlarmFactory(
3179 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193180 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553181 &clock_));
rch9ecde09b2017-04-08 00:18:233182
Ryan Hamilton9835e662018-08-02 05:36:273183 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233184
3185 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3186 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363187 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233188 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3189
3190 // Pump the message loop to get the request started.
3191 base::RunLoop().RunUntilIdle();
3192 // Explicitly confirm the handshake.
3193 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523194 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233195
3196 // Run the QUIC session to completion.
3197 quic_task_runner_->RunUntilIdle();
3198
3199 ExpectQuicAlternateProtocolMapping();
3200 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3201 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3202}
3203
3204// Verify that if a QUIC connection RTOs, while there are no active streams
3205// QUIC will not be marked as broken.
3206TEST_P(QuicNetworkTransactionTest,
3207 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Nick Harper72ade192019-07-17 03:30:423208 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233209
3210 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593211 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133212 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233213 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3214
Ryan Hamiltone940bd12019-06-30 02:46:453215 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033216 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023217 quic_data.AddWrite(
3218 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453219 client_maker_.MakeRequestHeadersPacket(
3220 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3221 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3222
3223 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233224
Renjie Tangaadb84b2019-08-31 01:00:233225 quic_data.AddWrite(SYNCHRONOUS,
3226 client_maker_.MakeRstPacket(
Ryan Hamiltonb01f886f2019-07-10 02:25:553227 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
3228 quic::QUIC_STREAM_CANCELLED));
Renjie Tangaadb84b2019-08-31 01:00:233229 // Since the headers are sent on the data stream, when the stream is reset
3230 // the headers are no longer retransmitted.
3231 client_maker_.RemoveSavedStreamFrames(
3232 GetNthClientInitiatedBidirectionalStreamId(0));
3233 // TLP 1
3234 quic_data.AddWrite(SYNCHRONOUS,
3235 client_maker_.MakeRetransmissionPacket(1, 3, true));
3236 // TLP 2
3237 quic_data.AddWrite(SYNCHRONOUS,
3238 client_maker_.MakeRetransmissionPacket(2, 4, true));
3239 // RTO 1
3240 quic_data.AddWrite(SYNCHRONOUS,
3241 client_maker_.MakeRetransmissionPacket(1, 5, true));
3242 quic_data.AddWrite(SYNCHRONOUS,
3243 client_maker_.MakeRetransmissionPacket(2, 6, true));
3244 // RTO 2
3245 quic_data.AddWrite(SYNCHRONOUS,
3246 client_maker_.MakeRetransmissionPacket(1, 7, true));
3247 quic_data.AddWrite(SYNCHRONOUS,
3248 client_maker_.MakeRetransmissionPacket(2, 8, true));
3249 // RTO 3
3250 quic_data.AddWrite(SYNCHRONOUS,
3251 client_maker_.MakeRetransmissionPacket(1, 9, true));
3252 quic_data.AddWrite(SYNCHRONOUS,
3253 client_maker_.MakeRetransmissionPacket(2, 10, true));
3254 // RTO 4
3255 quic_data.AddWrite(SYNCHRONOUS,
3256 client_maker_.MakeRetransmissionPacket(1, 11, true));
3257 quic_data.AddWrite(SYNCHRONOUS,
3258 client_maker_.MakeRetransmissionPacket(2, 12, true));
rch9ecde09b2017-04-08 00:18:233259 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433260 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Renjie Tangaadb84b2019-08-31 01:00:233261 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433262 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233263
3264 quic_data.AddRead(ASYNC, OK);
3265 quic_data.AddSocketDataToFactory(&socket_factory_);
3266
3267 // In order for a new QUIC session to be established via alternate-protocol
3268 // without racing an HTTP connection, we need the host resolution to happen
3269 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3270 // connection to the the server, in this test we require confirmation
3271 // before encrypting so the HTTP job will still start.
3272 host_resolver_.set_synchronous_mode(true);
3273 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3274 "");
rch9ecde09b2017-04-08 00:18:233275
3276 CreateSession();
3277 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233278 QuicStreamFactoryPeer::SetAlarmFactory(
3279 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193280 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553281 &clock_));
rch9ecde09b2017-04-08 00:18:233282
Ryan Hamilton9835e662018-08-02 05:36:273283 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233284
Jeremy Roman0579ed62017-08-29 15:56:193285 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233286 session_.get());
3287 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363288 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233289 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3290
3291 // Pump the message loop to get the request started.
3292 base::RunLoop().RunUntilIdle();
3293 // Explicitly confirm the handshake.
3294 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523295 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233296
3297 // Now cancel the request.
3298 trans.reset();
3299
3300 // Run the QUIC session to completion.
3301 quic_task_runner_->RunUntilIdle();
3302
3303 ExpectQuicAlternateProtocolMapping();
3304
3305 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3306}
3307
rch2f2991c2017-04-13 19:28:173308// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3309// the request fails with QUIC_PROTOCOL_ERROR.
3310TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:423311 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173312 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593313 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033314 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433315 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:023316 ConstructClientRequestHeadersPacket(
3317 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3318 true, GetRequestHeaders("GET", "https", "/")));
3319 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton3cc2c152019-07-09 19:36:013320 uint64_t packet_number = 2;
Ryan Hamiltonb01f886f2019-07-10 02:25:553321 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173322 // Peer sending data from an non-existing stream causes this end to raise
3323 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333324 quic_data.AddRead(
3325 ASYNC, ConstructServerRstPacket(
3326 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3327 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173328 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton3cc2c152019-07-09 19:36:013329 quic_data.AddWrite(
3330 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
3331 packet_number++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
Renjie Tangff0d6372019-08-30 22:03:293332 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3333 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173334 quic_data.AddSocketDataToFactory(&socket_factory_);
3335
3336 // In order for a new QUIC session to be established via alternate-protocol
3337 // without racing an HTTP connection, we need the host resolution to happen
3338 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3339 // connection to the the server, in this test we require confirmation
3340 // before encrypting so the HTTP job will still start.
3341 host_resolver_.set_synchronous_mode(true);
3342 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3343 "");
rch2f2991c2017-04-13 19:28:173344
3345 CreateSession();
3346
Ryan Hamilton9835e662018-08-02 05:36:273347 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173348
3349 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3350 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363351 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173352 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3353
3354 // Pump the message loop to get the request started.
3355 base::RunLoop().RunUntilIdle();
3356 // Explicitly confirm the handshake.
3357 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523358 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173359
3360 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553361 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173362
3363 // Run the QUIC session to completion.
3364 base::RunLoop().RunUntilIdle();
3365 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3366 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3367
3368 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3369 ExpectQuicAlternateProtocolMapping();
3370 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3371}
3372
rch2f2991c2017-04-13 19:28:173373// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3374// connection times out, then QUIC will be marked as broken and the request
3375// retried over TCP.
3376TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Ryan Sleevi2e8255b2019-07-17 21:02:213377 session_params_.quic_params.idle_connection_timeout =
3378 base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173379
3380 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593381 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133382 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173383 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3384
Ryan Hamiltone940bd12019-06-30 02:46:453385 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033386 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023387 quic_data.AddWrite(
3388 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453389 client_maker_.MakeRequestHeadersPacket(
3390 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3391 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3392
3393 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Renjie Tangaadb84b2019-08-31 01:00:233394 // TLP 1
3395 quic_data.AddWrite(SYNCHRONOUS,
3396 client_maker_.MakeRetransmissionPacket(1, 2, true));
3397 // TLP 2
3398 quic_data.AddWrite(SYNCHRONOUS,
3399 client_maker_.MakeRetransmissionPacket(1, 3, true));
3400 // RTO 1
3401 quic_data.AddWrite(SYNCHRONOUS,
3402 client_maker_.MakeRetransmissionPacket(1, 4, true));
3403 // RTO 2
3404 quic_data.AddWrite(SYNCHRONOUS,
3405 client_maker_.MakeRetransmissionPacket(1, 5, true));
3406 // RTO 3
3407 quic_data.AddWrite(SYNCHRONOUS,
3408 client_maker_.MakeRetransmissionPacket(1, 6, true));
rch2f2991c2017-04-13 19:28:173409
Renjie Tangaadb84b2019-08-31 01:00:233410 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
3411 7, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3412 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223413
rch2f2991c2017-04-13 19:28:173414 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3415 quic_data.AddRead(ASYNC, OK);
3416 quic_data.AddSocketDataToFactory(&socket_factory_);
3417
3418 // After that fails, it will be resent via TCP.
3419 MockWrite http_writes[] = {
3420 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3421 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3422 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3423
3424 MockRead http_reads[] = {
3425 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3426 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3427 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013428 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173429 socket_factory_.AddSocketDataProvider(&http_data);
3430 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3431
3432 // In order for a new QUIC session to be established via alternate-protocol
3433 // without racing an HTTP connection, we need the host resolution to happen
3434 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3435 // connection to the the server, in this test we require confirmation
3436 // before encrypting so the HTTP job will still start.
3437 host_resolver_.set_synchronous_mode(true);
3438 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3439 "");
rch2f2991c2017-04-13 19:28:173440
3441 CreateSession();
3442 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173443 QuicStreamFactoryPeer::SetAlarmFactory(
3444 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193445 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553446 &clock_));
rch2f2991c2017-04-13 19:28:173447
Ryan Hamilton9835e662018-08-02 05:36:273448 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173449
3450 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3451 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363452 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173453 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3454
3455 // Pump the message loop to get the request started.
3456 base::RunLoop().RunUntilIdle();
3457 // Explicitly confirm the handshake.
3458 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523459 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173460
3461 // Run the QUIC session to completion.
3462 quic_task_runner_->RunUntilIdle();
3463 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3464
3465 ExpectQuicAlternateProtocolMapping();
3466
3467 // Let the transaction proceed which will result in QUIC being marked
3468 // as broken and the request falling back to TCP.
3469 EXPECT_THAT(callback.WaitForResult(), IsOk());
3470
3471 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3472 ASSERT_FALSE(http_data.AllReadDataConsumed());
3473
3474 // Read the response body over TCP.
3475 CheckResponseData(&trans, "hello world");
3476 ExpectBrokenAlternateProtocolMapping();
3477 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3478 ASSERT_TRUE(http_data.AllReadDataConsumed());
3479}
3480
rch2f2991c2017-04-13 19:28:173481// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3482// protocol error occurs after the handshake is confirmed, the request
3483// retried over TCP and the QUIC will be marked as broken.
3484TEST_P(QuicNetworkTransactionTest,
3485 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Ryan Sleevi2e8255b2019-07-17 21:02:213486 session_params_.quic_params.idle_connection_timeout =
3487 base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173488
3489 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593490 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033491 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433492 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:023493 ConstructClientRequestHeadersPacket(
3494 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3495 true, GetRequestHeaders("GET", "https", "/")));
3496 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553497 uint64_t packet_number = 2;
Ryan Hamiltonb01f886f2019-07-10 02:25:553498 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3499
rch2f2991c2017-04-13 19:28:173500 // Peer sending data from an non-existing stream causes this end to raise
3501 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333502 quic_data.AddRead(
3503 ASYNC, ConstructServerRstPacket(
3504 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3505 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173506 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamiltonb01f886f2019-07-10 02:25:553507 quic_data.AddWrite(
3508 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
3509 packet_number++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
Renjie Tangff0d6372019-08-30 22:03:293510 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3511 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173512 quic_data.AddSocketDataToFactory(&socket_factory_);
3513
3514 // After that fails, it will be resent via TCP.
3515 MockWrite http_writes[] = {
3516 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3517 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3518 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3519
3520 MockRead http_reads[] = {
3521 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3522 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3523 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013524 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173525 socket_factory_.AddSocketDataProvider(&http_data);
3526 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3527
3528 // In order for a new QUIC session to be established via alternate-protocol
3529 // without racing an HTTP connection, we need the host resolution to happen
3530 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3531 // connection to the the server, in this test we require confirmation
3532 // before encrypting so the HTTP job will still start.
3533 host_resolver_.set_synchronous_mode(true);
3534 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3535 "");
rch2f2991c2017-04-13 19:28:173536
3537 CreateSession();
3538
Ryan Hamilton9835e662018-08-02 05:36:273539 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173540
3541 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3542 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363543 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173544 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3545
3546 // Pump the message loop to get the request started.
3547 base::RunLoop().RunUntilIdle();
3548 // Explicitly confirm the handshake.
3549 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523550 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553551 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173552
3553 // Run the QUIC session to completion.
3554 base::RunLoop().RunUntilIdle();
3555 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3556
3557 ExpectQuicAlternateProtocolMapping();
3558
3559 // Let the transaction proceed which will result in QUIC being marked
3560 // as broken and the request falling back to TCP.
3561 EXPECT_THAT(callback.WaitForResult(), IsOk());
3562
3563 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3564 ASSERT_FALSE(http_data.AllReadDataConsumed());
3565
3566 // Read the response body over TCP.
3567 CheckResponseData(&trans, "hello world");
3568 ExpectBrokenAlternateProtocolMapping();
3569 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3570 ASSERT_TRUE(http_data.AllReadDataConsumed());
3571}
3572
Matt Menkeb32ba5122019-09-10 19:17:053573// Much like above test, but verifies that NetworkIsolationKey is respected.
3574TEST_P(QuicNetworkTransactionTest,
3575 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
3576 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
3577 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
3578 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
3579 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
3580
3581 base::test::ScopedFeatureList feature_list;
3582 feature_list.InitWithFeatures(
3583 // enabled_features
3584 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3585 features::kPartitionConnectionsByNetworkIsolationKey},
3586 // disabled_features
3587 {});
3588 // Since HttpServerProperties caches the feature value, have to create a new
3589 // one.
3590 http_server_properties_ = std::make_unique<HttpServerProperties>();
3591
3592 session_params_.quic_params.idle_connection_timeout =
3593 base::TimeDelta::FromSeconds(5);
3594
3595 // The request will initially go out over QUIC.
3596 MockQuicData quic_data(version_);
3597 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
3598 quic_data.AddWrite(SYNCHRONOUS,
3599 ConstructClientRequestHeadersPacket(
3600 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3601 true, GetRequestHeaders("GET", "https", "/")));
3602 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
3603 uint64_t packet_number = 2;
3604 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3605
3606 // Peer sending data from an non-existing stream causes this end to raise
3607 // error and close connection.
3608 quic_data.AddRead(
3609 ASYNC, ConstructServerRstPacket(
3610 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3611 quic::QUIC_STREAM_LAST_ERROR));
3612 std::string quic_error_details = "Data for nonexistent stream";
3613 quic_data.AddWrite(
3614 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
3615 packet_number++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3616 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3617 quic::IETF_RST_STREAM));
3618 quic_data.AddSocketDataToFactory(&socket_factory_);
3619
3620 // After that fails, it will be resent via TCP.
3621 MockWrite http_writes[] = {
3622 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3623 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3624 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3625
3626 MockRead http_reads[] = {
3627 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3628 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3629 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3630 SequencedSocketData http_data(http_reads, http_writes);
3631 socket_factory_.AddSocketDataProvider(&http_data);
3632 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3633
3634 // In order for a new QUIC session to be established via alternate-protocol
3635 // without racing an HTTP connection, we need the host resolution to happen
3636 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3637 // connection to the the server, in this test we require confirmation
3638 // before encrypting so the HTTP job will still start.
3639 host_resolver_.set_synchronous_mode(true);
3640 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3641 "");
3642
3643 CreateSession();
3644
3645 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3646 kNetworkIsolationKey1);
3647 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3648 kNetworkIsolationKey2);
3649
3650 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3651 TestCompletionCallback callback;
3652 request_.network_isolation_key = kNetworkIsolationKey1;
3653 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3654 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3655
3656 // Pump the message loop to get the request started.
3657 base::RunLoop().RunUntilIdle();
3658 // Explicitly confirm the handshake.
3659 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
3660 quic::QuicSession::HANDSHAKE_CONFIRMED);
3661 quic_data.Resume();
3662
3663 // Run the QUIC session to completion.
3664 base::RunLoop().RunUntilIdle();
3665 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3666
3667 // Let the transaction proceed which will result in QUIC being marked
3668 // as broken and the request falling back to TCP.
3669 EXPECT_THAT(callback.WaitForResult(), IsOk());
3670 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3671 ASSERT_FALSE(http_data.AllReadDataConsumed());
3672
3673 // Read the response body over TCP.
3674 CheckResponseData(&trans, "hello world");
3675 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3676 ASSERT_TRUE(http_data.AllReadDataConsumed());
3677
3678 // The alternative service shouldhave been marked as broken under
3679 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3680 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3681 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3682
3683 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3684 AddHttpDataAndRunRequest();
3685 // Requests using other NetworkIsolationKeys can still use QUIC.
3686 request_.network_isolation_key = kNetworkIsolationKey2;
3687 AddQuicDataAndRunRequest();
3688
3689 // The last two requests should not have changed the alternative service
3690 // mappings.
3691 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3692 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3693}
3694
rch30943ee2017-06-12 21:28:443695// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3696// request is reset from, then QUIC will be marked as broken and the request
3697// retried over TCP.
3698TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443699 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593700 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133701 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443702 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3703
Michael Warres167db3e2019-03-01 21:38:033704 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023705 quic_data.AddWrite(
3706 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453707 client_maker_.MakeRequestHeadersPacket(
3708 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3709 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3710
3711 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553712 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443713
Fan Yang32c5a112018-12-10 20:06:333714 quic_data.AddRead(ASYNC,
3715 ConstructServerRstPacket(
3716 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3717 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443718
3719 quic_data.AddRead(ASYNC, OK);
3720 quic_data.AddSocketDataToFactory(&socket_factory_);
3721
3722 // After that fails, it will be resent via TCP.
3723 MockWrite http_writes[] = {
3724 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3725 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3726 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3727
3728 MockRead http_reads[] = {
3729 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3730 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3731 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013732 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443733 socket_factory_.AddSocketDataProvider(&http_data);
3734 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3735
3736 // In order for a new QUIC session to be established via alternate-protocol
3737 // without racing an HTTP connection, we need the host resolution to happen
3738 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3739 // connection to the the server, in this test we require confirmation
3740 // before encrypting so the HTTP job will still start.
3741 host_resolver_.set_synchronous_mode(true);
3742 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3743 "");
rch30943ee2017-06-12 21:28:443744
3745 CreateSession();
3746
Ryan Hamilton9835e662018-08-02 05:36:273747 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443748
3749 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3750 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363751 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443752 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3753
3754 // Pump the message loop to get the request started.
3755 base::RunLoop().RunUntilIdle();
3756 // Explicitly confirm the handshake.
3757 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523758 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553759 quic_data.Resume();
rch30943ee2017-06-12 21:28:443760
3761 // Run the QUIC session to completion.
3762 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3763
3764 ExpectQuicAlternateProtocolMapping();
3765
3766 // Let the transaction proceed which will result in QUIC being marked
3767 // as broken and the request falling back to TCP.
3768 EXPECT_THAT(callback.WaitForResult(), IsOk());
3769
3770 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3771 ASSERT_FALSE(http_data.AllReadDataConsumed());
3772
3773 // Read the response body over TCP.
3774 CheckResponseData(&trans, "hello world");
3775 ExpectBrokenAlternateProtocolMapping();
3776 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3777 ASSERT_TRUE(http_data.AllReadDataConsumed());
3778}
3779
Ryan Hamilton6c2a2a82017-12-15 02:06:283780// Verify that when an origin has two alt-svc advertisements, one local and one
3781// remote, that when the local is broken the request will go over QUIC via
3782// the remote Alt-Svc.
3783// This is a regression test for crbug/825646.
3784TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Nick Harper72ade192019-07-17 03:30:423785 session_params_.quic_params.allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:283786
3787 GURL origin1 = request_.url; // mail.example.org
3788 GURL origin2("https://www.example.org/");
3789 ASSERT_NE(origin1.host(), origin2.host());
3790
3791 scoped_refptr<X509Certificate> cert(
3792 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243793 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3794 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283795
3796 ProofVerifyDetailsChromium verify_details;
3797 verify_details.cert_verify_result.verified_cert = cert;
3798 verify_details.cert_verify_result.is_issued_by_known_root = true;
3799 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3800
Ryan Hamiltonabad59e2019-06-06 04:02:593801 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233802 int packet_num = 1;
3803 if (VersionUsesQpack(version_.transport_version)) {
3804 mock_quic_data.AddWrite(SYNCHRONOUS,
3805 ConstructInitialSettingsPacket(packet_num++));
3806 }
Ryan Hamilton6c2a2a82017-12-15 02:06:283807 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233808 SYNCHRONOUS,
3809 ConstructClientRequestHeadersPacket(
3810 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3811 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433812 mock_quic_data.AddRead(
3813 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333814 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:023815 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:433816 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433817 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333818 ASYNC, ConstructServerDataPacket(
3819 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173820 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:233821 mock_quic_data.AddWrite(SYNCHRONOUS,
3822 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283823 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3824 mock_quic_data.AddRead(ASYNC, 0); // EOF
3825
3826 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:593827 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:283828 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3829 AddHangingNonAlternateProtocolSocketData();
3830
3831 CreateSession();
3832
3833 // Set up alternative service for |origin1|.
3834 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3835 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
3836 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3837 AlternativeServiceInfoVector alternative_services;
3838 alternative_services.push_back(
3839 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3840 local_alternative, expiration,
Nick Harper72ade192019-07-17 03:30:423841 session_->params().quic_params.supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:283842 alternative_services.push_back(
3843 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3844 remote_alternative, expiration,
Nick Harper72ade192019-07-17 03:30:423845 session_->params().quic_params.supported_versions));
Matt Menke3233d8f22019-08-20 21:01:493846 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
3847 NetworkIsolationKey(),
3848 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:283849
Matt Menkeb32ba5122019-09-10 19:17:053850 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
3851 NetworkIsolationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:283852
3853 SendRequestAndExpectQuicResponse("hello!");
3854}
3855
rch30943ee2017-06-12 21:28:443856// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3857// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:053858// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:443859// connection instead of going back to the broken QUIC connection.
3860// This is a regression tests for crbug/731303.
3861TEST_P(QuicNetworkTransactionTest,
3862 ResetPooledAfterHandshakeConfirmedThenBroken) {
Nick Harper72ade192019-07-17 03:30:423863 session_params_.quic_params.allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:443864
3865 GURL origin1 = request_.url;
3866 GURL origin2("https://www.example.org/");
3867 ASSERT_NE(origin1.host(), origin2.host());
3868
Ryan Hamiltonabad59e2019-06-06 04:02:593869 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:443870
3871 scoped_refptr<X509Certificate> cert(
3872 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243873 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3874 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:443875
3876 ProofVerifyDetailsChromium verify_details;
3877 verify_details.cert_verify_result.verified_cert = cert;
3878 verify_details.cert_verify_result.is_issued_by_known_root = true;
3879 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3880
Renjie Tangaadb84b2019-08-31 01:00:233881 int packet_num = 1;
3882 if (VersionUsesQpack(version_.transport_version)) {
3883 mock_quic_data.AddWrite(SYNCHRONOUS,
3884 ConstructInitialSettingsPacket(packet_num++));
3885 }
rch30943ee2017-06-12 21:28:443886 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433887 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233888 SYNCHRONOUS,
3889 ConstructClientRequestHeadersPacket(
3890 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3891 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433892 mock_quic_data.AddRead(
3893 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333894 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:023895 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:433896 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433897 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333898 ASYNC, ConstructServerDataPacket(
3899 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173900 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:233901 mock_quic_data.AddWrite(SYNCHRONOUS,
3902 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rch30943ee2017-06-12 21:28:443903
3904 // Second request will go over the pooled QUIC connection, but will be
3905 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:053906 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:173907 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
3908 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:053909 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:173910 QuicTestPacketMaker server_maker2(
3911 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
3912 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:433913 mock_quic_data.AddWrite(
3914 SYNCHRONOUS,
3915 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:233916 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
3917 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:023918 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:333919 mock_quic_data.AddRead(
3920 ASYNC, ConstructServerRstPacket(
3921 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
3922 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443923 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3924 mock_quic_data.AddRead(ASYNC, 0); // EOF
3925
3926 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3927
3928 // After that fails, it will be resent via TCP.
3929 MockWrite http_writes[] = {
3930 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3931 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
3932 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3933
3934 MockRead http_reads[] = {
3935 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3936 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3937 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013938 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443939 socket_factory_.AddSocketDataProvider(&http_data);
3940 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3941
Ryan Hamilton6c2a2a82017-12-15 02:06:283942 // Then the next request to the second origin will be sent over TCP.
3943 socket_factory_.AddSocketDataProvider(&http_data);
3944 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:443945
3946 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563947 QuicStreamFactoryPeer::SetAlarmFactory(
3948 session_->quic_stream_factory(),
3949 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
3950 &clock_));
rch30943ee2017-06-12 21:28:443951
3952 // Set up alternative service for |origin1|.
3953 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:243954 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:493955 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:073956 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
3957 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:443958
3959 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:243960 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:493961 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:073962 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
3963 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:343964
rch30943ee2017-06-12 21:28:443965 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:523966 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:443967 SendRequestAndExpectQuicResponse("hello!");
3968
3969 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:523970 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:053971 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:443972 request_.url = origin2;
3973 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:053974 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
3975 alternative1, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:243976 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:053977 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
3978 alternative2, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:243979 << alternative2.ToString();
rch30943ee2017-06-12 21:28:443980
Matt Menkeb32ba5122019-09-10 19:17:053981 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:443982 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:283983 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:443984}
3985
bnc8be55ebb2015-10-30 14:12:073986TEST_P(QuicNetworkTransactionTest,
3987 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:563988 std::string altsvc_header =
3989 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
3990 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:073991 MockRead http_reads[] = {
3992 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
3993 MockRead("hello world"),
3994 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3995 MockRead(ASYNC, OK)};
3996
Ryan Sleevib8d7ea02018-05-07 20:01:013997 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:073998 socket_factory_.AddSocketDataProvider(&http_data);
3999 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4000 socket_factory_.AddSocketDataProvider(&http_data);
4001 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4002
rch3f4b8452016-02-23 16:59:324003 CreateSession();
bnc8be55ebb2015-10-30 14:12:074004
4005 SendRequestAndExpectHttpResponse("hello world");
4006 SendRequestAndExpectHttpResponse("hello world");
4007}
4008
Xida Chen9bfe0b62018-04-24 19:52:214009// When multiple alternative services are advertised, HttpStreamFactory should
4010// select the alternative service which uses existing QUIC session if available.
4011// If no existing QUIC session can be used, use the first alternative service
4012// from the list.
zhongyi32569c62016-01-08 02:54:304013TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Nick Harper72ade192019-07-17 03:30:424014 session_params_.quic_params.allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524015 MockRead http_reads[] = {
4016 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294017 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524018 MockRead("hello world"),
4019 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4020 MockRead(ASYNC, OK)};
4021
Ryan Sleevib8d7ea02018-05-07 20:01:014022 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524023 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084024 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564025 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524026
zhongyi32569c62016-01-08 02:54:304027 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294028 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304029 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594030 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234031 int packet_num = 1;
4032 if (VersionUsesQpack(version_.transport_version)) {
4033 mock_quic_data.AddWrite(SYNCHRONOUS,
4034 ConstructInitialSettingsPacket(packet_num++));
4035 }
rch5cb522462017-04-25 20:18:364036 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234037 SYNCHRONOUS,
4038 ConstructClientRequestHeadersPacket(
4039 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4040 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304041
4042 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294043 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4044 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434045 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024046 ASYNC, ConstructServerResponseHeadersPacket(
4047 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4048 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434049 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434050 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334051 ASYNC, ConstructServerDataPacket(
4052 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174053 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234054 mock_quic_data.AddWrite(SYNCHRONOUS,
4055 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304056
4057 // Second QUIC request data.
4058 // Connection pooling, using existing session, no need to include version
4059 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584060 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234061 SYNCHRONOUS,
4062 ConstructClientRequestHeadersPacket(
4063 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4064 true, GetRequestHeaders("GET", "https", "/"),
4065 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434066 mock_quic_data.AddRead(
4067 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334068 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024069 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434070 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334071 ASYNC, ConstructServerDataPacket(
4072 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174073 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434074 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234075 SYNCHRONOUS,
4076 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bncc958faa2015-07-31 18:14:524077 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594078 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524079
4080 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4081
rtennetib8e80fb2016-05-16 00:12:094082 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324083 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564084 QuicStreamFactoryPeer::SetAlarmFactory(
4085 session_->quic_stream_factory(),
4086 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4087 &clock_));
bncc958faa2015-07-31 18:14:524088
4089 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304090
bnc359ed2a2016-04-29 20:43:454091 SendRequestAndExpectQuicResponse("hello!");
4092 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304093}
4094
tbansal6490783c2016-09-20 17:55:274095// Check that an existing QUIC connection to an alternative proxy server is
4096// used.
4097TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4098 base::HistogramTester histogram_tester;
4099
tbansal6490783c2016-09-20 17:55:274100 // First QUIC request data.
4101 // Open a session to foo.example.org:443 using the first entry of the
4102 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594103 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234104 int packet_num = 1;
4105 if (VersionUsesQpack(version_.transport_version)) {
4106 mock_quic_data.AddWrite(SYNCHRONOUS,
4107 ConstructInitialSettingsPacket(packet_num++));
4108 }
rch5cb522462017-04-25 20:18:364109 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234110 SYNCHRONOUS,
4111 ConstructClientRequestHeadersPacket(
4112 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4113 true, GetRequestHeaders("GET", "http", "/")));
tbansal6490783c2016-09-20 17:55:274114
4115 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434116 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024117 ASYNC, ConstructServerResponseHeadersPacket(
4118 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4119 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434120 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434121 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334122 ASYNC, ConstructServerDataPacket(
4123 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174124 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234125 mock_quic_data.AddWrite(SYNCHRONOUS,
4126 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274127
4128 // Second QUIC request data.
4129 // Connection pooling, using existing session, no need to include version
4130 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274131 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234132 SYNCHRONOUS,
4133 ConstructClientRequestHeadersPacket(
4134 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4135 true, GetRequestHeaders("GET", "http", "/"),
4136 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434137 mock_quic_data.AddRead(
4138 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334139 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024140 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434141 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334142 ASYNC, ConstructServerDataPacket(
4143 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174144 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434145 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234146 SYNCHRONOUS,
4147 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274148 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4149 mock_quic_data.AddRead(ASYNC, 0); // EOF
4150
4151 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4152
4153 AddHangingNonAlternateProtocolSocketData();
4154
4155 TestProxyDelegate test_proxy_delegate;
4156
Lily Houghton8c2f97d2018-01-22 05:06:594157 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494158 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274159
4160 test_proxy_delegate.set_alternative_proxy_server(
4161 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524162 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274163
4164 request_.url = GURL("http://mail.example.org/");
4165
4166 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564167 QuicStreamFactoryPeer::SetAlarmFactory(
4168 session_->quic_stream_factory(),
4169 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4170 &clock_));
tbansal6490783c2016-09-20 17:55:274171
4172 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4173 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4174 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4175 1);
4176
4177 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4178 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4179 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4180 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4181 1);
4182}
4183
Ryan Hamilton8d9ee76e2018-05-29 23:52:524184// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454185// even if alternative service destination is different.
4186TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Nick Harper72ade192019-07-17 03:30:424187 session_params_.quic_params.allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594188 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454189
Renjie Tangaadb84b2019-08-31 01:00:234190 int packet_num = 1;
4191 if (VersionUsesQpack(version_.transport_version)) {
4192 mock_quic_data.AddWrite(SYNCHRONOUS,
4193 ConstructInitialSettingsPacket(packet_num++));
4194 }
bnc359ed2a2016-04-29 20:43:454195 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434196 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234197 SYNCHRONOUS,
4198 ConstructClientRequestHeadersPacket(
4199 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4200 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434201 mock_quic_data.AddRead(
4202 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334203 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024204 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434205 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434206 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334207 ASYNC, ConstructServerDataPacket(
4208 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174209 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234210 mock_quic_data.AddWrite(SYNCHRONOUS,
4211 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304212
bnc359ed2a2016-04-29 20:43:454213 // Second request.
alyssar2adf3ac2016-05-03 17:12:584214 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234215 SYNCHRONOUS,
4216 ConstructClientRequestHeadersPacket(
4217 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4218 true, GetRequestHeaders("GET", "https", "/"),
4219 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434220 mock_quic_data.AddRead(
4221 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334222 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024223 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434224 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334225 ASYNC, ConstructServerDataPacket(
4226 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174227 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434228 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234229 SYNCHRONOUS,
4230 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304231 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4232 mock_quic_data.AddRead(ASYNC, 0); // EOF
4233
4234 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454235
4236 AddHangingNonAlternateProtocolSocketData();
4237 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304238
rch3f4b8452016-02-23 16:59:324239 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564240 QuicStreamFactoryPeer::SetAlarmFactory(
4241 session_->quic_stream_factory(),
4242 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4243 &clock_));
zhongyi32569c62016-01-08 02:54:304244
bnc359ed2a2016-04-29 20:43:454245 const char destination1[] = "first.example.com";
4246 const char destination2[] = "second.example.com";
4247
4248 // Set up alternative service entry to destination1.
4249 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214250 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454251 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494252 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074253 server, NetworkIsolationKey(), alternative_service, expiration,
4254 supported_versions_);
bnc359ed2a2016-04-29 20:43:454255 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524256 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454257 SendRequestAndExpectQuicResponse("hello!");
4258
4259 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214260 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494261 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074262 server, NetworkIsolationKey(), alternative_service, expiration,
4263 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524264 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454265 // even though alternative service destination is different.
4266 SendRequestAndExpectQuicResponse("hello!");
4267}
4268
4269// Pool to existing session with matching destination and matching certificate
4270// even if origin is different, and even if the alternative service with
4271// matching destination is not the first one on the list.
4272TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Nick Harper72ade192019-07-17 03:30:424273 session_params_.quic_params.allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454274 GURL origin1 = request_.url;
4275 GURL origin2("https://www.example.org/");
4276 ASSERT_NE(origin1.host(), origin2.host());
4277
Ryan Hamiltonabad59e2019-06-06 04:02:594278 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454279
Renjie Tangaadb84b2019-08-31 01:00:234280 int packet_num = 1;
4281 if (VersionUsesQpack(version_.transport_version)) {
4282 mock_quic_data.AddWrite(SYNCHRONOUS,
4283 ConstructInitialSettingsPacket(packet_num++));
4284 }
bnc359ed2a2016-04-29 20:43:454285 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434286 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234287 SYNCHRONOUS,
4288 ConstructClientRequestHeadersPacket(
4289 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4290 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434291 mock_quic_data.AddRead(
4292 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334293 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024294 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434295 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434296 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334297 ASYNC, ConstructServerDataPacket(
4298 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174299 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234300 mock_quic_data.AddWrite(SYNCHRONOUS,
4301 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454302
4303 // Second request.
Yixin Wang079ad542018-01-11 04:06:054304 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174305 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4306 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054307 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174308 QuicTestPacketMaker server_maker2(
4309 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4310 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584311 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434312 SYNCHRONOUS,
4313 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234314 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4315 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024316 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434317 mock_quic_data.AddRead(
4318 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334319 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024320 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434321 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334322 ASYNC, ConstructServerDataPacket(
4323 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174324 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434325 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234326 SYNCHRONOUS,
4327 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454328 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4329 mock_quic_data.AddRead(ASYNC, 0); // EOF
4330
4331 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4332
4333 AddHangingNonAlternateProtocolSocketData();
4334 AddHangingNonAlternateProtocolSocketData();
4335
4336 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564337 QuicStreamFactoryPeer::SetAlarmFactory(
4338 session_->quic_stream_factory(),
4339 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4340 &clock_));
bnc359ed2a2016-04-29 20:43:454341
4342 const char destination1[] = "first.example.com";
4343 const char destination2[] = "second.example.com";
4344
4345 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214346 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454347 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494348 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074349 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4350 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454351
4352 // Set up multiple alternative service entries for |origin2|,
4353 // the first one with a different destination as for |origin1|,
4354 // the second one with the same. The second one should be used,
4355 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214356 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454357 AlternativeServiceInfoVector alternative_services;
4358 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214359 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4360 alternative_service2, expiration,
Nick Harper72ade192019-07-17 03:30:424361 session_->params().quic_params.supported_versions));
bnc359ed2a2016-04-29 20:43:454362 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214363 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4364 alternative_service1, expiration,
Nick Harper72ade192019-07-17 03:30:424365 session_->params().quic_params.supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494366 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4367 NetworkIsolationKey(),
4368 alternative_services);
bnc359ed2a2016-04-29 20:43:454369 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524370 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454371 SendRequestAndExpectQuicResponse("hello!");
4372
4373 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524374 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454375 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584376
bnc359ed2a2016-04-29 20:43:454377 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304378}
4379
4380// Multiple origins have listed the same alternative services. When there's a
4381// existing QUIC session opened by a request to other origin,
4382// if the cert is valid, should select this QUIC session to make the request
4383// if this is also the first existing QUIC session.
4384TEST_P(QuicNetworkTransactionTest,
4385 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Nick Harper72ade192019-07-17 03:30:424386 session_params_.quic_params.allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294387 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304388
rch9ae5b3b2016-02-11 00:36:294389 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304390 MockRead http_reads[] = {
4391 MockRead("HTTP/1.1 200 OK\r\n"),
4392 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294393 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304394 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4395 MockRead(ASYNC, OK)};
4396
Ryan Sleevib8d7ea02018-05-07 20:01:014397 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304398 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084399 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304400 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4401
4402 // HTTP data for request to mail.example.org.
4403 MockRead http_reads2[] = {
4404 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294405 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304406 MockRead("hello world from mail.example.org"),
4407 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4408 MockRead(ASYNC, OK)};
4409
Ryan Sleevib8d7ea02018-05-07 20:01:014410 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304411 socket_factory_.AddSocketDataProvider(&http_data2);
4412 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4413
Yixin Wang079ad542018-01-11 04:06:054414 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174415 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4416 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054417 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584418 server_maker_.set_hostname("www.example.org");
4419 client_maker_.set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594420 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234421 int packet_num = 1;
4422 if (VersionUsesQpack(version_.transport_version)) {
4423 mock_quic_data.AddWrite(SYNCHRONOUS,
4424 ConstructInitialSettingsPacket(packet_num++));
4425 }
zhongyi32569c62016-01-08 02:54:304426 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584427 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234428 SYNCHRONOUS,
4429 ConstructClientRequestHeadersPacket(
4430 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4431 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434432
4433 mock_quic_data.AddRead(
4434 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334435 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024436 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434437 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334438 mock_quic_data.AddRead(
4439 ASYNC, ConstructServerDataPacket(
4440 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174441 header + "hello from mail QUIC!"));
Renjie Tangaadb84b2019-08-31 01:00:234442 mock_quic_data.AddWrite(SYNCHRONOUS,
4443 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434444 // Second QUIC request data.
4445 mock_quic_data.AddWrite(
4446 SYNCHRONOUS,
4447 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234448 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4449 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024450 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434451 mock_quic_data.AddRead(
4452 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334453 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024454 GetResponseHeaders("200 OK")));
Fan Yang32c5a112018-12-10 20:06:334455 mock_quic_data.AddRead(
4456 ASYNC, ConstructServerDataPacket(
4457 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174458 header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434459 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234460 SYNCHRONOUS,
4461 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304462 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4463 mock_quic_data.AddRead(ASYNC, 0); // EOF
4464
4465 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304466
rtennetib8e80fb2016-05-16 00:12:094467 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324468 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564469 QuicStreamFactoryPeer::SetAlarmFactory(
4470 session_->quic_stream_factory(),
4471 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4472 &clock_));
zhongyi32569c62016-01-08 02:54:304473
4474 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294475 request_.url = GURL("https://www.example.org/");
4476 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304477 request_.url = GURL("https://mail.example.org/");
4478 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4479
rch9ae5b3b2016-02-11 00:36:294480 // Open a QUIC session to mail.example.org:443 when making request
4481 // to mail.example.org.
4482 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454483 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304484
rch9ae5b3b2016-02-11 00:36:294485 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304486 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454487 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524488}
4489
4490TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524491 MockRead http_reads[] = {
4492 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564493 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524494 MockRead("hello world"),
4495 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4496 MockRead(ASYNC, OK)};
4497
Ryan Sleevib8d7ea02018-05-07 20:01:014498 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524499 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084500 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564501 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524502
rtennetib8e80fb2016-05-16 00:12:094503 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324504 CreateSession();
bncc958faa2015-07-31 18:14:524505
4506 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454507
4508 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344509 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494510 http_server_properties_->GetAlternativeServiceInfos(
4511 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344512 ASSERT_EQ(1u, alternative_service_info_vector.size());
4513 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544514 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344515 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4516 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4517 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524518}
4519
4520TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524521 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564522 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4523 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524524 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4525 MockRead(ASYNC, OK)};
4526
Ryan Sleevib8d7ea02018-05-07 20:01:014527 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524528 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084529 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564530 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524531
Ryan Hamiltonabad59e2019-06-06 04:02:594532 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234533 int packet_num = 1;
4534 if (VersionUsesQpack(version_.transport_version)) {
4535 mock_quic_data.AddWrite(SYNCHRONOUS,
4536 ConstructInitialSettingsPacket(packet_num++));
4537 }
rch5cb522462017-04-25 20:18:364538 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234539 SYNCHRONOUS,
4540 ConstructClientRequestHeadersPacket(
4541 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4542 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434543 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334544 ASYNC, ConstructServerResponseHeadersPacket(
4545 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4546 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434547 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334548 mock_quic_data.AddRead(
4549 ASYNC, ConstructServerDataPacket(
4550 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174551 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234552 mock_quic_data.AddWrite(SYNCHRONOUS,
4553 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524554 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4555 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524556
4557 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4558
rtennetib8e80fb2016-05-16 00:12:094559 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324560 CreateSession();
bncc958faa2015-07-31 18:14:524561
bnc3472afd2016-11-17 15:27:214562 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524563 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494564 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054565 alternative_service, NetworkIsolationKey());
Matt Menke3233d8f22019-08-20 21:01:494566 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054567 alternative_service, NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524568
4569 SendRequestAndExpectHttpResponse("hello world");
4570 SendRequestAndExpectQuicResponse("hello!");
4571
mmenkee24011922015-12-17 22:12:594572 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524573
Matt Menke3233d8f22019-08-20 21:01:494574 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054575 alternative_service, NetworkIsolationKey()));
Matt Menke19475f72019-08-21 18:57:444576 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4577 url::SchemeHostPort("https", request_.url.host(), 443),
4578 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524579}
4580
Matt Menkeb32ba5122019-09-10 19:17:054581TEST_P(QuicNetworkTransactionTest,
4582 ConfirmAlternativeServiceWithNetworkIsolationKey) {
4583 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
4584 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
4585 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
4586 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
4587
4588 base::test::ScopedFeatureList feature_list;
4589 feature_list.InitWithFeatures(
4590 // enabled_features
4591 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4592 features::kPartitionConnectionsByNetworkIsolationKey},
4593 // disabled_features
4594 {});
4595 // Since HttpServerProperties caches the feature value, have to create a new
4596 // one.
4597 http_server_properties_ = std::make_unique<HttpServerProperties>();
4598
4599 MockRead http_reads[] = {
4600 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4601 MockRead("hello world"),
4602 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4603 MockRead(ASYNC, OK)};
4604
4605 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4606 socket_factory_.AddSocketDataProvider(&http_data);
4607 AddCertificate(&ssl_data_);
4608 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4609
4610 MockQuicData mock_quic_data(version_);
4611 int packet_num = 1;
4612 if (VersionUsesQpack(version_.transport_version)) {
4613 mock_quic_data.AddWrite(SYNCHRONOUS,
4614 ConstructInitialSettingsPacket(packet_num++));
4615 }
4616 mock_quic_data.AddWrite(
4617 SYNCHRONOUS,
4618 ConstructClientRequestHeadersPacket(
4619 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4620 true, GetRequestHeaders("GET", "https", "/")));
4621 mock_quic_data.AddRead(
4622 ASYNC, ConstructServerResponseHeadersPacket(
4623 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4624 GetResponseHeaders("200 OK")));
4625 std::string header = ConstructDataHeader(6);
4626 mock_quic_data.AddRead(
4627 ASYNC, ConstructServerDataPacket(
4628 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4629 header + "hello!"));
4630 mock_quic_data.AddWrite(SYNCHRONOUS,
4631 ConstructClientAckPacket(packet_num++, 2, 1, 1));
4632 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4633 mock_quic_data.AddRead(ASYNC, 0); // EOF
4634
4635 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4636
4637 CreateSession();
4638
4639 AlternativeService alternative_service(kProtoQUIC,
4640 HostPortPair::FromURL(request_.url));
4641 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4642 alternative_service, kNetworkIsolationKey1);
4643 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4644 alternative_service, kNetworkIsolationKey2);
4645 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4646 alternative_service, kNetworkIsolationKey1));
4647 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4648 alternative_service, kNetworkIsolationKey2));
4649
4650 request_.network_isolation_key = kNetworkIsolationKey1;
4651 SendRequestAndExpectHttpResponse("hello world");
4652 SendRequestAndExpectQuicResponse("hello!");
4653
4654 mock_quic_data.Resume();
4655
4656 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4657 alternative_service, kNetworkIsolationKey1));
4658 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4659 url::SchemeHostPort("https", request_.url.host(), 443),
4660 kNetworkIsolationKey1));
4661 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4662 alternative_service, kNetworkIsolationKey2));
4663 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4664 url::SchemeHostPort("https", request_.url.host(), 443),
4665 kNetworkIsolationKey2));
4666}
4667
bncc958faa2015-07-31 18:14:524668TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524669 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564670 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4671 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524672 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4673 MockRead(ASYNC, OK)};
4674
Ryan Sleevib8d7ea02018-05-07 20:01:014675 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524676 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564677 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524678
Ryan Hamiltonabad59e2019-06-06 04:02:594679 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234680 int packet_num = 1;
4681 if (VersionUsesQpack(version_.transport_version)) {
4682 mock_quic_data.AddWrite(SYNCHRONOUS,
4683 ConstructInitialSettingsPacket(packet_num++));
4684 }
rch5cb522462017-04-25 20:18:364685 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234686 SYNCHRONOUS,
4687 ConstructClientRequestHeadersPacket(
4688 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4689 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434690 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334691 ASYNC, ConstructServerResponseHeadersPacket(
4692 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4693 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434694 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334695 mock_quic_data.AddRead(
4696 ASYNC, ConstructServerDataPacket(
4697 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174698 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234699 mock_quic_data.AddWrite(SYNCHRONOUS,
4700 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524701 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4702
4703 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4704
4705 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324706 CreateSession();
bncc958faa2015-07-31 18:14:524707
4708 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4709 SendRequestAndExpectHttpResponse("hello world");
4710}
4711
tbansalc3308d72016-08-27 10:25:044712// Tests that the connection to an HTTPS proxy is raced with an available
4713// alternative proxy server.
4714TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274715 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594716 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494717 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044718
Ryan Hamiltonabad59e2019-06-06 04:02:594719 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234720 int packet_num = 1;
4721 if (VersionUsesQpack(version_.transport_version)) {
4722 mock_quic_data.AddWrite(SYNCHRONOUS,
4723 ConstructInitialSettingsPacket(packet_num++));
4724 }
rch5cb522462017-04-25 20:18:364725 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234726 SYNCHRONOUS,
4727 ConstructClientRequestHeadersPacket(
4728 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4729 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434730 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334731 ASYNC, ConstructServerResponseHeadersPacket(
4732 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4733 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434734 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334735 mock_quic_data.AddRead(
4736 ASYNC, ConstructServerDataPacket(
4737 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174738 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234739 mock_quic_data.AddWrite(SYNCHRONOUS,
4740 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044741 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4742 mock_quic_data.AddRead(ASYNC, 0); // EOF
4743
4744 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4745
4746 // There is no need to set up main job, because no attempt will be made to
4747 // speak to the proxy over TCP.
4748 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044749 TestProxyDelegate test_proxy_delegate;
4750 const HostPortPair host_port_pair("mail.example.org", 443);
4751
4752 test_proxy_delegate.set_alternative_proxy_server(
4753 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524754 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044755 CreateSession();
4756 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4757
4758 // The main job needs to hang in order to guarantee that the alternative
4759 // proxy server job will "win".
4760 AddHangingNonAlternateProtocolSocketData();
4761
4762 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4763
4764 // Verify that the alternative proxy server is not marked as broken.
4765 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4766
4767 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594768 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274769
4770 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4771 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4772 1);
tbansalc3308d72016-08-27 10:25:044773}
4774
bnc1c196c6e2016-05-28 13:51:484775TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304776 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274777 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304778
4779 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564780 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294781 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564782 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304783
4784 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564785 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484786 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564787 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304788
Ryan Sleevib8d7ea02018-05-07 20:01:014789 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504790 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084791 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504792 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304793
4794 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454795 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304796 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454797 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304798 };
Ryan Sleevib8d7ea02018-05-07 20:01:014799 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504800 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304801
4802 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014803 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504804 socket_factory_.AddSocketDataProvider(&http_data2);
4805 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304806
bnc912a04b2016-04-20 14:19:504807 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304808
4809 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304810 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174811 ASSERT_TRUE(http_data.AllReadDataConsumed());
4812 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304813
4814 // Now run the second request in which the QUIC socket hangs,
4815 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304816 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454817 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304818
rch37de576c2015-05-17 20:28:174819 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4820 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454821 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304822}
4823
[email protected]1e960032013-12-20 19:00:204824TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594825 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:034826 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:434827 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024828 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4829 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4830 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434831 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334832 ASYNC, ConstructServerResponseHeadersPacket(
4833 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4834 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434835 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334836 mock_quic_data.AddRead(
4837 ASYNC, ConstructServerDataPacket(
4838 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174839 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434840 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504841 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594842 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484843
rcha5399e02015-04-21 19:32:044844 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484845
rtennetib8e80fb2016-05-16 00:12:094846 // The non-alternate protocol job needs to hang in order to guarantee that
4847 // the alternate-protocol job will "win".
4848 AddHangingNonAlternateProtocolSocketData();
4849
rch3f4b8452016-02-23 16:59:324850 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274851 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194852 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304853
Matt Menke19475f72019-08-21 18:57:444854 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4855 url::SchemeHostPort("https", request_.url.host(), 443),
4856 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:484857}
4858
[email protected]1e960032013-12-20 19:00:204859TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594860 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:034861 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Fan Yang32c5a112018-12-10 20:06:334862 mock_quic_data.AddWrite(
4863 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4864 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4865 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434866 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334867 ASYNC, ConstructServerResponseHeadersPacket(
4868 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4869 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434870 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334871 mock_quic_data.AddRead(
4872 ASYNC, ConstructServerDataPacket(
4873 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174874 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434875 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504876 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594877 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044878 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274879
4880 // In order for a new QUIC session to be established via alternate-protocol
4881 // without racing an HTTP connection, we need the host resolution to happen
4882 // synchronously.
4883 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294884 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564885 "");
[email protected]3a120a6b2013-06-25 01:08:274886
rtennetib8e80fb2016-05-16 00:12:094887 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324888 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274889 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274890 SendRequestAndExpectQuicResponse("hello!");
4891}
4892
[email protected]0fc924b2014-03-31 04:34:154893TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494894 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4895 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154896
4897 // Since we are using a proxy, the QUIC job will not succeed.
4898 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294899 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4900 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564901 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154902
4903 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564904 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484905 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564906 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154907
Ryan Sleevib8d7ea02018-05-07 20:01:014908 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154909 socket_factory_.AddSocketDataProvider(&http_data);
4910
4911 // In order for a new QUIC session to be established via alternate-protocol
4912 // without racing an HTTP connection, we need the host resolution to happen
4913 // synchronously.
4914 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294915 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564916 "");
[email protected]0fc924b2014-03-31 04:34:154917
rch9ae5b3b2016-02-11 00:36:294918 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324919 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274920 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154921 SendRequestAndExpectHttpResponse("hello world");
4922}
4923
[email protected]1e960032013-12-20 19:00:204924TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:594925 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234926 int packet_num = 1;
4927 if (VersionUsesQpack(version_.transport_version)) {
4928 mock_quic_data.AddWrite(SYNCHRONOUS,
4929 ConstructInitialSettingsPacket(packet_num++));
4930 }
rch5cb522462017-04-25 20:18:364931 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234932 SYNCHRONOUS,
4933 ConstructClientRequestHeadersPacket(
4934 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4935 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434936 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334937 ASYNC, ConstructServerResponseHeadersPacket(
4938 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4939 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434940 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334941 mock_quic_data.AddRead(
4942 ASYNC, ConstructServerDataPacket(
4943 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174944 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234945 mock_quic_data.AddWrite(SYNCHRONOUS,
4946 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:594947 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044948 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124949
rtennetib8e80fb2016-05-16 00:12:094950 // The non-alternate protocol job needs to hang in order to guarantee that
4951 // the alternate-protocol job will "win".
4952 AddHangingNonAlternateProtocolSocketData();
4953
[email protected]11c05872013-08-20 02:04:124954 // In order for a new QUIC session to be established via alternate-protocol
4955 // without racing an HTTP connection, we need the host resolution to happen
4956 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4957 // connection to the the server, in this test we require confirmation
4958 // before encrypting so the HTTP job will still start.
4959 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294960 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564961 "");
[email protected]11c05872013-08-20 02:04:124962
rch3f4b8452016-02-23 16:59:324963 CreateSession();
[email protected]11c05872013-08-20 02:04:124964 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274965 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:124966
bnc691fda62016-08-12 00:43:164967 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:124968 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364969 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014970 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:124971
4972 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524973 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:014974 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:504975
bnc691fda62016-08-12 00:43:164976 CheckWasQuicResponse(&trans);
4977 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:124978}
4979
Steven Valdez58097ec32018-07-16 18:29:044980TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:014981 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594982 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:034983 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:044984 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014985 SYNCHRONOUS,
4986 ConstructClientRequestHeadersPacket(
4987 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4988 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334989 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024990 ASYNC, ConstructServerResponseHeadersPacket(
4991 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4992 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:014993 mock_quic_data.AddWrite(
4994 SYNCHRONOUS,
4995 ConstructClientAckAndRstPacket(
4996 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
4997 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:044998
4999 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5000
Steven Valdez58097ec32018-07-16 18:29:045001 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015002 SYNCHRONOUS,
5003 ConstructClientRequestHeadersPacket(
5004 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5005 true, GetRequestHeaders("GET", "https", "/"),
5006 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045007 mock_quic_data.AddRead(
5008 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335009 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025010 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435011 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045012 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335013 ASYNC, ConstructServerDataPacket(
5014 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175015 header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045016 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015017 SYNCHRONOUS,
5018 ConstructClientAckAndConnectionClosePacket(packet_number++, 3, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045019 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5020 mock_quic_data.AddRead(ASYNC, 0); // EOF
5021
5022 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5023
5024 // In order for a new QUIC session to be established via alternate-protocol
5025 // without racing an HTTP connection, we need the host resolution to happen
5026 // synchronously.
5027 host_resolver_.set_synchronous_mode(true);
5028 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5029 "");
Steven Valdez58097ec32018-07-16 18:29:045030
5031 AddHangingNonAlternateProtocolSocketData();
5032 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275033 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565034 QuicStreamFactoryPeer::SetAlarmFactory(
5035 session_->quic_stream_factory(),
5036 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5037 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045038
5039 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5040 TestCompletionCallback callback;
5041 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5043
5044 // Confirm the handshake after the 425 Too Early.
5045 base::RunLoop().RunUntilIdle();
5046
5047 // The handshake hasn't been confirmed yet, so the retry should not have
5048 // succeeded.
5049 EXPECT_FALSE(callback.have_result());
5050
5051 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5052 quic::QuicSession::HANDSHAKE_CONFIRMED);
5053
5054 EXPECT_THAT(callback.WaitForResult(), IsOk());
5055 CheckWasQuicResponse(&trans);
5056 CheckResponseData(&trans, "hello!");
5057}
5058
5059TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015060 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595061 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035062 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045063 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015064 SYNCHRONOUS,
5065 ConstructClientRequestHeadersPacket(
5066 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5067 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335068 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025069 ASYNC, ConstructServerResponseHeadersPacket(
5070 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5071 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015072 mock_quic_data.AddWrite(
5073 SYNCHRONOUS,
5074 ConstructClientAckAndRstPacket(
5075 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5076 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045077
5078 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5079
Steven Valdez58097ec32018-07-16 18:29:045080 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015081 SYNCHRONOUS,
5082 ConstructClientRequestHeadersPacket(
5083 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5084 true, GetRequestHeaders("GET", "https", "/"),
5085 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335086 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025087 ASYNC, ConstructServerResponseHeadersPacket(
5088 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5089 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015090 mock_quic_data.AddWrite(
5091 SYNCHRONOUS,
5092 ConstructClientAckAndRstPacket(
5093 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
5094 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045095 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5096 mock_quic_data.AddRead(ASYNC, 0); // EOF
5097
5098 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5099
5100 // In order for a new QUIC session to be established via alternate-protocol
5101 // without racing an HTTP connection, we need the host resolution to happen
5102 // synchronously.
5103 host_resolver_.set_synchronous_mode(true);
5104 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5105 "");
Steven Valdez58097ec32018-07-16 18:29:045106
5107 AddHangingNonAlternateProtocolSocketData();
5108 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275109 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565110 QuicStreamFactoryPeer::SetAlarmFactory(
5111 session_->quic_stream_factory(),
5112 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5113 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045114
5115 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5116 TestCompletionCallback callback;
5117 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5118 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5119
5120 // Confirm the handshake after the 425 Too Early.
5121 base::RunLoop().RunUntilIdle();
5122
5123 // The handshake hasn't been confirmed yet, so the retry should not have
5124 // succeeded.
5125 EXPECT_FALSE(callback.have_result());
5126
5127 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5128 quic::QuicSession::HANDSHAKE_CONFIRMED);
5129
5130 EXPECT_THAT(callback.WaitForResult(), IsOk());
5131 const HttpResponseInfo* response = trans.GetResponseInfo();
5132 ASSERT_TRUE(response != nullptr);
5133 ASSERT_TRUE(response->headers.get() != nullptr);
5134 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5135 EXPECT_TRUE(response->was_fetched_via_spdy);
5136 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565137 EXPECT_EQ(
5138 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5139 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045140}
5141
zhongyica364fbb2015-12-12 03:39:125142TEST_P(QuicNetworkTransactionTest,
5143 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Nick Harper72ade192019-07-17 03:30:425144 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595145 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235146 int packet_num = 1;
5147 if (VersionUsesQpack(version_.transport_version)) {
5148 mock_quic_data.AddWrite(SYNCHRONOUS,
5149 ConstructInitialSettingsPacket(packet_num++));
5150 }
rch5cb522462017-04-25 20:18:365151 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235152 SYNCHRONOUS,
5153 ConstructClientRequestHeadersPacket(
5154 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5155 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125156 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525157 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435158 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125159 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5160
5161 // The non-alternate protocol job needs to hang in order to guarantee that
5162 // the alternate-protocol job will "win".
5163 AddHangingNonAlternateProtocolSocketData();
5164
5165 // In order for a new QUIC session to be established via alternate-protocol
5166 // without racing an HTTP connection, we need the host resolution to happen
5167 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5168 // connection to the the server, in this test we require confirmation
5169 // before encrypting so the HTTP job will still start.
5170 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295171 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125172 "");
zhongyica364fbb2015-12-12 03:39:125173
rch3f4b8452016-02-23 16:59:325174 CreateSession();
zhongyica364fbb2015-12-12 03:39:125175 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275176 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125177
bnc691fda62016-08-12 00:43:165178 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125179 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365180 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015181 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125182
5183 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525184 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015185 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125186
5187 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525188 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125189
bnc691fda62016-08-12 00:43:165190 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125191 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525192 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5193 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125194}
5195
5196TEST_P(QuicNetworkTransactionTest,
5197 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Nick Harper72ade192019-07-17 03:30:425198 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595199 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235200 int packet_num = 1;
5201 if (VersionUsesQpack(version_.transport_version)) {
5202 mock_quic_data.AddWrite(SYNCHRONOUS,
5203 ConstructInitialSettingsPacket(packet_num++));
5204 }
rch5cb522462017-04-25 20:18:365205 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235206 SYNCHRONOUS,
5207 ConstructClientRequestHeadersPacket(
5208 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5209 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215210 // Peer sending data from an non-existing stream causes this end to raise
5211 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335212 mock_quic_data.AddRead(
5213 ASYNC, ConstructServerRstPacket(
5214 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5215 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215216 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tangaadb84b2019-08-31 01:00:235217 mock_quic_data.AddWrite(
5218 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5219 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5220 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
5221 quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125222 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5223
5224 // The non-alternate protocol job needs to hang in order to guarantee that
5225 // the alternate-protocol job will "win".
5226 AddHangingNonAlternateProtocolSocketData();
5227
5228 // In order for a new QUIC session to be established via alternate-protocol
5229 // without racing an HTTP connection, we need the host resolution to happen
5230 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5231 // connection to the the server, in this test we require confirmation
5232 // before encrypting so the HTTP job will still start.
5233 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295234 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125235 "");
zhongyica364fbb2015-12-12 03:39:125236
rch3f4b8452016-02-23 16:59:325237 CreateSession();
zhongyica364fbb2015-12-12 03:39:125238 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275239 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125240
bnc691fda62016-08-12 00:43:165241 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125242 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365243 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015244 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125245
5246 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525247 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015248 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125249 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525250 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125251
bnc691fda62016-08-12 00:43:165252 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525253 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125254}
5255
rchcd5f1c62016-06-23 02:43:485256TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:595257 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235258 int packet_num = 1;
5259 if (VersionUsesQpack(version_.transport_version)) {
5260 mock_quic_data.AddWrite(SYNCHRONOUS,
5261 ConstructInitialSettingsPacket(packet_num++));
5262 }
rch5cb522462017-04-25 20:18:365263 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235264 SYNCHRONOUS,
5265 ConstructClientRequestHeadersPacket(
5266 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5267 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485268 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335269 mock_quic_data.AddRead(
5270 ASYNC, ConstructServerResponseHeadersPacket(
5271 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5272 GetResponseHeaders("200 OK")));
5273 mock_quic_data.AddRead(
5274 ASYNC, ConstructServerRstPacket(
5275 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5276 quic::QUIC_STREAM_CANCELLED));
Renjie Tangaadb84b2019-08-31 01:00:235277 mock_quic_data.AddWrite(SYNCHRONOUS,
5278 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485279 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5280 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5281
5282 // The non-alternate protocol job needs to hang in order to guarantee that
5283 // the alternate-protocol job will "win".
5284 AddHangingNonAlternateProtocolSocketData();
5285
5286 // In order for a new QUIC session to be established via alternate-protocol
5287 // without racing an HTTP connection, we need the host resolution to happen
5288 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5289 // connection to the the server, in this test we require confirmation
5290 // before encrypting so the HTTP job will still start.
5291 host_resolver_.set_synchronous_mode(true);
5292 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5293 "");
rchcd5f1c62016-06-23 02:43:485294
5295 CreateSession();
5296 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275297 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485298
bnc691fda62016-08-12 00:43:165299 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485300 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365301 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015302 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485303
5304 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525305 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485306 // Read the headers.
robpercival214763f2016-07-01 23:27:015307 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485308
bnc691fda62016-08-12 00:43:165309 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485310 ASSERT_TRUE(response != nullptr);
5311 ASSERT_TRUE(response->headers.get() != nullptr);
5312 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5313 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525314 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565315 EXPECT_EQ(
5316 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5317 response->connection_info);
rchcd5f1c62016-06-23 02:43:485318
5319 std::string response_data;
bnc691fda62016-08-12 00:43:165320 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485321}
5322
5323TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Nick Harper72ade192019-07-17 03:30:425324 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595325 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235326 int packet_num = 1;
5327 if (VersionUsesQpack(version_.transport_version)) {
5328 mock_quic_data.AddWrite(SYNCHRONOUS,
5329 ConstructInitialSettingsPacket(packet_num++));
5330 }
rch5cb522462017-04-25 20:18:365331 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235332 SYNCHRONOUS,
5333 ConstructClientRequestHeadersPacket(
5334 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5335 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335336 mock_quic_data.AddRead(
5337 ASYNC, ConstructServerRstPacket(
5338 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5339 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485340 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5341 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5342
5343 // The non-alternate protocol job needs to hang in order to guarantee that
5344 // the alternate-protocol job will "win".
5345 AddHangingNonAlternateProtocolSocketData();
5346
5347 // In order for a new QUIC session to be established via alternate-protocol
5348 // without racing an HTTP connection, we need the host resolution to happen
5349 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5350 // connection to the the server, in this test we require confirmation
5351 // before encrypting so the HTTP job will still start.
5352 host_resolver_.set_synchronous_mode(true);
5353 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5354 "");
rchcd5f1c62016-06-23 02:43:485355
5356 CreateSession();
5357 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275358 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485359
bnc691fda62016-08-12 00:43:165360 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485361 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365362 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015363 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485364
5365 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525366 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485367 // Read the headers.
robpercival214763f2016-07-01 23:27:015368 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485369}
5370
[email protected]1e960032013-12-20 19:00:205371TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305372 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525373 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585374 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305375 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505376 MockRead(ASYNC, close->data(), close->length()),
5377 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5378 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305379 };
Ryan Sleevib8d7ea02018-05-07 20:01:015380 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305381 socket_factory_.AddSocketDataProvider(&quic_data);
5382
5383 // Main job which will succeed even though the alternate job fails.
5384 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025385 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5386 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5387 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305388
Ryan Sleevib8d7ea02018-05-07 20:01:015389 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305390 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565391 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305392
rch3f4b8452016-02-23 16:59:325393 CreateSession();
David Schinazic8281052019-01-24 06:14:175394 AddQuicAlternateProtocolMapping(
5395 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195396 SendRequestAndExpectHttpResponse("hello from http");
5397 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305398}
5399
Matt Menkeb32ba5122019-09-10 19:17:055400TEST_P(QuicNetworkTransactionTest,
5401 BrokenAlternateProtocolWithNetworkIsolationKey) {
5402 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5403 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5404 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5405 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5406
5407 base::test::ScopedFeatureList feature_list;
5408 feature_list.InitWithFeatures(
5409 // enabled_features
5410 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5411 features::kPartitionConnectionsByNetworkIsolationKey},
5412 // disabled_features
5413 {});
5414 // Since HttpServerProperties caches the feature value, have to create a new
5415 // one.
5416 http_server_properties_ = std::make_unique<HttpServerProperties>();
5417
5418 // Alternate-protocol job
5419 std::unique_ptr<quic::QuicEncryptedPacket> close(
5420 ConstructServerConnectionClosePacket(1));
5421 MockRead quic_reads[] = {
5422 MockRead(ASYNC, close->data(), close->length()),
5423 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5424 MockRead(ASYNC, OK), // EOF
5425 };
5426 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5427 socket_factory_.AddSocketDataProvider(&quic_data);
5428
5429 // Main job which will succeed even though the alternate job fails.
5430 MockRead http_reads[] = {
5431 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5432 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5433 MockRead(ASYNC, OK)};
5434
5435 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5436 socket_factory_.AddSocketDataProvider(&http_data);
5437 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5438
5439 CreateSession();
5440 AddQuicAlternateProtocolMapping(
5441 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5442 AddQuicAlternateProtocolMapping(
5443 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5444 request_.network_isolation_key = kNetworkIsolationKey1;
5445 SendRequestAndExpectHttpResponse("hello from http");
5446
5447 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5448 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5449}
5450
[email protected]1e960032013-12-20 19:00:205451TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595452 // Alternate-protocol job
5453 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025454 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595455 };
Ryan Sleevib8d7ea02018-05-07 20:01:015456 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595457 socket_factory_.AddSocketDataProvider(&quic_data);
5458
5459 // Main job which will succeed even though the alternate job fails.
5460 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025461 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5462 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5463 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595464
Ryan Sleevib8d7ea02018-05-07 20:01:015465 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595466 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565467 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595468
rch3f4b8452016-02-23 16:59:325469 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595470
Ryan Hamilton9835e662018-08-02 05:36:275471 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195472 SendRequestAndExpectHttpResponse("hello from http");
5473 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595474}
5475
[email protected]00c159f2014-05-21 22:38:165476TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535477 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165478 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025479 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165480 };
Ryan Sleevib8d7ea02018-05-07 20:01:015481 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165482 socket_factory_.AddSocketDataProvider(&quic_data);
5483
[email protected]eb71ab62014-05-23 07:57:535484 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165485 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025486 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165487 };
5488
Ryan Sleevib8d7ea02018-05-07 20:01:015489 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165490 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5491 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565492 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165493
rtennetib8e80fb2016-05-16 00:12:095494 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325495 CreateSession();
[email protected]00c159f2014-05-21 22:38:165496
Ryan Hamilton9835e662018-08-02 05:36:275497 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165498 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165499 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165500 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015501 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5502 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165503 ExpectQuicAlternateProtocolMapping();
5504}
5505
Zhongyi Shia0cef1082017-08-25 01:49:505506TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5507 // Tests that TCP job is delayed and QUIC job does not require confirmation
5508 // if QUIC was recently supported on the same IP on start.
5509
5510 // Set QUIC support on the last IP address, which is same with the local IP
5511 // address. Require confirmation mode will be turned off immediately when
5512 // local IP address is sorted out after we configure the UDP socket.
Matt Menke3233d8f22019-08-20 21:01:495513 http_server_properties_->SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:505514
Ryan Hamiltonabad59e2019-06-06 04:02:595515 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035516 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:435517 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025518 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5519 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5520 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435521 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335522 ASYNC, ConstructServerResponseHeadersPacket(
5523 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5524 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435525 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335526 mock_quic_data.AddRead(
5527 ASYNC, ConstructServerDataPacket(
5528 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175529 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435530 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505531 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5532 mock_quic_data.AddRead(ASYNC, 0); // EOF
5533
5534 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5535 // No HTTP data is mocked as TCP job never starts in this case.
5536
5537 CreateSession();
5538 // QuicStreamFactory by default requires confirmation on construction.
5539 session_->quic_stream_factory()->set_require_confirmation(true);
5540
Ryan Hamilton9835e662018-08-02 05:36:275541 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505542
5543 // Stall host resolution so that QUIC job will not succeed synchronously.
5544 // Socket will not be configured immediately and QUIC support is not sorted
5545 // out, TCP job will still be delayed as server properties indicates QUIC
5546 // support on last IP address.
5547 host_resolver_.set_synchronous_mode(false);
5548
5549 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5550 TestCompletionCallback callback;
5551 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5552 IsError(ERR_IO_PENDING));
5553 // Complete host resolution in next message loop so that QUIC job could
5554 // proceed.
5555 base::RunLoop().RunUntilIdle();
5556 EXPECT_THAT(callback.WaitForResult(), IsOk());
5557
5558 CheckWasQuicResponse(&trans);
5559 CheckResponseData(&trans, "hello!");
5560}
5561
5562TEST_P(QuicNetworkTransactionTest,
5563 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5564 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5565 // was recently supported on a different IP address on start.
5566
5567 // Set QUIC support on the last IP address, which is different with the local
5568 // IP address. Require confirmation mode will remain when local IP address is
5569 // sorted out after we configure the UDP socket.
Matt Menke3233d8f22019-08-20 21:01:495570 http_server_properties_->SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:505571
Ryan Hamiltonabad59e2019-06-06 04:02:595572 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235573 int packet_num = 1;
5574 if (VersionUsesQpack(version_.transport_version)) {
5575 mock_quic_data.AddWrite(SYNCHRONOUS,
5576 ConstructInitialSettingsPacket(packet_num++));
5577 }
Zhongyi Shia0cef1082017-08-25 01:49:505578 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235579 SYNCHRONOUS,
5580 ConstructClientRequestHeadersPacket(
5581 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5582 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435583 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335584 ASYNC, ConstructServerResponseHeadersPacket(
5585 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5586 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435587 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335588 mock_quic_data.AddRead(
5589 ASYNC, ConstructServerDataPacket(
5590 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175591 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235592 mock_quic_data.AddWrite(SYNCHRONOUS,
5593 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505594 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5595 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5596 // No HTTP data is mocked as TCP job will be delayed and never starts.
5597
5598 CreateSession();
5599 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275600 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505601
5602 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5603 // Socket will not be configured immediately and QUIC support is not sorted
5604 // out, TCP job will still be delayed as server properties indicates QUIC
5605 // support on last IP address.
5606 host_resolver_.set_synchronous_mode(false);
5607
5608 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5609 TestCompletionCallback callback;
5610 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5611 IsError(ERR_IO_PENDING));
5612
5613 // Complete host resolution in next message loop so that QUIC job could
5614 // proceed.
5615 base::RunLoop().RunUntilIdle();
5616 // Explicitly confirm the handshake so that QUIC job could succeed.
5617 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525618 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505619 EXPECT_THAT(callback.WaitForResult(), IsOk());
5620
5621 CheckWasQuicResponse(&trans);
5622 CheckResponseData(&trans, "hello!");
5623}
5624
Ryan Hamilton75f197262017-08-17 14:00:075625TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5626 // Test that NetErrorDetails is correctly populated, even if the
5627 // handshake has not yet been confirmed and no stream has been created.
5628
5629 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595630 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075631 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5632 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5633 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5634
5635 // Main job will also fail.
5636 MockRead http_reads[] = {
5637 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5638 };
5639
Ryan Sleevib8d7ea02018-05-07 20:01:015640 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075641 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5642 socket_factory_.AddSocketDataProvider(&http_data);
5643 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5644
5645 AddHangingNonAlternateProtocolSocketData();
5646 CreateSession();
5647 // Require handshake confirmation to ensure that no QUIC streams are
5648 // created, and to ensure that the TCP job does not wait for the QUIC
5649 // job to fail before it starts.
5650 session_->quic_stream_factory()->set_require_confirmation(true);
5651
Ryan Hamilton9835e662018-08-02 05:36:275652 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075653 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5654 TestCompletionCallback callback;
5655 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5657 // Allow the TCP job to fail.
5658 base::RunLoop().RunUntilIdle();
5659 // Now let the QUIC job fail.
5660 mock_quic_data.Resume();
5661 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5662 ExpectQuicAlternateProtocolMapping();
5663 NetErrorDetails details;
5664 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525665 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075666}
5667
[email protected]1e960032013-12-20 19:00:205668TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455669 // Alternate-protocol job
5670 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025671 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455672 };
Ryan Sleevib8d7ea02018-05-07 20:01:015673 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455674 socket_factory_.AddSocketDataProvider(&quic_data);
5675
[email protected]c92c1b52014-05-31 04:16:065676 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015677 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065678 socket_factory_.AddSocketDataProvider(&quic_data2);
5679
[email protected]4d283b32013-10-17 12:57:275680 // Final job that will proceed when the QUIC job fails.
5681 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025682 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5683 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5684 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275685
Ryan Sleevib8d7ea02018-05-07 20:01:015686 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275687 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565688 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275689
rch3f4b8452016-02-23 16:59:325690 CreateSession();
[email protected]77c6c162013-08-17 02:57:455691
Ryan Hamilton9835e662018-08-02 05:36:275692 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455693
[email protected]4d283b32013-10-17 12:57:275694 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455695
5696 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275697
rch37de576c2015-05-17 20:28:175698 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5699 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455700}
5701
Matt Menkeb32ba5122019-09-10 19:17:055702TEST_P(QuicNetworkTransactionTest,
5703 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
5704 base::test::ScopedFeatureList feature_list;
5705 feature_list.InitWithFeatures(
5706 // enabled_features
5707 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5708 features::kPartitionConnectionsByNetworkIsolationKey},
5709 // disabled_features
5710 {});
5711 // Since HttpServerProperties caches the feature value, have to create a new
5712 // one.
5713 http_server_properties_ = std::make_unique<HttpServerProperties>();
5714
5715 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5716 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5717 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5718 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5719
5720 // Alternate-protocol job
5721 MockRead quic_reads[] = {
5722 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5723 };
5724 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5725 socket_factory_.AddSocketDataProvider(&quic_data);
5726
5727 // Second Alternate-protocol job which will race with the TCP job.
5728 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
5729 socket_factory_.AddSocketDataProvider(&quic_data2);
5730
5731 // Final job that will proceed when the QUIC job fails.
5732 MockRead http_reads[] = {
5733 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5734 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5735 MockRead(ASYNC, OK)};
5736
5737 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5738 socket_factory_.AddSocketDataProvider(&http_data);
5739 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5740
5741 CreateSession();
5742
5743 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
5744 kNetworkIsolationKey1);
5745 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
5746 kNetworkIsolationKey2);
5747
5748 request_.network_isolation_key = kNetworkIsolationKey1;
5749 SendRequestAndExpectHttpResponse("hello from http");
5750 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5751 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
5752
5753 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5754 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5755
5756 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
5757 AddHttpDataAndRunRequest();
5758 // Requests using other NetworkIsolationKeys can still use QUIC.
5759 request_.network_isolation_key = kNetworkIsolationKey2;
5760 AddQuicDataAndRunRequest();
5761
5762 // The last two requests should not have changed the alternative service
5763 // mappings.
5764 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5765 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5766}
5767
[email protected]93b31772014-06-19 08:03:355768TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035769 // Alternate-protocol job
5770 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595771 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035772 };
Ryan Sleevib8d7ea02018-05-07 20:01:015773 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035774 socket_factory_.AddSocketDataProvider(&quic_data);
5775
5776 // Main job that will proceed when the QUIC job fails.
5777 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025778 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5779 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5780 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035781
Ryan Sleevib8d7ea02018-05-07 20:01:015782 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035783 socket_factory_.AddSocketDataProvider(&http_data);
5784
rtennetib8e80fb2016-05-16 00:12:095785 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325786 CreateSession();
[email protected]65768442014-06-06 23:37:035787
Ryan Hamilton9835e662018-08-02 05:36:275788 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035789
5790 SendRequestAndExpectHttpResponse("hello from http");
5791}
5792
[email protected]eb71ab62014-05-23 07:57:535793TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335794 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015795 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495796 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335797 socket_factory_.AddSocketDataProvider(&quic_data);
5798
5799 // Main job which will succeed even though the alternate job fails.
5800 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025801 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5802 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5803 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335804
Ryan Sleevib8d7ea02018-05-07 20:01:015805 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335806 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565807 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335808
rch3f4b8452016-02-23 16:59:325809 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275810 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335811 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535812
5813 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335814}
5815
[email protected]4fee9672014-01-08 14:47:155816TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltonabad59e2019-06-06 04:02:595817 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:175818 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5819 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045820 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155821
5822 // When the QUIC connection fails, we will try the request again over HTTP.
5823 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485824 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565825 MockRead("hello world"),
5826 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5827 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155828
Ryan Sleevib8d7ea02018-05-07 20:01:015829 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155830 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565831 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155832
5833 // In order for a new QUIC session to be established via alternate-protocol
5834 // without racing an HTTP connection, we need the host resolution to happen
5835 // synchronously.
5836 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295837 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565838 "");
[email protected]4fee9672014-01-08 14:47:155839
rch3f4b8452016-02-23 16:59:325840 CreateSession();
David Schinazic8281052019-01-24 06:14:175841 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5842 AddQuicAlternateProtocolMapping(
5843 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155844 SendRequestAndExpectHttpResponse("hello world");
5845}
5846
tbansalc3308d72016-08-27 10:25:045847// For an alternative proxy that supports QUIC, test that the request is
5848// successfully fetched by the main job when the alternate proxy job encounters
5849// an error.
5850TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5851 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5852}
5853TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5854 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5855}
5856TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5857 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5858}
5859TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5860 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5861}
5862TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5863 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5864}
5865TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5866 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5867}
5868TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5869 TestAlternativeProxy(ERR_IO_PENDING);
5870}
5871TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5872 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5873}
5874
5875TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltonabad59e2019-06-06 04:02:595876 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:175877 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5878 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335879 mock_quic_data.AddWrite(
5880 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5881 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5882 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435883 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045884 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5885
5886 // When the QUIC connection fails, we will try the request again over HTTP.
5887 MockRead http_reads[] = {
5888 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5889 MockRead("hello world"),
5890 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5891 MockRead(ASYNC, OK)};
5892
Ryan Sleevib8d7ea02018-05-07 20:01:015893 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045894 socket_factory_.AddSocketDataProvider(&http_data);
5895 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5896
5897 TestProxyDelegate test_proxy_delegate;
5898 const HostPortPair host_port_pair("myproxy.org", 443);
5899 test_proxy_delegate.set_alternative_proxy_server(
5900 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5901 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5902
Ramin Halavatica8d5252018-03-12 05:33:495903 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5904 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525905 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045906 request_.url = GURL("http://mail.example.org/");
5907
5908 // In order for a new QUIC session to be established via alternate-protocol
5909 // without racing an HTTP connection, we need the host resolution to happen
5910 // synchronously.
5911 host_resolver_.set_synchronous_mode(true);
5912 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045913
5914 CreateSession();
David Schinazic8281052019-01-24 06:14:175915 crypto_client_stream_factory_.set_handshake_mode(
5916 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045917 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595918 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165919 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045920}
5921
bnc508835902015-05-12 20:10:295922TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585923 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385924 EXPECT_FALSE(
5925 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:595926 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235927 int packet_num = 1;
5928 if (VersionUsesQpack(version_.transport_version)) {
5929 mock_quic_data.AddWrite(SYNCHRONOUS,
5930 ConstructInitialSettingsPacket(packet_num++));
5931 }
rch5cb522462017-04-25 20:18:365932 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235933 SYNCHRONOUS,
5934 ConstructClientRequestHeadersPacket(
5935 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5936 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435937 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335938 ASYNC, ConstructServerResponseHeadersPacket(
5939 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5940 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435941 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335942 mock_quic_data.AddRead(
5943 ASYNC, ConstructServerDataPacket(
5944 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175945 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235946 mock_quic_data.AddWrite(SYNCHRONOUS,
5947 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505948 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295949 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5950
bncb07c05532015-05-14 19:07:205951 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095952 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325953 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275954 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295955 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385956 EXPECT_TRUE(
5957 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295958}
5959
zhongyi363c91c2017-03-23 23:16:085960// TODO(zhongyi): disabled this broken test as it was not testing the correct
5961// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5962TEST_P(QuicNetworkTransactionTest,
5963 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275964 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595965 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495966 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045967
5968 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045969
5970 test_proxy_delegate.set_alternative_proxy_server(
5971 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525972 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045973
5974 request_.url = GURL("http://mail.example.org/");
5975
5976 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5977 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015978 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045979 socket_factory_.AddSocketDataProvider(&socket_data);
5980
5981 // The non-alternate protocol job needs to hang in order to guarantee that
5982 // the alternate-protocol job will "win".
5983 AddHangingNonAlternateProtocolSocketData();
5984
5985 CreateSession();
5986 request_.method = "POST";
5987 ChunkedUploadDataStream upload_data(0);
5988 upload_data.AppendData("1", 1, true);
5989
5990 request_.upload_data_stream = &upload_data;
5991
5992 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5993 TestCompletionCallback callback;
5994 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5996 EXPECT_NE(OK, callback.WaitForResult());
5997
5998 // Verify that the alternative proxy server is not marked as broken.
5999 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6000
6001 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596002 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276003
6004 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6005 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6006 1);
tbansalc3308d72016-08-27 10:25:046007}
6008
rtenneti56977812016-01-15 19:26:566009TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Nick Harper72ade192019-07-17 03:30:426010 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576011 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566012
Renjie Tangaadb84b2019-08-31 01:00:236013 MockQuicData mock_quic_data(version_);
6014 if (!VersionUsesQpack(version_.transport_version))
6015 mock_quic_data.AddRead(SYNCHRONOUS, OK);
6016 else
6017 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6018 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6019 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6020
6021 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6022 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
6023 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:016024 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:236025 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:566026
rtennetib8e80fb2016-05-16 00:12:096027 // The non-alternate protocol job needs to hang in order to guarantee that
6028 // the alternate-protocol job will "win".
6029 AddHangingNonAlternateProtocolSocketData();
6030
rtenneti56977812016-01-15 19:26:566031 CreateSession();
6032 request_.method = "POST";
6033 ChunkedUploadDataStream upload_data(0);
6034 upload_data.AppendData("1", 1, true);
6035
6036 request_.upload_data_stream = &upload_data;
6037
bnc691fda62016-08-12 00:43:166038 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566039 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166040 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016041 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566042 EXPECT_NE(OK, callback.WaitForResult());
6043}
6044
rche11300ef2016-09-02 01:44:286045TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Nick Harper72ade192019-07-17 03:30:426046 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286047 ScopedMockNetworkChangeNotifier network_change_notifier;
6048 MockNetworkChangeNotifier* mock_ncn =
6049 network_change_notifier.mock_network_change_notifier();
6050 mock_ncn->ForceNetworkHandlesSupported();
6051 mock_ncn->SetConnectedNetworksList(
6052 {kDefaultNetworkForTests, kNewNetworkForTests});
6053
Nick Harper72ade192019-07-17 03:30:426054 session_params_.quic_params.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286055 HostPortPair::FromString("mail.example.org:443"));
Nick Harper72ade192019-07-17 03:30:426056 session_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286057
Ryan Hamiltonabad59e2019-06-06 04:02:596058 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286059 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236060 int packet_num = 1;
6061 if (VersionUsesQpack(version_.transport_version)) {
6062 socket_data.AddWrite(SYNCHRONOUS,
6063 ConstructInitialSettingsPacket(packet_num++));
6064 }
Fan Yang32c5a112018-12-10 20:06:336065 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236066 SYNCHRONOUS,
6067 ConstructClientRequestHeadersPacket(
6068 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6069 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:286070 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6071 socket_data.AddSocketDataToFactory(&socket_factory_);
6072
Ryan Hamiltonabad59e2019-06-06 04:02:596073 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286074 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6075 socket_data2.AddSocketDataToFactory(&socket_factory_);
6076
6077 // The non-alternate protocol job needs to hang in order to guarantee that
6078 // the alternate-protocol job will "win".
6079 AddHangingNonAlternateProtocolSocketData();
6080
6081 CreateSession();
6082 request_.method = "POST";
6083 ChunkedUploadDataStream upload_data(0);
6084
6085 request_.upload_data_stream = &upload_data;
6086
rdsmith1d343be52016-10-21 20:37:506087 std::unique_ptr<HttpNetworkTransaction> trans(
6088 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286089 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506090 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286091 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6092
6093 base::RunLoop().RunUntilIdle();
6094 upload_data.AppendData("1", 1, true);
6095 base::RunLoop().RunUntilIdle();
6096
6097 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506098 trans.reset();
rche11300ef2016-09-02 01:44:286099 session_.reset();
6100}
6101
Ryan Hamilton4b3574532017-10-30 20:17:256102TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426103 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256104 HostPortPair::FromString("mail.example.org:443"));
6105
Ryan Hamiltonabad59e2019-06-06 04:02:596106 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236107 int packet_num = 1;
6108 if (VersionUsesQpack(version_.transport_version)) {
6109 socket_data.AddWrite(SYNCHRONOUS,
6110 ConstructInitialSettingsPacket(packet_num++));
6111 }
Ryan Hamilton4b3574532017-10-30 20:17:256112 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336113 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236114 SYNCHRONOUS,
6115 ConstructClientRequestHeadersPacket(
6116 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6117 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436118 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336119 ASYNC, ConstructServerResponseHeadersPacket(
6120 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6121 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436122 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336123 socket_data.AddRead(
6124 ASYNC, ConstructServerDataPacket(
6125 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176126 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236127 socket_data.AddWrite(SYNCHRONOUS,
6128 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256129 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166130 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236131 SYNCHRONOUS,
6132 client_maker_.MakeAckAndConnectionClosePacket(
6133 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2, 1,
6134 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256135
6136 socket_data.AddSocketDataToFactory(&socket_factory_);
6137
6138 CreateSession();
6139
6140 SendRequestAndExpectQuicResponse("hello!");
6141 session_.reset();
6142}
6143
6144TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426145 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256146 HostPortPair::FromString("mail.example.org:443"));
6147
Ryan Hamiltonabad59e2019-06-06 04:02:596148 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236149 int packet_num = 1;
6150 if (VersionUsesQpack(version_.transport_version)) {
6151 socket_data.AddWrite(SYNCHRONOUS,
6152 ConstructInitialSettingsPacket(packet_num++));
6153 }
Ryan Hamilton4b3574532017-10-30 20:17:256154 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336155 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236156 SYNCHRONOUS,
6157 ConstructClientRequestHeadersPacket(
6158 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6159 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436160 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336161 ASYNC, ConstructServerResponseHeadersPacket(
6162 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6163 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436164 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336165 socket_data.AddRead(
6166 ASYNC, ConstructServerDataPacket(
6167 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176168 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236169 socket_data.AddWrite(SYNCHRONOUS,
6170 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256171 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166172 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236173 SYNCHRONOUS,
6174 client_maker_.MakeAckAndConnectionClosePacket(
6175 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2, 1,
6176 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256177
6178 socket_data.AddSocketDataToFactory(&socket_factory_);
6179
6180 CreateSession();
6181
6182 SendRequestAndExpectQuicResponse("hello!");
6183 session_.reset();
6184}
6185
Ryan Hamilton9edcf1a2017-11-22 05:55:176186TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426187 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6188 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256189 HostPortPair::FromString("mail.example.org:443"));
6190
Ryan Hamiltonabad59e2019-06-06 04:02:596191 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256192 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:236193 if (VersionUsesQpack(version_.transport_version))
6194 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176195 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256196 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6197 }
6198 socket_data.AddSocketDataToFactory(&socket_factory_);
6199
6200 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176201 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176202 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6203 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256204
Ryan Hamilton8d9ee76e2018-05-29 23:52:526205 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256206 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6207 TestCompletionCallback callback;
6208 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6209 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176210 while (!callback.have_result()) {
6211 base::RunLoop().RunUntilIdle();
6212 quic_task_runner_->RunUntilIdle();
6213 }
6214 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256215 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176216 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6217 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6218 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526219 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6220 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256221}
6222
Ryan Hamilton9edcf1a2017-11-22 05:55:176223TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426224 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6225 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256226 HostPortPair::FromString("mail.example.org:443"));
6227
Ryan Hamiltonabad59e2019-06-06 04:02:596228 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256229 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:236230 if (VersionUsesQpack(version_.transport_version))
6231 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176232 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256233 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6234 }
6235 socket_data.AddSocketDataToFactory(&socket_factory_);
6236
6237 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176238 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176239 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6240 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256241
Ryan Hamilton8d9ee76e2018-05-29 23:52:526242 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256243 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6244 TestCompletionCallback callback;
6245 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6246 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176247 while (!callback.have_result()) {
6248 base::RunLoop().RunUntilIdle();
6249 quic_task_runner_->RunUntilIdle();
6250 }
6251 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256252 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176253 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6254 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6255 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526256 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6257 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256258}
6259
Cherie Shi7596de632018-02-22 07:28:186260TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Nick Harper72ade192019-07-17 03:30:426261 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6262 session_params_.quic_params.origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186263 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436264 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:526265 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6266 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186267
Ryan Hamiltonabad59e2019-06-06 04:02:596268 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186269 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236270 int packet_num = 1;
6271 if (VersionUsesQpack(version_.transport_version)) {
6272 socket_data.AddWrite(SYNCHRONOUS,
6273 ConstructInitialSettingsPacket(packet_num++));
6274 }
Cherie Shi7596de632018-02-22 07:28:186275 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6276 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526277 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236278 SYNCHRONOUS,
6279 client_maker_.MakeConnectionClosePacket(
6280 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186281 socket_data.AddSocketDataToFactory(&socket_factory_);
6282
6283 CreateSession();
6284
6285 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6286 TestCompletionCallback callback;
6287 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6288 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6289 base::RunLoop().RunUntilIdle();
6290 ASSERT_TRUE(callback.have_result());
6291 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6292 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6293 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6294}
6295
ckrasic769733c2016-06-30 00:42:136296// Adds coverage to catch regression such as https://crbug.com/622043
6297TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Nick Harper72ade192019-07-17 03:30:426298 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136299 HostPortPair::FromString("mail.example.org:443"));
6300
Ryan Hamiltonabad59e2019-06-06 04:02:596301 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236302 uint64_t client_packet_number = 1;
Renjie Tangaadb84b2019-08-31 01:00:236303 if (VersionUsesQpack(version_.transport_version)) {
6304 mock_quic_data.AddWrite(
6305 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6306 }
Zhongyi Shi32f2fd02018-04-16 18:23:436307 mock_quic_data.AddWrite(
6308 SYNCHRONOUS,
6309 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336310 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026311 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436312 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026313 ASYNC,
6314 ConstructServerPushPromisePacket(
6315 1, GetNthClientInitiatedBidirectionalStreamId(0),
6316 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6317 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316318 if ((client_headers_include_h2_stream_dependency_ &&
6319 version_.transport_version >= quic::QUIC_VERSION_43) ||
6320 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026321 mock_quic_data.AddWrite(
6322 SYNCHRONOUS,
6323 ConstructClientPriorityPacket(
6324 client_packet_number++, false,
6325 GetNthServerInitiatedUnidirectionalStreamId(0),
6326 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576327 }
Zhongyi Shi32f2fd02018-04-16 18:23:436328 mock_quic_data.AddRead(
6329 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336330 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026331 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:576332 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436333 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6334 mock_quic_data.AddRead(
6335 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336336 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026337 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436338 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436339 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336340 ASYNC, ConstructServerDataPacket(
6341 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176342 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576343 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436344 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436345 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436346 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336347 ASYNC, ConstructServerDataPacket(
6348 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176349 header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336350 mock_quic_data.AddWrite(SYNCHRONOUS,
6351 ConstructClientAckAndRstPacket(
6352 client_packet_number++,
6353 GetNthServerInitiatedUnidirectionalStreamId(0),
6354 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136355 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6356 mock_quic_data.AddRead(ASYNC, 0); // EOF
6357 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6358
6359 // The non-alternate protocol job needs to hang in order to guarantee that
6360 // the alternate-protocol job will "win".
6361 AddHangingNonAlternateProtocolSocketData();
6362
6363 CreateSession();
6364
6365 // PUSH_PROMISE handling in the http layer gets exercised here.
6366 SendRequestAndExpectQuicResponse("hello!");
6367
6368 request_.url = GURL("https://mail.example.org/pushed.jpg");
6369 SendRequestAndExpectQuicResponse("and hello!");
6370
6371 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:546372 auto entries = net_log_.GetEntries();
ckrasic769733c2016-06-30 00:42:136373 EXPECT_LT(0u, entries.size());
6374
6375 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6376 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006377 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6378 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136379 EXPECT_LT(0, pos);
6380}
6381
rch56ec40a2017-06-23 14:48:446382// Regression test for http://crbug.com/719461 in which a promised stream
6383// is closed before the pushed headers arrive, but after the connection
6384// is closed and before the callbacks are executed.
6385TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Nick Harper72ade192019-07-17 03:30:426386 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6387 session_params_.quic_params.origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446388 HostPortPair::FromString("mail.example.org:443"));
6389
Ryan Hamiltonabad59e2019-06-06 04:02:596390 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236391 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446392 // Initial SETTINGS frame.
Renjie Tangaadb84b2019-08-31 01:00:236393 if (VersionUsesQpack(version_.transport_version)) {
6394 mock_quic_data.AddWrite(
6395 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6396 }
rch56ec40a2017-06-23 14:48:446397 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436398 mock_quic_data.AddWrite(
6399 SYNCHRONOUS,
6400 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336401 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026402 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446403 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436404 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026405 ASYNC,
6406 ConstructServerPushPromisePacket(
6407 1, GetNthClientInitiatedBidirectionalStreamId(0),
6408 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6409 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316410 if ((client_headers_include_h2_stream_dependency_ &&
6411 version_.transport_version >= quic::QUIC_VERSION_43) ||
6412 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026413 mock_quic_data.AddWrite(
6414 SYNCHRONOUS,
6415 ConstructClientPriorityPacket(
6416 client_packet_number++, false,
6417 GetNthServerInitiatedUnidirectionalStreamId(0),
6418 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576419 }
rch56ec40a2017-06-23 14:48:446420 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436421 mock_quic_data.AddRead(
6422 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336423 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026424 GetResponseHeaders("200 OK")));
rch56ec40a2017-06-23 14:48:446425 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576426 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436427 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446428 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:436429 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436430 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336431 ASYNC, ConstructServerDataPacket(
6432 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176433 header + "hello!"));
rch56ec40a2017-06-23 14:48:446434 // Write error for the third request.
6435 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6436 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6437 mock_quic_data.AddRead(ASYNC, 0); // EOF
6438 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6439
6440 CreateSession();
6441
6442 // Send a request which triggers a push promise from the server.
6443 SendRequestAndExpectQuicResponse("hello!");
6444
6445 // Start a push transaction that will be cancelled after the connection
6446 // is closed, but before the callback is executed.
6447 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196448 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446449 session_.get());
6450 TestCompletionCallback callback2;
6451 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6452 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6453 base::RunLoop().RunUntilIdle();
6454
6455 // Cause the connection to close on a write error.
6456 HttpRequestInfo request3;
6457 request3.method = "GET";
6458 request3.url = GURL("https://mail.example.org/");
6459 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106460 request3.traffic_annotation =
6461 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446462 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6463 TestCompletionCallback callback3;
6464 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6465 IsError(ERR_IO_PENDING));
6466
6467 base::RunLoop().RunUntilIdle();
6468
6469 // When |trans2| is destroyed, the underlying stream will be closed.
6470 EXPECT_FALSE(callback2.have_result());
6471 trans2 = nullptr;
6472
6473 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6474}
6475
ckrasicda193a82016-07-09 00:39:366476TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Nick Harper72ade192019-07-17 03:30:426477 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366478 HostPortPair::FromString("mail.example.org:443"));
6479
Ryan Hamiltonabad59e2019-06-06 04:02:596480 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:366481
Renjief49758b2019-01-11 23:32:416482 int write_packet_index = 1;
Renjie Tangaadb84b2019-08-31 01:00:236483 if (VersionUsesQpack(version_.transport_version)) {
6484 mock_quic_data.AddWrite(
6485 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
6486 }
ckrasicda193a82016-07-09 00:39:366487
Victor Vasiliev076657c2019-03-12 02:46:436488 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:566489 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416490 mock_quic_data.AddWrite(
6491 SYNCHRONOUS,
6492 ConstructClientRequestHeadersAndDataFramesPacket(
6493 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6494 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:026495 GetRequestHeaders("POST", "https", "/"), 0, nullptr, {"1"}));
Renjief49758b2019-01-11 23:32:416496 } else {
6497 mock_quic_data.AddWrite(
6498 SYNCHRONOUS,
6499 ConstructClientRequestHeadersAndDataFramesPacket(
6500 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6501 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:026502 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
Renjief49758b2019-01-11 23:32:416503 {header, "1"}));
6504 }
ckrasicda193a82016-07-09 00:39:366505
Zhongyi Shi32f2fd02018-04-16 18:23:436506 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336507 ASYNC, ConstructServerResponseHeadersPacket(
6508 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6509 GetResponseHeaders("200 OK")));
6510
Victor Vasiliev076657c2019-03-12 02:46:436511 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336512 mock_quic_data.AddRead(
6513 ASYNC, ConstructServerDataPacket(
6514 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176515 header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366516
Renjief49758b2019-01-11 23:32:416517 mock_quic_data.AddWrite(
6518 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366519
6520 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6521 mock_quic_data.AddRead(ASYNC, 0); // EOF
6522 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6523
6524 // The non-alternate protocol job needs to hang in order to guarantee that
6525 // the alternate-protocol job will "win".
6526 AddHangingNonAlternateProtocolSocketData();
6527
6528 CreateSession();
6529 request_.method = "POST";
6530 ChunkedUploadDataStream upload_data(0);
6531 upload_data.AppendData("1", 1, true);
6532
6533 request_.upload_data_stream = &upload_data;
6534
6535 SendRequestAndExpectQuicResponse("hello!");
6536}
6537
allada71b2efb2016-09-09 04:57:486538class QuicURLRequestContext : public URLRequestContext {
6539 public:
6540 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6541 MockClientSocketFactory* socket_factory)
6542 : storage_(this) {
6543 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076544 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046545 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486546 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046547 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596548 storage_.set_proxy_resolution_service(
6549 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076550 storage_.set_ssl_config_service(
6551 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486552 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:116553 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:486554 storage_.set_http_server_properties(
Matt Menke609160742019-08-02 18:47:266555 std::make_unique<HttpServerProperties>());
Bence Béky8f9d7d3952017-10-09 19:58:046556 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486557 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046558 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6559 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6560 false));
allada71b2efb2016-09-09 04:57:486561 }
6562
6563 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6564
6565 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6566
6567 private:
6568 MockClientSocketFactory* socket_factory_;
6569 URLRequestContextStorage storage_;
6570};
6571
6572TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
Nick Harper72ade192019-07-17 03:30:426573 session_params_.quic_params.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486574 HostPortPair::FromString("mail.example.org:443"));
6575
Ryan Hamiltonabad59e2019-06-06 04:02:596576 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236577 int packet_num = 1;
6578 if (VersionUsesQpack(version_.transport_version)) {
6579 mock_quic_data.AddWrite(SYNCHRONOUS,
6580 ConstructInitialSettingsPacket(packet_num++));
6581 }
Ryan Hamilton0239aac2018-05-19 00:03:136582 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486583 headers["user-agent"] = "";
6584 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336585 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236586 SYNCHRONOUS,
6587 ConstructClientRequestHeadersPacket(
6588 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6589 true, std::move(headers)));
allada71b2efb2016-09-09 04:57:486590
Fan Yang32c5a112018-12-10 20:06:336591 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026592 ASYNC, ConstructServerResponseHeadersPacket(
6593 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6594 GetResponseHeaders("200 OK")));
6595 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:456596 server_maker_.stream_offset(
6597 quic::VersionUsesQpack(version_.transport_version)
6598 ? GetNthClientInitiatedBidirectionalStreamId(0)
6599 : quic::QuicUtils::GetHeadersStreamId(
6600 version_.transport_version));
allada71b2efb2016-09-09 04:57:486601
Victor Vasiliev076657c2019-03-12 02:46:436602 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366603 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336604 ASYNC, ConstructServerDataPacket(
6605 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176606 "Main Resource Data"));
Renjie Tangaadb84b2019-08-31 01:00:236607 mock_quic_data.AddWrite(SYNCHRONOUS,
6608 ConstructClientAckPacket(packet_num++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486609
6610 mock_quic_data.AddRead(ASYNC, 0); // EOF
6611
6612 CreateSession();
6613
6614 TestDelegate delegate;
6615 QuicURLRequestContext quic_url_request_context(std::move(session_),
6616 &socket_factory_);
6617
6618 mock_quic_data.AddSocketDataToFactory(
6619 &quic_url_request_context.socket_factory());
6620 TestNetworkDelegate network_delegate;
6621 quic_url_request_context.set_network_delegate(&network_delegate);
6622
6623 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296624 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6625 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486626 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6627 &ssl_data_);
6628
6629 request->Start();
Wez2a31b222018-06-07 22:07:156630 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486631
6632 EXPECT_LT(0, request->GetTotalSentBytes());
6633 EXPECT_LT(0, request->GetTotalReceivedBytes());
6634 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6635 request->GetTotalSentBytes());
6636 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6637 request->GetTotalReceivedBytes());
6638 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6639 request->raw_header_size());
Wez0e717112018-06-18 23:09:226640
6641 // Pump the message loop to allow all data to be consumed.
6642 base::RunLoop().RunUntilIdle();
6643
allada71b2efb2016-09-09 04:57:486644 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6645 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6646}
6647
6648TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
Nick Harper72ade192019-07-17 03:30:426649 session_params_.quic_params.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486650 HostPortPair::FromString("mail.example.org:443"));
6651
Ryan Hamiltonabad59e2019-06-06 04:02:596652 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236653 uint64_t client_packet_number = 1;
Renjie Tangaadb84b2019-08-31 01:00:236654 if (VersionUsesQpack(version_.transport_version)) {
6655 mock_quic_data.AddWrite(
6656 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6657 }
Ryan Hamilton0239aac2018-05-19 00:03:136658 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486659 headers["user-agent"] = "";
6660 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436661 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336662 SYNCHRONOUS,
6663 ConstructClientRequestHeadersPacket(
6664 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026665 true, true, std::move(headers)));
allada71b2efb2016-09-09 04:57:486666
Fan Yang2330d182019-08-05 14:50:506667 const quic::QuicStreamOffset initial = server_maker_.stream_offset(
6668 GetNthClientInitiatedBidirectionalStreamId(0));
Zhongyi Shi32f2fd02018-04-16 18:23:436669 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026670 ASYNC,
6671 ConstructServerPushPromisePacket(
6672 1, GetNthClientInitiatedBidirectionalStreamId(0),
6673 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6674 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Fan Yang2330d182019-08-05 14:50:506675 quic::QuicStreamOffset push_promise_offset = 0;
6676 if (VersionUsesQpack(version_.transport_version)) {
6677 push_promise_offset = server_maker_.stream_offset(
6678 GetNthClientInitiatedBidirectionalStreamId(0)) -
6679 initial;
6680 }
allada71b2efb2016-09-09 04:57:486681
Renjie Tang703fea92019-07-23 21:08:316682 if ((client_headers_include_h2_stream_dependency_ &&
6683 version_.transport_version >= quic::QUIC_VERSION_43) ||
6684 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026685 mock_quic_data.AddWrite(
6686 SYNCHRONOUS,
6687 ConstructClientPriorityPacket(
6688 client_packet_number++, false,
6689 GetNthServerInitiatedUnidirectionalStreamId(0),
6690 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576691 }
6692
Ryan Hamiltone940bd12019-06-30 02:46:456693 const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
6694 quic::VersionUsesQpack(version_.transport_version)
6695 ? GetNthClientInitiatedBidirectionalStreamId(0)
6696 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Zhongyi Shi32f2fd02018-04-16 18:23:436697 mock_quic_data.AddRead(
6698 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336699 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026700 GetResponseHeaders("200 OK")));
Ryan Hamiltone940bd12019-06-30 02:46:456701 const quic::QuicStreamOffset final_offset = server_maker_.stream_offset(
6702 quic::VersionUsesQpack(version_.transport_version)
6703 ? GetNthClientInitiatedBidirectionalStreamId(0)
6704 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Ryan Hamilton0d65a8c2019-06-07 00:46:026705 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:456706 final_offset - initial_offset;
allada71b2efb2016-09-09 04:57:486707
Yixin Wangb470bc882018-02-15 18:43:576708 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436709 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486710
ckrasicbf2f59c2017-05-04 23:54:366711 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436712 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336713 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026714 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436715 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436716 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336717 ASYNC, ConstructServerDataPacket(
6718 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176719 header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486720
Yixin Wangb470bc882018-02-15 18:43:576721 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436722 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436723 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366724 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336725 ASYNC, ConstructServerDataPacket(
6726 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176727 header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486728
Zhongyi Shi32f2fd02018-04-16 18:23:436729 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486730
6731 CreateSession();
6732
6733 TestDelegate delegate;
6734 QuicURLRequestContext quic_url_request_context(std::move(session_),
6735 &socket_factory_);
6736
6737 mock_quic_data.AddSocketDataToFactory(
6738 &quic_url_request_context.socket_factory());
6739 TestNetworkDelegate network_delegate;
6740 quic_url_request_context.set_network_delegate(&network_delegate);
6741
6742 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296743 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6744 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486745 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6746 &ssl_data_);
6747
6748 request->Start();
Wez2a31b222018-06-07 22:07:156749 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486750
6751 EXPECT_LT(0, request->GetTotalSentBytes());
6752 EXPECT_LT(0, request->GetTotalReceivedBytes());
6753 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6754 request->GetTotalSentBytes());
6755 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6756 request->GetTotalReceivedBytes());
Fan Yang2330d182019-08-05 14:50:506757 EXPECT_EQ(
6758 static_cast<int>(expected_raw_header_response_size + push_promise_offset),
6759 request->raw_header_size());
Wez0e717112018-06-18 23:09:226760
6761 // Pump the message loop to allow all data to be consumed.
6762 base::RunLoop().RunUntilIdle();
6763
allada71b2efb2016-09-09 04:57:486764 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6765 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6766}
6767
Ryan Sleevia9d6aa62019-07-26 13:32:186768TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
6769 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:206770
6771 MockRead http_reads[] = {
6772 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6773 MockRead("hello world"),
6774 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6775 MockRead(ASYNC, OK)};
6776
Ryan Sleevib8d7ea02018-05-07 20:01:016777 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206778 socket_factory_.AddSocketDataProvider(&http_data);
6779 AddCertificate(&ssl_data_);
6780 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6781
Ryan Hamiltonabad59e2019-06-06 04:02:596782 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236783 int packet_num = 1;
6784 if (VersionUsesQpack(version_.transport_version)) {
6785 mock_quic_data.AddWrite(SYNCHRONOUS,
6786 ConstructInitialSettingsPacket(packet_num++));
6787 }
Yixin Wang10f477ed2017-11-21 04:20:206788 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236789 SYNCHRONOUS,
6790 ConstructClientRequestHeadersPacket(
6791 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6792 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436793 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336794 ASYNC, ConstructServerResponseHeadersPacket(
6795 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6796 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436797 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336798 mock_quic_data.AddRead(
6799 ASYNC, ConstructServerDataPacket(
6800 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176801 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236802 mock_quic_data.AddWrite(SYNCHRONOUS,
6803 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206804 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6805 mock_quic_data.AddRead(ASYNC, 0); // EOF
6806
6807 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6808
6809 AddHangingNonAlternateProtocolSocketData();
6810 CreateSession();
6811
6812 SendRequestAndExpectHttpResponse("hello world");
6813 SendRequestAndExpectQuicResponse("hello!");
6814}
6815
Ryan Sleevia9d6aa62019-07-26 13:32:186816TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
6817 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:206818
6819 MockRead http_reads[] = {
6820 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6821 MockRead("hello world"),
6822 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6823 MockRead(ASYNC, OK)};
6824
Ryan Sleevib8d7ea02018-05-07 20:01:016825 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206826 socket_factory_.AddSocketDataProvider(&http_data);
6827 AddCertificate(&ssl_data_);
6828 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6829 socket_factory_.AddSocketDataProvider(&http_data);
6830 AddCertificate(&ssl_data_);
6831 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6832
6833 AddHangingNonAlternateProtocolSocketData();
6834 CreateSession();
6835
6836 SendRequestAndExpectHttpResponse("hello world");
6837 SendRequestAndExpectHttpResponse("hello world");
6838}
6839
bnc359ed2a2016-04-29 20:43:456840class QuicNetworkTransactionWithDestinationTest
6841 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016842 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:056843 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456844 protected:
6845 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556846 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056847 client_headers_include_h2_stream_dependency_(
6848 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:566849 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:456850 destination_type_(GetParam().destination_type),
6851 cert_transparency_verifier_(new MultiLogCTVerifier()),
6852 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596853 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:116854 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:456855 random_generator_(0),
6856 ssl_data_(ASYNC, OK) {}
6857
6858 void SetUp() override {
6859 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556860 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456861
mmenke6ddfbea2017-05-31 21:48:416862 HttpNetworkSession::Params session_params;
6863 session_params.enable_quic = true;
Nick Harper72ade192019-07-17 03:30:426864 session_params.quic_params.allow_remote_alt_svc = true;
6865 session_params.quic_params.supported_versions = supported_versions_;
6866 session_params.quic_params.headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:056867 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416868
6869 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456870
Ryan Hamilton8d9ee76e2018-05-29 23:52:526871 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416872 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456873
6874 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276875 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416876 session_context.quic_crypto_client_stream_factory =
6877 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456878
mmenke6ddfbea2017-05-31 21:48:416879 session_context.quic_random = &random_generator_;
6880 session_context.client_socket_factory = &socket_factory_;
6881 session_context.host_resolver = &host_resolver_;
6882 session_context.cert_verifier = &cert_verifier_;
6883 session_context.transport_security_state = &transport_security_state_;
6884 session_context.cert_transparency_verifier =
6885 cert_transparency_verifier_.get();
6886 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6887 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456888 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416889 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596890 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416891 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6892 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456893
mmenke6ddfbea2017-05-31 21:48:416894 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456895 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456896 }
6897
6898 void TearDown() override {
6899 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6900 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556901 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456902 PlatformTest::TearDown();
6903 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556904 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406905 session_.reset();
bnc359ed2a2016-04-29 20:43:456906 }
6907
zhongyie537a002017-06-27 16:48:216908 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456909 HostPortPair destination;
6910 switch (destination_type_) {
6911 case SAME_AS_FIRST:
6912 destination = HostPortPair(origin1_, 443);
6913 break;
6914 case SAME_AS_SECOND:
6915 destination = HostPortPair(origin2_, 443);
6916 break;
6917 case DIFFERENT:
6918 destination = HostPortPair(kDifferentHostname, 443);
6919 break;
6920 }
bnc3472afd2016-11-17 15:27:216921 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456922 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216923 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:076924 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
6925 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456926 }
6927
Ryan Hamilton8d9ee76e2018-05-29 23:52:526928 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236929 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526930 quic::QuicStreamId stream_id,
6931 bool should_include_version,
6932 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526933 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136934 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456935 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136936 spdy::SpdyHeaderBlock headers(
6937 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:026938 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456939 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:026940 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:456941 }
6942
Ryan Hamilton8d9ee76e2018-05-29 23:52:526943 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236944 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526945 quic::QuicStreamId stream_id,
6946 bool should_include_version,
6947 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586948 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:026949 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:456950 }
6951
Ryan Hamilton8d9ee76e2018-05-29 23:52:526952 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236953 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526954 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526955 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136956 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
Ryan Hamilton0d65a8c2019-06-07 00:46:026957 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
6958 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:456959 }
6960
Ryan Hamilton8d9ee76e2018-05-29 23:52:526961 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:236962 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526963 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456964 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:436965 std::string header = "";
Nick Harper23290b82019-05-02 00:02:566966 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416967 quic::HttpEncoder encoder;
6968 std::unique_ptr<char[]> buffer;
6969 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:436970 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:416971 }
Ryan Hamilton7505eb92019-06-08 00:22:176972 return maker->MakeDataPacket(packet_number, stream_id, false, true,
Renjief49758b2019-01-11 23:32:416973 header + "hello");
bnc359ed2a2016-04-29 20:43:456974 }
6975
Ryan Hamilton8d9ee76e2018-05-29 23:52:526976 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:236977 uint64_t packet_number,
6978 uint64_t largest_received,
6979 uint64_t smallest_received,
6980 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:456981 QuicTestPacketMaker* maker) {
6982 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496983 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456984 }
6985
Ryan Hamilton8d9ee76e2018-05-29 23:52:526986 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:236987 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:376988 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026989 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:376990 }
6991
bnc359ed2a2016-04-29 20:43:456992 void AddRefusedSocketData() {
6993 std::unique_ptr<StaticSocketDataProvider> refused_data(
6994 new StaticSocketDataProvider());
6995 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6996 refused_data->set_connect_data(refused_connect);
6997 socket_factory_.AddSocketDataProvider(refused_data.get());
6998 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6999 }
7000
7001 void AddHangingSocketData() {
7002 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7003 new StaticSocketDataProvider());
7004 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7005 hanging_data->set_connect_data(hanging_connect);
7006 socket_factory_.AddSocketDataProvider(hanging_data.get());
7007 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7008 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7009 }
7010
7011 bool AllDataConsumed() {
7012 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7013 if (!socket_data_ptr->AllReadDataConsumed() ||
7014 !socket_data_ptr->AllWriteDataConsumed()) {
7015 return false;
7016 }
7017 }
7018 return true;
7019 }
7020
7021 void SendRequestAndExpectQuicResponse(const std::string& host) {
7022 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7023 HttpRequestInfo request;
7024 std::string url("https://");
7025 url.append(host);
7026 request.url = GURL(url);
7027 request.load_flags = 0;
7028 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107029 request.traffic_annotation =
7030 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457031 TestCompletionCallback callback;
7032 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017033 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457034
7035 std::string response_data;
robpercival214763f2016-07-01 23:27:017036 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457037 EXPECT_EQ("hello", response_data);
7038
7039 const HttpResponseInfo* response = trans.GetResponseInfo();
7040 ASSERT_TRUE(response != nullptr);
7041 ASSERT_TRUE(response->headers.get() != nullptr);
7042 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7043 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527044 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:567045 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
7046 version_.transport_version),
bnc359ed2a2016-04-29 20:43:457047 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377048 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457049 }
7050
Fan Yang32c5a112018-12-10 20:06:337051 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567052 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7053 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367054 }
7055
Ryan Hamilton8d9ee76e2018-05-29 23:52:527056 quic::MockClock clock_;
Nick Harper23290b82019-05-02 00:02:567057 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057058 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567059 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457060 DestinationType destination_type_;
7061 std::string origin1_;
7062 std::string origin2_;
7063 std::unique_ptr<HttpNetworkSession> session_;
7064 MockClientSocketFactory socket_factory_;
7065 MockHostResolver host_resolver_;
7066 MockCertVerifier cert_verifier_;
7067 TransportSecurityState transport_security_state_;
7068 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237069 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457070 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077071 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597072 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457073 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527074 quic::test::MockRandom random_generator_;
Matt Menke609160742019-08-02 18:47:267075 HttpServerProperties http_server_properties_;
bnc359ed2a2016-04-29 20:43:457076 BoundTestNetLog net_log_;
7077 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7078 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7079 static_socket_data_provider_vector_;
7080 SSLSocketDataProvider ssl_data_;
7081};
7082
Victor Costane635086f2019-01-27 05:20:307083INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7084 QuicNetworkTransactionWithDestinationTest,
7085 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:457086
7087// A single QUIC request fails because the certificate does not match the origin
7088// hostname, regardless of whether it matches the alternative service hostname.
7089TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7090 if (destination_type_ == DIFFERENT)
7091 return;
7092
7093 GURL url("https://mail.example.com/");
7094 origin1_ = url.host();
7095
7096 // Not used for requests, but this provides a test case where the certificate
7097 // is valid for the hostname of the alternative service.
7098 origin2_ = "mail.example.org";
7099
zhongyie537a002017-06-27 16:48:217100 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457101
7102 scoped_refptr<X509Certificate> cert(
7103 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247104 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7105 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457106
7107 ProofVerifyDetailsChromium verify_details;
7108 verify_details.cert_verify_result.verified_cert = cert;
7109 verify_details.cert_verify_result.is_issued_by_known_root = true;
7110 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7111
Ryan Hamiltonabad59e2019-06-06 04:02:597112 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457113 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7114 mock_quic_data.AddRead(ASYNC, 0);
7115
7116 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7117
7118 AddRefusedSocketData();
7119
7120 HttpRequestInfo request;
7121 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107122 request.traffic_annotation =
7123 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457124
7125 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7126 TestCompletionCallback callback;
7127 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017128 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457129
7130 EXPECT_TRUE(AllDataConsumed());
7131}
7132
7133// First request opens QUIC session to alternative service. Second request
7134// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527135// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457136TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7137 origin1_ = "mail.example.org";
7138 origin2_ = "news.example.org";
7139
zhongyie537a002017-06-27 16:48:217140 SetQuicAlternativeService(origin1_);
7141 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457142
7143 scoped_refptr<X509Certificate> cert(
7144 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247145 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7146 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7147 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457148
7149 ProofVerifyDetailsChromium verify_details;
7150 verify_details.cert_verify_result.verified_cert = cert;
7151 verify_details.cert_verify_result.is_issued_by_known_root = true;
7152 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7153
Yixin Wang079ad542018-01-11 04:06:057154 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177155 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7156 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057157 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177158 QuicTestPacketMaker server_maker(
7159 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7160 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457161
Ryan Hamiltonabad59e2019-06-06 04:02:597162 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237163 int packet_num = 1;
7164 if (VersionUsesQpack(version_.transport_version)) {
7165 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7166 packet_num++, &client_maker));
7167 }
Fan Yang32c5a112018-12-10 20:06:337168 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237169 SYNCHRONOUS,
7170 ConstructClientRequestHeadersPacket(
7171 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7172 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:027173 mock_quic_data.AddRead(
7174 ASYNC,
7175 ConstructServerResponseHeadersPacket(
7176 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437177 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337178 ASYNC,
7179 ConstructServerDataPacket(
7180 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237181 mock_quic_data.AddWrite(
7182 SYNCHRONOUS,
7183 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457184
Yixin Wang079ad542018-01-11 04:06:057185 client_maker.set_hostname(origin2_);
7186 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457187
Zhongyi Shi32f2fd02018-04-16 18:23:437188 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027189 SYNCHRONOUS,
7190 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237191 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027192 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7193 mock_quic_data.AddRead(
7194 ASYNC,
7195 ConstructServerResponseHeadersPacket(
7196 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437197 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337198 ASYNC,
7199 ConstructServerDataPacket(
7200 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237201 mock_quic_data.AddWrite(
7202 SYNCHRONOUS,
7203 ConstructClientAckPacket(packet_num++, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457204 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7205 mock_quic_data.AddRead(ASYNC, 0); // EOF
7206
7207 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7208
7209 AddHangingSocketData();
7210 AddHangingSocketData();
7211
Nick Harpereb483e12019-05-14 00:18:097212 scoped_refptr<TestTaskRunner> quic_task_runner(new TestTaskRunner(&clock_));
Fan Yangc9e00dc2018-10-09 14:17:567213 QuicStreamFactoryPeer::SetAlarmFactory(
7214 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097215 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Fan Yangc9e00dc2018-10-09 14:17:567216 &clock_));
7217
bnc359ed2a2016-04-29 20:43:457218 SendRequestAndExpectQuicResponse(origin1_);
7219 SendRequestAndExpectQuicResponse(origin2_);
7220
7221 EXPECT_TRUE(AllDataConsumed());
7222}
7223
7224// First request opens QUIC session to alternative service. Second request does
7225// not pool to it, even though destination matches, because certificate is not
7226// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527227// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457228TEST_P(QuicNetworkTransactionWithDestinationTest,
7229 DoNotPoolIfCertificateInvalid) {
7230 origin1_ = "news.example.org";
7231 origin2_ = "mail.example.com";
7232
zhongyie537a002017-06-27 16:48:217233 SetQuicAlternativeService(origin1_);
7234 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457235
7236 scoped_refptr<X509Certificate> cert1(
7237 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247238 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7239 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7240 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457241
7242 scoped_refptr<X509Certificate> cert2(
7243 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247244 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7245 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457246
7247 ProofVerifyDetailsChromium verify_details1;
7248 verify_details1.cert_verify_result.verified_cert = cert1;
7249 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7250 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7251
7252 ProofVerifyDetailsChromium verify_details2;
7253 verify_details2.cert_verify_result.verified_cert = cert2;
7254 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7255 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7256
Yixin Wang079ad542018-01-11 04:06:057257 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177258 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7259 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057260 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177261 QuicTestPacketMaker server_maker1(
7262 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7263 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457264
Ryan Hamiltonabad59e2019-06-06 04:02:597265 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:237266 int packet_num = 1;
7267 if (VersionUsesQpack(version_.transport_version)) {
7268 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7269 packet_num++, &client_maker1));
7270 }
Fan Yang32c5a112018-12-10 20:06:337271 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237272 SYNCHRONOUS,
7273 ConstructClientRequestHeadersPacket(
7274 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7275 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437276 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337277 ASYNC,
7278 ConstructServerResponseHeadersPacket(
7279 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437280 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337281 ASYNC,
7282 ConstructServerDataPacket(
7283 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437284 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237285 SYNCHRONOUS,
7286 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457287 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7288 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7289
7290 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7291
Yixin Wang079ad542018-01-11 04:06:057292 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177293 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7294 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057295 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177296 QuicTestPacketMaker server_maker2(
7297 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7298 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457299
Ryan Hamiltonabad59e2019-06-06 04:02:597300 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:237301 int packet_num2 = 1;
7302 if (VersionUsesQpack(version_.transport_version)) {
7303 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7304 packet_num2++, &client_maker2));
7305 }
Fan Yang32c5a112018-12-10 20:06:337306 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237307 SYNCHRONOUS,
7308 ConstructClientRequestHeadersPacket(
7309 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7310 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437311 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337312 ASYNC,
7313 ConstructServerResponseHeadersPacket(
7314 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437315 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337316 ASYNC,
7317 ConstructServerDataPacket(
7318 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437319 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237320 SYNCHRONOUS,
7321 ConstructClientAckPacket(packet_num2++, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457322 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7323 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7324
7325 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7326
bnc359ed2a2016-04-29 20:43:457327 SendRequestAndExpectQuicResponse(origin1_);
7328 SendRequestAndExpectQuicResponse(origin2_);
7329
7330 EXPECT_TRUE(AllDataConsumed());
7331}
7332
ckrasicdee37572017-04-06 22:42:277333// crbug.com/705109 - this confirms that matching request with a body
7334// triggers a crash (pre-fix).
7335TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Nick Harper72ade192019-07-17 03:30:427336 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277337 HostPortPair::FromString("mail.example.org:443"));
7338
Ryan Hamiltonabad59e2019-06-06 04:02:597339 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237340 uint64_t client_packet_number = 1;
Renjie Tangaadb84b2019-08-31 01:00:237341 if (VersionUsesQpack(version_.transport_version)) {
7342 mock_quic_data.AddWrite(
7343 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7344 }
Zhongyi Shi32f2fd02018-04-16 18:23:437345 mock_quic_data.AddWrite(
7346 SYNCHRONOUS,
7347 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337348 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027349 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437350 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027351 ASYNC,
7352 ConstructServerPushPromisePacket(
7353 1, GetNthClientInitiatedBidirectionalStreamId(0),
7354 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7355 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:317356
7357 if ((client_headers_include_h2_stream_dependency_ &&
7358 version_.transport_version >= quic::QUIC_VERSION_43) ||
7359 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027360 mock_quic_data.AddWrite(
7361 SYNCHRONOUS,
7362 ConstructClientPriorityPacket(
7363 client_packet_number++, false,
7364 GetNthServerInitiatedUnidirectionalStreamId(0),
7365 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577366 }
Zhongyi Shi32f2fd02018-04-16 18:23:437367 mock_quic_data.AddRead(
7368 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337369 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027370 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:577371 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437372 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7373 mock_quic_data.AddRead(
7374 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337375 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027376 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437377 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437378 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337379 ASYNC, ConstructServerDataPacket(
7380 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177381 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577382 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437383 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417384
Victor Vasiliev076657c2019-03-12 02:46:437385 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437386 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337387 ASYNC, ConstructServerDataPacket(
7388 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177389 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277390
7391 // Because the matching request has a body, we will see the push
7392 // stream get cancelled, and the matching request go out on the
7393 // wire.
Fan Yang32c5a112018-12-10 20:06:337394 mock_quic_data.AddWrite(SYNCHRONOUS,
7395 ConstructClientAckAndRstPacket(
7396 client_packet_number++,
7397 GetNthServerInitiatedUnidirectionalStreamId(0),
7398 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277399 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437400 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567401 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417402 mock_quic_data.AddWrite(
7403 SYNCHRONOUS,
7404 ConstructClientRequestHeadersAndDataFramesPacket(
7405 client_packet_number++,
7406 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7407 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027408 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, {kBody}));
Renjief49758b2019-01-11 23:32:417409 } else {
7410 mock_quic_data.AddWrite(
7411 SYNCHRONOUS,
7412 ConstructClientRequestHeadersAndDataFramesPacket(
7413 client_packet_number++,
7414 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7415 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027416 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7417 {header3, kBody}));
Renjief49758b2019-01-11 23:32:417418 }
ckrasicdee37572017-04-06 22:42:277419
7420 // We see the same response as for the earlier pushed and cancelled
7421 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437422 mock_quic_data.AddRead(
7423 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337424 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027425 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:437426 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337427 ASYNC, ConstructServerDataPacket(
7428 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177429 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277430
Yixin Wangb470bc882018-02-15 18:43:577431 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437432 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277433 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7434 mock_quic_data.AddRead(ASYNC, 0); // EOF
7435 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7436
7437 // The non-alternate protocol job needs to hang in order to guarantee that
7438 // the alternate-protocol job will "win".
7439 AddHangingNonAlternateProtocolSocketData();
7440
7441 CreateSession();
7442
7443 // PUSH_PROMISE handling in the http layer gets exercised here.
7444 SendRequestAndExpectQuicResponse("hello!");
7445
7446 request_.url = GURL("https://mail.example.org/pushed.jpg");
7447 ChunkedUploadDataStream upload_data(0);
7448 upload_data.AppendData("1", 1, true);
7449 request_.upload_data_stream = &upload_data;
7450 SendRequestAndExpectQuicResponse("and hello!");
7451}
7452
Bence Béky7538a952018-02-01 16:59:527453// Regression test for https://crbug.com/797825: If pushed headers describe a
7454// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7455// not be called (otherwise a DCHECK fails).
7456TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137457 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527458 pushed_request_headers[":authority"] = "";
7459 pushed_request_headers[":method"] = "GET";
7460 pushed_request_headers[":path"] = "/";
7461 pushed_request_headers[":scheme"] = "nosuchscheme";
7462
Nick Harper72ade192019-07-17 03:30:427463 session_params_.quic_params.origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:527464 HostPortPair::FromString("mail.example.org:443"));
7465
Ryan Hamiltonabad59e2019-06-06 04:02:597466 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:527467
Renjie Tangaadb84b2019-08-31 01:00:237468 int packet_num = 1;
7469 if (VersionUsesQpack(version_.transport_version)) {
7470 mock_quic_data.AddWrite(SYNCHRONOUS,
7471 ConstructInitialSettingsPacket(packet_num++));
7472 }
Bence Béky7538a952018-02-01 16:59:527473 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237474 SYNCHRONOUS,
7475 ConstructClientRequestHeadersPacket(
7476 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7477 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:527478
Fan Yang32c5a112018-12-10 20:06:337479 mock_quic_data.AddRead(
7480 ASYNC, ConstructServerPushPromisePacket(
7481 1, GetNthClientInitiatedBidirectionalStreamId(0),
7482 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027483 std::move(pushed_request_headers), &server_maker_));
Renjie Tangaadb84b2019-08-31 01:00:237484 mock_quic_data.AddWrite(
7485 SYNCHRONOUS,
7486 ConstructClientRstPacket(packet_num++,
7487 GetNthServerInitiatedUnidirectionalStreamId(0),
7488 quic::QUIC_INVALID_PROMISE_URL));
Bence Béky7538a952018-02-01 16:59:527489
Zhongyi Shi32f2fd02018-04-16 18:23:437490 mock_quic_data.AddRead(
7491 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337492 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027493 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:237494 mock_quic_data.AddWrite(SYNCHRONOUS,
7495 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527496
Zhongyi Shi32f2fd02018-04-16 18:23:437497 mock_quic_data.AddRead(
7498 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337499 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027500 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437501 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437502 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337503 ASYNC, ConstructServerDataPacket(
7504 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177505 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:237506 mock_quic_data.AddWrite(SYNCHRONOUS,
7507 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527508
7509 mock_quic_data.AddRead(ASYNC, 0);
7510 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7511
7512 // The non-alternate protocol job needs to hang in order to guarantee that
7513 // the alternate-protocol job will "win".
7514 AddHangingNonAlternateProtocolSocketData();
7515
7516 CreateSession();
7517
7518 // PUSH_PROMISE handling in the http layer gets exercised here.
7519 SendRequestAndExpectQuicResponse("hello!");
7520
7521 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7522 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7523}
7524
Yixin Wang46a273ec302018-01-23 17:59:567525// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147526TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567527 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147528 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567529 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497530 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567531
Ryan Hamiltonabad59e2019-06-06 04:02:597532 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237533 int packet_num = 1;
7534 if (VersionUsesQpack(version_.transport_version)) {
7535 mock_quic_data.AddWrite(SYNCHRONOUS,
7536 ConstructInitialSettingsPacket(packet_num++));
7537 }
Fan Yang32c5a112018-12-10 20:06:337538 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237539 SYNCHRONOUS,
7540 ConstructClientRequestHeadersPacket(
7541 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7542 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7543 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337544 mock_quic_data.AddRead(
7545 ASYNC, ConstructServerResponseHeadersPacket(
7546 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7547 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567548
7549 const char get_request[] =
7550 "GET / HTTP/1.1\r\n"
7551 "Host: mail.example.org\r\n"
7552 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437553 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567554 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417555 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357556 SYNCHRONOUS,
7557 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237558 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7559 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417560 } else {
7561 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417562 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357563 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:237564 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7565 1, 1, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417566 }
7567
Yixin Wang46a273ec302018-01-23 17:59:567568 const char get_response[] =
7569 "HTTP/1.1 200 OK\r\n"
7570 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437571 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437572 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337573 ASYNC, ConstructServerDataPacket(
7574 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177575 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:437576 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337577 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417578 SYNCHRONOUS, ConstructServerDataPacket(
7579 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:177580 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:237581 mock_quic_data.AddWrite(SYNCHRONOUS,
7582 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567583 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7584
7585 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417586 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237587 ConstructClientRstPacket(packet_num++,
7588 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417589 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567590
7591 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7592
7593 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7594
7595 CreateSession();
7596
7597 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097598 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7600 HeadersHandler headers_handler;
7601 trans.SetBeforeHeadersSentCallback(
7602 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7603 base::Unretained(&headers_handler)));
7604 RunTransaction(&trans);
7605 CheckWasHttpResponse(&trans);
7606 CheckResponsePort(&trans, 70);
7607 CheckResponseData(&trans, "0123456789");
7608 EXPECT_TRUE(headers_handler.was_proxied());
7609 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7610
7611 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7612 // proxy socket to disconnect.
7613 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7614
7615 base::RunLoop().RunUntilIdle();
7616 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7617 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7618}
7619
7620// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147621TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567622 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147623 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567624 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497625 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567626
Ryan Hamiltonabad59e2019-06-06 04:02:597627 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237628 int packet_num = 1;
7629 if (VersionUsesQpack(version_.transport_version)) {
7630 mock_quic_data.AddWrite(SYNCHRONOUS,
7631 ConstructInitialSettingsPacket(packet_num++));
7632 }
Fan Yang32c5a112018-12-10 20:06:337633 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237634 SYNCHRONOUS,
7635 ConstructClientRequestHeadersPacket(
7636 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7637 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7638 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337639 mock_quic_data.AddRead(
7640 ASYNC, ConstructServerResponseHeadersPacket(
7641 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7642 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567643
7644 SpdyTestUtil spdy_util;
7645
Ryan Hamilton0239aac2018-05-19 00:03:137646 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567647 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437648 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567649 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417650 mock_quic_data.AddWrite(
7651 SYNCHRONOUS,
7652 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237653 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7654 1, 1, 1, false,
7655 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:417656 } else {
7657 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417658 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357659 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:237660 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7661 1, 1, 1, false,
7662 {header, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417663 }
Ryan Hamilton0239aac2018-05-19 00:03:137664 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567665 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437666 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437667 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177668 ASYNC, ConstructServerDataPacket(
7669 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7670 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567671
Ryan Hamilton0239aac2018-05-19 00:03:137672 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197673 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:437674 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437675 mock_quic_data.AddRead(
7676 SYNCHRONOUS,
7677 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337678 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437679 header3 + std::string(data_frame.data(), data_frame.size())));
Renjie Tangaadb84b2019-08-31 01:00:237680 mock_quic_data.AddWrite(SYNCHRONOUS,
7681 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567682 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7683
7684 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437685 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237686 ConstructClientRstPacket(packet_num++,
7687 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417688 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567689
7690 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7691
7692 SSLSocketDataProvider ssl_data(ASYNC, OK);
7693 ssl_data.next_proto = kProtoHTTP2;
7694 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7695
7696 CreateSession();
7697
7698 request_.url = GURL("https://mail.example.org/");
7699 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7700 HeadersHandler headers_handler;
7701 trans.SetBeforeHeadersSentCallback(
7702 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7703 base::Unretained(&headers_handler)));
7704 RunTransaction(&trans);
7705 CheckWasSpdyResponse(&trans);
7706 CheckResponsePort(&trans, 70);
7707 CheckResponseData(&trans, "0123456789");
7708 EXPECT_TRUE(headers_handler.was_proxied());
7709 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7710
Wez0e717112018-06-18 23:09:227711 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7712 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567713 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7714
7715 base::RunLoop().RunUntilIdle();
7716 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7717 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7718}
7719
7720// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7721// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147722TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567723 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147724 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567725 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497726 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567727
Ryan Hamiltonabad59e2019-06-06 04:02:597728 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:417729 int write_packet_index = 1;
Renjie Tangaadb84b2019-08-31 01:00:237730 if (VersionUsesQpack(version_.transport_version)) {
7731 mock_quic_data.AddWrite(
7732 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7733 }
Fan Yang32c5a112018-12-10 20:06:337734 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417735 SYNCHRONOUS,
7736 ConstructClientRequestHeadersPacket(
7737 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:047738 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027739 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337740 mock_quic_data.AddRead(
7741 ASYNC, ConstructServerResponseHeadersPacket(
7742 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7743 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567744
Ryan Hamilton8d9ee76e2018-05-29 23:52:527745 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567746 const char get_request_1[] =
7747 "GET / HTTP/1.1\r\n"
7748 "Host: mail.example.org\r\n"
7749 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437750 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:567751 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417752 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:177753 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7754 write_packet_index++, false,
7755 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7756 false, quic::QuicStringPiece(get_request_1)));
Renjief49758b2019-01-11 23:32:417757 } else {
7758 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:177759 SYNCHRONOUS, ConstructClientAckAndMultipleDataFramesPacket(
7760 write_packet_index++, false,
7761 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7762 false, {header, std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:417763 }
7764
Yixin Wang46a273ec302018-01-23 17:59:567765 const char get_response_1[] =
7766 "HTTP/1.1 200 OK\r\n"
7767 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437768 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437769 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437770 ASYNC, ConstructServerDataPacket(
7771 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177772 header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:417773 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567774
Victor Vasiliev076657c2019-03-12 02:46:437775 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337776 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177777 SYNCHRONOUS, ConstructServerDataPacket(
7778 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7779 false, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:417780 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567781
Renjief49758b2019-01-11 23:32:417782 mock_quic_data.AddWrite(
7783 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567784
7785 const char get_request_2[] =
7786 "GET /2 HTTP/1.1\r\n"
7787 "Host: mail.example.org\r\n"
7788 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437789 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:567790 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417791 mock_quic_data.AddWrite(
7792 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357793 ConstructClientMultipleDataFramesPacket(
7794 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:177795 false, false, {header4, std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:357796 } else {
7797 mock_quic_data.AddWrite(
7798 SYNCHRONOUS,
Ryan Hamilton7505eb92019-06-08 00:22:177799 ConstructClientDataPacket(
7800 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7801 false, false, quic::QuicStringPiece(get_request_2)));
Renjief49758b2019-01-11 23:32:417802 }
Yixin Wang46a273ec302018-01-23 17:59:567803
7804 const char get_response_2[] =
7805 "HTTP/1.1 200 OK\r\n"
7806 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437807 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437808 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437809 ASYNC, ConstructServerDataPacket(
7810 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177811 header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:417812 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567813
Victor Vasiliev076657c2019-03-12 02:46:437814 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527815 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177816 SYNCHRONOUS, ConstructServerDataPacket(
7817 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
7818 false, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:417819 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567820
Renjief49758b2019-01-11 23:32:417821 mock_quic_data.AddWrite(
7822 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567823 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7824
Renjief49758b2019-01-11 23:32:417825 mock_quic_data.AddWrite(
7826 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417827 ConstructClientRstPacket(write_packet_index++,
7828 GetNthClientInitiatedBidirectionalStreamId(0),
7829 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567830
7831 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7832
7833 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7834
7835 CreateSession();
7836
7837 request_.url = GURL("https://mail.example.org/");
7838 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7839 HeadersHandler headers_handler_1;
7840 trans_1.SetBeforeHeadersSentCallback(
7841 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7842 base::Unretained(&headers_handler_1)));
7843 RunTransaction(&trans_1);
7844 CheckWasHttpResponse(&trans_1);
7845 CheckResponsePort(&trans_1, 70);
7846 CheckResponseData(&trans_1, "0123456789");
7847 EXPECT_TRUE(headers_handler_1.was_proxied());
7848 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7849
7850 request_.url = GURL("https://mail.example.org/2");
7851 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7852 HeadersHandler headers_handler_2;
7853 trans_2.SetBeforeHeadersSentCallback(
7854 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7855 base::Unretained(&headers_handler_2)));
7856 RunTransaction(&trans_2);
7857 CheckWasHttpResponse(&trans_2);
7858 CheckResponsePort(&trans_2, 70);
7859 CheckResponseData(&trans_2, "0123456");
7860 EXPECT_TRUE(headers_handler_2.was_proxied());
7861 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7862
7863 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7864 // proxy socket to disconnect.
7865 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7866
7867 base::RunLoop().RunUntilIdle();
7868 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7869 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7870}
7871
7872// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7873// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7874// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147875TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567876 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147877 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567878 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497879 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567880
Ryan Hamiltonabad59e2019-06-06 04:02:597881 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237882 int packet_num = 1;
7883 if (VersionUsesQpack(version_.transport_version)) {
7884 mock_quic_data.AddWrite(SYNCHRONOUS,
7885 ConstructInitialSettingsPacket(packet_num++));
7886 }
Yixin Wang46a273ec302018-01-23 17:59:567887
7888 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337889 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237890 SYNCHRONOUS,
7891 ConstructClientRequestHeadersPacket(
7892 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7893 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7894 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:437895 mock_quic_data.AddRead(
7896 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337897 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027898 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567899
7900 // GET request, response, and data over QUIC tunnel for first request
7901 const char get_request[] =
7902 "GET / HTTP/1.1\r\n"
7903 "Host: mail.example.org\r\n"
7904 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437905 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567906 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417907 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357908 SYNCHRONOUS,
7909 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237910 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7911 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417912 } else {
7913 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417914 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357915 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:237916 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7917 1, 1, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417918 }
7919
Yixin Wang46a273ec302018-01-23 17:59:567920 const char get_response[] =
7921 "HTTP/1.1 200 OK\r\n"
7922 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437923 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567924 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337925 ASYNC, ConstructServerDataPacket(
7926 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177927 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:437928 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337929 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417930 SYNCHRONOUS, ConstructServerDataPacket(
7931 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:177932 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:237933 mock_quic_data.AddWrite(SYNCHRONOUS,
7934 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567935
7936 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437937 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237938 SYNCHRONOUS,
7939 ConstructClientRequestHeadersPacket(
7940 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
7941 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7942 ConnectRequestHeaders("different.example.org:443"),
7943 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:437944 mock_quic_data.AddRead(
7945 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337946 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027947 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567948
7949 // GET request, response, and data over QUIC tunnel for second request
7950 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137951 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567952 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437953 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567954 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417955 mock_quic_data.AddWrite(
7956 SYNCHRONOUS,
7957 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237958 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
7959 4, 4, 1, false,
7960 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:417961 } else {
7962 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417963 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357964 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:237965 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
7966 4, 4, 1, false,
7967 {header4, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417968 }
Yixin Wang46a273ec302018-01-23 17:59:567969
Ryan Hamilton0239aac2018-05-19 00:03:137970 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567971 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437972 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437973 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177974 ASYNC, ConstructServerDataPacket(
7975 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7976 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567977
Ryan Hamilton0239aac2018-05-19 00:03:137978 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197979 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:437980 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437981 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437982 ASYNC, ConstructServerDataPacket(
7983 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437984 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567985
Renjie Tangaadb84b2019-08-31 01:00:237986 mock_quic_data.AddWrite(SYNCHRONOUS,
7987 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567988 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7989
7990 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417991 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237992 ConstructClientRstPacket(packet_num++,
7993 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417994 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567995 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437996 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237997 ConstructClientRstPacket(packet_num++,
7998 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417999 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568000
8001 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8002
8003 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8004
8005 SSLSocketDataProvider ssl_data(ASYNC, OK);
8006 ssl_data.next_proto = kProtoHTTP2;
8007 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8008
8009 CreateSession();
8010
8011 request_.url = GURL("https://mail.example.org/");
8012 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8013 HeadersHandler headers_handler_1;
8014 trans_1.SetBeforeHeadersSentCallback(
8015 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8016 base::Unretained(&headers_handler_1)));
8017 RunTransaction(&trans_1);
8018 CheckWasHttpResponse(&trans_1);
8019 CheckResponsePort(&trans_1, 70);
8020 CheckResponseData(&trans_1, "0123456789");
8021 EXPECT_TRUE(headers_handler_1.was_proxied());
8022 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8023
8024 request_.url = GURL("https://different.example.org/");
8025 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8026 HeadersHandler headers_handler_2;
8027 trans_2.SetBeforeHeadersSentCallback(
8028 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8029 base::Unretained(&headers_handler_2)));
8030 RunTransaction(&trans_2);
8031 CheckWasSpdyResponse(&trans_2);
8032 CheckResponsePort(&trans_2, 70);
8033 CheckResponseData(&trans_2, "0123456");
8034 EXPECT_TRUE(headers_handler_2.was_proxied());
8035 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8036
8037 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8038 // proxy socket to disconnect.
8039 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8040
8041 base::RunLoop().RunUntilIdle();
8042 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8043 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8044}
8045
8046// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148047TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568048 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148049 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568050 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498051 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568052
Ryan Hamiltonabad59e2019-06-06 04:02:598053 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238054 int packet_num = 1;
8055 if (VersionUsesQpack(version_.transport_version)) {
8056 mock_quic_data.AddWrite(SYNCHRONOUS,
8057 ConstructInitialSettingsPacket(packet_num++));
8058 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:528059 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238060 SYNCHRONOUS,
8061 ConstructClientRequestHeadersPacket(
8062 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8063 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8064 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338065 mock_quic_data.AddRead(
8066 ASYNC, ConstructServerResponseHeadersPacket(
8067 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8068 GetResponseHeaders("500")));
8069 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:238070 mock_quic_data.AddWrite(
8071 SYNCHRONOUS,
8072 ConstructClientAckAndRstPacket(
8073 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8074 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568075
8076 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8077
8078 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8079
8080 CreateSession();
8081
8082 request_.url = GURL("https://mail.example.org/");
8083 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8084 HeadersHandler headers_handler;
8085 trans.SetBeforeHeadersSentCallback(
8086 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8087 base::Unretained(&headers_handler)));
8088 TestCompletionCallback callback;
8089 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8090 EXPECT_EQ(ERR_IO_PENDING, rv);
8091 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8092 EXPECT_EQ(false, headers_handler.was_proxied());
8093
8094 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8095 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8096}
8097
8098// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148099TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568100 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148101 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568102 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498103 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568104
Ryan Hamiltonabad59e2019-06-06 04:02:598105 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238106 int packet_num = 1;
8107 if (VersionUsesQpack(version_.transport_version)) {
8108 mock_quic_data.AddWrite(SYNCHRONOUS,
8109 ConstructInitialSettingsPacket(packet_num++));
8110 }
Fan Yang32c5a112018-12-10 20:06:338111 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238112 SYNCHRONOUS,
8113 ConstructClientRequestHeadersPacket(
8114 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8115 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8116 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:568117 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8118
8119 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8120
8121 CreateSession();
8122
8123 request_.url = GURL("https://mail.example.org/");
8124 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8125 HeadersHandler headers_handler;
8126 trans.SetBeforeHeadersSentCallback(
8127 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8128 base::Unretained(&headers_handler)));
8129 TestCompletionCallback callback;
8130 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8131 EXPECT_EQ(ERR_IO_PENDING, rv);
8132 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8133
8134 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8135 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8136}
8137
8138// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8139// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148140TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568141 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148142 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568143 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498144 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568145
Ryan Hamiltonabad59e2019-06-06 04:02:598146 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238147 int packet_num = 1;
8148 if (VersionUsesQpack(version_.transport_version)) {
8149 mock_quic_data.AddWrite(SYNCHRONOUS,
8150 ConstructInitialSettingsPacket(packet_num++));
8151 }
Fan Yang32c5a112018-12-10 20:06:338152 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238153 SYNCHRONOUS,
8154 ConstructClientRequestHeadersPacket(
8155 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8156 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8157 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438158 mock_quic_data.AddRead(
8159 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338160 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028161 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238162 mock_quic_data.AddWrite(
8163 SYNCHRONOUS,
8164 ConstructClientAckAndRstPacket(
8165 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8166 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568167
Zhongyi Shi32f2fd02018-04-16 18:23:438168 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238169 SYNCHRONOUS,
8170 ConstructClientRequestHeadersPacket(
8171 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8172 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8173 ConnectRequestHeaders("mail.example.org:443"),
8174 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438175 mock_quic_data.AddRead(
8176 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338177 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028178 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568179
8180 const char get_request[] =
8181 "GET / HTTP/1.1\r\n"
8182 "Host: mail.example.org\r\n"
8183 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438184 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568185 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418186 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358187 SYNCHRONOUS,
8188 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238189 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8190 2, 2, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418191 } else {
8192 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418193 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358194 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238195 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8196 2, 2, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418197 }
Yixin Wang46a273ec302018-01-23 17:59:568198 const char get_response[] =
8199 "HTTP/1.1 200 OK\r\n"
8200 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438201 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438202 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338203 ASYNC, ConstructServerDataPacket(
8204 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178205 header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528206
Victor Vasiliev076657c2019-03-12 02:46:438207 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338208 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418209 SYNCHRONOUS, ConstructServerDataPacket(
8210 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178211 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238212 mock_quic_data.AddWrite(SYNCHRONOUS,
8213 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568214 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8215
8216 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418217 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238218 ConstructClientRstPacket(packet_num++,
8219 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418220 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568221
8222 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8223
8224 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8225 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8226
8227 SSLSocketDataProvider ssl_data(ASYNC, OK);
8228 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8229
8230 CreateSession();
8231
8232 request_.url = GURL("https://mail.example.org/");
8233 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8234 HeadersHandler headers_handler;
8235 trans.SetBeforeHeadersSentCallback(
8236 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8237 base::Unretained(&headers_handler)));
8238 TestCompletionCallback callback;
8239 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8240 EXPECT_EQ(ERR_IO_PENDING, rv);
8241 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8242
8243 rv = trans.RestartIgnoringLastError(callback.callback());
8244 EXPECT_EQ(ERR_IO_PENDING, rv);
8245 EXPECT_EQ(OK, callback.WaitForResult());
8246
8247 CheckWasHttpResponse(&trans);
8248 CheckResponsePort(&trans, 70);
8249 CheckResponseData(&trans, "0123456789");
8250 EXPECT_EQ(true, headers_handler.was_proxied());
8251 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8252
8253 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8254 // proxy socket to disconnect.
8255 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8256
8257 base::RunLoop().RunUntilIdle();
8258 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8259 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8260}
8261
8262// Checks if a request's specified "user-agent" header shows up correctly in the
8263// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148264TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008265 const char kConfiguredUserAgent[] = "Configured User-Agent";
8266 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568267 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148268 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568269 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498270 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568271
Ryan Hamiltonabad59e2019-06-06 04:02:598272 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238273 int packet_num = 1;
8274 if (VersionUsesQpack(version_.transport_version)) {
8275 mock_quic_data.AddWrite(SYNCHRONOUS,
8276 ConstructInitialSettingsPacket(packet_num++));
8277 }
Yixin Wang46a273ec302018-01-23 17:59:568278
Ryan Hamilton0239aac2018-05-19 00:03:138279 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008280 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338281 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028282 SYNCHRONOUS,
8283 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238284 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8285 false, HttpProxyConnectJob::kH2QuicTunnelPriority, std::move(headers),
8286 0));
Yixin Wang46a273ec302018-01-23 17:59:568287 // Return an error, so the transaction stops here (this test isn't interested
8288 // in the rest).
8289 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8290
8291 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8292
Matt Menked732ea42019-03-08 12:05:008293 StaticHttpUserAgentSettings http_user_agent_settings(
8294 std::string() /* accept_language */, kConfiguredUserAgent);
8295 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568296 CreateSession();
8297
8298 request_.url = GURL("https://mail.example.org/");
8299 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008300 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568301 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8302 HeadersHandler headers_handler;
8303 trans.SetBeforeHeadersSentCallback(
8304 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8305 base::Unretained(&headers_handler)));
8306 TestCompletionCallback callback;
8307 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8308 EXPECT_EQ(ERR_IO_PENDING, rv);
8309 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8310
8311 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8312 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8313}
8314
Yixin Wang00fc44c2018-01-23 21:12:208315// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8316// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148317TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208318 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148319 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208320 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498321 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208322
8323 const RequestPriority request_priority = MEDIUM;
8324
Ryan Hamiltonabad59e2019-06-06 04:02:598325 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238326 int packet_num = 1;
8327 if (VersionUsesQpack(version_.transport_version)) {
8328 mock_quic_data.AddWrite(SYNCHRONOUS,
8329 ConstructInitialSettingsPacket(packet_num++));
8330 }
Zhongyi Shi32f2fd02018-04-16 18:23:438331 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238332 SYNCHRONOUS,
8333 ConstructClientRequestHeadersPacket(
8334 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8335 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8336 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:208337 // Return an error, so the transaction stops here (this test isn't interested
8338 // in the rest).
8339 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8340
8341 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8342
8343 CreateSession();
8344
8345 request_.url = GURL("https://mail.example.org/");
8346 HttpNetworkTransaction trans(request_priority, session_.get());
8347 TestCompletionCallback callback;
8348 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8349 EXPECT_EQ(ERR_IO_PENDING, rv);
8350 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8351
8352 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8353 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8354}
8355
Matt Menkeedaf3b82019-03-14 21:39:448356// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8357// HTTP/2 stream dependency and weights given the request priority.
8358TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8359 session_params_.enable_quic = true;
8360 session_params_.enable_quic_proxies_for_https_urls = true;
8361 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8362 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8363
8364 const RequestPriority kRequestPriority = MEDIUM;
8365 const RequestPriority kRequestPriority2 = LOWEST;
8366
Ryan Hamiltonabad59e2019-06-06 04:02:598367 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238368 if (VersionUsesQpack(version_.transport_version)) {
8369 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
8370 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8371 } else {
8372 mock_quic_data.AddWrite(
8373 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8374 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
8375 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8376 ConnectRequestHeaders("mail.example.org:443"), 0));
8377 }
Matt Menkeedaf3b82019-03-14 21:39:448378 // This should never be reached.
8379 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8380 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8381
8382 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:598383 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:448384 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8385 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8386
8387 int original_max_sockets_per_group =
8388 ClientSocketPoolManager::max_sockets_per_group(
8389 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8390 ClientSocketPoolManager::set_max_sockets_per_group(
8391 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8392 int original_max_sockets_per_pool =
8393 ClientSocketPoolManager::max_sockets_per_pool(
8394 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8395 ClientSocketPoolManager::set_max_sockets_per_pool(
8396 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8397 CreateSession();
8398
8399 request_.url = GURL("https://mail.example.org/");
8400 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8401 TestCompletionCallback callback;
8402 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8403 EXPECT_EQ(ERR_IO_PENDING, rv);
8404
8405 HttpRequestInfo request2;
8406 request2.url = GURL("https://mail.example.org/some/other/path/");
8407 request2.traffic_annotation =
8408 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8409
8410 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8411 TestCompletionCallback callback2;
8412 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8413 EXPECT_EQ(ERR_IO_PENDING, rv2);
8414
8415 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8416 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8417
8418 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8419
8420 ClientSocketPoolManager::set_max_sockets_per_pool(
8421 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8422 original_max_sockets_per_pool);
8423 ClientSocketPoolManager::set_max_sockets_per_group(
8424 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8425 original_max_sockets_per_group);
8426}
8427
Yixin Wang46a273ec302018-01-23 17:59:568428// Test the request-challenge-retry sequence for basic auth, over a QUIC
8429// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148430TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568431 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8432 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:568433
8434 std::unique_ptr<QuicTestPacketMaker> client_maker;
8435 std::unique_ptr<QuicTestPacketMaker> server_maker;
8436
8437 // On the second pass, the body read of the auth challenge is synchronous, so
8438 // IsConnectedAndIdle returns false. The socket should still be drained and
8439 // reused. See http://crbug.com/544255.
8440 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338441 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178442 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8443 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338444 client_headers_include_h2_stream_dependency_));
8445 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178446 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8447 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568448
8449 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148450 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568451 proxy_resolution_service_ =
8452 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498453 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568454
Ryan Hamiltonabad59e2019-06-06 04:02:598455 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528456 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568457
Renjie Tangaadb84b2019-08-31 01:00:238458 int packet_num = 1;
8459 if (VersionUsesQpack(version_.transport_version)) {
8460 mock_quic_data.AddWrite(
8461 SYNCHRONOUS, client_maker->MakeInitialSettingsPacket(packet_num++));
8462 }
Yixin Wang46a273ec302018-01-23 17:59:568463
8464 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438465 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028466 client_maker->MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238467 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8468 false,
Matt Menke6e879bd2019-03-18 17:26:048469 ConvertRequestPriorityToQuicPriority(
8470 HttpProxyConnectJob::kH2QuicTunnelPriority),
Yixin Wang46a273ec302018-01-23 17:59:568471 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028472 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568473
Ryan Hamilton0239aac2018-05-19 00:03:138474 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568475 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8476 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8477 headers["content-length"] = "10";
8478 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028479 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338480 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028481 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568482
8483 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438484 mock_quic_data.AddRead(
8485 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338486 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178487 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568488 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438489 mock_quic_data.AddRead(
8490 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338491 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:178492 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568493 }
8494 server_data_offset += 10;
8495
Renjie Tangaadb84b2019-08-31 01:00:238496 mock_quic_data.AddWrite(
8497 SYNCHRONOUS, client_maker->MakeAckPacket(packet_num++, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568498
8499 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338500 SYNCHRONOUS,
8501 client_maker->MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:238502 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418503 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:188504 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568505
8506 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8507 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8508 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048509 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028510 client_maker->MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238511 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8512 false,
Matt Menke6e879bd2019-03-18 17:26:048513 ConvertRequestPriorityToQuicPriority(
8514 HttpProxyConnectJob::kH2QuicTunnelPriority),
8515 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:028516 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568517
8518 // Response to wrong password
8519 headers =
8520 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8521 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8522 headers["content-length"] = "10";
8523 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028524 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338525 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028526 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568527 mock_quic_data.AddRead(SYNCHRONOUS,
8528 ERR_IO_PENDING); // No more data to read
8529
Fan Yang32c5a112018-12-10 20:06:338530 mock_quic_data.AddWrite(
8531 SYNCHRONOUS,
8532 client_maker->MakeAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:238533 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Fan Yang32c5a112018-12-10 20:06:338534 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568535
8536 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8537 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8538
8539 CreateSession();
8540
8541 request_.url = GURL("https://mail.example.org/");
8542 // Ensure that proxy authentication is attempted even
8543 // when the no authentication data flag is set.
8544 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8545 {
8546 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8547 HeadersHandler headers_handler;
8548 trans.SetBeforeHeadersSentCallback(
8549 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8550 base::Unretained(&headers_handler)));
8551 RunTransaction(&trans);
8552
8553 const HttpResponseInfo* response = trans.GetResponseInfo();
8554 ASSERT_TRUE(response != nullptr);
8555 ASSERT_TRUE(response->headers.get() != nullptr);
8556 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8557 response->headers->GetStatusLine());
8558 EXPECT_TRUE(response->headers->IsKeepAlive());
8559 EXPECT_EQ(407, response->headers->response_code());
8560 EXPECT_EQ(10, response->headers->GetContentLength());
8561 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588562 base::Optional<AuthChallengeInfo> auth_challenge =
8563 response->auth_challenge;
8564 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568565 EXPECT_TRUE(auth_challenge->is_proxy);
8566 EXPECT_EQ("https://proxy.example.org:70",
8567 auth_challenge->challenger.Serialize());
8568 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8569 EXPECT_EQ("basic", auth_challenge->scheme);
8570
8571 TestCompletionCallback callback;
8572 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8573 callback.callback());
8574 EXPECT_EQ(ERR_IO_PENDING, rv);
8575 EXPECT_EQ(OK, callback.WaitForResult());
8576
8577 response = trans.GetResponseInfo();
8578 ASSERT_TRUE(response != nullptr);
8579 ASSERT_TRUE(response->headers.get() != nullptr);
8580 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8581 response->headers->GetStatusLine());
8582 EXPECT_TRUE(response->headers->IsKeepAlive());
8583 EXPECT_EQ(407, response->headers->response_code());
8584 EXPECT_EQ(10, response->headers->GetContentLength());
8585 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588586 auth_challenge = response->auth_challenge;
8587 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568588 EXPECT_TRUE(auth_challenge->is_proxy);
8589 EXPECT_EQ("https://proxy.example.org:70",
8590 auth_challenge->challenger.Serialize());
8591 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8592 EXPECT_EQ("basic", auth_challenge->scheme);
8593 }
8594 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8595 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8596 // reused because it's not connected).
8597 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8598 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8599 }
8600}
8601
Yixin Wang385652a2018-02-16 02:37:238602TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8603 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8604 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:568605 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238606 !client_headers_include_h2_stream_dependency_) {
8607 return;
8608 }
8609
Ryan Hamiltone940bd12019-06-30 02:46:458610 if (quic::VersionUsesQpack(version_.transport_version)) {
8611 // TODO(rch): both stream_dependencies and priority frames need to be
8612 // supported in IETF QUIC.
8613 return;
8614 }
8615
Nick Harper72ade192019-07-17 03:30:428616 session_params_.quic_params.origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:238617 HostPortPair::FromString("mail.example.org:443"));
8618
Fan Yang32c5a112018-12-10 20:06:338619 const quic::QuicStreamId client_stream_0 =
8620 GetNthClientInitiatedBidirectionalStreamId(0);
8621 const quic::QuicStreamId client_stream_1 =
8622 GetNthClientInitiatedBidirectionalStreamId(1);
8623 const quic::QuicStreamId client_stream_2 =
8624 GetNthClientInitiatedBidirectionalStreamId(2);
8625 const quic::QuicStreamId push_stream_0 =
8626 GetNthServerInitiatedUnidirectionalStreamId(0);
8627 const quic::QuicStreamId push_stream_1 =
8628 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238629
Ryan Hamiltonabad59e2019-06-06 04:02:598630 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238631 int packet_num = 1;
8632 if (VersionUsesQpack(version_.transport_version)) {
8633 mock_quic_data.AddWrite(SYNCHRONOUS,
8634 ConstructInitialSettingsPacket(packet_num++));
8635 }
Yixin Wang385652a2018-02-16 02:37:238636
8637 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:238638 mock_quic_data.AddWrite(
8639 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8640 packet_num++, client_stream_0, true, true, HIGHEST,
8641 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:028642 mock_quic_data.AddWrite(
8643 SYNCHRONOUS,
8644 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238645 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028646 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
8647 mock_quic_data.AddWrite(
8648 SYNCHRONOUS,
8649 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238650 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028651 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:238652
8653 // Server replies "OK" for the three requests.
Ryan Hamilton0d65a8c2019-06-07 00:46:028654 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8655 1, client_stream_0, false, false,
8656 GetResponseHeaders("200 OK")));
8657 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8658 2, client_stream_1, false, false,
8659 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238660 mock_quic_data.AddWrite(SYNCHRONOUS,
8661 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton0d65a8c2019-06-07 00:46:028662 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8663 3, client_stream_2, false, false,
8664 GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:238665
8666 // Server sends two push promises associated with |client_stream_0|; client
8667 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8668 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:028669 mock_quic_data.AddRead(
8670 ASYNC,
8671 ConstructServerPushPromisePacket(
8672 4, client_stream_0, push_stream_0, false,
8673 GetRequestHeaders("GET", "https", "/pushed_0.jpg"), &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238674 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438675 SYNCHRONOUS,
8676 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238677 packet_num++, false, 4, 3, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:438678 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:028679 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
8680 mock_quic_data.AddRead(
8681 ASYNC,
8682 ConstructServerPushPromisePacket(
8683 5, client_stream_0, push_stream_1, false,
8684 GetRequestHeaders("GET", "https", "/pushed_1.jpg"), &server_maker_));
8685 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientPriorityPacket(
Renjie Tangaadb84b2019-08-31 01:00:238686 packet_num++, false, push_stream_1,
Ryan Hamilton0d65a8c2019-06-07 00:46:028687 push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:238688
8689 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438690 mock_quic_data.AddRead(
8691 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:028692 6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238693 mock_quic_data.AddWrite(SYNCHRONOUS,
8694 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:438695 mock_quic_data.AddRead(
8696 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:028697 7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:238698
8699 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8700 // priority updates to match the request's priority. Client sends PRIORITY
8701 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438702 mock_quic_data.AddWrite(
8703 SYNCHRONOUS,
8704 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238705 packet_num++, false, 7, 7, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:438706 {{push_stream_1, client_stream_2,
8707 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8708 {push_stream_0, client_stream_0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028709 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:238710
8711 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:438712 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438713 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178714 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Renjief49758b2019-01-11 23:32:418715 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438716 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178717 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Renjief49758b2019-01-11 23:32:418718 header + "hello 1!"));
Renjie Tangaadb84b2019-08-31 01:00:238719 mock_quic_data.AddWrite(SYNCHRONOUS,
8720 ConstructClientAckPacket(packet_num++, 9, 8, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:438721 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178722 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Renjief49758b2019-01-11 23:32:418723 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:438724 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438725 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178726 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true,
Renjief49758b2019-01-11 23:32:418727 header2 + "and hello 0!"));
Renjie Tangaadb84b2019-08-31 01:00:238728 mock_quic_data.AddWrite(SYNCHRONOUS,
8729 ConstructClientAckPacket(packet_num++, 11, 10, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:438730 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178731 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Renjief49758b2019-01-11 23:32:418732 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238733
Yixin Wang385652a2018-02-16 02:37:238734 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8735 mock_quic_data.AddRead(ASYNC, 0); // EOF
8736 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8737
8738 // The non-alternate protocol job needs to hang in order to guarantee that
8739 // the alternate-protocol job will "win".
8740 AddHangingNonAlternateProtocolSocketData();
8741
8742 CreateSession();
8743
8744 request_.url = GURL("https://mail.example.org/0.jpg");
8745 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8746 TestCompletionCallback callback_0;
8747 EXPECT_EQ(ERR_IO_PENDING,
8748 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8749 base::RunLoop().RunUntilIdle();
8750
8751 request_.url = GURL("https://mail.example.org/1.jpg");
8752 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8753 TestCompletionCallback callback_1;
8754 EXPECT_EQ(ERR_IO_PENDING,
8755 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8756 base::RunLoop().RunUntilIdle();
8757
8758 request_.url = GURL("https://mail.example.org/2.jpg");
8759 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8760 TestCompletionCallback callback_2;
8761 EXPECT_EQ(ERR_IO_PENDING,
8762 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8763 base::RunLoop().RunUntilIdle();
8764
8765 // Client makes request that matches resource pushed in |pushed_stream_0|.
8766 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8767 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8768 TestCompletionCallback callback_3;
8769 EXPECT_EQ(ERR_IO_PENDING,
8770 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8771 base::RunLoop().RunUntilIdle();
8772
8773 EXPECT_TRUE(callback_0.have_result());
8774 EXPECT_EQ(OK, callback_0.WaitForResult());
8775 EXPECT_TRUE(callback_1.have_result());
8776 EXPECT_EQ(OK, callback_1.WaitForResult());
8777 EXPECT_TRUE(callback_2.have_result());
8778 EXPECT_EQ(OK, callback_2.WaitForResult());
8779
8780 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8781 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8782 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8783 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8784
8785 mock_quic_data.Resume();
8786 base::RunLoop().RunUntilIdle();
8787 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8788 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8789}
8790
Matt Menke26e41542019-06-05 01:09:518791// Test that NetworkIsolationKey is respected by QUIC connections, when
8792// kPartitionConnectionsByNetworkIsolationKey is enabled.
8793TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Shivani Sharma8ae506c2019-07-21 21:08:278794 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
8795 const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
8796 NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
8797 NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
Matt Menke26e41542019-06-05 01:09:518798
Nick Harper72ade192019-07-17 03:30:428799 session_params_.quic_params.origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:518800 HostPortPair::FromString("mail.example.org:443"));
8801
8802 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
8803 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
8804 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
8805 // the same way as the HTTP over H2 proxy case.
8806 for (bool use_proxy : {false, true}) {
8807 SCOPED_TRACE(use_proxy);
8808
8809 if (use_proxy) {
8810 proxy_resolution_service_ =
8811 ProxyResolutionService::CreateFixedFromPacResult(
8812 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
8813 } else {
8814 proxy_resolution_service_ = ProxyResolutionService::CreateDirect();
8815 }
8816
8817 GURL url1;
8818 GURL url2;
8819 GURL url3;
8820 if (use_proxy) {
8821 url1 = GURL("http://mail.example.org/1");
8822 url2 = GURL("http://mail.example.org/2");
8823 url3 = GURL("http://mail.example.org/3");
8824 } else {
8825 url1 = GURL("https://mail.example.org/1");
8826 url2 = GURL("https://mail.example.org/2");
8827 url3 = GURL("https://mail.example.org/3");
8828 }
8829
8830 for (bool partition_connections : {false, true}) {
8831 SCOPED_TRACE(partition_connections);
8832
8833 base::test::ScopedFeatureList feature_list;
8834 if (partition_connections) {
8835 feature_list.InitAndEnableFeature(
8836 features::kPartitionConnectionsByNetworkIsolationKey);
8837 } else {
8838 feature_list.InitAndDisableFeature(
8839 features::kPartitionConnectionsByNetworkIsolationKey);
8840 }
8841
8842 // Reads and writes for the unpartitioned case, where only one socket is
8843 // used.
8844
Nick Harper72ade192019-07-17 03:30:428845 session_params_.quic_params.origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:518846 HostPortPair::FromString("mail.example.org:443"));
8847
Ryan Hamiltonabad59e2019-06-06 04:02:598848 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:518849 QuicTestPacketMaker client_maker1(
8850 version_,
8851 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8852 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8853 client_headers_include_h2_stream_dependency_);
8854 QuicTestPacketMaker server_maker1(
8855 version_,
8856 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8857 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8858
Renjie Tangaadb84b2019-08-31 01:00:238859 int packet_num = 1;
8860 if (VersionUsesQpack(version_.transport_version)) {
8861 unpartitioned_mock_quic_data.AddWrite(
8862 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
8863 }
Matt Menke26e41542019-06-05 01:09:518864
8865 unpartitioned_mock_quic_data.AddWrite(
8866 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028867 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238868 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8869 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028870 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518871 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028872 ASYNC, server_maker1.MakeResponseHeadersPacket(
8873 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8874 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518875 unpartitioned_mock_quic_data.AddRead(
8876 ASYNC, server_maker1.MakeDataPacket(
8877 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178878 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:518879 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238880 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke26e41542019-06-05 01:09:518881
8882 unpartitioned_mock_quic_data.AddWrite(
8883 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028884 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238885 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
8886 false, true,
Matt Menke26e41542019-06-05 01:09:518887 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028888 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518889 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028890 ASYNC, server_maker1.MakeResponseHeadersPacket(
8891 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8892 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518893 unpartitioned_mock_quic_data.AddRead(
8894 ASYNC, server_maker1.MakeDataPacket(
8895 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178896 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:518897 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238898 SYNCHRONOUS,
8899 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
Matt Menke26e41542019-06-05 01:09:518900
8901 unpartitioned_mock_quic_data.AddWrite(
8902 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028903 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238904 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
8905 false, true,
Matt Menke26e41542019-06-05 01:09:518906 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028907 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518908 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028909 ASYNC, server_maker1.MakeResponseHeadersPacket(
8910 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
8911 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518912 unpartitioned_mock_quic_data.AddRead(
8913 ASYNC, server_maker1.MakeDataPacket(
8914 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Ryan Hamilton7505eb92019-06-08 00:22:178915 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:518916 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238917 SYNCHRONOUS,
8918 ConstructClientAckAndConnectionClosePacket(packet_num++, 6, 5, 1));
Matt Menke26e41542019-06-05 01:09:518919
8920 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8921
8922 // Reads and writes for the partitioned case, where two sockets are used.
8923
Ryan Hamiltonabad59e2019-06-06 04:02:598924 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:518925 QuicTestPacketMaker client_maker2(
8926 version_,
8927 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8928 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8929 client_headers_include_h2_stream_dependency_);
8930 QuicTestPacketMaker server_maker2(
8931 version_,
8932 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8933 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8934
Renjie Tangaadb84b2019-08-31 01:00:238935 int packet_num2 = 1;
8936 if (VersionUsesQpack(version_.transport_version)) {
8937 partitioned_mock_quic_data1.AddWrite(
8938 SYNCHRONOUS,
8939 client_maker2.MakeInitialSettingsPacket(packet_num2++));
8940 }
Matt Menke26e41542019-06-05 01:09:518941
8942 partitioned_mock_quic_data1.AddWrite(
8943 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028944 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238945 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
8946 true, true,
Matt Menke26e41542019-06-05 01:09:518947 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028948 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518949 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028950 ASYNC, server_maker2.MakeResponseHeadersPacket(
8951 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8952 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518953 partitioned_mock_quic_data1.AddRead(
8954 ASYNC, server_maker2.MakeDataPacket(
8955 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178956 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:518957 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238958 SYNCHRONOUS,
8959 client_maker2.MakeAckPacket(packet_num2++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:518960
8961 partitioned_mock_quic_data1.AddWrite(
8962 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028963 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238964 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
8965 false, true,
Matt Menke26e41542019-06-05 01:09:518966 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028967 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518968 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028969 ASYNC, server_maker2.MakeResponseHeadersPacket(
8970 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8971 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518972 partitioned_mock_quic_data1.AddRead(
8973 ASYNC, server_maker2.MakeDataPacket(
8974 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178975 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:518976 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238977 SYNCHRONOUS,
8978 client_maker2.MakeAckPacket(packet_num2++, 4, 3, 1, true));
Matt Menke26e41542019-06-05 01:09:518979
8980 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8981
Ryan Hamiltonabad59e2019-06-06 04:02:598982 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:518983 QuicTestPacketMaker client_maker3(
8984 version_,
8985 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8986 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8987 client_headers_include_h2_stream_dependency_);
8988 QuicTestPacketMaker server_maker3(
8989 version_,
8990 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8991 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8992
Renjie Tangaadb84b2019-08-31 01:00:238993 int packet_num3 = 1;
8994 if (VersionUsesQpack(version_.transport_version)) {
8995 partitioned_mock_quic_data2.AddWrite(
8996 SYNCHRONOUS,
8997 client_maker3.MakeInitialSettingsPacket(packet_num3++));
8998 }
Matt Menke26e41542019-06-05 01:09:518999
9000 partitioned_mock_quic_data2.AddWrite(
9001 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029002 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239003 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9004 true, true,
Matt Menke26e41542019-06-05 01:09:519005 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029006 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519007 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029008 ASYNC, server_maker3.MakeResponseHeadersPacket(
9009 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9010 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519011 partitioned_mock_quic_data2.AddRead(
9012 ASYNC, server_maker3.MakeDataPacket(
9013 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179014 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519015 partitioned_mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239016 SYNCHRONOUS,
9017 client_maker3.MakeAckPacket(packet_num3++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519018
9019 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9020
9021 if (partition_connections) {
9022 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9023 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9024 } else {
9025 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9026 }
9027
9028 CreateSession();
9029
9030 TestCompletionCallback callback;
9031 HttpRequestInfo request1;
9032 request1.method = "GET";
9033 request1.url = GURL(url1);
9034 request1.traffic_annotation =
9035 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9036 request1.network_isolation_key = network_isolation_key1;
9037 HttpNetworkTransaction trans1(LOWEST, session_.get());
9038 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9039 EXPECT_THAT(callback.GetResult(rv), IsOk());
9040 std::string response_data1;
9041 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9042 EXPECT_EQ("1", response_data1);
9043
9044 HttpRequestInfo request2;
9045 request2.method = "GET";
9046 request2.url = GURL(url2);
9047 request2.traffic_annotation =
9048 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9049 request2.network_isolation_key = network_isolation_key2;
9050 HttpNetworkTransaction trans2(LOWEST, session_.get());
9051 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9052 EXPECT_THAT(callback.GetResult(rv), IsOk());
9053 std::string response_data2;
9054 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9055 EXPECT_EQ("2", response_data2);
9056
9057 HttpRequestInfo request3;
9058 request3.method = "GET";
9059 request3.url = GURL(url3);
9060 request3.traffic_annotation =
9061 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9062 request3.network_isolation_key = network_isolation_key1;
9063 HttpNetworkTransaction trans3(LOWEST, session_.get());
9064 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9065 EXPECT_THAT(callback.GetResult(rv), IsOk());
9066 std::string response_data3;
9067 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9068 EXPECT_EQ("3", response_data3);
9069
9070 if (partition_connections) {
9071 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9072 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9073 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9074 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9075 } else {
9076 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9077 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9078 }
9079 }
9080 }
9081}
9082
9083// Test that two requests to the same origin over QUIC tunnels use different
9084// QUIC sessions if their NetworkIsolationKeys don't match, and
9085// kPartitionConnectionsByNetworkIsolationKey is enabled.
9086TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9087 base::test::ScopedFeatureList feature_list;
9088 feature_list.InitAndEnableFeature(
9089 features::kPartitionConnectionsByNetworkIsolationKey);
9090
9091 session_params_.enable_quic = true;
9092 session_params_.enable_quic_proxies_for_https_urls = true;
9093 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
9094 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9095
9096 const char kGetRequest[] =
9097 "GET / HTTP/1.1\r\n"
9098 "Host: mail.example.org\r\n"
9099 "Connection: keep-alive\r\n\r\n";
9100 const char kGetResponse[] =
9101 "HTTP/1.1 200 OK\r\n"
9102 "Content-Length: 10\r\n\r\n";
9103
Ryan Hamiltonabad59e2019-06-06 04:02:599104 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9105 std::make_unique<MockQuicData>(version_),
9106 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519107
9108 for (int index : {0, 1}) {
9109 QuicTestPacketMaker client_maker(
9110 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9111 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9112 client_headers_include_h2_stream_dependency_);
9113 QuicTestPacketMaker server_maker(
9114 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9115 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
9116
Renjie Tangaadb84b2019-08-31 01:00:239117 int packet_num = 1;
9118 if (VersionUsesQpack(version_.transport_version)) {
9119 mock_quic_data[index]->AddWrite(
9120 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
9121 }
Matt Menke26e41542019-06-05 01:09:519122
Ryan Hamiltonabad59e2019-06-06 04:02:599123 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519124 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029125 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239126 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9127 false,
Matt Menke26e41542019-06-05 01:09:519128 ConvertRequestPriorityToQuicPriority(
9129 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:029130 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:599131 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029132 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:519133 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9134 false, GetResponseHeaders("200 OK"), nullptr));
9135
9136 std::string header = ConstructDataHeader(strlen(kGetRequest));
9137 if (version_.transport_version != quic::QUIC_VERSION_99) {
Ryan Hamiltonabad59e2019-06-06 04:02:599138 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239139 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
9140 packet_num++, false,
9141 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
9142 1, false, quic::QuicStringPiece(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:519143 } else {
Ryan Hamiltonabad59e2019-06-06 04:02:599144 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239145 SYNCHRONOUS, client_maker.MakeAckAndMultipleDataFramesPacket(
9146 packet_num++, false,
9147 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
9148 1, false, {header, std::string(kGetRequest)}));
Matt Menke26e41542019-06-05 01:09:519149 }
9150
9151 std::string header2 = ConstructDataHeader(strlen(kGetResponse));
Ryan Hamiltonabad59e2019-06-06 04:02:599152 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519153 ASYNC, server_maker.MakeDataPacket(
9154 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179155 false, header2 + std::string(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599156 mock_quic_data[index]->AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179157 SYNCHRONOUS,
9158 server_maker.MakeDataPacket(
9159 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
9160 ConstructDataHeader(10) + std::string("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599161 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239162 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2, 1, true));
Ryan Hamiltonabad59e2019-06-06 04:02:599163 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9164 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:519165
Ryan Hamiltonabad59e2019-06-06 04:02:599166 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:519167 }
9168
9169 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9170 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9171 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9172
9173 CreateSession();
9174
9175 request_.url = GURL("https://mail.example.org/");
9176 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9177 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9178 RunTransaction(&trans);
9179 CheckResponseData(&trans, "0123456789");
9180
9181 HttpRequestInfo request2;
Shivani Sharma8ae506c2019-07-21 21:08:279182 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9183 request_.network_isolation_key = NetworkIsolationKey(kOrigin1, kOrigin1);
Matt Menke26e41542019-06-05 01:09:519184 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9185 RunTransaction(&trans2);
9186 CheckResponseData(&trans2, "0123456789");
9187
Ryan Hamiltonabad59e2019-06-06 04:02:599188 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9189 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9190 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9191 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:519192}
9193
[email protected]61a527782013-02-21 03:58:009194} // namespace test
9195} // namespace net