blob: c5ac6ddbf4c9ff5e104e3483536093824e8e613b [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_));
Matt Menkeb566c392019-09-11 23:22:43674 session_->quic_stream_factory()
675 ->set_is_quic_known_to_work_on_current_network(true);
Yixin Wang46a273ec302018-01-23 17:59:56676 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
677 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00678 }
679
zhongyi86838d52017-06-30 01:19:44680 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21681
bnc691fda62016-08-12 00:43:16682 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19683 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42684 ASSERT_TRUE(response != nullptr);
685 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19686 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
687 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52688 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:56689 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
690 version_.transport_version),
[email protected]aa9b14d2013-05-10 23:45:19691 response->connection_info);
692 }
693
bnc691fda62016-08-12 00:43:16694 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41695 const HttpResponseInfo* response = trans->GetResponseInfo();
696 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37697 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41698 }
699
bnc691fda62016-08-12 00:43:16700 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19701 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42702 ASSERT_TRUE(response != nullptr);
703 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19704 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
705 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52706 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52707 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19708 response->connection_info);
709 }
710
Yixin Wang46a273ec302018-01-23 17:59:56711 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
712 const HttpResponseInfo* response = trans->GetResponseInfo();
713 ASSERT_TRUE(response != nullptr);
714 ASSERT_TRUE(response->headers.get() != nullptr);
715 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
716 EXPECT_TRUE(response->was_fetched_via_spdy);
717 EXPECT_TRUE(response->was_alpn_negotiated);
718 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
719 response->connection_info);
720 }
721
bnc691fda62016-08-12 00:43:16722 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19723 const std::string& expected) {
724 std::string response_data;
bnc691fda62016-08-12 00:43:16725 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19726 EXPECT_EQ(expected, response_data);
727 }
728
bnc691fda62016-08-12 00:43:16729 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19730 TestCompletionCallback callback;
731 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01732 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
733 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19734 }
735
736 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
738 RunTransaction(&trans);
739 CheckWasHttpResponse(&trans);
740 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19741 }
742
tbansalc3308d72016-08-27 10:25:04743 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
744 bool used_proxy,
745 uint16_t port) {
746 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
747 HeadersHandler headers_handler;
748 trans.SetBeforeHeadersSentCallback(
749 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
750 base::Unretained(&headers_handler)));
751 RunTransaction(&trans);
752 CheckWasHttpResponse(&trans);
753 CheckResponsePort(&trans, port);
754 CheckResponseData(&trans, expected);
755 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47756 if (used_proxy) {
757 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
758 } else {
759 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
760 }
tbansalc3308d72016-08-27 10:25:04761 }
762
[email protected]aa9b14d2013-05-10 23:45:19763 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56764 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12765 }
766
bnc62a44f022015-04-02 15:59:41767 void SendRequestAndExpectQuicResponseFromProxyOnPort(
768 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46769 uint16_t port) {
bnc62a44f022015-04-02 15:59:41770 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19771 }
772
773 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05774 MockCryptoClientStream::HandshakeMode handshake_mode,
775 const NetworkIsolationKey& network_isolation_key =
776 NetworkIsolationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19777 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46778 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21779 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12780 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49781 http_server_properties_->SetQuicAlternativeService(
Matt Menkeb32ba5122019-09-10 19:17:05782 server, network_isolation_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07783 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19784 }
785
rchbe69cb902016-02-11 01:10:48786 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27787 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48788 const HostPortPair& alternative) {
789 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46790 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21791 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48792 alternative.port());
793 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49794 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07795 server, NetworkIsolationKey(), alternative_service, expiration,
796 supported_versions_);
rchbe69cb902016-02-11 01:10:48797 }
798
Matt Menkeb32ba5122019-09-10 19:17:05799 void ExpectBrokenAlternateProtocolMapping(
800 const NetworkIsolationKey& network_isolation_key =
801 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46802 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34803 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49804 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05805 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34806 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49807 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05808 alternative_service_info_vector[0].alternative_service(),
809 network_isolation_key));
[email protected]aa9b14d2013-05-10 23:45:19810 }
811
Matt Menkeb32ba5122019-09-10 19:17:05812 void ExpectQuicAlternateProtocolMapping(
813 const NetworkIsolationKey& network_isolation_key =
814 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46815 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34816 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49817 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05818 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34819 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54820 EXPECT_EQ(
821 kProtoQUIC,
822 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49823 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05824 alternative_service_info_vector[0].alternative_service(),
825 network_isolation_key));
[email protected]4d590c9c2014-05-02 05:14:33826 }
827
[email protected]aa9b14d2013-05-10 23:45:19828 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42829 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30830 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30831 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30832 hanging_data->set_connect_data(hanging_connect);
833 hanging_data_.push_back(std::move(hanging_data));
834 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56835 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19836 }
837
Zhongyi Shia6b68d112018-09-24 07:49:03838 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Nick Harper72ade192019-07-17 03:30:42839 session_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
840 session_params_.quic_params.migrate_sessions_early_v2 = true;
841 session_params_.quic_params.retry_on_alternate_network_before_handshake =
842 true;
Zhongyi Shia6b68d112018-09-24 07:49:03843 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
844 MockNetworkChangeNotifier* mock_ncn =
845 scoped_mock_change_notifier_->mock_network_change_notifier();
846 mock_ncn->ForceNetworkHandlesSupported();
847 mock_ncn->SetConnectedNetworksList(
848 {kDefaultNetworkForTests, kNewNetworkForTests});
849 }
850
tbansalc3308d72016-08-27 10:25:04851 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
852 // alternative proxy. Verifies that if the alternative proxy job returns
853 // |error_code|, the request is fetched successfully by the main job.
854 void TestAlternativeProxy(int error_code) {
855 // Use a non-cryptographic scheme for the request URL since this request
856 // will be fetched via proxy with QUIC as the alternative service.
857 request_.url = GURL("http://example.org/");
858 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27859 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04860 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27861 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04862 };
863
Ryan Sleevib8d7ea02018-05-07 20:01:01864 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04865 socket_factory_.AddSocketDataProvider(&quic_data);
866
867 // Main job succeeds and the alternative job fails.
868 // Add data for two requests that will be read by the main job.
869 MockRead http_reads_1[] = {
870 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
871 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
872 MockRead(ASYNC, OK)};
873
874 MockRead http_reads_2[] = {
875 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
876 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
877 MockRead(ASYNC, OK)};
878
Ryan Sleevib8d7ea02018-05-07 20:01:01879 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
880 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04881 socket_factory_.AddSocketDataProvider(&http_data_1);
882 socket_factory_.AddSocketDataProvider(&http_data_2);
883 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
884 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
885
886 TestProxyDelegate test_proxy_delegate;
887 // Proxy URL is different from the request URL.
888 test_proxy_delegate.set_alternative_proxy_server(
889 ProxyServer::FromPacString("QUIC myproxy.org:443"));
890
Lily Houghton8c2f97d2018-01-22 05:06:59891 proxy_resolution_service_ =
892 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49893 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52894 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04895
896 CreateSession();
897 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
898
899 // The first request should be fetched via the HTTPS proxy.
900 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
901
Reilly Grant89a7e512018-01-20 01:57:16902 // Since the main job succeeded only the alternative proxy server should be
903 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59904 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16905 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04906
907 // Verify that the second request completes successfully, and the
908 // alternative proxy server job is not started.
909 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
910 }
911
Matt Menkeb32ba5122019-09-10 19:17:05912 // Adds a new socket data provider for an HTTP request, and runs a request,
913 // expecting it to be used.
914 void AddHttpDataAndRunRequest() {
915 MockWrite http_writes[] = {
916 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
917 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
918 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
919
920 MockRead http_reads[] = {
921 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
922 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
923 MockRead(SYNCHRONOUS, 5, "http used"),
924 // Connection closed.
925 MockRead(SYNCHRONOUS, OK, 6)};
926 SequencedSocketData http_data(http_reads, http_writes);
927 socket_factory_.AddSocketDataProvider(&http_data);
928 SSLSocketDataProvider ssl_data(ASYNC, OK);
929 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
930 SendRequestAndExpectHttpResponse("http used");
931 EXPECT_TRUE(http_data.AllWriteDataConsumed());
932 EXPECT_TRUE(http_data.AllReadDataConsumed());
933 }
934
935 // Adds a new socket data provider for a QUIC request, and runs a request,
936 // expecting it to be used. The new QUIC session is not closed.
937 void AddQuicDataAndRunRequest() {
938 QuicTestPacketMaker client_maker(
939 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
940 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
941 client_headers_include_h2_stream_dependency_);
942 QuicTestPacketMaker server_maker(
943 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
944 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
945 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56946 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05947 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjie Tang874398a2019-09-13 18:32:56948 if (VersionUsesQpack(version_.transport_version)) {
949 quic_data.AddWrite(
950 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_number++));
951 }
Matt Menkeb32ba5122019-09-10 19:17:05952 quic_data.AddWrite(
953 SYNCHRONOUS,
954 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56955 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
956 true, true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Matt Menkeb32ba5122019-09-10 19:17:05957 GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
958 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
959 quic_data.AddRead(
960 ASYNC, server_maker.MakeResponseHeadersPacket(
961 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
962 false, server_maker.GetResponseHeaders("200 OK"), nullptr));
963 std::string header = ConstructDataHeader(9);
964 quic_data.AddRead(
965 ASYNC, server_maker.MakeDataPacket(
966 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
967 true, header + "quic used"));
968 // Don't care about the final ack.
969 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
970 // No more data to read.
971 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
972 quic_data.AddSocketDataToFactory(&socket_factory_);
973 SendRequestAndExpectQuicResponse("quic used");
974
975 EXPECT_TRUE(quic_data.AllReadDataConsumed());
976 }
977
Fan Yang32c5a112018-12-10 20:06:33978 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56979 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
980 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36981 }
982
Fan Yang32c5a112018-12-10 20:06:33983 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56984 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
985 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36986 }
987
Bence Béky230ac612017-08-30 19:17:08988 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49989 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08990 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49991 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08992 }
993
Nick Harper23290b82019-05-02 00:02:56994 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05995 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:56996 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01997 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52998 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:17999 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:581000 QuicTestPacketMaker client_maker_;
1001 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:091002 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:421003 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:001004 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:561005 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:051006 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:431007 MockHostResolver host_resolver_;
1008 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:111009 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:421010 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:231011 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:381012 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:071013 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:591014 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:421015 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:491016 std::unique_ptr<HttpServerProperties> http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:411017 HttpNetworkSession::Params session_params_;
1018 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:191019 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:511020 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:421021 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:561022 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:031023 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:121024
1025 private:
1026 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1027 const std::string& expected,
bnc62a44f022015-04-02 15:59:411028 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:461029 uint16_t port) {
bnc691fda62016-08-12 00:43:161030 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:091031 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:161032 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091033 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
1034 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:161035 RunTransaction(&trans);
1036 CheckWasQuicResponse(&trans);
1037 CheckResponsePort(&trans, port);
1038 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:091039 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:471040 if (used_proxy) {
1041 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
1042 } else {
1043 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1044 }
tbansal7cec3812015-02-05 21:25:121045 }
[email protected]61a527782013-02-21 03:58:001046};
1047
Ryan Hamiltone940bd12019-06-30 02:46:451048quic::ParsedQuicVersionVector AllSupportedVersionsWithoutTls() {
1049 quic::ParsedQuicVersionVector versions;
Ryan Hamilton93424eb82019-08-23 04:28:401050 for (auto version : quic::AllSupportedVersions()) {
Ryan Hamiltone940bd12019-06-30 02:46:451051 // TODO(rch): crbug.com/978745 - Make this work with TLS
1052 if (version.handshake_protocol != quic::PROTOCOL_TLS1_3) {
1053 versions.push_back(version);
1054 }
1055 }
1056 return versions;
1057}
1058
Victor Costane635086f2019-01-27 05:20:301059INSTANTIATE_TEST_SUITE_P(
Yixin Wang385652a2018-02-16 02:37:231060 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051061 QuicNetworkTransactionTest,
Ryan Hamiltone940bd12019-06-30 02:46:451062 ::testing::Combine(::testing::ValuesIn(AllSupportedVersionsWithoutTls()),
Nick Harper23290b82019-05-02 00:02:561063 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:201064
Shivani Sharma8ae506c2019-07-21 21:08:271065// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
1066// kAppendInitiatingFrameOriginToNetworkIsolationKey.
1067
Ryan Hamiltona64a5bcf2017-11-30 07:35:281068TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:421069 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281070 base::HistogramTester histograms;
Nick Harper72ade192019-07-17 03:30:421071 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281072 HostPortPair::FromString("mail.example.org:443"));
1073 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271074 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281075
Ryan Hamiltonabad59e2019-06-06 04:02:591076 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231077 if (VersionUsesQpack(version_.transport_version))
1078 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281079 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1080 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1081 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1082
1083 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1084
1085 CreateSession();
1086
1087 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1088 TestCompletionCallback callback;
1089 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1091 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1092
1093 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1094 -ERR_INTERNET_DISCONNECTED, 1);
1095 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1096 -ERR_INTERNET_DISCONNECTED, 1);
1097}
1098
1099TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Nick Harper72ade192019-07-17 03:30:421100 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281101 base::HistogramTester histograms;
Nick Harper72ade192019-07-17 03:30:421102 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281103 HostPortPair::FromString("mail.example.org:443"));
1104 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271105 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281106
Ryan Hamiltonabad59e2019-06-06 04:02:591107 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231108 if (VersionUsesQpack(version_.transport_version))
1109 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281110 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1111 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1112 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1113
1114 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1115
1116 CreateSession();
1117
1118 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1119 TestCompletionCallback callback;
1120 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1121 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1122 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1123
1124 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1125 -ERR_INTERNET_DISCONNECTED, 1);
1126 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1127 -ERR_INTERNET_DISCONNECTED, 1);
1128}
1129
tbansal180587c2017-02-16 15:13:231130TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Nick Harper72ade192019-07-17 03:30:421131 session_params_.quic_params.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231132 HostPortPair::FromString("mail.example.org:443"));
1133
Ryan Hamiltonabad59e2019-06-06 04:02:591134 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231135 int packet_num = 1;
1136 if (VersionUsesQpack(version_.transport_version)) {
1137 mock_quic_data.AddWrite(SYNCHRONOUS,
1138 ConstructInitialSettingsPacket(packet_num++));
1139 }
rch5cb522462017-04-25 20:18:361140 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231141 SYNCHRONOUS,
1142 ConstructClientRequestHeadersPacket(
1143 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1144 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431145 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331146 ASYNC, ConstructServerResponseHeadersPacket(
1147 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1148 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431149 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331150 mock_quic_data.AddRead(
1151 ASYNC, ConstructServerDataPacket(
1152 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171153 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231154 mock_quic_data.AddWrite(SYNCHRONOUS,
1155 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231156 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1157
1158 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1159
1160 CreateSession();
1161 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1162
1163 EXPECT_FALSE(
1164 test_socket_performance_watcher_factory_.rtt_notification_received());
1165 SendRequestAndExpectQuicResponse("hello!");
1166 EXPECT_TRUE(
1167 test_socket_performance_watcher_factory_.rtt_notification_received());
1168}
1169
1170TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Nick Harper72ade192019-07-17 03:30:421171 session_params_.quic_params.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231172 HostPortPair::FromString("mail.example.org:443"));
1173
Ryan Hamiltonabad59e2019-06-06 04:02:591174 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231175 int packet_num = 1;
1176 if (VersionUsesQpack(version_.transport_version)) {
1177 mock_quic_data.AddWrite(SYNCHRONOUS,
1178 ConstructInitialSettingsPacket(packet_num++));
1179 }
rch5cb522462017-04-25 20:18:361180 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231181 SYNCHRONOUS,
1182 ConstructClientRequestHeadersPacket(
1183 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1184 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431185 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331186 ASYNC, ConstructServerResponseHeadersPacket(
1187 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1188 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431189 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331190 mock_quic_data.AddRead(
1191 ASYNC, ConstructServerDataPacket(
1192 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171193 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231194 mock_quic_data.AddWrite(SYNCHRONOUS,
1195 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231196 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1197
1198 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1199
1200 CreateSession();
1201 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1202
1203 EXPECT_FALSE(
1204 test_socket_performance_watcher_factory_.rtt_notification_received());
1205 SendRequestAndExpectQuicResponse("hello!");
1206 EXPECT_FALSE(
1207 test_socket_performance_watcher_factory_.rtt_notification_received());
1208}
1209
[email protected]1e960032013-12-20 19:00:201210TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Nick Harper72ade192019-07-17 03:30:421211 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571212 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471213
Ryan Hamiltonabad59e2019-06-06 04:02:591214 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231215 int packet_num = 1;
1216 if (VersionUsesQpack(version_.transport_version)) {
1217 mock_quic_data.AddWrite(SYNCHRONOUS,
1218 ConstructInitialSettingsPacket(packet_num++));
1219 }
rch5cb522462017-04-25 20:18:361220 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231221 SYNCHRONOUS,
1222 ConstructClientRequestHeadersPacket(
1223 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1224 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431225 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331226 ASYNC, ConstructServerResponseHeadersPacket(
1227 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1228 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431229 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331230 mock_quic_data.AddRead(
1231 ASYNC, ConstructServerDataPacket(
1232 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171233 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231234 mock_quic_data.AddWrite(SYNCHRONOUS,
1235 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591236 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471237
rcha5399e02015-04-21 19:32:041238 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471239
[email protected]4dca587c2013-03-07 16:54:471240 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471241
[email protected]aa9b14d2013-05-10 23:45:191242 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471243
[email protected]98b20ce2013-05-10 05:55:261244 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:541245 auto entries = net_log_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261246 EXPECT_LT(0u, entries.size());
1247
1248 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291249 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001250 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1251 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261252 EXPECT_LT(0, pos);
1253
rchfd527212015-08-25 00:41:261254 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291255 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261256 entries, 0,
mikecirone8b85c432016-09-08 19:11:001257 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1258 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261259 EXPECT_LT(0, pos);
1260
Eric Roman79cc7552019-07-19 02:17:541261 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261262
rchfd527212015-08-25 00:41:261263 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1264 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001265 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1266 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261267 EXPECT_LT(0, pos);
1268
[email protected]98b20ce2013-05-10 05:55:261269 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291270 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001271 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1272 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261273 EXPECT_LT(0, pos);
1274
Eric Roman79cc7552019-07-19 02:17:541275 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Ryan Hamiltone940bd12019-06-30 02:46:451276 if (quic::VersionUsesQpack(version_.transport_version)) {
1277 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1278 static_cast<quic::QuicStreamId>(log_stream_id));
1279 } else {
1280 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1281 static_cast<quic::QuicStreamId>(log_stream_id));
1282 }
[email protected]4dca587c2013-03-07 16:54:471283}
1284
rchbd089ab2017-05-26 23:05:041285TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Ryan Hamiltone940bd12019-06-30 02:46:451286 // TODO(rch): honor the max header list size. b/136108828
1287 if (quic::VersionUsesQpack(version_.transport_version))
1288 return;
1289
Nick Harper72ade192019-07-17 03:30:421290 session_params_.quic_params.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041291 HostPortPair::FromString("mail.example.org:443"));
1292
Ryan Hamiltonabad59e2019-06-06 04:02:591293 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231294 int packet_num = 1;
1295 if (VersionUsesQpack(version_.transport_version)) {
1296 mock_quic_data.AddWrite(SYNCHRONOUS,
1297 ConstructInitialSettingsPacket(packet_num++));
1298 }
rchbd089ab2017-05-26 23:05:041299 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231300 SYNCHRONOUS,
1301 ConstructClientRequestHeadersPacket(
1302 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1303 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0239aac2018-05-19 00:03:131304 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041305 response_headers["key1"] = std::string(30000, 'A');
1306 response_headers["key2"] = std::string(30000, 'A');
1307 response_headers["key3"] = std::string(30000, 'A');
1308 response_headers["key4"] = std::string(30000, 'A');
1309 response_headers["key5"] = std::string(30000, 'A');
1310 response_headers["key6"] = std::string(30000, 'A');
1311 response_headers["key7"] = std::string(30000, 'A');
1312 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451313 quic::QuicStreamId stream_id;
1314 std::string response_data;
1315 if (quic::VersionUsesQpack(version_.transport_version)) {
1316 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1317 std::vector<std::string> encoded = server_maker_.QpackEncodeHeaders(
1318 stream_id, std::move(response_headers), nullptr);
1319 for (const auto& e : encoded) {
1320 response_data += e;
1321 }
1322 } else {
1323 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1324 spdy::SpdyHeadersIR headers_frame(
1325 GetNthClientInitiatedBidirectionalStreamId(0),
1326 std::move(response_headers));
1327 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1328 spdy::SpdySerializedFrame spdy_frame =
1329 response_framer.SerializeFrame(headers_frame);
1330 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1331 }
rchbd089ab2017-05-26 23:05:041332
Fan Yangac867502019-01-28 21:10:231333 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041334 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451335 for (size_t offset = 0; offset < response_data.length();
1336 offset += chunk_size) {
1337 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431338 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451339 ASYNC, ConstructServerDataPacket(
1340 packet_number++, stream_id, false, false,
1341 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041342 }
1343
Victor Vasiliev076657c2019-03-12 02:46:431344 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041345 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331346 ASYNC, ConstructServerDataPacket(
1347 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171348 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041349 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431350 mock_quic_data.AddWrite(ASYNC,
Renjie Tangaadb84b2019-08-31 01:00:231351 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1352 mock_quic_data.AddWrite(
1353 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041354
1355 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1356
1357 CreateSession();
1358
1359 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421360 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1361 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041362}
1363
1364TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Nick Harper72ade192019-07-17 03:30:421365 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
1366 session_params_.quic_params.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041367 HostPortPair::FromString("mail.example.org:443"));
1368
Ryan Hamiltonabad59e2019-06-06 04:02:591369 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231370 int packet_num = 1;
1371 if (VersionUsesQpack(version_.transport_version)) {
1372 mock_quic_data.AddWrite(SYNCHRONOUS,
1373 ConstructInitialSettingsPacket(packet_num++));
1374 }
rchbd089ab2017-05-26 23:05:041375 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231376 SYNCHRONOUS,
1377 ConstructClientRequestHeadersPacket(
1378 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1379 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451380
Ryan Hamilton0239aac2018-05-19 00:03:131381 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041382 response_headers["key1"] = std::string(30000, 'A');
1383 response_headers["key2"] = std::string(30000, 'A');
1384 response_headers["key3"] = std::string(30000, 'A');
1385 response_headers["key4"] = std::string(30000, 'A');
1386 response_headers["key5"] = std::string(30000, 'A');
1387 response_headers["key6"] = std::string(30000, 'A');
1388 response_headers["key7"] = std::string(30000, 'A');
1389 response_headers["key8"] = std::string(30000, 'A');
1390 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451391
1392 quic::QuicStreamId stream_id;
1393 std::string response_data;
1394 if (quic::VersionUsesQpack(version_.transport_version)) {
1395 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1396 std::vector<std::string> encoded = server_maker_.QpackEncodeHeaders(
1397 stream_id, std::move(response_headers), nullptr);
1398 for (const auto& e : encoded) {
1399 response_data += e;
1400 }
1401 } else {
1402 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1403 spdy::SpdyHeadersIR headers_frame(
1404 GetNthClientInitiatedBidirectionalStreamId(0),
1405 std::move(response_headers));
1406 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1407 spdy::SpdySerializedFrame spdy_frame =
1408 response_framer.SerializeFrame(headers_frame);
1409 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1410 }
rchbd089ab2017-05-26 23:05:041411
Fan Yangac867502019-01-28 21:10:231412 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041413 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451414 for (size_t offset = 0; offset < response_data.length();
1415 offset += chunk_size) {
1416 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431417 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451418 ASYNC, ConstructServerDataPacket(
1419 packet_number++, stream_id, false, false,
1420 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041421 }
1422
Victor Vasiliev076657c2019-03-12 02:46:431423 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411424
rchbd089ab2017-05-26 23:05:041425 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331426 ASYNC, ConstructServerDataPacket(
1427 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171428 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041429 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:231430 mock_quic_data.AddWrite(ASYNC,
1431 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431432 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331433 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231434 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:331435 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041436
1437 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1438
1439 CreateSession();
1440
1441 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1442 TestCompletionCallback callback;
1443 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1444 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1445 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1446}
1447
rcha2bd44b2016-07-02 00:42:551448TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Nick Harper72ade192019-07-17 03:30:421449 session_params_.quic_params.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551450
Ryan Hamilton9835e662018-08-02 05:36:271451 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551452
Ryan Hamiltonabad59e2019-06-06 04:02:591453 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231454 int packet_num = 1;
1455 if (VersionUsesQpack(version_.transport_version)) {
1456 mock_quic_data.AddWrite(SYNCHRONOUS,
1457 ConstructInitialSettingsPacket(packet_num++));
1458 }
rch5cb522462017-04-25 20:18:361459 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231460 SYNCHRONOUS,
1461 ConstructClientRequestHeadersPacket(
1462 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1463 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431464 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331465 ASYNC, ConstructServerResponseHeadersPacket(
1466 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1467 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431468 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331469 mock_quic_data.AddRead(
1470 ASYNC, ConstructServerDataPacket(
1471 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171472 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231473 mock_quic_data.AddWrite(SYNCHRONOUS,
1474 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551475 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1476
1477 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1478
1479 CreateSession();
1480
1481 SendRequestAndExpectQuicResponse("hello!");
1482 EXPECT_TRUE(
1483 test_socket_performance_watcher_factory_.rtt_notification_received());
1484}
1485
[email protected]cf3e3cd62014-02-05 16:16:161486TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411487 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591488 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491489 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161490
Ryan Hamiltonabad59e2019-06-06 04:02:591491 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231492 int packet_num = 1;
1493 if (VersionUsesQpack(version_.transport_version)) {
1494 mock_quic_data.AddWrite(SYNCHRONOUS,
1495 ConstructInitialSettingsPacket(packet_num++));
1496 }
rch5cb522462017-04-25 20:18:361497 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231498 SYNCHRONOUS,
1499 ConstructClientRequestHeadersPacket(
1500 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1501 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431502 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331503 ASYNC, ConstructServerResponseHeadersPacket(
1504 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1505 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431506 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331507 mock_quic_data.AddRead(
1508 ASYNC, ConstructServerDataPacket(
1509 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171510 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231511 mock_quic_data.AddWrite(SYNCHRONOUS,
1512 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501513 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591514 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161515
rcha5399e02015-04-21 19:32:041516 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161517
tbansal0f56a39a2016-04-07 22:03:381518 EXPECT_FALSE(
1519 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161520 // There is no need to set up an alternate protocol job, because
1521 // no attempt will be made to speak to the proxy over TCP.
1522
rch9ae5b3b2016-02-11 00:36:291523 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161524 CreateSession();
1525
bnc62a44f022015-04-02 15:59:411526 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381527 EXPECT_TRUE(
1528 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161529}
1530
bnc313ba9c2015-06-11 15:42:311531// Regression test for https://crbug.com/492458. Test that for an HTTP
1532// connection through a QUIC proxy, the certificate exhibited by the proxy is
1533// checked against the proxy hostname, not the origin hostname.
1534TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291535 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311536 const std::string proxy_host = "www.example.org";
1537
mmenke6ddfbea2017-05-31 21:48:411538 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591539 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491540 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311541
alyssar2adf3ac2016-05-03 17:12:581542 client_maker_.set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591543 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231544 int packet_num = 1;
1545 if (VersionUsesQpack(version_.transport_version)) {
1546 mock_quic_data.AddWrite(SYNCHRONOUS,
1547 ConstructInitialSettingsPacket(packet_num++));
1548 }
rch5cb522462017-04-25 20:18:361549 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231550 SYNCHRONOUS,
1551 ConstructClientRequestHeadersPacket(
1552 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1553 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431554 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331555 ASYNC, ConstructServerResponseHeadersPacket(
1556 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1557 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431558 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331559 mock_quic_data.AddRead(
1560 ASYNC, ConstructServerDataPacket(
1561 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171562 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231563 mock_quic_data.AddWrite(SYNCHRONOUS,
1564 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501565 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591566 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311567 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1568
1569 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291570 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311571 ASSERT_TRUE(cert.get());
1572 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241573 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1574 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311575 ProofVerifyDetailsChromium verify_details;
1576 verify_details.cert_verify_result.verified_cert = cert;
1577 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561578 ProofVerifyDetailsChromium verify_details2;
1579 verify_details2.cert_verify_result.verified_cert = cert;
1580 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311581
1582 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091583 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321584 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271585 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311586 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1587}
1588
rchbe69cb902016-02-11 01:10:481589TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Nick Harper72ade192019-07-17 03:30:421590 session_params_.quic_params.allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481591 HostPortPair origin("www.example.org", 443);
1592 HostPortPair alternative("mail.example.org", 443);
1593
1594 base::FilePath certs_dir = GetTestCertsDirectory();
1595 scoped_refptr<X509Certificate> cert(
1596 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1597 ASSERT_TRUE(cert.get());
1598 // TODO(rch): the connection should be "to" the origin, so if the cert is
1599 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241600 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1601 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481602 ProofVerifyDetailsChromium verify_details;
1603 verify_details.cert_verify_result.verified_cert = cert;
1604 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1605
alyssar2adf3ac2016-05-03 17:12:581606 client_maker_.set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591607 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021608
Renjie Tangaadb84b2019-08-31 01:00:231609 int packet_num = 1;
1610 if (VersionUsesQpack(version_.transport_version)) {
1611 mock_quic_data.AddWrite(SYNCHRONOUS,
1612 ConstructInitialSettingsPacket(packet_num++));
1613 }
rch5cb522462017-04-25 20:18:361614 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231615 SYNCHRONOUS,
1616 ConstructClientRequestHeadersPacket(
1617 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1618 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431619 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331620 ASYNC, ConstructServerResponseHeadersPacket(
1621 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1622 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431623 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331624 mock_quic_data.AddRead(
1625 ASYNC, ConstructServerDataPacket(
1626 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171627 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231628 mock_quic_data.AddWrite(SYNCHRONOUS,
1629 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481630 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1631 mock_quic_data.AddRead(ASYNC, 0);
1632 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1633
1634 request_.url = GURL("https://" + origin.host());
1635 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271636 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091637 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321638 CreateSession();
rchbe69cb902016-02-11 01:10:481639
1640 SendRequestAndExpectQuicResponse("hello!");
1641}
1642
zhongyief3f4ce52017-07-05 23:53:281643TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:561644 quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
zhongyief3f4ce52017-07-05 23:53:281645 // Add support for another QUIC version besides |version_|. Also find a
1646 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561647 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281648 if (version == version_)
1649 continue;
1650 if (supported_versions_.size() != 2) {
1651 supported_versions_.push_back(version);
1652 continue;
1653 }
1654 unsupported_version = version;
1655 break;
1656 }
Nick Harper23290b82019-05-02 00:02:561657 DCHECK_NE(unsupported_version, quic::UnsupportedQuicVersion());
zhongyief3f4ce52017-07-05 23:53:281658
1659 // Set up alternative service to use QUIC with a version that is not
1660 // supported.
1661 url::SchemeHostPort server(request_.url);
1662 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1663 443);
1664 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491665 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071666 server, NetworkIsolationKey(), alternative_service, expiration,
1667 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281668
1669 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491670 http_server_properties_->GetAlternativeServiceInfos(
1671 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281672 EXPECT_EQ(1u, alt_svc_info_vector.size());
1673 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1674 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1675 EXPECT_EQ(unsupported_version,
1676 alt_svc_info_vector[0].advertised_versions()[0]);
1677
1678 // First request should still be sent via TCP as the QUIC version advertised
1679 // in the stored AlternativeService is not supported by the client. However,
1680 // the response from the server will advertise new Alt-Svc with supported
1681 // versions.
Ryan Hamilton8380c652019-06-04 02:25:061682 quic::ParsedQuicVersionVector versions;
1683 for (quic::QuicTransportVersion version :
1684 quic::AllSupportedTransportVersions()) {
1685 versions.push_back(
1686 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
1687 }
zhongyief3f4ce52017-07-05 23:53:281688 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:061689 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyief3f4ce52017-07-05 23:53:281690 std::string altsvc_header =
1691 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1692 advertised_versions_list_str.c_str());
1693 MockRead http_reads[] = {
1694 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1695 MockRead("hello world"),
1696 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1697 MockRead(ASYNC, OK)};
1698
Ryan Sleevib8d7ea02018-05-07 20:01:011699 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281700 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081701 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281702 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1703
1704 // Second request should be sent via QUIC as a new list of verions supported
1705 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591706 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231707 int packet_num = 1;
1708 if (VersionUsesQpack(version_.transport_version)) {
1709 mock_quic_data.AddWrite(SYNCHRONOUS,
1710 ConstructInitialSettingsPacket(packet_num++));
1711 }
zhongyief3f4ce52017-07-05 23:53:281712 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231713 SYNCHRONOUS,
1714 ConstructClientRequestHeadersPacket(
1715 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1716 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431717 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331718 ASYNC, ConstructServerResponseHeadersPacket(
1719 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1720 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431721 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331722 mock_quic_data.AddRead(
1723 ASYNC, ConstructServerDataPacket(
1724 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171725 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231726 mock_quic_data.AddWrite(SYNCHRONOUS,
1727 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281728 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1729 mock_quic_data.AddRead(ASYNC, 0); // EOF
1730
1731 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1732
1733 AddHangingNonAlternateProtocolSocketData();
1734
1735 CreateSession(supported_versions_);
1736
1737 SendRequestAndExpectHttpResponse("hello world");
1738 SendRequestAndExpectQuicResponse("hello!");
1739
1740 // Check alternative service list is updated with new versions.
1741 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491742 session_->http_server_properties()->GetAlternativeServiceInfos(
1743 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281744 EXPECT_EQ(1u, alt_svc_info_vector.size());
1745 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1746 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1747 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:561748 std::sort(
1749 supported_versions_.begin(), supported_versions_.end(),
1750 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
1751 return a.transport_version < b.transport_version;
1752 });
zhongyief3f4ce52017-07-05 23:53:281753 EXPECT_EQ(supported_versions_[0],
1754 alt_svc_info_vector[0].advertised_versions()[0]);
1755 EXPECT_EQ(supported_versions_[1],
1756 alt_svc_info_vector[0].advertised_versions()[1]);
1757}
1758
bncaccd4962017-04-06 21:00:261759// Regression test for https://crbug.com/546991.
1760// The server might not be able to serve a request on an alternative connection,
1761// and might send a 421 Misdirected Request response status to indicate this.
1762// HttpNetworkTransaction should reset the request and retry without using
1763// alternative services.
1764TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1765 // Set up alternative service to use QUIC.
1766 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1767 // that overrides |enable_alternative_services|.
1768 url::SchemeHostPort server(request_.url);
1769 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1770 443);
1771 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491772 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071773 server, NetworkIsolationKey(), alternative_service, expiration,
1774 supported_versions_);
bncaccd4962017-04-06 21:00:261775
davidbena4449722017-05-05 23:30:531776 // First try: The alternative job uses QUIC and reports an HTTP 421
1777 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1778 // paused at Connect(), so it will never exit the socket pool. This ensures
1779 // that the alternate job always wins the race and keeps whether the
1780 // |http_data| exits the socket pool before the main job is aborted
1781 // deterministic. The first main job gets aborted without the socket pool ever
1782 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591783 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231784 int packet_num = 1;
1785 if (VersionUsesQpack(version_.transport_version)) {
1786 mock_quic_data.AddWrite(SYNCHRONOUS,
1787 ConstructInitialSettingsPacket(packet_num++));
1788 }
rch5cb522462017-04-25 20:18:361789 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231790 SYNCHRONOUS,
1791 ConstructClientRequestHeadersPacket(
1792 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1793 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331794 mock_quic_data.AddRead(
1795 ASYNC, ConstructServerResponseHeadersPacket(
1796 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021797 GetResponseHeaders("421")));
bncaccd4962017-04-06 21:00:261798 mock_quic_data.AddRead(ASYNC, OK);
1799 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1800
davidbena4449722017-05-05 23:30:531801 // Second try: The main job uses TCP, and there is no alternate job. Once the
1802 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1803 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261804 // Note that if there was an alternative QUIC Job created for the second try,
1805 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1806 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531807 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1808 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1809 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1810 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1811 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1812 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011813 reads, writes);
bncaccd4962017-04-06 21:00:261814 socket_factory_.AddSocketDataProvider(&http_data);
1815 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1816
bncaccd4962017-04-06 21:00:261817 CreateSession();
1818 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531819
1820 // Run until |mock_quic_data| has failed and |http_data| has paused.
1821 TestCompletionCallback callback;
1822 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1823 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1824 base::RunLoop().RunUntilIdle();
1825
1826 // |mock_quic_data| must have run to completion.
1827 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1828 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1829
1830 // Now that the QUIC data has been consumed, unblock |http_data|.
1831 http_data.socket()->OnConnectComplete(MockConnect());
1832
1833 // The retry logic must hide the 421 status. The transaction succeeds on
1834 // |http_data|.
1835 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261836 CheckWasHttpResponse(&trans);
1837 CheckResponsePort(&trans, 443);
1838 CheckResponseData(&trans, "hello!");
1839}
1840
[email protected]1e960032013-12-20 19:00:201841TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Nick Harper72ade192019-07-17 03:30:421842 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571843 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301844
Ryan Hamiltonabad59e2019-06-06 04:02:591845 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:231846 if (VersionUsesQpack(version_.transport_version))
1847 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401848 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Ryan Hamilton0d65a8c2019-06-07 00:46:021849 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591850 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:231851 if (VersionUsesQpack(version_.transport_version))
1852 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301853 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401854 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431855 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401856
1857 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1858 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301859
1860 CreateSession();
1861
tbansal0f56a39a2016-04-07 22:03:381862 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401863 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161864 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401865 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161866 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011867 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1868 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381869 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531870
1871 NetErrorDetails details;
1872 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521873 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401874 }
[email protected]cebe3282013-05-22 23:49:301875}
1876
tbansalc8a94ea2015-11-02 23:58:511877TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1878 // Attempt to "force" quic on 443, which will not be honored.
Nick Harper72ade192019-07-17 03:30:421879 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571880 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511881
1882 MockRead http_reads[] = {
1883 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1884 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1885 MockRead(ASYNC, OK)};
1886
Ryan Sleevib8d7ea02018-05-07 20:01:011887 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511888 socket_factory_.AddSocketDataProvider(&data);
1889 SSLSocketDataProvider ssl(ASYNC, OK);
1890 socket_factory_.AddSSLSocketDataProvider(&ssl);
1891
1892 CreateSession();
1893
1894 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381895 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511896}
1897
bncc958faa2015-07-31 18:14:521898TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521899 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561900 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1901 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521902 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1903 MockRead(ASYNC, OK)};
1904
Ryan Sleevib8d7ea02018-05-07 20:01:011905 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521906 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081907 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561908 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521909
Ryan Hamiltonabad59e2019-06-06 04:02:591910 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231911 int packet_num = 1;
1912 if (VersionUsesQpack(version_.transport_version)) {
1913 mock_quic_data.AddWrite(SYNCHRONOUS,
1914 ConstructInitialSettingsPacket(packet_num++));
1915 }
rch5cb522462017-04-25 20:18:361916 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231917 SYNCHRONOUS,
1918 ConstructClientRequestHeadersPacket(
1919 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1920 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431921 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331922 ASYNC, ConstructServerResponseHeadersPacket(
1923 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1924 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431925 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331926 mock_quic_data.AddRead(
1927 ASYNC, ConstructServerDataPacket(
1928 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171929 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231930 mock_quic_data.AddWrite(SYNCHRONOUS,
1931 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:521932 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591933 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521934
1935 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1936
rtennetib8e80fb2016-05-16 00:12:091937 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321938 CreateSession();
bncc958faa2015-07-31 18:14:521939
1940 SendRequestAndExpectHttpResponse("hello world");
1941 SendRequestAndExpectQuicResponse("hello!");
1942}
1943
Ryan Hamilton64f21d52019-08-31 07:10:511944TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
1945 std::string alt_svc_header =
1946 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
1947 MockRead http_reads[] = {
1948 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
1949 MockRead("hello world"),
1950 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1951 MockRead(ASYNC, OK)};
1952
1953 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
1954 socket_factory_.AddSocketDataProvider(&http_data);
1955 AddCertificate(&ssl_data_);
1956 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1957
1958 MockQuicData mock_quic_data(version_);
1959 int packet_num = 1;
1960 if (VersionUsesQpack(version_.transport_version)) {
1961 mock_quic_data.AddWrite(SYNCHRONOUS,
1962 ConstructInitialSettingsPacket(packet_num++));
1963 }
1964 mock_quic_data.AddWrite(
1965 SYNCHRONOUS,
1966 ConstructClientRequestHeadersPacket(
1967 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1968 true, GetRequestHeaders("GET", "https", "/")));
1969 mock_quic_data.AddRead(
1970 ASYNC, ConstructServerResponseHeadersPacket(
1971 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1972 GetResponseHeaders("200 OK")));
1973 std::string header = ConstructDataHeader(6);
1974 mock_quic_data.AddRead(
1975 ASYNC, ConstructServerDataPacket(
1976 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1977 header + "hello!"));
1978 mock_quic_data.AddWrite(SYNCHRONOUS,
1979 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1980 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1981 mock_quic_data.AddRead(ASYNC, 0); // EOF
1982
1983 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1984
1985 AddHangingNonAlternateProtocolSocketData();
1986 CreateSession();
1987
1988 SendRequestAndExpectHttpResponse("hello world");
1989 SendRequestAndExpectQuicResponse("hello!");
1990}
1991
Matt Menke3233d8f22019-08-20 21:01:491992// Much like above, but makes sure NetworkIsolationKey is respected.
1993TEST_P(QuicNetworkTransactionTest,
1994 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
1995 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:051996 feature_list.InitWithFeatures(
1997 // enabled_features
1998 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
1999 features::kPartitionConnectionsByNetworkIsolationKey},
2000 // disabled_features
2001 {});
Matt Menke3233d8f22019-08-20 21:01:492002 // Since HttpServerProperties caches the feature value, have to create a new
2003 // one.
2004 http_server_properties_ = std::make_unique<HttpServerProperties>();
2005
2006 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2007 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2008 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2009 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2010
2011 MockRead http_reads[] = {
2012 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
2013 MockRead("hello world"),
2014 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2015 MockRead(ASYNC, OK)};
2016
2017 AddCertificate(&ssl_data_);
2018
2019 // Request with empty NetworkIsolationKey.
2020 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2021 socket_factory_.AddSocketDataProvider(&http_data1);
2022 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2023
2024 // First request with kNetworkIsolationKey1.
2025 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2026 socket_factory_.AddSocketDataProvider(&http_data2);
2027 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2028
2029 // Request with kNetworkIsolationKey2.
2030 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2031 socket_factory_.AddSocketDataProvider(&http_data3);
2032 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2033
2034 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2035 // alternative service infrmation has been received in this context before.
2036 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232037 int packet_num = 1;
2038 if (VersionUsesQpack(version_.transport_version)) {
2039 mock_quic_data.AddWrite(SYNCHRONOUS,
2040 ConstructInitialSettingsPacket(packet_num++));
2041 }
Matt Menke3233d8f22019-08-20 21:01:492042 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232043 SYNCHRONOUS,
2044 ConstructClientRequestHeadersPacket(
2045 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2046 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492047 mock_quic_data.AddRead(
2048 ASYNC, ConstructServerResponseHeadersPacket(
2049 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2050 GetResponseHeaders("200 OK")));
2051 std::string header = ConstructDataHeader(6);
2052 mock_quic_data.AddRead(
2053 ASYNC, ConstructServerDataPacket(
2054 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2055 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232056 mock_quic_data.AddWrite(SYNCHRONOUS,
2057 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke3233d8f22019-08-20 21:01:492058 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2059 mock_quic_data.AddRead(ASYNC, 0); // EOF
2060
2061 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2062
2063 AddHangingNonAlternateProtocolSocketData();
2064 CreateSession();
2065
2066 // This is first so that the test fails if alternative service info is
2067 // written with the right NetworkIsolationKey, but always queried with an
2068 // empty one.
2069 request_.network_isolation_key = NetworkIsolationKey();
2070 SendRequestAndExpectHttpResponse("hello world");
2071 request_.network_isolation_key = kNetworkIsolationKey1;
2072 SendRequestAndExpectHttpResponse("hello world");
2073 request_.network_isolation_key = kNetworkIsolationKey2;
2074 SendRequestAndExpectHttpResponse("hello world");
2075
2076 // Only use QUIC when using a NetworkIsolationKey which has been used when
2077 // alternative service information was received.
2078 request_.network_isolation_key = kNetworkIsolationKey1;
2079 SendRequestAndExpectQuicResponse("hello!");
2080}
2081
zhongyia00ca012017-07-06 23:36:392082TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
2083 // Both server advertises and client supports two QUIC versions.
2084 // Only |version_| is advertised and supported.
2085 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2086 // PacketMakers are using |version_|.
2087
2088 // Add support for another QUIC version besides |version_| on the client side.
2089 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:562090 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
2091 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392092 if (version == version_)
2093 continue;
2094 if (supported_versions_.size() != 2) {
2095 supported_versions_.push_back(version);
2096 continue;
2097 }
2098 advertised_version_2 = version;
2099 break;
2100 }
Nick Harper23290b82019-05-02 00:02:562101 DCHECK_NE(advertised_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392102
Nick Harper23290b82019-05-02 00:02:562103 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
2104 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2105 advertised_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392106
2107 MockRead http_reads[] = {
2108 MockRead("HTTP/1.1 200 OK\r\n"),
2109 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2110 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2111 MockRead(ASYNC, OK)};
2112
Ryan Sleevib8d7ea02018-05-07 20:01:012113 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392114 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082115 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392116 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2117
Ryan Hamiltonabad59e2019-06-06 04:02:592118 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232119 int packet_num = 1;
2120 if (VersionUsesQpack(version_.transport_version)) {
2121 mock_quic_data.AddWrite(SYNCHRONOUS,
2122 ConstructInitialSettingsPacket(packet_num++));
2123 }
zhongyia00ca012017-07-06 23:36:392124 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232125 SYNCHRONOUS,
2126 ConstructClientRequestHeadersPacket(
2127 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2128 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432129 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332130 ASYNC, ConstructServerResponseHeadersPacket(
2131 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2132 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432133 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332134 mock_quic_data.AddRead(
2135 ASYNC, ConstructServerDataPacket(
2136 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172137 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232138 mock_quic_data.AddWrite(SYNCHRONOUS,
2139 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392140 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2141 mock_quic_data.AddRead(ASYNC, 0); // EOF
2142
2143 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2144
2145 AddHangingNonAlternateProtocolSocketData();
2146 CreateSession(supported_versions_);
2147
2148 SendRequestAndExpectHttpResponse("hello world");
2149 SendRequestAndExpectQuicResponse("hello!");
2150}
2151
2152TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
2153 // Client and server mutually support more than one QUIC_VERSION.
2154 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
2155 // which is verified as the PacketMakers are using |version_|.
2156
Nick Harper23290b82019-05-02 00:02:562157 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
2158 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392159 if (version == version_)
2160 continue;
2161 common_version_2 = version;
2162 break;
2163 }
Nick Harper23290b82019-05-02 00:02:562164 DCHECK_NE(common_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392165
2166 supported_versions_.push_back(
2167 common_version_2); // Supported but unpreferred.
2168
2169 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:562170 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2171 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392172
2173 MockRead http_reads[] = {
2174 MockRead("HTTP/1.1 200 OK\r\n"),
2175 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2176 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2177 MockRead(ASYNC, OK)};
2178
Ryan Sleevib8d7ea02018-05-07 20:01:012179 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392180 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082181 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392182 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2183
Ryan Hamiltonabad59e2019-06-06 04:02:592184 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232185 int packet_num = 1;
2186 if (VersionUsesQpack(version_.transport_version)) {
2187 mock_quic_data.AddWrite(SYNCHRONOUS,
2188 ConstructInitialSettingsPacket(packet_num++));
2189 }
zhongyia00ca012017-07-06 23:36:392190 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232191 SYNCHRONOUS,
2192 ConstructClientRequestHeadersPacket(
2193 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2194 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432195 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332196 ASYNC, ConstructServerResponseHeadersPacket(
2197 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2198 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432199 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332200 mock_quic_data.AddRead(
2201 ASYNC, ConstructServerDataPacket(
2202 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172203 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232204 mock_quic_data.AddWrite(SYNCHRONOUS,
2205 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392206 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2207 mock_quic_data.AddRead(ASYNC, 0); // EOF
2208
2209 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2210
2211 AddHangingNonAlternateProtocolSocketData();
2212 CreateSession(supported_versions_);
2213
2214 SendRequestAndExpectHttpResponse("hello world");
2215 SendRequestAndExpectQuicResponse("hello!");
2216}
2217
rchf47265dc2016-03-21 21:33:122218TEST_P(QuicNetworkTransactionTest,
2219 UseAlternativeServiceWithProbabilityForQuic) {
2220 MockRead http_reads[] = {
2221 MockRead("HTTP/1.1 200 OK\r\n"),
2222 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
2223 MockRead("hello world"),
2224 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2225 MockRead(ASYNC, OK)};
2226
Ryan Sleevib8d7ea02018-05-07 20:01:012227 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:122228 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082229 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:122230 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2231
Ryan Hamiltonabad59e2019-06-06 04:02:592232 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232233 int packet_num = 1;
2234 if (VersionUsesQpack(version_.transport_version)) {
2235 mock_quic_data.AddWrite(SYNCHRONOUS,
2236 ConstructInitialSettingsPacket(packet_num++));
2237 }
rch5cb522462017-04-25 20:18:362238 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232239 SYNCHRONOUS,
2240 ConstructClientRequestHeadersPacket(
2241 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2242 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432243 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332244 ASYNC, ConstructServerResponseHeadersPacket(
2245 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2246 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432247 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332248 mock_quic_data.AddRead(
2249 ASYNC, ConstructServerDataPacket(
2250 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172251 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232252 mock_quic_data.AddWrite(SYNCHRONOUS,
2253 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchf47265dc2016-03-21 21:33:122254 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2255 mock_quic_data.AddRead(ASYNC, 0); // EOF
2256
2257 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2258
rtennetib8e80fb2016-05-16 00:12:092259 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:122260 CreateSession();
2261
2262 SendRequestAndExpectHttpResponse("hello world");
2263 SendRequestAndExpectQuicResponse("hello!");
2264}
2265
zhongyi3d4a55e72016-04-22 20:36:462266TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2267 MockRead http_reads[] = {
2268 MockRead("HTTP/1.1 200 OK\r\n"),
2269 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2270 MockRead("hello world"),
2271 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2272 MockRead(ASYNC, OK)};
2273
Ryan Sleevib8d7ea02018-05-07 20:01:012274 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462275 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082276 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462277 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2278
2279 CreateSession();
bncb26024382016-06-29 02:39:452280 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462281 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452282 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462283 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402284 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462285 session_->http_server_properties();
2286 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2287 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2288 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462289 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492290 2u, http_server_properties
2291 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2292 .size());
bncb26024382016-06-29 02:39:452293 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492294 http_server_properties
2295 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2296 .empty());
zhongyi3d4a55e72016-04-22 20:36:462297}
2298
2299TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2300 MockRead http_reads[] = {
2301 MockRead("HTTP/1.1 200 OK\r\n"),
2302 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2303 MockRead("hello world"),
2304 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2305 MockRead(ASYNC, OK)};
2306
Ryan Sleevib8d7ea02018-05-07 20:01:012307 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082308 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462309
2310 socket_factory_.AddSocketDataProvider(&http_data);
2311 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2312 socket_factory_.AddSocketDataProvider(&http_data);
2313 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2314
2315 CreateSession();
2316
2317 // Send https request and set alternative services if response header
2318 // advertises alternative service for mail.example.org.
2319 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402320 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462321 session_->http_server_properties();
2322
2323 const url::SchemeHostPort https_server(request_.url);
2324 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342325 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492326 2u, http_server_properties
2327 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2328 .size());
zhongyi3d4a55e72016-04-22 20:36:462329
2330 // Send http request to the same origin but with diffrent scheme, should not
2331 // use QUIC.
2332 request_.url = GURL("http://mail.example.org:443");
2333 SendRequestAndExpectHttpResponse("hello world");
2334}
2335
zhongyie537a002017-06-27 16:48:212336TEST_P(QuicNetworkTransactionTest,
2337 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442338 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562339 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyi86838d52017-06-30 01:19:442340 if (version == version_)
2341 continue;
2342 supported_versions_.push_back(version);
2343 break;
2344 }
2345
Ryan Hamilton8380c652019-06-04 02:25:062346 quic::ParsedQuicVersionVector versions;
2347 for (quic::QuicTransportVersion version :
2348 quic::AllSupportedTransportVersions()) {
2349 versions.push_back(
2350 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
2351 }
zhongyie537a002017-06-27 16:48:212352 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:062353 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyie537a002017-06-27 16:48:212354 std::string altsvc_header =
2355 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2356 advertised_versions_list_str.c_str());
2357 MockRead http_reads[] = {
2358 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2359 MockRead("hello world"),
2360 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2361 MockRead(ASYNC, OK)};
2362
Ryan Sleevib8d7ea02018-05-07 20:01:012363 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212364 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082365 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212366 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2367
Ryan Hamiltonabad59e2019-06-06 04:02:592368 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232369 int packet_num = 1;
2370 if (VersionUsesQpack(version_.transport_version)) {
2371 mock_quic_data.AddWrite(SYNCHRONOUS,
2372 ConstructInitialSettingsPacket(packet_num++));
2373 }
zhongyie537a002017-06-27 16:48:212374 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232375 SYNCHRONOUS,
2376 ConstructClientRequestHeadersPacket(
2377 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2378 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432379 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332380 ASYNC, ConstructServerResponseHeadersPacket(
2381 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2382 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432383 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332384 mock_quic_data.AddRead(
2385 ASYNC, ConstructServerDataPacket(
2386 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172387 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232388 mock_quic_data.AddWrite(SYNCHRONOUS,
2389 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212390 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2391 mock_quic_data.AddRead(ASYNC, 0); // EOF
2392
2393 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2394
2395 AddHangingNonAlternateProtocolSocketData();
2396
zhongyi86838d52017-06-30 01:19:442397 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212398
2399 SendRequestAndExpectHttpResponse("hello world");
2400 SendRequestAndExpectQuicResponse("hello!");
2401
2402 // Check alternative service is set with only mutually supported versions.
2403 const url::SchemeHostPort https_server(request_.url);
2404 const AlternativeServiceInfoVector alt_svc_info_vector =
2405 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492406 https_server, NetworkIsolationKey());
zhongyie537a002017-06-27 16:48:212407 EXPECT_EQ(1u, alt_svc_info_vector.size());
2408 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2409 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2410 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:562411 std::sort(
2412 supported_versions_.begin(), supported_versions_.end(),
2413 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
2414 return a.transport_version < b.transport_version;
2415 });
zhongyi86838d52017-06-30 01:19:442416 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212417 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442418 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212419 alt_svc_info_vector[0].advertised_versions()[1]);
2420}
2421
danzh3134c2562016-08-12 14:07:522422TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562423 std::string altsvc_header = base::StringPrintf(
2424 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_.transport_version);
bnc8be55ebb2015-10-30 14:12:072425 MockRead http_reads[] = {
2426 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2427 MockRead("hello world"),
2428 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2429 MockRead(ASYNC, OK)};
2430
Ryan Sleevib8d7ea02018-05-07 20:01:012431 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072432 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082433 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072434 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2435
Ryan Hamiltonabad59e2019-06-06 04:02:592436 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232437 int packet_num = 1;
2438 if (VersionUsesQpack(version_.transport_version)) {
2439 mock_quic_data.AddWrite(SYNCHRONOUS,
2440 ConstructInitialSettingsPacket(packet_num++));
2441 }
rch5cb522462017-04-25 20:18:362442 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232443 SYNCHRONOUS,
2444 ConstructClientRequestHeadersPacket(
2445 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2446 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432447 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332448 ASYNC, ConstructServerResponseHeadersPacket(
2449 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2450 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432451 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332452 mock_quic_data.AddRead(
2453 ASYNC, ConstructServerDataPacket(
2454 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172455 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232456 mock_quic_data.AddWrite(SYNCHRONOUS,
2457 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072458 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592459 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072460
2461 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2462
rtennetib8e80fb2016-05-16 00:12:092463 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322464 CreateSession();
bnc8be55ebb2015-10-30 14:12:072465
2466 SendRequestAndExpectHttpResponse("hello world");
2467 SendRequestAndExpectQuicResponse("hello!");
2468}
2469
zhongyi6b5a3892016-03-12 04:46:202470TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562471 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz6e4c5382018-06-21 23:00:092472 // Not available under version 99
2473 return;
2474 }
Ryan Hamiltonabad59e2019-06-06 04:02:592475 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232476 int packet_num = 1;
2477 if (VersionUsesQpack(version_.transport_version)) {
2478 mock_quic_data.AddWrite(SYNCHRONOUS,
2479 ConstructInitialSettingsPacket(packet_num++));
2480 }
rch5cb522462017-04-25 20:18:362481 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232482 SYNCHRONOUS,
2483 ConstructClientRequestHeadersPacket(
2484 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2485 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332486 mock_quic_data.AddRead(
2487 ASYNC, ConstructServerResponseHeadersPacket(
2488 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2489 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202490 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522491 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432492 mock_quic_data.AddRead(SYNCHRONOUS,
2493 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522494 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432495 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232496 mock_quic_data.AddWrite(SYNCHRONOUS,
2497 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432498 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332499 mock_quic_data.AddRead(
2500 SYNCHRONOUS, ConstructServerDataPacket(
2501 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:172502 true, header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232503 mock_quic_data.AddWrite(
2504 SYNCHRONOUS,
2505 ConstructClientAckAndRstPacket(
2506 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2507 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202508 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2509 mock_quic_data.AddRead(ASYNC, 0); // EOF
2510
2511 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2512
2513 // The non-alternate protocol job needs to hang in order to guarantee that
2514 // the alternate-protocol job will "win".
2515 AddHangingNonAlternateProtocolSocketData();
2516
2517 // In order for a new QUIC session to be established via alternate-protocol
2518 // without racing an HTTP connection, we need the host resolution to happen
2519 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2520 // connection to the the server, in this test we require confirmation
2521 // before encrypting so the HTTP job will still start.
2522 host_resolver_.set_synchronous_mode(true);
2523 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2524 "");
zhongyi6b5a3892016-03-12 04:46:202525
2526 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432527 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2528 false);
Ryan Hamilton9835e662018-08-02 05:36:272529 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202530
bnc691fda62016-08-12 00:43:162531 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202532 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362533 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202535
2536 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522537 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012538 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202539
2540 // Check whether this transaction is correctly marked as received a go-away
2541 // because of migrating port.
2542 NetErrorDetails details;
2543 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162544 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202545 EXPECT_TRUE(details.quic_port_migration_detected);
2546}
2547
Zhongyi Shia6b68d112018-09-24 07:49:032548// This test verifies that a new QUIC connection will be attempted on the
2549// alternate network if the original QUIC connection fails with idle timeout
2550// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2551// alternate network as well, QUIC is marked as broken and the brokenness will
2552// not expire when default network changes.
2553TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2554 SetUpTestForRetryConnectionOnAlternateNetwork();
2555
Michael Warres167db3e2019-03-01 21:38:032556 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032557
2558 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592559 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032560 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2561 int packet_num = 1;
2562 quic_data.AddWrite(SYNCHRONOUS,
2563 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2564 // Retranmit the handshake messages.
2565 quic_data.AddWrite(SYNCHRONOUS,
2566 client_maker_.MakeDummyCHLOPacket(packet_num++));
2567 quic_data.AddWrite(SYNCHRONOUS,
2568 client_maker_.MakeDummyCHLOPacket(packet_num++));
2569 quic_data.AddWrite(SYNCHRONOUS,
2570 client_maker_.MakeDummyCHLOPacket(packet_num++));
2571 quic_data.AddWrite(SYNCHRONOUS,
2572 client_maker_.MakeDummyCHLOPacket(packet_num++));
2573 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562574 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032575 quic_data.AddWrite(SYNCHRONOUS,
2576 client_maker_.MakeDummyCHLOPacket(packet_num++));
2577 }
2578 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2579 quic_data.AddWrite(SYNCHRONOUS,
2580 client_maker_.MakeConnectionClosePacket(
2581 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2582 "No recent network activity."));
2583 quic_data.AddSocketDataToFactory(&socket_factory_);
2584
2585 // Add successful TCP data so that TCP job will succeed.
2586 MockWrite http_writes[] = {
2587 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2588 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2589 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2590
2591 MockRead http_reads[] = {
2592 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2593 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2594 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2595 SequencedSocketData http_data(http_reads, http_writes);
2596 socket_factory_.AddSocketDataProvider(&http_data);
2597 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2598
2599 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592600 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032601 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2602 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2603 quic_data2.AddSocketDataToFactory(&socket_factory_);
2604
2605 // Resolve the host resolution synchronously.
2606 host_resolver_.set_synchronous_mode(true);
2607 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2608 "");
Zhongyi Shia6b68d112018-09-24 07:49:032609
2610 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432611 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2612 false);
Zhongyi Shia6b68d112018-09-24 07:49:032613 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032614 QuicStreamFactoryPeer::SetAlarmFactory(
2615 session_->quic_stream_factory(),
2616 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2617 &clock_));
2618 // Add alternate protocol mapping to race QUIC and TCP.
2619 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2620 // peer.
2621 AddQuicAlternateProtocolMapping(
2622 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2623
2624 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2625 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362626 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032627 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2628
2629 // Pump the message loop to get the request started.
2630 // Request will be served with TCP job.
2631 base::RunLoop().RunUntilIdle();
2632 EXPECT_THAT(callback.WaitForResult(), IsOk());
2633 CheckResponseData(&trans, "TCP succeeds");
2634
Zhongyi Shia6b68d112018-09-24 07:49:032635 // Fast forward to idle timeout the original connection. A new connection will
2636 // be kicked off on the alternate network.
2637 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2638 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2639 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2640
2641 // Run the message loop to execute posted tasks, which will report job status.
2642 base::RunLoop().RunUntilIdle();
2643
2644 // Verify that QUIC is marked as broken.
2645 ExpectBrokenAlternateProtocolMapping();
2646
2647 // Deliver a message to notify the new network becomes default, the brokenness
2648 // will not expire as QUIC is broken on both networks.
2649 scoped_mock_change_notifier_->mock_network_change_notifier()
2650 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2651 ExpectBrokenAlternateProtocolMapping();
2652
2653 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2654 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2655}
2656
2657// This test verifies that a new QUIC connection will be attempted on the
2658// alternate network if the original QUIC connection fails with idle timeout
2659// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2660// alternate network, QUIC is marked as broken. The brokenness will expire when
2661// the default network changes.
2662TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2663 SetUpTestForRetryConnectionOnAlternateNetwork();
2664
Michael Warres167db3e2019-03-01 21:38:032665 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032666
2667 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592668 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032669 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2670 int packet_num = 1;
2671 quic_data.AddWrite(SYNCHRONOUS,
2672 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2673 // Retranmit the handshake messages.
2674 quic_data.AddWrite(SYNCHRONOUS,
2675 client_maker_.MakeDummyCHLOPacket(packet_num++));
2676 quic_data.AddWrite(SYNCHRONOUS,
2677 client_maker_.MakeDummyCHLOPacket(packet_num++));
2678 quic_data.AddWrite(SYNCHRONOUS,
2679 client_maker_.MakeDummyCHLOPacket(packet_num++));
2680 quic_data.AddWrite(SYNCHRONOUS,
2681 client_maker_.MakeDummyCHLOPacket(packet_num++));
2682 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562683 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032684 quic_data.AddWrite(SYNCHRONOUS,
2685 client_maker_.MakeDummyCHLOPacket(packet_num++));
2686 }
2687 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2688 quic_data.AddWrite(SYNCHRONOUS,
2689 client_maker_.MakeConnectionClosePacket(
2690 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2691 "No recent network activity."));
2692 quic_data.AddSocketDataToFactory(&socket_factory_);
2693
2694 // Add successful TCP data so that TCP job will succeed.
2695 MockWrite http_writes[] = {
2696 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2697 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2698 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2699
2700 MockRead http_reads[] = {
2701 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2702 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2703 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2704 SequencedSocketData http_data(http_reads, http_writes);
2705 socket_factory_.AddSocketDataProvider(&http_data);
2706 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2707
2708 // Quic connection will be retried on the alternate network after the initial
2709 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592710 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032711 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2712 quic_data2.AddWrite(SYNCHRONOUS,
2713 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2714
2715 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Renjie Tangaadb84b2019-08-31 01:00:232716 if (VersionUsesQpack(version_.transport_version))
2717 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032718 quic_data2.AddSocketDataToFactory(&socket_factory_);
2719
2720 // Resolve the host resolution synchronously.
2721 host_resolver_.set_synchronous_mode(true);
2722 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2723 "");
Zhongyi Shia6b68d112018-09-24 07:49:032724
2725 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432726 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2727 false);
Zhongyi Shia6b68d112018-09-24 07:49:032728 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032729 QuicStreamFactoryPeer::SetAlarmFactory(
2730 session_->quic_stream_factory(),
2731 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2732 &clock_));
2733 // Add alternate protocol mapping to race QUIC and TCP.
2734 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2735 // peer.
2736 AddQuicAlternateProtocolMapping(
2737 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2738
2739 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2740 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362741 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2743
2744 // Pump the message loop to get the request started.
2745 // Request will be served with TCP job.
2746 base::RunLoop().RunUntilIdle();
2747 EXPECT_THAT(callback.WaitForResult(), IsOk());
2748 CheckResponseData(&trans, "TCP succeeds");
2749
Zhongyi Shia6b68d112018-09-24 07:49:032750 // Fast forward to idle timeout the original connection. A new connection will
2751 // be kicked off on the alternate network.
2752 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2753 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2754 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2755
2756 // The second connection hasn't finish handshake, verify that QUIC is not
2757 // marked as broken.
2758 ExpectQuicAlternateProtocolMapping();
2759 // Explicitly confirm the handshake on the second connection.
2760 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2761 quic::QuicSession::HANDSHAKE_CONFIRMED);
2762 // Run message loop to execute posted tasks, which will notify JoController
2763 // about the orphaned job status.
2764 base::RunLoop().RunUntilIdle();
2765
2766 // Verify that QUIC is marked as broken.
2767 ExpectBrokenAlternateProtocolMapping();
2768
2769 // Deliver a message to notify the new network becomes default, the previous
2770 // brokenness will be clear as the brokenness is bond with old default
2771 // network.
2772 scoped_mock_change_notifier_->mock_network_change_notifier()
2773 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2774 ExpectQuicAlternateProtocolMapping();
2775
2776 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2777 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2778}
2779
Matt Menkeb32ba5122019-09-10 19:17:052780// Much like above test, but verifies NetworkIsolationKeys are respected.
2781TEST_P(QuicNetworkTransactionTest,
2782 RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
2783 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2784 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2785 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2786 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2787
2788 base::test::ScopedFeatureList feature_list;
2789 feature_list.InitWithFeatures(
2790 // enabled_features
2791 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2792 // Need to partition connections by NetworkIsolationKey for
2793 // QuicSessionAliasKey to include NetworkIsolationKeys.
2794 features::kPartitionConnectionsByNetworkIsolationKey},
2795 // disabled_features
2796 {});
2797 // Since HttpServerProperties caches the feature value, have to create a new
2798 // one.
2799 http_server_properties_ = std::make_unique<HttpServerProperties>();
2800
2801 SetUpTestForRetryConnectionOnAlternateNetwork();
2802
2803 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
2804
2805 // The request will initially go out over QUIC.
2806 MockQuicData quic_data(version_);
2807 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2808 int packet_num = 1;
2809 quic_data.AddWrite(SYNCHRONOUS,
2810 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2811 // Retranmit the handshake messages.
2812 quic_data.AddWrite(SYNCHRONOUS,
2813 client_maker_.MakeDummyCHLOPacket(packet_num++));
2814 quic_data.AddWrite(SYNCHRONOUS,
2815 client_maker_.MakeDummyCHLOPacket(packet_num++));
2816 quic_data.AddWrite(SYNCHRONOUS,
2817 client_maker_.MakeDummyCHLOPacket(packet_num++));
2818 quic_data.AddWrite(SYNCHRONOUS,
2819 client_maker_.MakeDummyCHLOPacket(packet_num++));
2820 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2821 if (version_.transport_version <= quic::QUIC_VERSION_39) {
2822 quic_data.AddWrite(SYNCHRONOUS,
2823 client_maker_.MakeDummyCHLOPacket(packet_num++));
2824 }
2825 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2826 quic_data.AddWrite(SYNCHRONOUS,
2827 client_maker_.MakeConnectionClosePacket(
2828 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2829 "No recent network activity."));
2830 quic_data.AddSocketDataToFactory(&socket_factory_);
2831
2832 // Add successful TCP data so that TCP job will succeed.
2833 MockWrite http_writes[] = {
2834 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2835 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2836 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2837
2838 MockRead http_reads[] = {
2839 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2840 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2841 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2842 SequencedSocketData http_data(http_reads, http_writes);
2843 socket_factory_.AddSocketDataProvider(&http_data);
2844 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2845
2846 // Quic connection will be retried on the alternate network after the initial
2847 // one fails on the default network.
2848 MockQuicData quic_data2(version_);
2849 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2850 quic_data2.AddWrite(SYNCHRONOUS,
2851 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2852
2853 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2854 if (VersionUsesQpack(version_.transport_version))
2855 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
2856 quic_data2.AddSocketDataToFactory(&socket_factory_);
2857
2858 // Resolve the host resolution synchronously.
2859 host_resolver_.set_synchronous_mode(true);
2860 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2861 "");
2862
2863 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432864 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2865 false);
Matt Menkeb32ba5122019-09-10 19:17:052866 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2867 QuicStreamFactoryPeer::SetAlarmFactory(
2868 session_->quic_stream_factory(),
2869 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2870 &clock_));
2871 // Add alternate protocol mapping to race QUIC and TCP.
2872 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2873 // peer.
2874 AddQuicAlternateProtocolMapping(
2875 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
2876 AddQuicAlternateProtocolMapping(
2877 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
2878
2879 request_.network_isolation_key = kNetworkIsolationKey1;
2880 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2881 TestCompletionCallback callback;
2882 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2884
2885 // Pump the message loop to get the request started.
2886 // Request will be served with TCP job.
2887 base::RunLoop().RunUntilIdle();
2888 EXPECT_THAT(callback.WaitForResult(), IsOk());
2889 CheckResponseData(&trans, "TCP succeeds");
2890
2891 // Fast forward to idle timeout the original connection. A new connection will
2892 // be kicked off on the alternate network.
2893 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2894 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2895 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2896
2897 // The second connection hasn't finish handshake, verify that QUIC is not
2898 // marked as broken.
2899 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2900 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2901 // Explicitly confirm the handshake on the second connection.
2902 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2903 quic::QuicSession::HANDSHAKE_CONFIRMED);
2904 // Run message loop to execute posted tasks, which will notify JoController
2905 // about the orphaned job status.
2906 base::RunLoop().RunUntilIdle();
2907
2908 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
2909 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
2910 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2911
2912 // Deliver a message to notify the new network becomes default, the previous
2913 // brokenness will be clear as the brokenness is bond with old default
2914 // network.
2915 scoped_mock_change_notifier_->mock_network_change_notifier()
2916 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2917 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2918 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2919
2920 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2921 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2922}
2923
Zhongyi Shia6b68d112018-09-24 07:49:032924// This test verifies that a new QUIC connection will be attempted on the
2925// alternate network if the original QUIC connection fails with idle timeout
2926// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2927// alternative network succeeds, QUIC is not marked as broken.
2928TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2929 SetUpTestForRetryConnectionOnAlternateNetwork();
2930
Michael Warres167db3e2019-03-01 21:38:032931 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032932
2933 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592934 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032935 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2936 int packet_num = 1;
2937 quic_data.AddWrite(SYNCHRONOUS,
2938 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2939 // Retranmit the handshake messages.
2940 quic_data.AddWrite(SYNCHRONOUS,
2941 client_maker_.MakeDummyCHLOPacket(packet_num++));
2942 quic_data.AddWrite(SYNCHRONOUS,
2943 client_maker_.MakeDummyCHLOPacket(packet_num++));
2944 quic_data.AddWrite(SYNCHRONOUS,
2945 client_maker_.MakeDummyCHLOPacket(packet_num++));
2946 quic_data.AddWrite(SYNCHRONOUS,
2947 client_maker_.MakeDummyCHLOPacket(packet_num++));
2948 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2949 // quic_fix_has_pending_crypto_data is introduced and enabled.
Nick Harper23290b82019-05-02 00:02:562950 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032951 quic_data.AddWrite(SYNCHRONOUS,
2952 client_maker_.MakeDummyCHLOPacket(packet_num++));
2953 }
2954 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2955 quic_data.AddWrite(SYNCHRONOUS,
2956 client_maker_.MakeConnectionClosePacket(
2957 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2958 "No recent network activity."));
2959 quic_data.AddSocketDataToFactory(&socket_factory_);
2960
2961 // Add hanging TCP data so that TCP job will never succeeded.
2962 AddHangingNonAlternateProtocolSocketData();
2963
2964 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:592965 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:232966 packet_num = 1;
Zhongyi Shia6b68d112018-09-24 07:49:032967 quic_data2.AddWrite(SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:232968 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:032969
Victor Vasiliev076657c2019-03-12 02:46:432970 const std::string body = "hello!";
2971 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:412972
Zhongyi Shia6b68d112018-09-24 07:49:032973 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Renjie Tangaadb84b2019-08-31 01:00:232974 if (VersionUsesQpack(version_.transport_version)) {
2975 quic_data2.AddWrite(SYNCHRONOUS,
2976 ConstructInitialSettingsPacket(packet_num++));
2977 }
Zhongyi Shia6b68d112018-09-24 07:49:032978 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232979 SYNCHRONOUS,
2980 ConstructClientRequestHeadersPacket(
2981 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2982 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:032983 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332984 ASYNC, ConstructServerResponseHeadersPacket(
2985 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2986 GetResponseHeaders("200 OK")));
2987 quic_data2.AddRead(
2988 ASYNC, ConstructServerDataPacket(
2989 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172990 header + body));
Renjie Tangaadb84b2019-08-31 01:00:232991 quic_data2.AddWrite(SYNCHRONOUS,
2992 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia6b68d112018-09-24 07:49:032993 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2994 quic_data2.AddSocketDataToFactory(&socket_factory_);
2995
2996 // Resolve the host resolution synchronously.
2997 host_resolver_.set_synchronous_mode(true);
2998 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2999 "");
Zhongyi Shia6b68d112018-09-24 07:49:033000
3001 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433002 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3003 false);
Zhongyi Shia6b68d112018-09-24 07:49:033004 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:033005 QuicStreamFactoryPeer::SetAlarmFactory(
3006 session_->quic_stream_factory(),
3007 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
3008 &clock_));
3009 // Add alternate protocol mapping to race QUIC and TCP.
3010 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3011 // peer.
3012 AddQuicAlternateProtocolMapping(
3013 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3014
3015 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3016 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363017 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:033018 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3019
3020 // Pump the message loop to get the request started.
3021 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:033022
3023 // Fast forward to idle timeout the original connection. A new connection will
3024 // be kicked off on the alternate network.
3025 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3026 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3027 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3028
3029 // Verify that QUIC is not marked as broken.
3030 ExpectQuicAlternateProtocolMapping();
3031 // Explicitly confirm the handshake on the second connection.
3032 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
3033 quic::QuicSession::HANDSHAKE_CONFIRMED);
3034
3035 // Read the response.
3036 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:413037 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:033038 // Verify that QUIC is not marked as broken.
3039 ExpectQuicAlternateProtocolMapping();
3040
3041 // Deliver a message to notify the new network becomes default.
3042 scoped_mock_change_notifier_->mock_network_change_notifier()
3043 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3044 ExpectQuicAlternateProtocolMapping();
3045 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3046 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3047}
3048
rch9ecde09b2017-04-08 00:18:233049// Verify that if a QUIC connection times out, the QuicHttpStream will
3050// return QUIC_PROTOCOL_ERROR.
3051TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:423052 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Sleevi2e8255b2019-07-17 21:02:213053 session_params_.quic_params.idle_connection_timeout =
3054 base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:233055
3056 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593057 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133058 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233059 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3060
Ryan Hamiltone940bd12019-06-30 02:46:453061 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033062 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493063 int packet_num = 1;
3064 if (VersionUsesQpack(version_.transport_version)) {
3065 quic_data.AddWrite(SYNCHRONOUS,
3066 ConstructInitialSettingsPacket(packet_num++));
3067 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023068 quic_data.AddWrite(
3069 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453070 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493071 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3072 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453073
3074 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233075
Nick Harper057264a82019-09-12 23:33:493076 if (VersionUsesQpack(version_.transport_version)) {
3077 // TLP 1
3078 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3079 1, packet_num++, true));
3080 // TLP 2
3081 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3082 2, packet_num++, true));
3083 // RTO 1
3084 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3085 1, packet_num++, true));
3086 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3087 2, packet_num++, true));
3088 // RTO 2
3089 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3090 1, packet_num++, true));
3091 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3092 2, packet_num++, true));
3093 // RTO 3
3094 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3095 1, packet_num++, true));
3096 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3097 2, packet_num++, true));
Ryan Hamilton3cc2c152019-07-09 19:36:013098
Nick Harper057264a82019-09-12 23:33:493099 quic_data.AddWrite(SYNCHRONOUS,
3100 client_maker_.MakeConnectionClosePacket(
3101 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3102 "No recent network activity."));
3103 } else {
3104 // Settings were sent in the request packet so there is only 1 packet to
3105 // retransmit.
3106 // TLP 1
3107 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3108 1, packet_num++, true));
3109 // TLP 2
3110 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3111 1, packet_num++, true));
3112 // RTO 1
3113 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3114 1, packet_num++, true));
3115 // RTO 2
3116 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3117 1, packet_num++, true));
3118 // RTO 3
3119 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3120 1, packet_num++, true));
3121
3122 quic_data.AddWrite(SYNCHRONOUS,
3123 client_maker_.MakeConnectionClosePacket(
3124 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3125 "No recent network activity."));
3126 }
Fan Yang928f1632017-12-14 18:55:223127
rch9ecde09b2017-04-08 00:18:233128 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3129 quic_data.AddRead(ASYNC, OK);
3130 quic_data.AddSocketDataToFactory(&socket_factory_);
3131
3132 // In order for a new QUIC session to be established via alternate-protocol
3133 // without racing an HTTP connection, we need the host resolution to happen
3134 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3135 // connection to the the server, in this test we require confirmation
3136 // before encrypting so the HTTP job will still start.
3137 host_resolver_.set_synchronous_mode(true);
3138 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3139 "");
rch9ecde09b2017-04-08 00:18:233140
3141 CreateSession();
3142 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233143 QuicStreamFactoryPeer::SetAlarmFactory(
3144 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193145 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553146 &clock_));
rch9ecde09b2017-04-08 00:18:233147
Ryan Hamilton9835e662018-08-02 05:36:273148 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233149
3150 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3151 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363152 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233153 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3154
3155 // Pump the message loop to get the request started.
3156 base::RunLoop().RunUntilIdle();
3157 // Explicitly confirm the handshake.
3158 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523159 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233160
3161 // Run the QUIC session to completion.
3162 quic_task_runner_->RunUntilIdle();
3163
3164 ExpectQuicAlternateProtocolMapping();
3165 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3166 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3167}
3168
3169// Verify that if a QUIC connection RTOs, the QuicHttpStream will
3170// return QUIC_PROTOCOL_ERROR.
3171TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:423172 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
3173 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233174
3175 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593176 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133177 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233178 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3179
Ryan Hamiltone940bd12019-06-30 02:46:453180 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033181 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493182 int packet_number = 1;
3183 if (VersionUsesQpack(version_.transport_version)) {
3184 quic_data.AddWrite(
3185 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3186 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023187 quic_data.AddWrite(
3188 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453189 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493190 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3191 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453192
3193 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Nick Harper057264a82019-09-12 23:33:493194 if (VersionUsesQpack(version_.transport_version)) {
3195 // TLP 1
3196 quic_data.AddWrite(SYNCHRONOUS,
3197 client_maker_.MakeRetransmissionPacket(1, 3, true));
3198 // TLP 2
3199 quic_data.AddWrite(SYNCHRONOUS,
3200 client_maker_.MakeRetransmissionPacket(2, 4, true));
3201 // RTO 1
3202 quic_data.AddWrite(SYNCHRONOUS,
3203 client_maker_.MakeRetransmissionPacket(1, 5, true));
3204 quic_data.AddWrite(SYNCHRONOUS,
3205 client_maker_.MakeRetransmissionPacket(2, 6, true));
3206 // RTO 2
3207 quic_data.AddWrite(SYNCHRONOUS,
3208 client_maker_.MakeRetransmissionPacket(1, 7, true));
3209 quic_data.AddWrite(SYNCHRONOUS,
3210 client_maker_.MakeRetransmissionPacket(2, 8, true));
3211 // RTO 3
3212 quic_data.AddWrite(SYNCHRONOUS,
3213 client_maker_.MakeRetransmissionPacket(1, 9, true));
3214 quic_data.AddWrite(SYNCHRONOUS,
3215 client_maker_.MakeRetransmissionPacket(2, 10, true));
3216 // RTO 4
3217 quic_data.AddWrite(SYNCHRONOUS,
3218 client_maker_.MakeRetransmissionPacket(1, 11, true));
3219 quic_data.AddWrite(SYNCHRONOUS,
3220 client_maker_.MakeRetransmissionPacket(2, 12, true));
3221 // RTO 5
3222 quic_data.AddWrite(SYNCHRONOUS,
3223 client_maker_.MakeConnectionClosePacket(
3224 13, true, quic::QUIC_TOO_MANY_RTOS,
3225 "5 consecutive retransmission timeouts"));
3226 } else {
3227 // TLP 1
3228 quic_data.AddWrite(SYNCHRONOUS,
3229 client_maker_.MakeRetransmissionPacket(1, 2, true));
3230 // TLP 2
3231 quic_data.AddWrite(SYNCHRONOUS,
3232 client_maker_.MakeRetransmissionPacket(1, 3, true));
3233 // RTO 1
3234 quic_data.AddWrite(SYNCHRONOUS,
3235 client_maker_.MakeRetransmissionPacket(1, 4, true));
3236 // RTO 2
3237 quic_data.AddWrite(SYNCHRONOUS,
3238 client_maker_.MakeRetransmissionPacket(1, 5, true));
3239 // RTO 3
3240 quic_data.AddWrite(SYNCHRONOUS,
3241 client_maker_.MakeRetransmissionPacket(1, 6, true));
3242 // RTO 4
3243 quic_data.AddWrite(SYNCHRONOUS,
3244 client_maker_.MakeRetransmissionPacket(1, 7, true));
3245 // RTO 5
3246 quic_data.AddWrite(SYNCHRONOUS,
3247 client_maker_.MakeConnectionClosePacket(
3248 8, true, quic::QUIC_TOO_MANY_RTOS,
3249 "5 consecutive retransmission timeouts"));
3250 }
rch9ecde09b2017-04-08 00:18:233251
3252 quic_data.AddRead(ASYNC, OK);
3253 quic_data.AddSocketDataToFactory(&socket_factory_);
3254
3255 // In order for a new QUIC session to be established via alternate-protocol
3256 // without racing an HTTP connection, we need the host resolution to happen
3257 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3258 // connection to the the server, in this test we require confirmation
3259 // before encrypting so the HTTP job will still start.
3260 host_resolver_.set_synchronous_mode(true);
3261 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3262 "");
rch9ecde09b2017-04-08 00:18:233263
3264 CreateSession();
3265 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233266 QuicStreamFactoryPeer::SetAlarmFactory(
3267 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193268 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553269 &clock_));
rch9ecde09b2017-04-08 00:18:233270
Ryan Hamilton9835e662018-08-02 05:36:273271 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233272
3273 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3274 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363275 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233276 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3277
3278 // Pump the message loop to get the request started.
3279 base::RunLoop().RunUntilIdle();
3280 // Explicitly confirm the handshake.
3281 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523282 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233283
3284 // Run the QUIC session to completion.
3285 quic_task_runner_->RunUntilIdle();
3286
3287 ExpectQuicAlternateProtocolMapping();
3288 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3289 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3290}
3291
3292// Verify that if a QUIC connection RTOs, while there are no active streams
3293// QUIC will not be marked as broken.
3294TEST_P(QuicNetworkTransactionTest,
3295 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Nick Harper72ade192019-07-17 03:30:423296 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233297
3298 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593299 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133300 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233301 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3302
Ryan Hamiltone940bd12019-06-30 02:46:453303 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033304 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493305 int packet_number = 1;
3306 if (VersionUsesQpack(version_.transport_version)) {
3307 quic_data.AddWrite(
3308 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3309 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023310 quic_data.AddWrite(
3311 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453312 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493313 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3314 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453315
3316 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233317
Nick Harper057264a82019-09-12 23:33:493318 if (!VersionUsesQpack(version_.transport_version)) {
3319 quic_data.AddWrite(SYNCHRONOUS,
3320 client_maker_.MakeRstPacket(
3321 packet_number++, true,
3322 GetNthClientInitiatedBidirectionalStreamId(0),
3323 quic::QUIC_STREAM_CANCELLED));
3324 // TLP 1
3325 quic_data.AddWrite(SYNCHRONOUS,
3326 client_maker_.MakeRetransmissionPacket(1, 3, true));
3327 // TLP 2
3328 quic_data.AddWrite(SYNCHRONOUS,
3329 client_maker_.MakeRetransmissionPacket(2, 4, true));
3330 // RTO 1
3331 quic_data.AddWrite(SYNCHRONOUS,
3332 client_maker_.MakeRetransmissionPacket(1, 5, true));
3333 quic_data.AddWrite(SYNCHRONOUS,
3334 client_maker_.MakeRetransmissionPacket(2, 6, true));
3335 // RTO 2
3336 quic_data.AddWrite(SYNCHRONOUS,
3337 client_maker_.MakeRetransmissionPacket(1, 7, true));
3338 quic_data.AddWrite(SYNCHRONOUS,
3339 client_maker_.MakeRetransmissionPacket(2, 8, true));
3340 // RTO 3
3341 quic_data.AddWrite(SYNCHRONOUS,
3342 client_maker_.MakeRetransmissionPacket(1, 9, true));
3343 quic_data.AddWrite(SYNCHRONOUS,
3344 client_maker_.MakeRetransmissionPacket(2, 10, true));
3345 // RTO 4
3346 quic_data.AddWrite(SYNCHRONOUS,
3347 client_maker_.MakeRetransmissionPacket(1, 11, true));
3348 quic_data.AddWrite(SYNCHRONOUS,
3349 client_maker_.MakeRetransmissionPacket(2, 12, true));
3350 // RTO 5
3351 quic_data.AddWrite(SYNCHRONOUS,
3352 client_maker_.MakeConnectionClosePacket(
3353 13, true, quic::QUIC_TOO_MANY_RTOS,
3354 "5 consecutive retransmission timeouts"));
3355 } else {
3356 quic_data.AddWrite(
3357 SYNCHRONOUS, client_maker_.MakeRstPacket(
3358 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb01f886f2019-07-10 02:25:553359 quic::QUIC_STREAM_CANCELLED));
Nick Harper057264a82019-09-12 23:33:493360 client_maker_.RemoveSavedStreamFrames(
3361 GetNthClientInitiatedBidirectionalStreamId(0));
3362 // TLP 1
3363 quic_data.AddWrite(SYNCHRONOUS,
3364 client_maker_.MakeRetransmissionPacket(1, 4, true));
3365 // TLP 2
3366 quic_data.AddWrite(SYNCHRONOUS,
3367 client_maker_.MakeRetransmissionPacket(2, 5, true));
3368 // RTO 1
3369 quic_data.AddWrite(SYNCHRONOUS,
3370 client_maker_.MakeRetransmissionPacket(3, 6, true));
3371 quic_data.AddWrite(SYNCHRONOUS,
3372 client_maker_.MakeRetransmissionPacket(1, 7, true));
3373 // RTO 2
3374 quic_data.AddWrite(SYNCHRONOUS,
3375 client_maker_.MakeRetransmissionPacket(2, 8, true));
3376 quic_data.AddWrite(SYNCHRONOUS,
3377 client_maker_.MakeRetransmissionPacket(3, 9, true));
3378 // RTO 3
3379 quic_data.AddWrite(SYNCHRONOUS,
3380 client_maker_.MakeRetransmissionPacket(1, 10, true));
3381 quic_data.AddWrite(SYNCHRONOUS,
3382 client_maker_.MakeRetransmissionPacket(2, 11, true));
3383 // RTO 4
3384 quic_data.AddWrite(SYNCHRONOUS,
3385 client_maker_.MakeRetransmissionPacket(3, 12, true));
3386 quic_data.AddWrite(SYNCHRONOUS,
3387 client_maker_.MakeRetransmissionPacket(1, 13, true));
3388 // RTO 5
3389 quic_data.AddWrite(SYNCHRONOUS,
3390 client_maker_.MakeConnectionClosePacket(
3391 14, true, quic::QUIC_TOO_MANY_RTOS,
3392 "5 consecutive retransmission timeouts"));
3393 }
rch9ecde09b2017-04-08 00:18:233394
3395 quic_data.AddRead(ASYNC, OK);
3396 quic_data.AddSocketDataToFactory(&socket_factory_);
3397
3398 // In order for a new QUIC session to be established via alternate-protocol
3399 // without racing an HTTP connection, we need the host resolution to happen
3400 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3401 // connection to the the server, in this test we require confirmation
3402 // before encrypting so the HTTP job will still start.
3403 host_resolver_.set_synchronous_mode(true);
3404 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3405 "");
rch9ecde09b2017-04-08 00:18:233406
3407 CreateSession();
3408 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233409 QuicStreamFactoryPeer::SetAlarmFactory(
3410 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193411 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553412 &clock_));
rch9ecde09b2017-04-08 00:18:233413
Ryan Hamilton9835e662018-08-02 05:36:273414 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233415
Jeremy Roman0579ed62017-08-29 15:56:193416 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233417 session_.get());
3418 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363419 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233420 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3421
3422 // Pump the message loop to get the request started.
3423 base::RunLoop().RunUntilIdle();
3424 // Explicitly confirm the handshake.
3425 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523426 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233427
3428 // Now cancel the request.
3429 trans.reset();
3430
3431 // Run the QUIC session to completion.
3432 quic_task_runner_->RunUntilIdle();
3433
3434 ExpectQuicAlternateProtocolMapping();
3435
3436 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3437}
3438
rch2f2991c2017-04-13 19:28:173439// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3440// the request fails with QUIC_PROTOCOL_ERROR.
3441TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:423442 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173443 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593444 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033445 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493446 int packet_num = 1;
3447 if (VersionUsesQpack(version_.transport_version)) {
3448 quic_data.AddWrite(SYNCHRONOUS,
3449 ConstructInitialSettingsPacket(packet_num++));
3450 }
3451 quic_data.AddWrite(
3452 SYNCHRONOUS,
3453 ConstructClientRequestHeadersPacket(
3454 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3455 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023456 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553457 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173458 // Peer sending data from an non-existing stream causes this end to raise
3459 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333460 quic_data.AddRead(
3461 ASYNC, ConstructServerRstPacket(
3462 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3463 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173464 std::string quic_error_details = "Data for nonexistent stream";
Nick Harper057264a82019-09-12 23:33:493465 quic_data.AddWrite(SYNCHRONOUS,
3466 ConstructClientAckAndConnectionClosePacket(
3467 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3468 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3469 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173470 quic_data.AddSocketDataToFactory(&socket_factory_);
3471
3472 // In order for a new QUIC session to be established via alternate-protocol
3473 // without racing an HTTP connection, we need the host resolution to happen
3474 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3475 // connection to the the server, in this test we require confirmation
3476 // before encrypting so the HTTP job will still start.
3477 host_resolver_.set_synchronous_mode(true);
3478 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3479 "");
rch2f2991c2017-04-13 19:28:173480
3481 CreateSession();
3482
Ryan Hamilton9835e662018-08-02 05:36:273483 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173484
3485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3486 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363487 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173488 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3489
3490 // Pump the message loop to get the request started.
3491 base::RunLoop().RunUntilIdle();
3492 // Explicitly confirm the handshake.
3493 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523494 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173495
3496 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553497 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173498
3499 // Run the QUIC session to completion.
3500 base::RunLoop().RunUntilIdle();
3501 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3502 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3503
3504 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3505 ExpectQuicAlternateProtocolMapping();
3506 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3507}
3508
rch2f2991c2017-04-13 19:28:173509// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3510// connection times out, then QUIC will be marked as broken and the request
3511// retried over TCP.
3512TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Ryan Sleevi2e8255b2019-07-17 21:02:213513 session_params_.quic_params.idle_connection_timeout =
3514 base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173515
3516 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593517 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133518 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173519 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3520
Ryan Hamiltone940bd12019-06-30 02:46:453521 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033522 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493523 int packet_num = 1;
3524 if (VersionUsesQpack(version_.transport_version)) {
3525 quic_data.AddWrite(SYNCHRONOUS,
3526 client_maker_.MakeInitialSettingsPacket(packet_num++));
3527 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023528 quic_data.AddWrite(
3529 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453530 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493531 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3532 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453533
3534 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Nick Harper057264a82019-09-12 23:33:493535 if (VersionUsesQpack(version_.transport_version)) {
3536 // TLP 1
3537 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3538 1, packet_num++, true));
3539 // TLP 2
3540 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3541 2, packet_num++, true));
3542 // RTO 1
3543 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3544 1, packet_num++, true));
3545 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3546 2, packet_num++, true));
3547 // RTO 2
3548 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3549 1, packet_num++, true));
3550 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3551 2, packet_num++, true));
3552 // RTO 3
3553 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3554 1, packet_num++, true));
3555 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3556 2, packet_num++, true));
rch2f2991c2017-04-13 19:28:173557
Nick Harper057264a82019-09-12 23:33:493558 quic_data.AddWrite(SYNCHRONOUS,
3559 client_maker_.MakeConnectionClosePacket(
3560 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3561 "No recent network activity."));
3562 } else {
3563 // TLP 1
3564 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3565 1, packet_num++, true));
3566 // TLP 2
3567 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3568 1, packet_num++, true));
3569 // RTO 1
3570 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3571 1, packet_num++, true));
3572 // RTO 2
3573 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3574 1, packet_num++, true));
3575 // RTO 3
3576 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3577 1, packet_num++, true));
3578
3579 quic_data.AddWrite(SYNCHRONOUS,
3580 client_maker_.MakeConnectionClosePacket(
3581 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3582 "No recent network activity."));
3583 }
Fan Yang928f1632017-12-14 18:55:223584
rch2f2991c2017-04-13 19:28:173585 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3586 quic_data.AddRead(ASYNC, OK);
3587 quic_data.AddSocketDataToFactory(&socket_factory_);
3588
3589 // After that fails, it will be resent via TCP.
3590 MockWrite http_writes[] = {
3591 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3592 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3593 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3594
3595 MockRead http_reads[] = {
3596 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3597 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3598 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013599 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173600 socket_factory_.AddSocketDataProvider(&http_data);
3601 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3602
3603 // In order for a new QUIC session to be established via alternate-protocol
3604 // without racing an HTTP connection, we need the host resolution to happen
3605 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3606 // connection to the the server, in this test we require confirmation
3607 // before encrypting so the HTTP job will still start.
3608 host_resolver_.set_synchronous_mode(true);
3609 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3610 "");
rch2f2991c2017-04-13 19:28:173611
3612 CreateSession();
3613 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173614 QuicStreamFactoryPeer::SetAlarmFactory(
3615 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193616 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553617 &clock_));
rch2f2991c2017-04-13 19:28:173618
Ryan Hamilton9835e662018-08-02 05:36:273619 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173620
3621 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3622 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363623 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3625
3626 // Pump the message loop to get the request started.
3627 base::RunLoop().RunUntilIdle();
3628 // Explicitly confirm the handshake.
3629 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523630 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173631
3632 // Run the QUIC session to completion.
3633 quic_task_runner_->RunUntilIdle();
3634 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3635
3636 ExpectQuicAlternateProtocolMapping();
3637
3638 // Let the transaction proceed which will result in QUIC being marked
3639 // as broken and the request falling back to TCP.
3640 EXPECT_THAT(callback.WaitForResult(), IsOk());
3641
3642 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3643 ASSERT_FALSE(http_data.AllReadDataConsumed());
3644
3645 // Read the response body over TCP.
3646 CheckResponseData(&trans, "hello world");
3647 ExpectBrokenAlternateProtocolMapping();
3648 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3649 ASSERT_TRUE(http_data.AllReadDataConsumed());
3650}
3651
rch2f2991c2017-04-13 19:28:173652// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3653// protocol error occurs after the handshake is confirmed, the request
3654// retried over TCP and the QUIC will be marked as broken.
3655TEST_P(QuicNetworkTransactionTest,
3656 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Ryan Sleevi2e8255b2019-07-17 21:02:213657 session_params_.quic_params.idle_connection_timeout =
3658 base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173659
3660 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593661 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033662 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493663 int packet_num = 1;
3664 if (VersionUsesQpack(version_.transport_version)) {
3665 quic_data.AddWrite(SYNCHRONOUS,
3666 ConstructInitialSettingsPacket(packet_num++));
3667 }
3668 quic_data.AddWrite(
3669 SYNCHRONOUS,
3670 ConstructClientRequestHeadersPacket(
3671 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3672 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023673 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553674 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3675
rch2f2991c2017-04-13 19:28:173676 // Peer sending data from an non-existing stream causes this end to raise
3677 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333678 quic_data.AddRead(
3679 ASYNC, ConstructServerRstPacket(
3680 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3681 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173682 std::string quic_error_details = "Data for nonexistent stream";
Nick Harper057264a82019-09-12 23:33:493683 quic_data.AddWrite(SYNCHRONOUS,
3684 ConstructClientAckAndConnectionClosePacket(
3685 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3686 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3687 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173688 quic_data.AddSocketDataToFactory(&socket_factory_);
3689
3690 // After that fails, it will be resent via TCP.
3691 MockWrite http_writes[] = {
3692 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3693 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3694 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3695
3696 MockRead http_reads[] = {
3697 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3698 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3699 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013700 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173701 socket_factory_.AddSocketDataProvider(&http_data);
3702 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3703
3704 // In order for a new QUIC session to be established via alternate-protocol
3705 // without racing an HTTP connection, we need the host resolution to happen
3706 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3707 // connection to the the server, in this test we require confirmation
3708 // before encrypting so the HTTP job will still start.
3709 host_resolver_.set_synchronous_mode(true);
3710 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3711 "");
rch2f2991c2017-04-13 19:28:173712
3713 CreateSession();
3714
Ryan Hamilton9835e662018-08-02 05:36:273715 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173716
3717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3718 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363719 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3721
3722 // Pump the message loop to get the request started.
3723 base::RunLoop().RunUntilIdle();
3724 // Explicitly confirm the handshake.
3725 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523726 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553727 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173728
3729 // Run the QUIC session to completion.
3730 base::RunLoop().RunUntilIdle();
3731 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3732
3733 ExpectQuicAlternateProtocolMapping();
3734
3735 // Let the transaction proceed which will result in QUIC being marked
3736 // as broken and the request falling back to TCP.
3737 EXPECT_THAT(callback.WaitForResult(), IsOk());
3738
3739 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3740 ASSERT_FALSE(http_data.AllReadDataConsumed());
3741
3742 // Read the response body over TCP.
3743 CheckResponseData(&trans, "hello world");
3744 ExpectBrokenAlternateProtocolMapping();
3745 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3746 ASSERT_TRUE(http_data.AllReadDataConsumed());
3747}
3748
Matt Menkeb32ba5122019-09-10 19:17:053749// Much like above test, but verifies that NetworkIsolationKey is respected.
3750TEST_P(QuicNetworkTransactionTest,
3751 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
3752 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
3753 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
3754 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
3755 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
3756
3757 base::test::ScopedFeatureList feature_list;
3758 feature_list.InitWithFeatures(
3759 // enabled_features
3760 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3761 features::kPartitionConnectionsByNetworkIsolationKey},
3762 // disabled_features
3763 {});
3764 // Since HttpServerProperties caches the feature value, have to create a new
3765 // one.
3766 http_server_properties_ = std::make_unique<HttpServerProperties>();
3767
3768 session_params_.quic_params.idle_connection_timeout =
3769 base::TimeDelta::FromSeconds(5);
3770
3771 // The request will initially go out over QUIC.
3772 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:563773 uint64_t packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:053774 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjie Tang874398a2019-09-13 18:32:563775 if (VersionUsesQpack(version_.transport_version)) {
3776 quic_data.AddWrite(SYNCHRONOUS,
3777 ConstructInitialSettingsPacket(packet_number++));
3778 }
3779 quic_data.AddWrite(
3780 SYNCHRONOUS,
3781 ConstructClientRequestHeadersPacket(
3782 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3783 true, GetRequestHeaders("GET", "https", "/")));
Matt Menkeb32ba5122019-09-10 19:17:053784 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:053785 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3786
3787 // Peer sending data from an non-existing stream causes this end to raise
3788 // error and close connection.
3789 quic_data.AddRead(
3790 ASYNC, ConstructServerRstPacket(
3791 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3792 quic::QUIC_STREAM_LAST_ERROR));
3793 std::string quic_error_details = "Data for nonexistent stream";
3794 quic_data.AddWrite(
3795 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
3796 packet_number++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3797 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3798 quic::IETF_RST_STREAM));
3799 quic_data.AddSocketDataToFactory(&socket_factory_);
3800
3801 // After that fails, it will be resent via TCP.
3802 MockWrite http_writes[] = {
3803 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3804 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3805 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3806
3807 MockRead http_reads[] = {
3808 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3809 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3810 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3811 SequencedSocketData http_data(http_reads, http_writes);
3812 socket_factory_.AddSocketDataProvider(&http_data);
3813 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3814
3815 // In order for a new QUIC session to be established via alternate-protocol
3816 // without racing an HTTP connection, we need the host resolution to happen
3817 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3818 // connection to the the server, in this test we require confirmation
3819 // before encrypting so the HTTP job will still start.
3820 host_resolver_.set_synchronous_mode(true);
3821 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3822 "");
3823
3824 CreateSession();
3825
3826 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3827 kNetworkIsolationKey1);
3828 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3829 kNetworkIsolationKey2);
3830
3831 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3832 TestCompletionCallback callback;
3833 request_.network_isolation_key = kNetworkIsolationKey1;
3834 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3835 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3836
3837 // Pump the message loop to get the request started.
3838 base::RunLoop().RunUntilIdle();
3839 // Explicitly confirm the handshake.
3840 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
3841 quic::QuicSession::HANDSHAKE_CONFIRMED);
3842 quic_data.Resume();
3843
3844 // Run the QUIC session to completion.
3845 base::RunLoop().RunUntilIdle();
3846 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3847
3848 // Let the transaction proceed which will result in QUIC being marked
3849 // as broken and the request falling back to TCP.
3850 EXPECT_THAT(callback.WaitForResult(), IsOk());
3851 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3852 ASSERT_FALSE(http_data.AllReadDataConsumed());
3853
3854 // Read the response body over TCP.
3855 CheckResponseData(&trans, "hello world");
3856 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3857 ASSERT_TRUE(http_data.AllReadDataConsumed());
3858
3859 // The alternative service shouldhave been marked as broken under
3860 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3861 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3862 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3863
3864 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3865 AddHttpDataAndRunRequest();
3866 // Requests using other NetworkIsolationKeys can still use QUIC.
3867 request_.network_isolation_key = kNetworkIsolationKey2;
3868 AddQuicDataAndRunRequest();
3869
3870 // The last two requests should not have changed the alternative service
3871 // mappings.
3872 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3873 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3874}
3875
rch30943ee2017-06-12 21:28:443876// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3877// request is reset from, then QUIC will be marked as broken and the request
3878// retried over TCP.
3879TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443880 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593881 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133882 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443883 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3884
Michael Warres167db3e2019-03-01 21:38:033885 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493886 int packet_num = 1;
3887 if (VersionUsesQpack(version_.transport_version)) {
3888 quic_data.AddWrite(SYNCHRONOUS,
3889 ConstructInitialSettingsPacket(packet_num++));
3890 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023891 quic_data.AddWrite(
3892 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453893 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493894 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3895 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453896
3897 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553898 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443899
Fan Yang32c5a112018-12-10 20:06:333900 quic_data.AddRead(ASYNC,
3901 ConstructServerRstPacket(
3902 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3903 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443904
3905 quic_data.AddRead(ASYNC, OK);
3906 quic_data.AddSocketDataToFactory(&socket_factory_);
3907
3908 // After that fails, it will be resent via TCP.
3909 MockWrite http_writes[] = {
3910 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3911 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3912 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3913
3914 MockRead http_reads[] = {
3915 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3916 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3917 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013918 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443919 socket_factory_.AddSocketDataProvider(&http_data);
3920 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3921
3922 // In order for a new QUIC session to be established via alternate-protocol
3923 // without racing an HTTP connection, we need the host resolution to happen
3924 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3925 // connection to the the server, in this test we require confirmation
3926 // before encrypting so the HTTP job will still start.
3927 host_resolver_.set_synchronous_mode(true);
3928 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3929 "");
rch30943ee2017-06-12 21:28:443930
3931 CreateSession();
3932
Ryan Hamilton9835e662018-08-02 05:36:273933 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443934
3935 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3936 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363937 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443938 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3939
3940 // Pump the message loop to get the request started.
3941 base::RunLoop().RunUntilIdle();
3942 // Explicitly confirm the handshake.
3943 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523944 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553945 quic_data.Resume();
rch30943ee2017-06-12 21:28:443946
3947 // Run the QUIC session to completion.
3948 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3949
3950 ExpectQuicAlternateProtocolMapping();
3951
3952 // Let the transaction proceed which will result in QUIC being marked
3953 // as broken and the request falling back to TCP.
3954 EXPECT_THAT(callback.WaitForResult(), IsOk());
3955
3956 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3957 ASSERT_FALSE(http_data.AllReadDataConsumed());
3958
3959 // Read the response body over TCP.
3960 CheckResponseData(&trans, "hello world");
3961 ExpectBrokenAlternateProtocolMapping();
3962 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3963 ASSERT_TRUE(http_data.AllReadDataConsumed());
3964}
3965
Ryan Hamilton6c2a2a82017-12-15 02:06:283966// Verify that when an origin has two alt-svc advertisements, one local and one
3967// remote, that when the local is broken the request will go over QUIC via
3968// the remote Alt-Svc.
3969// This is a regression test for crbug/825646.
3970TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Nick Harper72ade192019-07-17 03:30:423971 session_params_.quic_params.allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:283972
3973 GURL origin1 = request_.url; // mail.example.org
3974 GURL origin2("https://www.example.org/");
3975 ASSERT_NE(origin1.host(), origin2.host());
3976
3977 scoped_refptr<X509Certificate> cert(
3978 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243979 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3980 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283981
3982 ProofVerifyDetailsChromium verify_details;
3983 verify_details.cert_verify_result.verified_cert = cert;
3984 verify_details.cert_verify_result.is_issued_by_known_root = true;
3985 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3986
Ryan Hamiltonabad59e2019-06-06 04:02:593987 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233988 int packet_num = 1;
3989 if (VersionUsesQpack(version_.transport_version)) {
3990 mock_quic_data.AddWrite(SYNCHRONOUS,
3991 ConstructInitialSettingsPacket(packet_num++));
3992 }
Ryan Hamilton6c2a2a82017-12-15 02:06:283993 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233994 SYNCHRONOUS,
3995 ConstructClientRequestHeadersPacket(
3996 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3997 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433998 mock_quic_data.AddRead(
3999 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334000 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024001 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434002 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434003 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334004 ASYNC, ConstructServerDataPacket(
4005 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174006 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234007 mock_quic_data.AddWrite(SYNCHRONOUS,
4008 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284009 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4010 mock_quic_data.AddRead(ASYNC, 0); // EOF
4011
4012 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:594013 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:284014 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4015 AddHangingNonAlternateProtocolSocketData();
4016
4017 CreateSession();
4018
4019 // Set up alternative service for |origin1|.
4020 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4021 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4022 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4023 AlternativeServiceInfoVector alternative_services;
4024 alternative_services.push_back(
4025 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4026 local_alternative, expiration,
Nick Harper72ade192019-07-17 03:30:424027 session_->params().quic_params.supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:284028 alternative_services.push_back(
4029 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4030 remote_alternative, expiration,
Nick Harper72ade192019-07-17 03:30:424031 session_->params().quic_params.supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494032 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4033 NetworkIsolationKey(),
4034 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:284035
Matt Menkeb32ba5122019-09-10 19:17:054036 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4037 NetworkIsolationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:284038
4039 SendRequestAndExpectQuicResponse("hello!");
4040}
4041
rch30943ee2017-06-12 21:28:444042// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4043// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:054044// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:444045// connection instead of going back to the broken QUIC connection.
4046// This is a regression tests for crbug/731303.
4047TEST_P(QuicNetworkTransactionTest,
4048 ResetPooledAfterHandshakeConfirmedThenBroken) {
Nick Harper72ade192019-07-17 03:30:424049 session_params_.quic_params.allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444050
4051 GURL origin1 = request_.url;
4052 GURL origin2("https://www.example.org/");
4053 ASSERT_NE(origin1.host(), origin2.host());
4054
Ryan Hamiltonabad59e2019-06-06 04:02:594055 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:444056
4057 scoped_refptr<X509Certificate> cert(
4058 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244059 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4060 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444061
4062 ProofVerifyDetailsChromium verify_details;
4063 verify_details.cert_verify_result.verified_cert = cert;
4064 verify_details.cert_verify_result.is_issued_by_known_root = true;
4065 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4066
Renjie Tangaadb84b2019-08-31 01:00:234067 int packet_num = 1;
4068 if (VersionUsesQpack(version_.transport_version)) {
4069 mock_quic_data.AddWrite(SYNCHRONOUS,
4070 ConstructInitialSettingsPacket(packet_num++));
4071 }
rch30943ee2017-06-12 21:28:444072 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434073 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234074 SYNCHRONOUS,
4075 ConstructClientRequestHeadersPacket(
4076 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4077 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434078 mock_quic_data.AddRead(
4079 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334080 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024081 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434082 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434083 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334084 ASYNC, ConstructServerDataPacket(
4085 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174086 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234087 mock_quic_data.AddWrite(SYNCHRONOUS,
4088 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rch30943ee2017-06-12 21:28:444089
4090 // Second request will go over the pooled QUIC connection, but will be
4091 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054092 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174093 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4094 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054095 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174096 QuicTestPacketMaker server_maker2(
4097 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4098 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434099 mock_quic_data.AddWrite(
4100 SYNCHRONOUS,
4101 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234102 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4103 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024104 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334105 mock_quic_data.AddRead(
4106 ASYNC, ConstructServerRstPacket(
4107 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4108 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444109 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4110 mock_quic_data.AddRead(ASYNC, 0); // EOF
4111
4112 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4113
4114 // After that fails, it will be resent via TCP.
4115 MockWrite http_writes[] = {
4116 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4117 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4118 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4119
4120 MockRead http_reads[] = {
4121 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4122 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4123 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014124 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444125 socket_factory_.AddSocketDataProvider(&http_data);
4126 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4127
Ryan Hamilton6c2a2a82017-12-15 02:06:284128 // Then the next request to the second origin will be sent over TCP.
4129 socket_factory_.AddSocketDataProvider(&http_data);
4130 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444131
4132 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564133 QuicStreamFactoryPeer::SetAlarmFactory(
4134 session_->quic_stream_factory(),
4135 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4136 &clock_));
rch30943ee2017-06-12 21:28:444137
4138 // Set up alternative service for |origin1|.
4139 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244140 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494141 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074142 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4143 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:444144
4145 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244146 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494147 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074148 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4149 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344150
rch30943ee2017-06-12 21:28:444151 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524152 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444153 SendRequestAndExpectQuicResponse("hello!");
4154
4155 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524156 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:054157 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:444158 request_.url = origin2;
4159 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:054160 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
4161 alternative1, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244162 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:054163 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
4164 alternative2, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244165 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444166
Matt Menkeb32ba5122019-09-10 19:17:054167 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:444168 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284169 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444170}
4171
bnc8be55ebb2015-10-30 14:12:074172TEST_P(QuicNetworkTransactionTest,
4173 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564174 std::string altsvc_header =
4175 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4176 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074177 MockRead http_reads[] = {
4178 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4179 MockRead("hello world"),
4180 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4181 MockRead(ASYNC, OK)};
4182
Ryan Sleevib8d7ea02018-05-07 20:01:014183 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074184 socket_factory_.AddSocketDataProvider(&http_data);
4185 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4186 socket_factory_.AddSocketDataProvider(&http_data);
4187 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4188
rch3f4b8452016-02-23 16:59:324189 CreateSession();
bnc8be55ebb2015-10-30 14:12:074190
4191 SendRequestAndExpectHttpResponse("hello world");
4192 SendRequestAndExpectHttpResponse("hello world");
4193}
4194
Xida Chen9bfe0b62018-04-24 19:52:214195// When multiple alternative services are advertised, HttpStreamFactory should
4196// select the alternative service which uses existing QUIC session if available.
4197// If no existing QUIC session can be used, use the first alternative service
4198// from the list.
zhongyi32569c62016-01-08 02:54:304199TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Nick Harper72ade192019-07-17 03:30:424200 session_params_.quic_params.allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524201 MockRead http_reads[] = {
4202 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294203 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524204 MockRead("hello world"),
4205 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4206 MockRead(ASYNC, OK)};
4207
Ryan Sleevib8d7ea02018-05-07 20:01:014208 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524209 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084210 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564211 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524212
zhongyi32569c62016-01-08 02:54:304213 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294214 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304215 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594216 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234217 int packet_num = 1;
4218 if (VersionUsesQpack(version_.transport_version)) {
4219 mock_quic_data.AddWrite(SYNCHRONOUS,
4220 ConstructInitialSettingsPacket(packet_num++));
4221 }
rch5cb522462017-04-25 20:18:364222 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234223 SYNCHRONOUS,
4224 ConstructClientRequestHeadersPacket(
4225 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4226 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304227
4228 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294229 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4230 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434231 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024232 ASYNC, ConstructServerResponseHeadersPacket(
4233 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4234 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434235 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434236 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334237 ASYNC, ConstructServerDataPacket(
4238 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174239 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234240 mock_quic_data.AddWrite(SYNCHRONOUS,
4241 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304242
4243 // Second QUIC request data.
4244 // Connection pooling, using existing session, no need to include version
4245 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584246 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234247 SYNCHRONOUS,
4248 ConstructClientRequestHeadersPacket(
4249 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4250 true, GetRequestHeaders("GET", "https", "/"),
4251 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434252 mock_quic_data.AddRead(
4253 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334254 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024255 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434256 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334257 ASYNC, ConstructServerDataPacket(
4258 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174259 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434260 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234261 SYNCHRONOUS,
4262 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bncc958faa2015-07-31 18:14:524263 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594264 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524265
4266 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4267
rtennetib8e80fb2016-05-16 00:12:094268 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324269 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564270 QuicStreamFactoryPeer::SetAlarmFactory(
4271 session_->quic_stream_factory(),
4272 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4273 &clock_));
bncc958faa2015-07-31 18:14:524274
4275 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304276
bnc359ed2a2016-04-29 20:43:454277 SendRequestAndExpectQuicResponse("hello!");
4278 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304279}
4280
tbansal6490783c2016-09-20 17:55:274281// Check that an existing QUIC connection to an alternative proxy server is
4282// used.
4283TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4284 base::HistogramTester histogram_tester;
4285
tbansal6490783c2016-09-20 17:55:274286 // First QUIC request data.
4287 // Open a session to foo.example.org:443 using the first entry of the
4288 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594289 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234290 int packet_num = 1;
4291 if (VersionUsesQpack(version_.transport_version)) {
4292 mock_quic_data.AddWrite(SYNCHRONOUS,
4293 ConstructInitialSettingsPacket(packet_num++));
4294 }
rch5cb522462017-04-25 20:18:364295 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234296 SYNCHRONOUS,
4297 ConstructClientRequestHeadersPacket(
4298 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4299 true, GetRequestHeaders("GET", "http", "/")));
tbansal6490783c2016-09-20 17:55:274300
4301 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434302 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024303 ASYNC, ConstructServerResponseHeadersPacket(
4304 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4305 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434306 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434307 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334308 ASYNC, ConstructServerDataPacket(
4309 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174310 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234311 mock_quic_data.AddWrite(SYNCHRONOUS,
4312 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274313
4314 // Second QUIC request data.
4315 // Connection pooling, using existing session, no need to include version
4316 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274317 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234318 SYNCHRONOUS,
4319 ConstructClientRequestHeadersPacket(
4320 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4321 true, GetRequestHeaders("GET", "http", "/"),
4322 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434323 mock_quic_data.AddRead(
4324 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334325 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024326 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434327 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334328 ASYNC, ConstructServerDataPacket(
4329 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174330 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434331 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234332 SYNCHRONOUS,
4333 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274334 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4335 mock_quic_data.AddRead(ASYNC, 0); // EOF
4336
4337 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4338
4339 AddHangingNonAlternateProtocolSocketData();
4340
4341 TestProxyDelegate test_proxy_delegate;
4342
Lily Houghton8c2f97d2018-01-22 05:06:594343 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494344 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274345
4346 test_proxy_delegate.set_alternative_proxy_server(
4347 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524348 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274349
4350 request_.url = GURL("http://mail.example.org/");
4351
4352 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564353 QuicStreamFactoryPeer::SetAlarmFactory(
4354 session_->quic_stream_factory(),
4355 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4356 &clock_));
tbansal6490783c2016-09-20 17:55:274357
4358 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4359 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4360 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4361 1);
4362
4363 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4364 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4365 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4366 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4367 1);
4368}
4369
Ryan Hamilton8d9ee76e2018-05-29 23:52:524370// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454371// even if alternative service destination is different.
4372TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Nick Harper72ade192019-07-17 03:30:424373 session_params_.quic_params.allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594374 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454375
Renjie Tangaadb84b2019-08-31 01:00:234376 int packet_num = 1;
4377 if (VersionUsesQpack(version_.transport_version)) {
4378 mock_quic_data.AddWrite(SYNCHRONOUS,
4379 ConstructInitialSettingsPacket(packet_num++));
4380 }
bnc359ed2a2016-04-29 20:43:454381 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434382 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234383 SYNCHRONOUS,
4384 ConstructClientRequestHeadersPacket(
4385 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4386 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434387 mock_quic_data.AddRead(
4388 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334389 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024390 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434391 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434392 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334393 ASYNC, ConstructServerDataPacket(
4394 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174395 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234396 mock_quic_data.AddWrite(SYNCHRONOUS,
4397 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304398
bnc359ed2a2016-04-29 20:43:454399 // Second request.
alyssar2adf3ac2016-05-03 17:12:584400 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234401 SYNCHRONOUS,
4402 ConstructClientRequestHeadersPacket(
4403 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4404 true, GetRequestHeaders("GET", "https", "/"),
4405 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434406 mock_quic_data.AddRead(
4407 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334408 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024409 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434410 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334411 ASYNC, ConstructServerDataPacket(
4412 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174413 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434414 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234415 SYNCHRONOUS,
4416 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304417 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4418 mock_quic_data.AddRead(ASYNC, 0); // EOF
4419
4420 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454421
4422 AddHangingNonAlternateProtocolSocketData();
4423 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304424
rch3f4b8452016-02-23 16:59:324425 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564426 QuicStreamFactoryPeer::SetAlarmFactory(
4427 session_->quic_stream_factory(),
4428 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4429 &clock_));
zhongyi32569c62016-01-08 02:54:304430
bnc359ed2a2016-04-29 20:43:454431 const char destination1[] = "first.example.com";
4432 const char destination2[] = "second.example.com";
4433
4434 // Set up alternative service entry to destination1.
4435 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214436 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454437 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494438 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074439 server, NetworkIsolationKey(), alternative_service, expiration,
4440 supported_versions_);
bnc359ed2a2016-04-29 20:43:454441 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524442 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454443 SendRequestAndExpectQuicResponse("hello!");
4444
4445 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214446 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494447 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074448 server, NetworkIsolationKey(), alternative_service, expiration,
4449 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524450 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454451 // even though alternative service destination is different.
4452 SendRequestAndExpectQuicResponse("hello!");
4453}
4454
4455// Pool to existing session with matching destination and matching certificate
4456// even if origin is different, and even if the alternative service with
4457// matching destination is not the first one on the list.
4458TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Nick Harper72ade192019-07-17 03:30:424459 session_params_.quic_params.allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454460 GURL origin1 = request_.url;
4461 GURL origin2("https://www.example.org/");
4462 ASSERT_NE(origin1.host(), origin2.host());
4463
Ryan Hamiltonabad59e2019-06-06 04:02:594464 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454465
Renjie Tangaadb84b2019-08-31 01:00:234466 int packet_num = 1;
4467 if (VersionUsesQpack(version_.transport_version)) {
4468 mock_quic_data.AddWrite(SYNCHRONOUS,
4469 ConstructInitialSettingsPacket(packet_num++));
4470 }
bnc359ed2a2016-04-29 20:43:454471 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434472 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234473 SYNCHRONOUS,
4474 ConstructClientRequestHeadersPacket(
4475 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4476 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434477 mock_quic_data.AddRead(
4478 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334479 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024480 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434481 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434482 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334483 ASYNC, ConstructServerDataPacket(
4484 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174485 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234486 mock_quic_data.AddWrite(SYNCHRONOUS,
4487 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454488
4489 // Second request.
Yixin Wang079ad542018-01-11 04:06:054490 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174491 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4492 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054493 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174494 QuicTestPacketMaker server_maker2(
4495 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4496 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584497 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434498 SYNCHRONOUS,
4499 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234500 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4501 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024502 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434503 mock_quic_data.AddRead(
4504 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334505 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024506 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434507 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334508 ASYNC, ConstructServerDataPacket(
4509 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174510 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434511 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234512 SYNCHRONOUS,
4513 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454514 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4515 mock_quic_data.AddRead(ASYNC, 0); // EOF
4516
4517 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4518
4519 AddHangingNonAlternateProtocolSocketData();
4520 AddHangingNonAlternateProtocolSocketData();
4521
4522 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564523 QuicStreamFactoryPeer::SetAlarmFactory(
4524 session_->quic_stream_factory(),
4525 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4526 &clock_));
bnc359ed2a2016-04-29 20:43:454527
4528 const char destination1[] = "first.example.com";
4529 const char destination2[] = "second.example.com";
4530
4531 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214532 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454533 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494534 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074535 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4536 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454537
4538 // Set up multiple alternative service entries for |origin2|,
4539 // the first one with a different destination as for |origin1|,
4540 // the second one with the same. The second one should be used,
4541 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214542 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454543 AlternativeServiceInfoVector alternative_services;
4544 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214545 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4546 alternative_service2, expiration,
Nick Harper72ade192019-07-17 03:30:424547 session_->params().quic_params.supported_versions));
bnc359ed2a2016-04-29 20:43:454548 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214549 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4550 alternative_service1, expiration,
Nick Harper72ade192019-07-17 03:30:424551 session_->params().quic_params.supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494552 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4553 NetworkIsolationKey(),
4554 alternative_services);
bnc359ed2a2016-04-29 20:43:454555 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524556 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454557 SendRequestAndExpectQuicResponse("hello!");
4558
4559 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524560 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454561 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584562
bnc359ed2a2016-04-29 20:43:454563 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304564}
4565
4566// Multiple origins have listed the same alternative services. When there's a
4567// existing QUIC session opened by a request to other origin,
4568// if the cert is valid, should select this QUIC session to make the request
4569// if this is also the first existing QUIC session.
4570TEST_P(QuicNetworkTransactionTest,
4571 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Nick Harper72ade192019-07-17 03:30:424572 session_params_.quic_params.allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294573 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304574
rch9ae5b3b2016-02-11 00:36:294575 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304576 MockRead http_reads[] = {
4577 MockRead("HTTP/1.1 200 OK\r\n"),
4578 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294579 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304580 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4581 MockRead(ASYNC, OK)};
4582
Ryan Sleevib8d7ea02018-05-07 20:01:014583 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304584 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084585 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304586 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4587
4588 // HTTP data for request to mail.example.org.
4589 MockRead http_reads2[] = {
4590 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294591 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304592 MockRead("hello world from mail.example.org"),
4593 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4594 MockRead(ASYNC, OK)};
4595
Ryan Sleevib8d7ea02018-05-07 20:01:014596 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304597 socket_factory_.AddSocketDataProvider(&http_data2);
4598 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4599
Yixin Wang079ad542018-01-11 04:06:054600 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174601 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4602 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054603 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584604 server_maker_.set_hostname("www.example.org");
4605 client_maker_.set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594606 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234607 int packet_num = 1;
4608 if (VersionUsesQpack(version_.transport_version)) {
4609 mock_quic_data.AddWrite(SYNCHRONOUS,
4610 ConstructInitialSettingsPacket(packet_num++));
4611 }
zhongyi32569c62016-01-08 02:54:304612 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584613 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234614 SYNCHRONOUS,
4615 ConstructClientRequestHeadersPacket(
4616 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4617 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434618
4619 mock_quic_data.AddRead(
4620 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334621 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024622 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434623 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334624 mock_quic_data.AddRead(
4625 ASYNC, ConstructServerDataPacket(
4626 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174627 header + "hello from mail QUIC!"));
Renjie Tangaadb84b2019-08-31 01:00:234628 mock_quic_data.AddWrite(SYNCHRONOUS,
4629 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434630 // Second QUIC request data.
4631 mock_quic_data.AddWrite(
4632 SYNCHRONOUS,
4633 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234634 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4635 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024636 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434637 mock_quic_data.AddRead(
4638 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334639 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024640 GetResponseHeaders("200 OK")));
Fan Yang32c5a112018-12-10 20:06:334641 mock_quic_data.AddRead(
4642 ASYNC, ConstructServerDataPacket(
4643 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174644 header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434645 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234646 SYNCHRONOUS,
4647 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304648 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4649 mock_quic_data.AddRead(ASYNC, 0); // EOF
4650
4651 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304652
rtennetib8e80fb2016-05-16 00:12:094653 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324654 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564655 QuicStreamFactoryPeer::SetAlarmFactory(
4656 session_->quic_stream_factory(),
4657 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4658 &clock_));
zhongyi32569c62016-01-08 02:54:304659
4660 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294661 request_.url = GURL("https://www.example.org/");
4662 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304663 request_.url = GURL("https://mail.example.org/");
4664 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4665
rch9ae5b3b2016-02-11 00:36:294666 // Open a QUIC session to mail.example.org:443 when making request
4667 // to mail.example.org.
4668 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454669 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304670
rch9ae5b3b2016-02-11 00:36:294671 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304672 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454673 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524674}
4675
4676TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524677 MockRead http_reads[] = {
4678 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564679 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524680 MockRead("hello world"),
4681 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4682 MockRead(ASYNC, OK)};
4683
Ryan Sleevib8d7ea02018-05-07 20:01:014684 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524685 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084686 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564687 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524688
rtennetib8e80fb2016-05-16 00:12:094689 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324690 CreateSession();
bncc958faa2015-07-31 18:14:524691
4692 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454693
4694 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344695 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494696 http_server_properties_->GetAlternativeServiceInfos(
4697 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344698 ASSERT_EQ(1u, alternative_service_info_vector.size());
4699 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544700 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344701 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4702 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4703 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524704}
4705
4706TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524707 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564708 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4709 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524710 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4711 MockRead(ASYNC, OK)};
4712
Ryan Sleevib8d7ea02018-05-07 20:01:014713 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524714 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084715 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564716 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524717
Ryan Hamiltonabad59e2019-06-06 04:02:594718 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234719 int packet_num = 1;
4720 if (VersionUsesQpack(version_.transport_version)) {
4721 mock_quic_data.AddWrite(SYNCHRONOUS,
4722 ConstructInitialSettingsPacket(packet_num++));
4723 }
rch5cb522462017-04-25 20:18:364724 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234725 SYNCHRONOUS,
4726 ConstructClientRequestHeadersPacket(
4727 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4728 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434729 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334730 ASYNC, ConstructServerResponseHeadersPacket(
4731 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4732 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434733 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334734 mock_quic_data.AddRead(
4735 ASYNC, ConstructServerDataPacket(
4736 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174737 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234738 mock_quic_data.AddWrite(SYNCHRONOUS,
4739 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524740 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4741 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524742
4743 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4744
rtennetib8e80fb2016-05-16 00:12:094745 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324746 CreateSession();
bncc958faa2015-07-31 18:14:524747
bnc3472afd2016-11-17 15:27:214748 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524749 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494750 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054751 alternative_service, NetworkIsolationKey());
Matt Menke3233d8f22019-08-20 21:01:494752 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054753 alternative_service, NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524754
4755 SendRequestAndExpectHttpResponse("hello world");
4756 SendRequestAndExpectQuicResponse("hello!");
4757
mmenkee24011922015-12-17 22:12:594758 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524759
Matt Menke3233d8f22019-08-20 21:01:494760 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054761 alternative_service, NetworkIsolationKey()));
Matt Menke19475f72019-08-21 18:57:444762 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4763 url::SchemeHostPort("https", request_.url.host(), 443),
4764 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524765}
4766
Matt Menkeb32ba5122019-09-10 19:17:054767TEST_P(QuicNetworkTransactionTest,
4768 ConfirmAlternativeServiceWithNetworkIsolationKey) {
4769 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
4770 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
4771 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
4772 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
4773
4774 base::test::ScopedFeatureList feature_list;
4775 feature_list.InitWithFeatures(
4776 // enabled_features
4777 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4778 features::kPartitionConnectionsByNetworkIsolationKey},
4779 // disabled_features
4780 {});
4781 // Since HttpServerProperties caches the feature value, have to create a new
4782 // one.
4783 http_server_properties_ = std::make_unique<HttpServerProperties>();
4784
4785 MockRead http_reads[] = {
4786 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4787 MockRead("hello world"),
4788 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4789 MockRead(ASYNC, OK)};
4790
4791 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4792 socket_factory_.AddSocketDataProvider(&http_data);
4793 AddCertificate(&ssl_data_);
4794 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4795
4796 MockQuicData mock_quic_data(version_);
4797 int packet_num = 1;
4798 if (VersionUsesQpack(version_.transport_version)) {
4799 mock_quic_data.AddWrite(SYNCHRONOUS,
4800 ConstructInitialSettingsPacket(packet_num++));
4801 }
4802 mock_quic_data.AddWrite(
4803 SYNCHRONOUS,
4804 ConstructClientRequestHeadersPacket(
4805 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4806 true, GetRequestHeaders("GET", "https", "/")));
4807 mock_quic_data.AddRead(
4808 ASYNC, ConstructServerResponseHeadersPacket(
4809 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4810 GetResponseHeaders("200 OK")));
4811 std::string header = ConstructDataHeader(6);
4812 mock_quic_data.AddRead(
4813 ASYNC, ConstructServerDataPacket(
4814 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4815 header + "hello!"));
4816 mock_quic_data.AddWrite(SYNCHRONOUS,
4817 ConstructClientAckPacket(packet_num++, 2, 1, 1));
4818 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4819 mock_quic_data.AddRead(ASYNC, 0); // EOF
4820
4821 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4822
4823 CreateSession();
4824
4825 AlternativeService alternative_service(kProtoQUIC,
4826 HostPortPair::FromURL(request_.url));
4827 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4828 alternative_service, kNetworkIsolationKey1);
4829 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4830 alternative_service, kNetworkIsolationKey2);
4831 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4832 alternative_service, kNetworkIsolationKey1));
4833 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4834 alternative_service, kNetworkIsolationKey2));
4835
4836 request_.network_isolation_key = kNetworkIsolationKey1;
4837 SendRequestAndExpectHttpResponse("hello world");
4838 SendRequestAndExpectQuicResponse("hello!");
4839
4840 mock_quic_data.Resume();
4841
4842 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4843 alternative_service, kNetworkIsolationKey1));
4844 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4845 url::SchemeHostPort("https", request_.url.host(), 443),
4846 kNetworkIsolationKey1));
4847 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4848 alternative_service, kNetworkIsolationKey2));
4849 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4850 url::SchemeHostPort("https", request_.url.host(), 443),
4851 kNetworkIsolationKey2));
4852}
4853
bncc958faa2015-07-31 18:14:524854TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524855 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564856 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4857 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524858 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4859 MockRead(ASYNC, OK)};
4860
Ryan Sleevib8d7ea02018-05-07 20:01:014861 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524862 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564863 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524864
Ryan Hamiltonabad59e2019-06-06 04:02:594865 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234866 int packet_num = 1;
4867 if (VersionUsesQpack(version_.transport_version)) {
4868 mock_quic_data.AddWrite(SYNCHRONOUS,
4869 ConstructInitialSettingsPacket(packet_num++));
4870 }
rch5cb522462017-04-25 20:18:364871 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234872 SYNCHRONOUS,
4873 ConstructClientRequestHeadersPacket(
4874 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4875 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434876 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334877 ASYNC, ConstructServerResponseHeadersPacket(
4878 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4879 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434880 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334881 mock_quic_data.AddRead(
4882 ASYNC, ConstructServerDataPacket(
4883 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174884 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234885 mock_quic_data.AddWrite(SYNCHRONOUS,
4886 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524887 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4888
4889 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4890
4891 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324892 CreateSession();
bncc958faa2015-07-31 18:14:524893
4894 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4895 SendRequestAndExpectHttpResponse("hello world");
4896}
4897
tbansalc3308d72016-08-27 10:25:044898// Tests that the connection to an HTTPS proxy is raced with an available
4899// alternative proxy server.
4900TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274901 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594902 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494903 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044904
Ryan Hamiltonabad59e2019-06-06 04:02:594905 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234906 int packet_num = 1;
4907 if (VersionUsesQpack(version_.transport_version)) {
4908 mock_quic_data.AddWrite(SYNCHRONOUS,
4909 ConstructInitialSettingsPacket(packet_num++));
4910 }
rch5cb522462017-04-25 20:18:364911 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234912 SYNCHRONOUS,
4913 ConstructClientRequestHeadersPacket(
4914 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4915 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434916 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334917 ASYNC, ConstructServerResponseHeadersPacket(
4918 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4919 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434920 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334921 mock_quic_data.AddRead(
4922 ASYNC, ConstructServerDataPacket(
4923 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174924 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234925 mock_quic_data.AddWrite(SYNCHRONOUS,
4926 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044927 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4928 mock_quic_data.AddRead(ASYNC, 0); // EOF
4929
4930 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4931
4932 // There is no need to set up main job, because no attempt will be made to
4933 // speak to the proxy over TCP.
4934 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044935 TestProxyDelegate test_proxy_delegate;
4936 const HostPortPair host_port_pair("mail.example.org", 443);
4937
4938 test_proxy_delegate.set_alternative_proxy_server(
4939 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524940 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044941 CreateSession();
4942 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4943
4944 // The main job needs to hang in order to guarantee that the alternative
4945 // proxy server job will "win".
4946 AddHangingNonAlternateProtocolSocketData();
4947
4948 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4949
4950 // Verify that the alternative proxy server is not marked as broken.
4951 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4952
4953 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594954 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274955
4956 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4957 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4958 1);
tbansalc3308d72016-08-27 10:25:044959}
4960
bnc1c196c6e2016-05-28 13:51:484961TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304962 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274963 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304964
4965 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564966 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294967 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564968 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304969
4970 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564971 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484972 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564973 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304974
Ryan Sleevib8d7ea02018-05-07 20:01:014975 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504976 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084977 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504978 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304979
4980 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454981 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304982 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454983 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304984 };
Ryan Sleevib8d7ea02018-05-07 20:01:014985 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504986 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304987
4988 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014989 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504990 socket_factory_.AddSocketDataProvider(&http_data2);
4991 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304992
bnc912a04b2016-04-20 14:19:504993 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304994
4995 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304996 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174997 ASSERT_TRUE(http_data.AllReadDataConsumed());
4998 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304999
5000 // Now run the second request in which the QUIC socket hangs,
5001 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:305002 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:455003 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:305004
rch37de576c2015-05-17 20:28:175005 ASSERT_TRUE(http_data2.AllReadDataConsumed());
5006 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:455007 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305008}
5009
[email protected]1e960032013-12-20 19:00:205010TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:595011 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035012 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495013 int packet_num = 1;
5014 if (VersionUsesQpack(version_.transport_version)) {
5015 mock_quic_data.AddWrite(SYNCHRONOUS,
5016 ConstructInitialSettingsPacket(packet_num++));
5017 }
Zhongyi Shi32f2fd02018-04-16 18:23:435018 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495019 SYNCHRONOUS,
5020 ConstructClientRequestHeadersPacket(
5021 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5022 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435023 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335024 ASYNC, ConstructServerResponseHeadersPacket(
5025 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5026 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435027 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335028 mock_quic_data.AddRead(
5029 ASYNC, ConstructServerDataPacket(
5030 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175031 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495032 mock_quic_data.AddWrite(SYNCHRONOUS,
5033 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505034 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595035 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:485036
rcha5399e02015-04-21 19:32:045037 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:485038
rtennetib8e80fb2016-05-16 00:12:095039 // The non-alternate protocol job needs to hang in order to guarantee that
5040 // the alternate-protocol job will "win".
5041 AddHangingNonAlternateProtocolSocketData();
5042
rch3f4b8452016-02-23 16:59:325043 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275044 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:195045 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:305046
Matt Menke19475f72019-08-21 18:57:445047 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5048 url::SchemeHostPort("https", request_.url.host(), 443),
5049 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:485050}
5051
[email protected]1e960032013-12-20 19:00:205052TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:595053 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035054 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495055 int packet_number = 1;
5056 if (VersionUsesQpack(version_.transport_version)) {
5057 mock_quic_data.AddWrite(
5058 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5059 }
Fan Yang32c5a112018-12-10 20:06:335060 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495061 SYNCHRONOUS,
5062 ConstructClientRequestHeadersPacket(
5063 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5064 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435065 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335066 ASYNC, ConstructServerResponseHeadersPacket(
5067 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5068 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435069 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335070 mock_quic_data.AddRead(
5071 ASYNC, ConstructServerDataPacket(
5072 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175073 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495074 mock_quic_data.AddWrite(SYNCHRONOUS,
5075 ConstructClientAckPacket(packet_number++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505076 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595077 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:045078 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275079
5080 // In order for a new QUIC session to be established via alternate-protocol
5081 // without racing an HTTP connection, we need the host resolution to happen
5082 // synchronously.
5083 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295084 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565085 "");
[email protected]3a120a6b2013-06-25 01:08:275086
rtennetib8e80fb2016-05-16 00:12:095087 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325088 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275089 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:275090 SendRequestAndExpectQuicResponse("hello!");
5091}
5092
[email protected]0fc924b2014-03-31 04:34:155093TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:495094 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5095 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155096
5097 // Since we are using a proxy, the QUIC job will not succeed.
5098 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295099 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5100 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565101 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155102
5103 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565104 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485105 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565106 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155107
Ryan Sleevib8d7ea02018-05-07 20:01:015108 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155109 socket_factory_.AddSocketDataProvider(&http_data);
5110
5111 // In order for a new QUIC session to be established via alternate-protocol
5112 // without racing an HTTP connection, we need the host resolution to happen
5113 // synchronously.
5114 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295115 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565116 "");
[email protected]0fc924b2014-03-31 04:34:155117
rch9ae5b3b2016-02-11 00:36:295118 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325119 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275120 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155121 SendRequestAndExpectHttpResponse("hello world");
5122}
5123
[email protected]1e960032013-12-20 19:00:205124TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:595125 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235126 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495127 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjie Tangaadb84b2019-08-31 01:00:235128 if (VersionUsesQpack(version_.transport_version)) {
5129 mock_quic_data.AddWrite(SYNCHRONOUS,
5130 ConstructInitialSettingsPacket(packet_num++));
5131 }
Nick Harper057264a82019-09-12 23:33:495132 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365133 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235134 SYNCHRONOUS,
5135 ConstructClientRequestHeadersPacket(
5136 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5137 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435138 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335139 ASYNC, ConstructServerResponseHeadersPacket(
5140 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5141 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435142 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335143 mock_quic_data.AddRead(
5144 ASYNC, ConstructServerDataPacket(
5145 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175146 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235147 mock_quic_data.AddWrite(SYNCHRONOUS,
5148 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595149 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045150 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125151
rtennetib8e80fb2016-05-16 00:12:095152 // The non-alternate protocol job needs to hang in order to guarantee that
5153 // the alternate-protocol job will "win".
5154 AddHangingNonAlternateProtocolSocketData();
5155
[email protected]11c05872013-08-20 02:04:125156 // In order for a new QUIC session to be established via alternate-protocol
5157 // without racing an HTTP connection, we need the host resolution to happen
5158 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5159 // connection to the the server, in this test we require confirmation
5160 // before encrypting so the HTTP job will still start.
5161 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295162 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565163 "");
[email protected]11c05872013-08-20 02:04:125164
rch3f4b8452016-02-23 16:59:325165 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435166 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5167 false);
Ryan Hamilton9835e662018-08-02 05:36:275168 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125169
bnc691fda62016-08-12 00:43:165170 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125171 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365172 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015173 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125174
5175 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525176 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015177 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505178
bnc691fda62016-08-12 00:43:165179 CheckWasQuicResponse(&trans);
5180 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125181}
5182
Steven Valdez58097ec32018-07-16 18:29:045183TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015184 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595185 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035186 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495187 if (VersionUsesQpack(version_.transport_version)) {
5188 mock_quic_data.AddWrite(
5189 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5190 }
Steven Valdez58097ec32018-07-16 18:29:045191 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015192 SYNCHRONOUS,
5193 ConstructClientRequestHeadersPacket(
5194 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5195 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335196 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025197 ASYNC, ConstructServerResponseHeadersPacket(
5198 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5199 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015200 mock_quic_data.AddWrite(
5201 SYNCHRONOUS,
5202 ConstructClientAckAndRstPacket(
5203 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5204 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045205
5206 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5207
Steven Valdez58097ec32018-07-16 18:29:045208 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015209 SYNCHRONOUS,
5210 ConstructClientRequestHeadersPacket(
5211 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5212 true, GetRequestHeaders("GET", "https", "/"),
5213 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045214 mock_quic_data.AddRead(
5215 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335216 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025217 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435218 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045219 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335220 ASYNC, ConstructServerDataPacket(
5221 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175222 header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045223 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015224 SYNCHRONOUS,
5225 ConstructClientAckAndConnectionClosePacket(packet_number++, 3, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045226 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5227 mock_quic_data.AddRead(ASYNC, 0); // EOF
5228
5229 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5230
5231 // In order for a new QUIC session to be established via alternate-protocol
5232 // without racing an HTTP connection, we need the host resolution to happen
5233 // synchronously.
5234 host_resolver_.set_synchronous_mode(true);
5235 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5236 "");
Steven Valdez58097ec32018-07-16 18:29:045237
5238 AddHangingNonAlternateProtocolSocketData();
5239 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275240 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565241 QuicStreamFactoryPeer::SetAlarmFactory(
5242 session_->quic_stream_factory(),
5243 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5244 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045245
5246 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5247 TestCompletionCallback callback;
5248 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5250
5251 // Confirm the handshake after the 425 Too Early.
5252 base::RunLoop().RunUntilIdle();
5253
5254 // The handshake hasn't been confirmed yet, so the retry should not have
5255 // succeeded.
5256 EXPECT_FALSE(callback.have_result());
5257
5258 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5259 quic::QuicSession::HANDSHAKE_CONFIRMED);
5260
5261 EXPECT_THAT(callback.WaitForResult(), IsOk());
5262 CheckWasQuicResponse(&trans);
5263 CheckResponseData(&trans, "hello!");
5264}
5265
5266TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:015267 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595268 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035269 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495270 if (VersionUsesQpack(version_.transport_version)) {
5271 mock_quic_data.AddWrite(
5272 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5273 }
Steven Valdez58097ec32018-07-16 18:29:045274 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015275 SYNCHRONOUS,
5276 ConstructClientRequestHeadersPacket(
5277 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5278 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335279 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025280 ASYNC, ConstructServerResponseHeadersPacket(
5281 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5282 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015283 mock_quic_data.AddWrite(
5284 SYNCHRONOUS,
5285 ConstructClientAckAndRstPacket(
5286 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5287 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045288
5289 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5290
Steven Valdez58097ec32018-07-16 18:29:045291 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015292 SYNCHRONOUS,
5293 ConstructClientRequestHeadersPacket(
5294 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5295 true, GetRequestHeaders("GET", "https", "/"),
5296 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335297 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025298 ASYNC, ConstructServerResponseHeadersPacket(
5299 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5300 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015301 mock_quic_data.AddWrite(
5302 SYNCHRONOUS,
5303 ConstructClientAckAndRstPacket(
5304 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
5305 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045306 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5307 mock_quic_data.AddRead(ASYNC, 0); // EOF
5308
5309 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5310
5311 // In order for a new QUIC session to be established via alternate-protocol
5312 // without racing an HTTP connection, we need the host resolution to happen
5313 // synchronously.
5314 host_resolver_.set_synchronous_mode(true);
5315 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5316 "");
Steven Valdez58097ec32018-07-16 18:29:045317
5318 AddHangingNonAlternateProtocolSocketData();
5319 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275320 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565321 QuicStreamFactoryPeer::SetAlarmFactory(
5322 session_->quic_stream_factory(),
5323 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5324 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045325
5326 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5327 TestCompletionCallback callback;
5328 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5330
5331 // Confirm the handshake after the 425 Too Early.
5332 base::RunLoop().RunUntilIdle();
5333
5334 // The handshake hasn't been confirmed yet, so the retry should not have
5335 // succeeded.
5336 EXPECT_FALSE(callback.have_result());
5337
5338 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5339 quic::QuicSession::HANDSHAKE_CONFIRMED);
5340
5341 EXPECT_THAT(callback.WaitForResult(), IsOk());
5342 const HttpResponseInfo* response = trans.GetResponseInfo();
5343 ASSERT_TRUE(response != nullptr);
5344 ASSERT_TRUE(response->headers.get() != nullptr);
5345 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5346 EXPECT_TRUE(response->was_fetched_via_spdy);
5347 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565348 EXPECT_EQ(
5349 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5350 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045351}
5352
zhongyica364fbb2015-12-12 03:39:125353TEST_P(QuicNetworkTransactionTest,
5354 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Nick Harper72ade192019-07-17 03:30:425355 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595356 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235357 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495358 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjie Tangaadb84b2019-08-31 01:00:235359 if (VersionUsesQpack(version_.transport_version)) {
5360 mock_quic_data.AddWrite(SYNCHRONOUS,
5361 ConstructInitialSettingsPacket(packet_num++));
5362 }
Nick Harper057264a82019-09-12 23:33:495363 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365364 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235365 SYNCHRONOUS,
5366 ConstructClientRequestHeadersPacket(
5367 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5368 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125369 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525370 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435371 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125372 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5373
5374 // The non-alternate protocol job needs to hang in order to guarantee that
5375 // the alternate-protocol job will "win".
5376 AddHangingNonAlternateProtocolSocketData();
5377
5378 // In order for a new QUIC session to be established via alternate-protocol
5379 // without racing an HTTP connection, we need the host resolution to happen
5380 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5381 // connection to the the server, in this test we require confirmation
5382 // before encrypting so the HTTP job will still start.
5383 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295384 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125385 "");
zhongyica364fbb2015-12-12 03:39:125386
rch3f4b8452016-02-23 16:59:325387 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435388 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5389 false);
Ryan Hamilton9835e662018-08-02 05:36:275390 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125391
bnc691fda62016-08-12 00:43:165392 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125393 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365394 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015395 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125396
5397 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525398 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015399 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125400
5401 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525402 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125403
bnc691fda62016-08-12 00:43:165404 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125405 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525406 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5407 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125408}
5409
5410TEST_P(QuicNetworkTransactionTest,
5411 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Nick Harper72ade192019-07-17 03:30:425412 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595413 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235414 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495415 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjie Tangaadb84b2019-08-31 01:00:235416 if (VersionUsesQpack(version_.transport_version)) {
5417 mock_quic_data.AddWrite(SYNCHRONOUS,
5418 ConstructInitialSettingsPacket(packet_num++));
5419 }
Nick Harper057264a82019-09-12 23:33:495420 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365421 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235422 SYNCHRONOUS,
5423 ConstructClientRequestHeadersPacket(
5424 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5425 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215426 // Peer sending data from an non-existing stream causes this end to raise
5427 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335428 mock_quic_data.AddRead(
5429 ASYNC, ConstructServerRstPacket(
5430 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5431 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215432 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tangaadb84b2019-08-31 01:00:235433 mock_quic_data.AddWrite(
5434 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5435 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5436 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
5437 quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125438 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5439
5440 // The non-alternate protocol job needs to hang in order to guarantee that
5441 // the alternate-protocol job will "win".
5442 AddHangingNonAlternateProtocolSocketData();
5443
5444 // In order for a new QUIC session to be established via alternate-protocol
5445 // without racing an HTTP connection, we need the host resolution to happen
5446 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5447 // connection to the the server, in this test we require confirmation
5448 // before encrypting so the HTTP job will still start.
5449 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295450 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125451 "");
zhongyica364fbb2015-12-12 03:39:125452
rch3f4b8452016-02-23 16:59:325453 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435454 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5455 false);
Ryan Hamilton9835e662018-08-02 05:36:275456 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125457
bnc691fda62016-08-12 00:43:165458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125459 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365460 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015461 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125462
5463 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525464 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015465 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125466 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525467 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125468
bnc691fda62016-08-12 00:43:165469 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525470 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125471}
5472
Nick Harper057264a82019-09-12 23:33:495473TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:595474 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235475 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495476 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjie Tangaadb84b2019-08-31 01:00:235477 if (VersionUsesQpack(version_.transport_version)) {
5478 mock_quic_data.AddWrite(SYNCHRONOUS,
5479 ConstructInitialSettingsPacket(packet_num++));
5480 }
Nick Harper057264a82019-09-12 23:33:495481 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365482 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235483 SYNCHRONOUS,
5484 ConstructClientRequestHeadersPacket(
5485 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5486 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485487 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335488 mock_quic_data.AddRead(
5489 ASYNC, ConstructServerResponseHeadersPacket(
5490 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5491 GetResponseHeaders("200 OK")));
5492 mock_quic_data.AddRead(
5493 ASYNC, ConstructServerRstPacket(
5494 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5495 quic::QUIC_STREAM_CANCELLED));
Renjie Tangaadb84b2019-08-31 01:00:235496 mock_quic_data.AddWrite(SYNCHRONOUS,
5497 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485498 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5499 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5500
5501 // The non-alternate protocol job needs to hang in order to guarantee that
5502 // the alternate-protocol job will "win".
5503 AddHangingNonAlternateProtocolSocketData();
5504
5505 // In order for a new QUIC session to be established via alternate-protocol
5506 // without racing an HTTP connection, we need the host resolution to happen
5507 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5508 // connection to the the server, in this test we require confirmation
5509 // before encrypting so the HTTP job will still start.
5510 host_resolver_.set_synchronous_mode(true);
5511 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5512 "");
rchcd5f1c62016-06-23 02:43:485513
5514 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435515 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5516 false);
Ryan Hamilton9835e662018-08-02 05:36:275517 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485518
bnc691fda62016-08-12 00:43:165519 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485520 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365521 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015522 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485523
5524 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525525 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485526 // Read the headers.
robpercival214763f2016-07-01 23:27:015527 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485528
bnc691fda62016-08-12 00:43:165529 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485530 ASSERT_TRUE(response != nullptr);
5531 ASSERT_TRUE(response->headers.get() != nullptr);
5532 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5533 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525534 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565535 EXPECT_EQ(
5536 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5537 response->connection_info);
rchcd5f1c62016-06-23 02:43:485538
5539 std::string response_data;
bnc691fda62016-08-12 00:43:165540 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485541}
5542
Nick Harper057264a82019-09-12 23:33:495543TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Nick Harper72ade192019-07-17 03:30:425544 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595545 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235546 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495547 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjie Tangaadb84b2019-08-31 01:00:235548 if (VersionUsesQpack(version_.transport_version)) {
5549 mock_quic_data.AddWrite(SYNCHRONOUS,
5550 ConstructInitialSettingsPacket(packet_num++));
5551 }
Nick Harper057264a82019-09-12 23:33:495552 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365553 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235554 SYNCHRONOUS,
5555 ConstructClientRequestHeadersPacket(
5556 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5557 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335558 mock_quic_data.AddRead(
5559 ASYNC, ConstructServerRstPacket(
5560 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5561 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485562 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5563 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5564
5565 // The non-alternate protocol job needs to hang in order to guarantee that
5566 // the alternate-protocol job will "win".
5567 AddHangingNonAlternateProtocolSocketData();
5568
5569 // In order for a new QUIC session to be established via alternate-protocol
5570 // without racing an HTTP connection, we need the host resolution to happen
5571 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5572 // connection to the the server, in this test we require confirmation
5573 // before encrypting so the HTTP job will still start.
5574 host_resolver_.set_synchronous_mode(true);
5575 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5576 "");
rchcd5f1c62016-06-23 02:43:485577
5578 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435579 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5580 false);
Ryan Hamilton9835e662018-08-02 05:36:275581 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485582
bnc691fda62016-08-12 00:43:165583 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485584 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365585 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015586 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485587
5588 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525589 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485590 // Read the headers.
robpercival214763f2016-07-01 23:27:015591 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485592}
5593
[email protected]1e960032013-12-20 19:00:205594TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305595 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525596 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585597 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305598 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505599 MockRead(ASYNC, close->data(), close->length()),
5600 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5601 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305602 };
Ryan Sleevib8d7ea02018-05-07 20:01:015603 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305604 socket_factory_.AddSocketDataProvider(&quic_data);
5605
5606 // Main job which will succeed even though the alternate job fails.
5607 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025608 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5609 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5610 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305611
Ryan Sleevib8d7ea02018-05-07 20:01:015612 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305613 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565614 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305615
rch3f4b8452016-02-23 16:59:325616 CreateSession();
David Schinazic8281052019-01-24 06:14:175617 AddQuicAlternateProtocolMapping(
5618 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195619 SendRequestAndExpectHttpResponse("hello from http");
5620 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305621}
5622
Matt Menkeb32ba5122019-09-10 19:17:055623TEST_P(QuicNetworkTransactionTest,
5624 BrokenAlternateProtocolWithNetworkIsolationKey) {
5625 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5626 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5627 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5628 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5629
5630 base::test::ScopedFeatureList feature_list;
5631 feature_list.InitWithFeatures(
5632 // enabled_features
5633 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5634 features::kPartitionConnectionsByNetworkIsolationKey},
5635 // disabled_features
5636 {});
5637 // Since HttpServerProperties caches the feature value, have to create a new
5638 // one.
5639 http_server_properties_ = std::make_unique<HttpServerProperties>();
5640
5641 // Alternate-protocol job
5642 std::unique_ptr<quic::QuicEncryptedPacket> close(
5643 ConstructServerConnectionClosePacket(1));
5644 MockRead quic_reads[] = {
5645 MockRead(ASYNC, close->data(), close->length()),
5646 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5647 MockRead(ASYNC, OK), // EOF
5648 };
5649 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5650 socket_factory_.AddSocketDataProvider(&quic_data);
5651
5652 // Main job which will succeed even though the alternate job fails.
5653 MockRead http_reads[] = {
5654 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5655 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5656 MockRead(ASYNC, OK)};
5657
5658 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5659 socket_factory_.AddSocketDataProvider(&http_data);
5660 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5661
5662 CreateSession();
5663 AddQuicAlternateProtocolMapping(
5664 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5665 AddQuicAlternateProtocolMapping(
5666 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5667 request_.network_isolation_key = kNetworkIsolationKey1;
5668 SendRequestAndExpectHttpResponse("hello from http");
5669
5670 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5671 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5672}
5673
[email protected]1e960032013-12-20 19:00:205674TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595675 // Alternate-protocol job
5676 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025677 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595678 };
Ryan Sleevib8d7ea02018-05-07 20:01:015679 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595680 socket_factory_.AddSocketDataProvider(&quic_data);
5681
5682 // Main job which will succeed even though the alternate job fails.
5683 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025684 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5685 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5686 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595687
Ryan Sleevib8d7ea02018-05-07 20:01:015688 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595689 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565690 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595691
rch3f4b8452016-02-23 16:59:325692 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595693
Ryan Hamilton9835e662018-08-02 05:36:275694 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195695 SendRequestAndExpectHttpResponse("hello from http");
5696 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595697}
5698
[email protected]00c159f2014-05-21 22:38:165699TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535700 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165701 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025702 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165703 };
Ryan Sleevib8d7ea02018-05-07 20:01:015704 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165705 socket_factory_.AddSocketDataProvider(&quic_data);
5706
[email protected]eb71ab62014-05-23 07:57:535707 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165708 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025709 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165710 };
5711
Ryan Sleevib8d7ea02018-05-07 20:01:015712 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165713 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5714 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565715 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165716
rtennetib8e80fb2016-05-16 00:12:095717 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325718 CreateSession();
[email protected]00c159f2014-05-21 22:38:165719
Ryan Hamilton9835e662018-08-02 05:36:275720 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165721 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165722 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165723 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015724 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5725 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165726 ExpectQuicAlternateProtocolMapping();
5727}
5728
Zhongyi Shia0cef1082017-08-25 01:49:505729TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5730 // Tests that TCP job is delayed and QUIC job does not require confirmation
5731 // if QUIC was recently supported on the same IP on start.
5732
5733 // Set QUIC support on the last IP address, which is same with the local IP
5734 // address. Require confirmation mode will be turned off immediately when
5735 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435736 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5737 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:505738
Ryan Hamiltonabad59e2019-06-06 04:02:595739 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035740 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495741 int packet_number = 1;
5742 if (VersionUsesQpack(version_.transport_version)) {
5743 mock_quic_data.AddWrite(SYNCHRONOUS,
5744 ConstructInitialSettingsPacket(packet_number++));
5745 }
Zhongyi Shi32f2fd02018-04-16 18:23:435746 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495747 SYNCHRONOUS,
5748 ConstructClientRequestHeadersPacket(
5749 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5750 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435751 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335752 ASYNC, ConstructServerResponseHeadersPacket(
5753 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5754 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435755 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335756 mock_quic_data.AddRead(
5757 ASYNC, ConstructServerDataPacket(
5758 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175759 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495760 mock_quic_data.AddWrite(SYNCHRONOUS,
5761 ConstructClientAckPacket(packet_number++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505762 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5763 mock_quic_data.AddRead(ASYNC, 0); // EOF
5764
5765 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5766 // No HTTP data is mocked as TCP job never starts in this case.
5767
5768 CreateSession();
5769 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:435770 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5771 false);
Zhongyi Shia0cef1082017-08-25 01:49:505772
Ryan Hamilton9835e662018-08-02 05:36:275773 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505774
5775 // Stall host resolution so that QUIC job will not succeed synchronously.
5776 // Socket will not be configured immediately and QUIC support is not sorted
5777 // out, TCP job will still be delayed as server properties indicates QUIC
5778 // support on last IP address.
5779 host_resolver_.set_synchronous_mode(false);
5780
5781 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5782 TestCompletionCallback callback;
5783 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5784 IsError(ERR_IO_PENDING));
5785 // Complete host resolution in next message loop so that QUIC job could
5786 // proceed.
5787 base::RunLoop().RunUntilIdle();
5788 EXPECT_THAT(callback.WaitForResult(), IsOk());
5789
5790 CheckWasQuicResponse(&trans);
5791 CheckResponseData(&trans, "hello!");
5792}
5793
5794TEST_P(QuicNetworkTransactionTest,
5795 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5796 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5797 // was recently supported on a different IP address on start.
5798
5799 // Set QUIC support on the last IP address, which is different with the local
5800 // IP address. Require confirmation mode will remain when local IP address is
5801 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435802 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5803 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:505804
Ryan Hamiltonabad59e2019-06-06 04:02:595805 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235806 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495807 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjie Tangaadb84b2019-08-31 01:00:235808 if (VersionUsesQpack(version_.transport_version)) {
5809 mock_quic_data.AddWrite(SYNCHRONOUS,
5810 ConstructInitialSettingsPacket(packet_num++));
5811 }
Nick Harper057264a82019-09-12 23:33:495812 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:505813 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235814 SYNCHRONOUS,
5815 ConstructClientRequestHeadersPacket(
5816 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5817 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435818 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335819 ASYNC, ConstructServerResponseHeadersPacket(
5820 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5821 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435822 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335823 mock_quic_data.AddRead(
5824 ASYNC, ConstructServerDataPacket(
5825 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175826 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235827 mock_quic_data.AddWrite(SYNCHRONOUS,
5828 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505829 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5830 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5831 // No HTTP data is mocked as TCP job will be delayed and never starts.
5832
5833 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435834 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5835 false);
Ryan Hamilton9835e662018-08-02 05:36:275836 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505837
5838 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5839 // Socket will not be configured immediately and QUIC support is not sorted
5840 // out, TCP job will still be delayed as server properties indicates QUIC
5841 // support on last IP address.
5842 host_resolver_.set_synchronous_mode(false);
5843
5844 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5845 TestCompletionCallback callback;
5846 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5847 IsError(ERR_IO_PENDING));
5848
5849 // Complete host resolution in next message loop so that QUIC job could
5850 // proceed.
5851 base::RunLoop().RunUntilIdle();
5852 // Explicitly confirm the handshake so that QUIC job could succeed.
5853 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525854 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505855 EXPECT_THAT(callback.WaitForResult(), IsOk());
5856
5857 CheckWasQuicResponse(&trans);
5858 CheckResponseData(&trans, "hello!");
5859}
5860
Ryan Hamilton75f197262017-08-17 14:00:075861TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5862 // Test that NetErrorDetails is correctly populated, even if the
5863 // handshake has not yet been confirmed and no stream has been created.
5864
5865 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595866 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075867 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5868 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5869 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5870
5871 // Main job will also fail.
5872 MockRead http_reads[] = {
5873 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5874 };
5875
Ryan Sleevib8d7ea02018-05-07 20:01:015876 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075877 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5878 socket_factory_.AddSocketDataProvider(&http_data);
5879 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5880
5881 AddHangingNonAlternateProtocolSocketData();
5882 CreateSession();
5883 // Require handshake confirmation to ensure that no QUIC streams are
5884 // created, and to ensure that the TCP job does not wait for the QUIC
5885 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:435886 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5887 false);
Ryan Hamilton75f197262017-08-17 14:00:075888
Ryan Hamilton9835e662018-08-02 05:36:275889 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075890 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5891 TestCompletionCallback callback;
5892 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5894 // Allow the TCP job to fail.
5895 base::RunLoop().RunUntilIdle();
5896 // Now let the QUIC job fail.
5897 mock_quic_data.Resume();
5898 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5899 ExpectQuicAlternateProtocolMapping();
5900 NetErrorDetails details;
5901 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525902 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075903}
5904
[email protected]1e960032013-12-20 19:00:205905TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455906 // Alternate-protocol job
5907 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025908 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455909 };
Ryan Sleevib8d7ea02018-05-07 20:01:015910 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455911 socket_factory_.AddSocketDataProvider(&quic_data);
5912
[email protected]c92c1b52014-05-31 04:16:065913 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015914 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065915 socket_factory_.AddSocketDataProvider(&quic_data2);
5916
[email protected]4d283b32013-10-17 12:57:275917 // Final job that will proceed when the QUIC job fails.
5918 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025919 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5920 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5921 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275922
Ryan Sleevib8d7ea02018-05-07 20:01:015923 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275924 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565925 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275926
rch3f4b8452016-02-23 16:59:325927 CreateSession();
[email protected]77c6c162013-08-17 02:57:455928
Ryan Hamilton9835e662018-08-02 05:36:275929 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455930
[email protected]4d283b32013-10-17 12:57:275931 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455932
5933 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275934
rch37de576c2015-05-17 20:28:175935 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5936 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455937}
5938
Matt Menkeb32ba5122019-09-10 19:17:055939TEST_P(QuicNetworkTransactionTest,
5940 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
5941 base::test::ScopedFeatureList feature_list;
5942 feature_list.InitWithFeatures(
5943 // enabled_features
5944 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5945 features::kPartitionConnectionsByNetworkIsolationKey},
5946 // disabled_features
5947 {});
5948 // Since HttpServerProperties caches the feature value, have to create a new
5949 // one.
5950 http_server_properties_ = std::make_unique<HttpServerProperties>();
5951
5952 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5953 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5954 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5955 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5956
5957 // Alternate-protocol job
5958 MockRead quic_reads[] = {
5959 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5960 };
5961 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5962 socket_factory_.AddSocketDataProvider(&quic_data);
5963
5964 // Second Alternate-protocol job which will race with the TCP job.
5965 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
5966 socket_factory_.AddSocketDataProvider(&quic_data2);
5967
5968 // Final job that will proceed when the QUIC job fails.
5969 MockRead http_reads[] = {
5970 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5971 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5972 MockRead(ASYNC, OK)};
5973
5974 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5975 socket_factory_.AddSocketDataProvider(&http_data);
5976 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5977
5978 CreateSession();
5979
5980 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
5981 kNetworkIsolationKey1);
5982 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
5983 kNetworkIsolationKey2);
5984
5985 request_.network_isolation_key = kNetworkIsolationKey1;
5986 SendRequestAndExpectHttpResponse("hello from http");
5987 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5988 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
5989
5990 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5991 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5992
5993 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
5994 AddHttpDataAndRunRequest();
5995 // Requests using other NetworkIsolationKeys can still use QUIC.
5996 request_.network_isolation_key = kNetworkIsolationKey2;
5997 AddQuicDataAndRunRequest();
5998
5999 // The last two requests should not have changed the alternative service
6000 // mappings.
6001 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6002 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6003}
6004
[email protected]93b31772014-06-19 08:03:356005TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:036006 // Alternate-protocol job
6007 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:596008 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:036009 };
Ryan Sleevib8d7ea02018-05-07 20:01:016010 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036011 socket_factory_.AddSocketDataProvider(&quic_data);
6012
6013 // Main job that will proceed when the QUIC job fails.
6014 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026015 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6016 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6017 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:036018
Ryan Sleevib8d7ea02018-05-07 20:01:016019 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036020 socket_factory_.AddSocketDataProvider(&http_data);
6021
rtennetib8e80fb2016-05-16 00:12:096022 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326023 CreateSession();
[email protected]65768442014-06-06 23:37:036024
Ryan Hamilton9835e662018-08-02 05:36:276025 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:036026
6027 SendRequestAndExpectHttpResponse("hello from http");
6028}
6029
[email protected]eb71ab62014-05-23 07:57:536030TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:336031 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:016032 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:496033 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:336034 socket_factory_.AddSocketDataProvider(&quic_data);
6035
6036 // Main job which will succeed even though the alternate job fails.
6037 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026038 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6039 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6040 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:336041
Ryan Sleevib8d7ea02018-05-07 20:01:016042 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:336043 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566044 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:336045
rch3f4b8452016-02-23 16:59:326046 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276047 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:336048 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:536049
6050 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:336051}
6052
[email protected]4fee9672014-01-08 14:47:156053TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltonabad59e2019-06-06 04:02:596054 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:176055 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
6056 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:046057 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:156058
6059 // When the QUIC connection fails, we will try the request again over HTTP.
6060 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:486061 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:566062 MockRead("hello world"),
6063 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6064 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:156065
Ryan Sleevib8d7ea02018-05-07 20:01:016066 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:156067 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566068 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:156069
6070 // In order for a new QUIC session to be established via alternate-protocol
6071 // without racing an HTTP connection, we need the host resolution to happen
6072 // synchronously.
6073 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:296074 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:566075 "");
[email protected]4fee9672014-01-08 14:47:156076
rch3f4b8452016-02-23 16:59:326077 CreateSession();
David Schinazic8281052019-01-24 06:14:176078 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
6079 AddQuicAlternateProtocolMapping(
6080 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:156081 SendRequestAndExpectHttpResponse("hello world");
6082}
6083
tbansalc3308d72016-08-27 10:25:046084// For an alternative proxy that supports QUIC, test that the request is
6085// successfully fetched by the main job when the alternate proxy job encounters
6086// an error.
6087TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
6088 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
6089}
6090TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
6091 TestAlternativeProxy(ERR_CONNECTION_FAILED);
6092}
6093TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
6094 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
6095}
6096TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
6097 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
6098}
6099TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
6100 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
6101}
6102TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
6103 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
6104}
6105TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
6106 TestAlternativeProxy(ERR_IO_PENDING);
6107}
6108TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
6109 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
6110}
6111
6112TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltonabad59e2019-06-06 04:02:596113 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:176114 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
6115 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:336116 mock_quic_data.AddWrite(
6117 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6118 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
6119 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436120 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:046121 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6122
6123 // When the QUIC connection fails, we will try the request again over HTTP.
6124 MockRead http_reads[] = {
6125 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6126 MockRead("hello world"),
6127 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6128 MockRead(ASYNC, OK)};
6129
Ryan Sleevib8d7ea02018-05-07 20:01:016130 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:046131 socket_factory_.AddSocketDataProvider(&http_data);
6132 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6133
6134 TestProxyDelegate test_proxy_delegate;
6135 const HostPortPair host_port_pair("myproxy.org", 443);
6136 test_proxy_delegate.set_alternative_proxy_server(
6137 ProxyServer::FromPacString("QUIC myproxy.org:443"));
6138 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6139
Ramin Halavatica8d5252018-03-12 05:33:496140 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
6141 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526142 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046143 request_.url = GURL("http://mail.example.org/");
6144
6145 // In order for a new QUIC session to be established via alternate-protocol
6146 // without racing an HTTP connection, we need the host resolution to happen
6147 // synchronously.
6148 host_resolver_.set_synchronous_mode(true);
6149 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:046150
6151 CreateSession();
David Schinazic8281052019-01-24 06:14:176152 crypto_client_stream_factory_.set_handshake_mode(
6153 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:046154 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596155 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166156 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046157}
6158
bnc508835902015-05-12 20:10:296159TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:586160 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386161 EXPECT_FALSE(
6162 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:596163 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236164 int packet_num = 1;
6165 if (VersionUsesQpack(version_.transport_version)) {
6166 mock_quic_data.AddWrite(SYNCHRONOUS,
6167 ConstructInitialSettingsPacket(packet_num++));
6168 }
rch5cb522462017-04-25 20:18:366169 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236170 SYNCHRONOUS,
6171 ConstructClientRequestHeadersPacket(
6172 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6173 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436174 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336175 ASYNC, ConstructServerResponseHeadersPacket(
6176 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6177 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436178 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336179 mock_quic_data.AddRead(
6180 ASYNC, ConstructServerDataPacket(
6181 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176182 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236183 mock_quic_data.AddWrite(SYNCHRONOUS,
6184 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:506185 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296186 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6187
bncb07c05532015-05-14 19:07:206188 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096189 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326190 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276191 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296192 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386193 EXPECT_TRUE(
6194 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296195}
6196
zhongyi363c91c2017-03-23 23:16:086197// TODO(zhongyi): disabled this broken test as it was not testing the correct
6198// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
6199TEST_P(QuicNetworkTransactionTest,
6200 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:276201 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:596202 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496203 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:046204
6205 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:046206
6207 test_proxy_delegate.set_alternative_proxy_server(
6208 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:526209 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046210
6211 request_.url = GURL("http://mail.example.org/");
6212
6213 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6214 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016215 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:046216 socket_factory_.AddSocketDataProvider(&socket_data);
6217
6218 // The non-alternate protocol job needs to hang in order to guarantee that
6219 // the alternate-protocol job will "win".
6220 AddHangingNonAlternateProtocolSocketData();
6221
6222 CreateSession();
6223 request_.method = "POST";
6224 ChunkedUploadDataStream upload_data(0);
6225 upload_data.AppendData("1", 1, true);
6226
6227 request_.upload_data_stream = &upload_data;
6228
6229 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6230 TestCompletionCallback callback;
6231 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6232 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6233 EXPECT_NE(OK, callback.WaitForResult());
6234
6235 // Verify that the alternative proxy server is not marked as broken.
6236 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6237
6238 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596239 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276240
6241 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6242 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6243 1);
tbansalc3308d72016-08-27 10:25:046244}
6245
rtenneti56977812016-01-15 19:26:566246TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Nick Harper72ade192019-07-17 03:30:426247 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576248 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566249
Renjie Tangaadb84b2019-08-31 01:00:236250 MockQuicData mock_quic_data(version_);
6251 if (!VersionUsesQpack(version_.transport_version))
6252 mock_quic_data.AddRead(SYNCHRONOUS, OK);
6253 else
6254 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6255 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6256 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6257
6258 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6259 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
6260 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:016261 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:236262 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:566263
rtennetib8e80fb2016-05-16 00:12:096264 // The non-alternate protocol job needs to hang in order to guarantee that
6265 // the alternate-protocol job will "win".
6266 AddHangingNonAlternateProtocolSocketData();
6267
rtenneti56977812016-01-15 19:26:566268 CreateSession();
6269 request_.method = "POST";
6270 ChunkedUploadDataStream upload_data(0);
6271 upload_data.AppendData("1", 1, true);
6272
6273 request_.upload_data_stream = &upload_data;
6274
bnc691fda62016-08-12 00:43:166275 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566276 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166277 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016278 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566279 EXPECT_NE(OK, callback.WaitForResult());
6280}
6281
rche11300ef2016-09-02 01:44:286282TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Nick Harper72ade192019-07-17 03:30:426283 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286284 ScopedMockNetworkChangeNotifier network_change_notifier;
6285 MockNetworkChangeNotifier* mock_ncn =
6286 network_change_notifier.mock_network_change_notifier();
6287 mock_ncn->ForceNetworkHandlesSupported();
6288 mock_ncn->SetConnectedNetworksList(
6289 {kDefaultNetworkForTests, kNewNetworkForTests});
6290
Nick Harper72ade192019-07-17 03:30:426291 session_params_.quic_params.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286292 HostPortPair::FromString("mail.example.org:443"));
Nick Harper72ade192019-07-17 03:30:426293 session_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286294
Ryan Hamiltonabad59e2019-06-06 04:02:596295 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286296 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236297 int packet_num = 1;
6298 if (VersionUsesQpack(version_.transport_version)) {
6299 socket_data.AddWrite(SYNCHRONOUS,
6300 ConstructInitialSettingsPacket(packet_num++));
6301 }
Fan Yang32c5a112018-12-10 20:06:336302 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236303 SYNCHRONOUS,
6304 ConstructClientRequestHeadersPacket(
6305 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6306 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:286307 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6308 socket_data.AddSocketDataToFactory(&socket_factory_);
6309
Ryan Hamiltonabad59e2019-06-06 04:02:596310 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286311 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6312 socket_data2.AddSocketDataToFactory(&socket_factory_);
6313
6314 // The non-alternate protocol job needs to hang in order to guarantee that
6315 // the alternate-protocol job will "win".
6316 AddHangingNonAlternateProtocolSocketData();
6317
6318 CreateSession();
6319 request_.method = "POST";
6320 ChunkedUploadDataStream upload_data(0);
6321
6322 request_.upload_data_stream = &upload_data;
6323
rdsmith1d343be52016-10-21 20:37:506324 std::unique_ptr<HttpNetworkTransaction> trans(
6325 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286326 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506327 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6329
6330 base::RunLoop().RunUntilIdle();
6331 upload_data.AppendData("1", 1, true);
6332 base::RunLoop().RunUntilIdle();
6333
6334 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506335 trans.reset();
rche11300ef2016-09-02 01:44:286336 session_.reset();
6337}
6338
Ryan Hamilton4b3574532017-10-30 20:17:256339TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426340 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256341 HostPortPair::FromString("mail.example.org:443"));
6342
Ryan Hamiltonabad59e2019-06-06 04:02:596343 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236344 int packet_num = 1;
6345 if (VersionUsesQpack(version_.transport_version)) {
6346 socket_data.AddWrite(SYNCHRONOUS,
6347 ConstructInitialSettingsPacket(packet_num++));
6348 }
Ryan Hamilton4b3574532017-10-30 20:17:256349 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336350 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236351 SYNCHRONOUS,
6352 ConstructClientRequestHeadersPacket(
6353 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6354 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436355 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336356 ASYNC, ConstructServerResponseHeadersPacket(
6357 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6358 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436359 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336360 socket_data.AddRead(
6361 ASYNC, ConstructServerDataPacket(
6362 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176363 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236364 socket_data.AddWrite(SYNCHRONOUS,
6365 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256366 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166367 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236368 SYNCHRONOUS,
6369 client_maker_.MakeAckAndConnectionClosePacket(
6370 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2, 1,
6371 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256372
6373 socket_data.AddSocketDataToFactory(&socket_factory_);
6374
6375 CreateSession();
6376
6377 SendRequestAndExpectQuicResponse("hello!");
6378 session_.reset();
6379}
6380
6381TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426382 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256383 HostPortPair::FromString("mail.example.org:443"));
6384
Ryan Hamiltonabad59e2019-06-06 04:02:596385 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236386 int packet_num = 1;
6387 if (VersionUsesQpack(version_.transport_version)) {
6388 socket_data.AddWrite(SYNCHRONOUS,
6389 ConstructInitialSettingsPacket(packet_num++));
6390 }
Ryan Hamilton4b3574532017-10-30 20:17:256391 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336392 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236393 SYNCHRONOUS,
6394 ConstructClientRequestHeadersPacket(
6395 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6396 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436397 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336398 ASYNC, ConstructServerResponseHeadersPacket(
6399 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6400 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436401 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336402 socket_data.AddRead(
6403 ASYNC, ConstructServerDataPacket(
6404 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176405 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236406 socket_data.AddWrite(SYNCHRONOUS,
6407 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256408 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166409 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236410 SYNCHRONOUS,
6411 client_maker_.MakeAckAndConnectionClosePacket(
6412 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2, 1,
6413 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:256414
6415 socket_data.AddSocketDataToFactory(&socket_factory_);
6416
6417 CreateSession();
6418
6419 SendRequestAndExpectQuicResponse("hello!");
6420 session_.reset();
6421}
6422
Ryan Hamilton9edcf1a2017-11-22 05:55:176423TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426424 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6425 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256426 HostPortPair::FromString("mail.example.org:443"));
6427
Ryan Hamiltonabad59e2019-06-06 04:02:596428 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256429 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:236430 if (VersionUsesQpack(version_.transport_version))
6431 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176432 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256433 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6434 }
6435 socket_data.AddSocketDataToFactory(&socket_factory_);
6436
6437 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176438 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176439 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6440 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256441
Ryan Hamilton8d9ee76e2018-05-29 23:52:526442 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256443 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6444 TestCompletionCallback callback;
6445 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6446 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176447 while (!callback.have_result()) {
6448 base::RunLoop().RunUntilIdle();
6449 quic_task_runner_->RunUntilIdle();
6450 }
6451 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256452 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176453 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6454 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6455 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526456 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6457 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256458}
6459
Ryan Hamilton9edcf1a2017-11-22 05:55:176460TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426461 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6462 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256463 HostPortPair::FromString("mail.example.org:443"));
6464
Ryan Hamiltonabad59e2019-06-06 04:02:596465 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256466 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:236467 if (VersionUsesQpack(version_.transport_version))
6468 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176469 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256470 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6471 }
6472 socket_data.AddSocketDataToFactory(&socket_factory_);
6473
6474 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176475 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176476 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6477 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256478
Ryan Hamilton8d9ee76e2018-05-29 23:52:526479 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256480 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6481 TestCompletionCallback callback;
6482 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6483 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176484 while (!callback.have_result()) {
6485 base::RunLoop().RunUntilIdle();
6486 quic_task_runner_->RunUntilIdle();
6487 }
6488 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256489 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176490 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6491 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6492 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526493 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6494 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256495}
6496
Cherie Shi7596de632018-02-22 07:28:186497TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Nick Harper72ade192019-07-17 03:30:426498 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6499 session_params_.quic_params.origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186500 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436501 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:526502 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6503 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186504
Ryan Hamiltonabad59e2019-06-06 04:02:596505 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186506 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236507 int packet_num = 1;
6508 if (VersionUsesQpack(version_.transport_version)) {
6509 socket_data.AddWrite(SYNCHRONOUS,
6510 ConstructInitialSettingsPacket(packet_num++));
6511 }
Cherie Shi7596de632018-02-22 07:28:186512 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6513 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526514 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236515 SYNCHRONOUS,
6516 client_maker_.MakeConnectionClosePacket(
6517 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186518 socket_data.AddSocketDataToFactory(&socket_factory_);
6519
6520 CreateSession();
6521
6522 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6523 TestCompletionCallback callback;
6524 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6525 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6526 base::RunLoop().RunUntilIdle();
6527 ASSERT_TRUE(callback.have_result());
6528 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6529 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6530 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6531}
6532
ckrasic769733c2016-06-30 00:42:136533// Adds coverage to catch regression such as https://crbug.com/622043
6534TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Nick Harper72ade192019-07-17 03:30:426535 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136536 HostPortPair::FromString("mail.example.org:443"));
6537
Ryan Hamiltonabad59e2019-06-06 04:02:596538 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236539 uint64_t client_packet_number = 1;
Renjie Tangaadb84b2019-08-31 01:00:236540 if (VersionUsesQpack(version_.transport_version)) {
6541 mock_quic_data.AddWrite(
6542 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6543 }
Zhongyi Shi32f2fd02018-04-16 18:23:436544 mock_quic_data.AddWrite(
6545 SYNCHRONOUS,
6546 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336547 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026548 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436549 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026550 ASYNC,
6551 ConstructServerPushPromisePacket(
6552 1, GetNthClientInitiatedBidirectionalStreamId(0),
6553 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6554 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316555 if ((client_headers_include_h2_stream_dependency_ &&
6556 version_.transport_version >= quic::QUIC_VERSION_43) ||
6557 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026558 mock_quic_data.AddWrite(
6559 SYNCHRONOUS,
6560 ConstructClientPriorityPacket(
6561 client_packet_number++, false,
6562 GetNthServerInitiatedUnidirectionalStreamId(0),
6563 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576564 }
Zhongyi Shi32f2fd02018-04-16 18:23:436565 mock_quic_data.AddRead(
6566 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336567 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026568 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:576569 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436570 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6571 mock_quic_data.AddRead(
6572 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336573 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026574 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436575 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436576 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336577 ASYNC, ConstructServerDataPacket(
6578 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176579 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576580 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436581 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436582 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436583 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336584 ASYNC, ConstructServerDataPacket(
6585 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176586 header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336587 mock_quic_data.AddWrite(SYNCHRONOUS,
6588 ConstructClientAckAndRstPacket(
6589 client_packet_number++,
6590 GetNthServerInitiatedUnidirectionalStreamId(0),
6591 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136592 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6593 mock_quic_data.AddRead(ASYNC, 0); // EOF
6594 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6595
6596 // The non-alternate protocol job needs to hang in order to guarantee that
6597 // the alternate-protocol job will "win".
6598 AddHangingNonAlternateProtocolSocketData();
6599
6600 CreateSession();
6601
6602 // PUSH_PROMISE handling in the http layer gets exercised here.
6603 SendRequestAndExpectQuicResponse("hello!");
6604
6605 request_.url = GURL("https://mail.example.org/pushed.jpg");
6606 SendRequestAndExpectQuicResponse("and hello!");
6607
6608 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:546609 auto entries = net_log_.GetEntries();
ckrasic769733c2016-06-30 00:42:136610 EXPECT_LT(0u, entries.size());
6611
6612 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6613 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006614 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6615 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136616 EXPECT_LT(0, pos);
6617}
6618
rch56ec40a2017-06-23 14:48:446619// Regression test for http://crbug.com/719461 in which a promised stream
6620// is closed before the pushed headers arrive, but after the connection
6621// is closed and before the callbacks are executed.
6622TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Nick Harper72ade192019-07-17 03:30:426623 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6624 session_params_.quic_params.origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446625 HostPortPair::FromString("mail.example.org:443"));
6626
Ryan Hamiltonabad59e2019-06-06 04:02:596627 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236628 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446629 // Initial SETTINGS frame.
Renjie Tangaadb84b2019-08-31 01:00:236630 if (VersionUsesQpack(version_.transport_version)) {
6631 mock_quic_data.AddWrite(
6632 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6633 }
rch56ec40a2017-06-23 14:48:446634 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436635 mock_quic_data.AddWrite(
6636 SYNCHRONOUS,
6637 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336638 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026639 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446640 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436641 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026642 ASYNC,
6643 ConstructServerPushPromisePacket(
6644 1, GetNthClientInitiatedBidirectionalStreamId(0),
6645 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6646 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316647 if ((client_headers_include_h2_stream_dependency_ &&
6648 version_.transport_version >= quic::QUIC_VERSION_43) ||
6649 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026650 mock_quic_data.AddWrite(
6651 SYNCHRONOUS,
6652 ConstructClientPriorityPacket(
6653 client_packet_number++, false,
6654 GetNthServerInitiatedUnidirectionalStreamId(0),
6655 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576656 }
rch56ec40a2017-06-23 14:48:446657 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436658 mock_quic_data.AddRead(
6659 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336660 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026661 GetResponseHeaders("200 OK")));
rch56ec40a2017-06-23 14:48:446662 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576663 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436664 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446665 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:436666 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436667 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336668 ASYNC, ConstructServerDataPacket(
6669 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176670 header + "hello!"));
rch56ec40a2017-06-23 14:48:446671 // Write error for the third request.
6672 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6673 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6674 mock_quic_data.AddRead(ASYNC, 0); // EOF
6675 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6676
6677 CreateSession();
6678
6679 // Send a request which triggers a push promise from the server.
6680 SendRequestAndExpectQuicResponse("hello!");
6681
6682 // Start a push transaction that will be cancelled after the connection
6683 // is closed, but before the callback is executed.
6684 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196685 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446686 session_.get());
6687 TestCompletionCallback callback2;
6688 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6689 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6690 base::RunLoop().RunUntilIdle();
6691
6692 // Cause the connection to close on a write error.
6693 HttpRequestInfo request3;
6694 request3.method = "GET";
6695 request3.url = GURL("https://mail.example.org/");
6696 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106697 request3.traffic_annotation =
6698 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446699 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6700 TestCompletionCallback callback3;
6701 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6702 IsError(ERR_IO_PENDING));
6703
6704 base::RunLoop().RunUntilIdle();
6705
6706 // When |trans2| is destroyed, the underlying stream will be closed.
6707 EXPECT_FALSE(callback2.have_result());
6708 trans2 = nullptr;
6709
6710 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6711}
6712
ckrasicda193a82016-07-09 00:39:366713TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Nick Harper72ade192019-07-17 03:30:426714 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366715 HostPortPair::FromString("mail.example.org:443"));
6716
Ryan Hamiltonabad59e2019-06-06 04:02:596717 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:366718
Renjief49758b2019-01-11 23:32:416719 int write_packet_index = 1;
Renjie Tangaadb84b2019-08-31 01:00:236720 if (VersionUsesQpack(version_.transport_version)) {
6721 mock_quic_data.AddWrite(
6722 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
6723 }
ckrasicda193a82016-07-09 00:39:366724
Victor Vasiliev076657c2019-03-12 02:46:436725 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:566726 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416727 mock_quic_data.AddWrite(
6728 SYNCHRONOUS,
6729 ConstructClientRequestHeadersAndDataFramesPacket(
6730 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6731 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:026732 GetRequestHeaders("POST", "https", "/"), 0, nullptr, {"1"}));
Renjief49758b2019-01-11 23:32:416733 } else {
6734 mock_quic_data.AddWrite(
6735 SYNCHRONOUS,
6736 ConstructClientRequestHeadersAndDataFramesPacket(
6737 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6738 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:026739 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
Renjief49758b2019-01-11 23:32:416740 {header, "1"}));
6741 }
ckrasicda193a82016-07-09 00:39:366742
Zhongyi Shi32f2fd02018-04-16 18:23:436743 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336744 ASYNC, ConstructServerResponseHeadersPacket(
6745 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6746 GetResponseHeaders("200 OK")));
6747
Victor Vasiliev076657c2019-03-12 02:46:436748 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336749 mock_quic_data.AddRead(
6750 ASYNC, ConstructServerDataPacket(
6751 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176752 header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366753
Renjief49758b2019-01-11 23:32:416754 mock_quic_data.AddWrite(
6755 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366756
6757 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6758 mock_quic_data.AddRead(ASYNC, 0); // EOF
6759 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6760
6761 // The non-alternate protocol job needs to hang in order to guarantee that
6762 // the alternate-protocol job will "win".
6763 AddHangingNonAlternateProtocolSocketData();
6764
6765 CreateSession();
6766 request_.method = "POST";
6767 ChunkedUploadDataStream upload_data(0);
6768 upload_data.AppendData("1", 1, true);
6769
6770 request_.upload_data_stream = &upload_data;
6771
6772 SendRequestAndExpectQuicResponse("hello!");
6773}
6774
allada71b2efb2016-09-09 04:57:486775class QuicURLRequestContext : public URLRequestContext {
6776 public:
6777 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6778 MockClientSocketFactory* socket_factory)
6779 : storage_(this) {
6780 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076781 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046782 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486783 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046784 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596785 storage_.set_proxy_resolution_service(
6786 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076787 storage_.set_ssl_config_service(
6788 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486789 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:116790 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:486791 storage_.set_http_server_properties(
Matt Menke609160742019-08-02 18:47:266792 std::make_unique<HttpServerProperties>());
Bence Béky8f9d7d3952017-10-09 19:58:046793 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486794 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046795 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6796 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6797 false));
allada71b2efb2016-09-09 04:57:486798 }
6799
6800 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6801
6802 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6803
6804 private:
6805 MockClientSocketFactory* socket_factory_;
6806 URLRequestContextStorage storage_;
6807};
6808
6809TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
Nick Harper72ade192019-07-17 03:30:426810 session_params_.quic_params.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486811 HostPortPair::FromString("mail.example.org:443"));
6812
Ryan Hamiltonabad59e2019-06-06 04:02:596813 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236814 int packet_num = 1;
6815 if (VersionUsesQpack(version_.transport_version)) {
6816 mock_quic_data.AddWrite(SYNCHRONOUS,
6817 ConstructInitialSettingsPacket(packet_num++));
6818 }
Ryan Hamilton0239aac2018-05-19 00:03:136819 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486820 headers["user-agent"] = "";
6821 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336822 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236823 SYNCHRONOUS,
6824 ConstructClientRequestHeadersPacket(
6825 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6826 true, std::move(headers)));
allada71b2efb2016-09-09 04:57:486827
Fan Yang32c5a112018-12-10 20:06:336828 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026829 ASYNC, ConstructServerResponseHeadersPacket(
6830 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6831 GetResponseHeaders("200 OK")));
6832 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:456833 server_maker_.stream_offset(
6834 quic::VersionUsesQpack(version_.transport_version)
6835 ? GetNthClientInitiatedBidirectionalStreamId(0)
6836 : quic::QuicUtils::GetHeadersStreamId(
6837 version_.transport_version));
allada71b2efb2016-09-09 04:57:486838
Victor Vasiliev076657c2019-03-12 02:46:436839 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366840 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336841 ASYNC, ConstructServerDataPacket(
6842 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176843 "Main Resource Data"));
Renjie Tangaadb84b2019-08-31 01:00:236844 mock_quic_data.AddWrite(SYNCHRONOUS,
6845 ConstructClientAckPacket(packet_num++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486846
6847 mock_quic_data.AddRead(ASYNC, 0); // EOF
6848
6849 CreateSession();
6850
6851 TestDelegate delegate;
6852 QuicURLRequestContext quic_url_request_context(std::move(session_),
6853 &socket_factory_);
6854
6855 mock_quic_data.AddSocketDataToFactory(
6856 &quic_url_request_context.socket_factory());
6857 TestNetworkDelegate network_delegate;
6858 quic_url_request_context.set_network_delegate(&network_delegate);
6859
6860 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296861 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6862 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486863 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6864 &ssl_data_);
6865
6866 request->Start();
Wez2a31b222018-06-07 22:07:156867 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486868
6869 EXPECT_LT(0, request->GetTotalSentBytes());
6870 EXPECT_LT(0, request->GetTotalReceivedBytes());
allada71b2efb2016-09-09 04:57:486871 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6872 request->raw_header_size());
Wez0e717112018-06-18 23:09:226873
6874 // Pump the message loop to allow all data to be consumed.
6875 base::RunLoop().RunUntilIdle();
6876
allada71b2efb2016-09-09 04:57:486877 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6878 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6879}
6880
6881TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
Nick Harper72ade192019-07-17 03:30:426882 session_params_.quic_params.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486883 HostPortPair::FromString("mail.example.org:443"));
6884
Ryan Hamiltonabad59e2019-06-06 04:02:596885 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236886 uint64_t client_packet_number = 1;
Renjie Tangaadb84b2019-08-31 01:00:236887 if (VersionUsesQpack(version_.transport_version)) {
6888 mock_quic_data.AddWrite(
6889 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6890 }
Ryan Hamilton0239aac2018-05-19 00:03:136891 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486892 headers["user-agent"] = "";
6893 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436894 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336895 SYNCHRONOUS,
6896 ConstructClientRequestHeadersPacket(
6897 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026898 true, true, std::move(headers)));
allada71b2efb2016-09-09 04:57:486899
Fan Yang2330d182019-08-05 14:50:506900 const quic::QuicStreamOffset initial = server_maker_.stream_offset(
6901 GetNthClientInitiatedBidirectionalStreamId(0));
Zhongyi Shi32f2fd02018-04-16 18:23:436902 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026903 ASYNC,
6904 ConstructServerPushPromisePacket(
6905 1, GetNthClientInitiatedBidirectionalStreamId(0),
6906 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6907 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Fan Yang2330d182019-08-05 14:50:506908 quic::QuicStreamOffset push_promise_offset = 0;
6909 if (VersionUsesQpack(version_.transport_version)) {
6910 push_promise_offset = server_maker_.stream_offset(
6911 GetNthClientInitiatedBidirectionalStreamId(0)) -
6912 initial;
6913 }
allada71b2efb2016-09-09 04:57:486914
Renjie Tang703fea92019-07-23 21:08:316915 if ((client_headers_include_h2_stream_dependency_ &&
6916 version_.transport_version >= quic::QUIC_VERSION_43) ||
6917 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026918 mock_quic_data.AddWrite(
6919 SYNCHRONOUS,
6920 ConstructClientPriorityPacket(
6921 client_packet_number++, false,
6922 GetNthServerInitiatedUnidirectionalStreamId(0),
6923 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576924 }
6925
Ryan Hamiltone940bd12019-06-30 02:46:456926 const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
6927 quic::VersionUsesQpack(version_.transport_version)
6928 ? GetNthClientInitiatedBidirectionalStreamId(0)
6929 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Zhongyi Shi32f2fd02018-04-16 18:23:436930 mock_quic_data.AddRead(
6931 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336932 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026933 GetResponseHeaders("200 OK")));
Ryan Hamiltone940bd12019-06-30 02:46:456934 const quic::QuicStreamOffset final_offset = server_maker_.stream_offset(
6935 quic::VersionUsesQpack(version_.transport_version)
6936 ? GetNthClientInitiatedBidirectionalStreamId(0)
6937 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Ryan Hamilton0d65a8c2019-06-07 00:46:026938 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:456939 final_offset - initial_offset;
allada71b2efb2016-09-09 04:57:486940
Yixin Wangb470bc882018-02-15 18:43:576941 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436942 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486943
ckrasicbf2f59c2017-05-04 23:54:366944 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436945 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336946 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026947 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436948 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436949 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336950 ASYNC, ConstructServerDataPacket(
6951 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176952 header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486953
Yixin Wangb470bc882018-02-15 18:43:576954 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436955 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436956 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366957 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336958 ASYNC, ConstructServerDataPacket(
6959 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176960 header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486961
Zhongyi Shi32f2fd02018-04-16 18:23:436962 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486963
6964 CreateSession();
6965
6966 TestDelegate delegate;
6967 QuicURLRequestContext quic_url_request_context(std::move(session_),
6968 &socket_factory_);
6969
6970 mock_quic_data.AddSocketDataToFactory(
6971 &quic_url_request_context.socket_factory());
6972 TestNetworkDelegate network_delegate;
6973 quic_url_request_context.set_network_delegate(&network_delegate);
6974
6975 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296976 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6977 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486978 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6979 &ssl_data_);
6980
6981 request->Start();
Wez2a31b222018-06-07 22:07:156982 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486983
6984 EXPECT_LT(0, request->GetTotalSentBytes());
6985 EXPECT_LT(0, request->GetTotalReceivedBytes());
Fan Yang2330d182019-08-05 14:50:506986 EXPECT_EQ(
6987 static_cast<int>(expected_raw_header_response_size + push_promise_offset),
6988 request->raw_header_size());
Wez0e717112018-06-18 23:09:226989
6990 // Pump the message loop to allow all data to be consumed.
6991 base::RunLoop().RunUntilIdle();
6992
allada71b2efb2016-09-09 04:57:486993 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6994 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6995}
6996
Ryan Sleevia9d6aa62019-07-26 13:32:186997TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
6998 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:206999
7000 MockRead http_reads[] = {
7001 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7002 MockRead("hello world"),
7003 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7004 MockRead(ASYNC, OK)};
7005
Ryan Sleevib8d7ea02018-05-07 20:01:017006 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207007 socket_factory_.AddSocketDataProvider(&http_data);
7008 AddCertificate(&ssl_data_);
7009 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7010
Ryan Hamiltonabad59e2019-06-06 04:02:597011 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237012 int packet_num = 1;
7013 if (VersionUsesQpack(version_.transport_version)) {
7014 mock_quic_data.AddWrite(SYNCHRONOUS,
7015 ConstructInitialSettingsPacket(packet_num++));
7016 }
Yixin Wang10f477ed2017-11-21 04:20:207017 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237018 SYNCHRONOUS,
7019 ConstructClientRequestHeadersPacket(
7020 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7021 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437022 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337023 ASYNC, ConstructServerResponseHeadersPacket(
7024 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7025 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437026 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:337027 mock_quic_data.AddRead(
7028 ASYNC, ConstructServerDataPacket(
7029 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177030 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:237031 mock_quic_data.AddWrite(SYNCHRONOUS,
7032 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:207033 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7034 mock_quic_data.AddRead(ASYNC, 0); // EOF
7035
7036 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7037
7038 AddHangingNonAlternateProtocolSocketData();
7039 CreateSession();
7040
7041 SendRequestAndExpectHttpResponse("hello world");
7042 SendRequestAndExpectQuicResponse("hello!");
7043}
7044
Ryan Sleevia9d6aa62019-07-26 13:32:187045TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
7046 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:207047
7048 MockRead http_reads[] = {
7049 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7050 MockRead("hello world"),
7051 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7052 MockRead(ASYNC, OK)};
7053
Ryan Sleevib8d7ea02018-05-07 20:01:017054 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207055 socket_factory_.AddSocketDataProvider(&http_data);
7056 AddCertificate(&ssl_data_);
7057 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7058 socket_factory_.AddSocketDataProvider(&http_data);
7059 AddCertificate(&ssl_data_);
7060 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7061
7062 AddHangingNonAlternateProtocolSocketData();
7063 CreateSession();
7064
7065 SendRequestAndExpectHttpResponse("hello world");
7066 SendRequestAndExpectHttpResponse("hello world");
7067}
7068
bnc359ed2a2016-04-29 20:43:457069class QuicNetworkTransactionWithDestinationTest
7070 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:017071 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:057072 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:457073 protected:
7074 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:557075 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:057076 client_headers_include_h2_stream_dependency_(
7077 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:567078 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:457079 destination_type_(GetParam().destination_type),
7080 cert_transparency_verifier_(new MultiLogCTVerifier()),
7081 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:597082 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:117083 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:457084 random_generator_(0),
7085 ssl_data_(ASYNC, OK) {}
7086
7087 void SetUp() override {
7088 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557089 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457090
mmenke6ddfbea2017-05-31 21:48:417091 HttpNetworkSession::Params session_params;
7092 session_params.enable_quic = true;
Nick Harper72ade192019-07-17 03:30:427093 session_params.quic_params.allow_remote_alt_svc = true;
7094 session_params.quic_params.supported_versions = supported_versions_;
7095 session_params.quic_params.headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:057096 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:417097
7098 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:457099
Ryan Hamilton8d9ee76e2018-05-29 23:52:527100 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:417101 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:457102
7103 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277104 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:417105 session_context.quic_crypto_client_stream_factory =
7106 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:457107
mmenke6ddfbea2017-05-31 21:48:417108 session_context.quic_random = &random_generator_;
7109 session_context.client_socket_factory = &socket_factory_;
7110 session_context.host_resolver = &host_resolver_;
7111 session_context.cert_verifier = &cert_verifier_;
7112 session_context.transport_security_state = &transport_security_state_;
7113 session_context.cert_transparency_verifier =
7114 cert_transparency_verifier_.get();
7115 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
7116 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:457117 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:417118 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:597119 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:417120 session_context.http_auth_handler_factory = auth_handler_factory_.get();
7121 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:457122
mmenke6ddfbea2017-05-31 21:48:417123 session_.reset(new HttpNetworkSession(session_params, session_context));
Matt Menkeb566c392019-09-11 23:22:437124 session_->quic_stream_factory()
7125 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:457126 }
7127
7128 void TearDown() override {
7129 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7130 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557131 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457132 PlatformTest::TearDown();
7133 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557134 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:407135 session_.reset();
bnc359ed2a2016-04-29 20:43:457136 }
7137
zhongyie537a002017-06-27 16:48:217138 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:457139 HostPortPair destination;
7140 switch (destination_type_) {
7141 case SAME_AS_FIRST:
7142 destination = HostPortPair(origin1_, 443);
7143 break;
7144 case SAME_AS_SECOND:
7145 destination = HostPortPair(origin2_, 443);
7146 break;
7147 case DIFFERENT:
7148 destination = HostPortPair(kDifferentHostname, 443);
7149 break;
7150 }
bnc3472afd2016-11-17 15:27:217151 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:457152 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:217153 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:077154 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
7155 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:457156 }
7157
Ryan Hamilton8d9ee76e2018-05-29 23:52:527158 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237159 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527160 quic::QuicStreamId stream_id,
7161 bool should_include_version,
7162 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527163 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137164 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457165 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:137166 spdy::SpdyHeaderBlock headers(
7167 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027168 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457169 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027170 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:457171 }
7172
Ryan Hamilton8d9ee76e2018-05-29 23:52:527173 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237174 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527175 quic::QuicStreamId stream_id,
7176 bool should_include_version,
7177 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587178 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:027179 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:457180 }
7181
Ryan Hamilton8d9ee76e2018-05-29 23:52:527182 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237183 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527184 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527185 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137186 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027187 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
7188 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:457189 }
7190
Ryan Hamilton8d9ee76e2018-05-29 23:52:527191 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237192 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527193 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457194 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:437195 std::string header = "";
Nick Harper23290b82019-05-02 00:02:567196 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417197 quic::HttpEncoder encoder;
7198 std::unique_ptr<char[]> buffer;
7199 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:437200 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:417201 }
Ryan Hamilton7505eb92019-06-08 00:22:177202 return maker->MakeDataPacket(packet_number, stream_id, false, true,
Renjief49758b2019-01-11 23:32:417203 header + "hello");
bnc359ed2a2016-04-29 20:43:457204 }
7205
Ryan Hamilton8d9ee76e2018-05-29 23:52:527206 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237207 uint64_t packet_number,
7208 uint64_t largest_received,
7209 uint64_t smallest_received,
7210 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:457211 QuicTestPacketMaker* maker) {
7212 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:497213 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:457214 }
7215
Ryan Hamilton8d9ee76e2018-05-29 23:52:527216 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237217 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:377218 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027219 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:377220 }
7221
bnc359ed2a2016-04-29 20:43:457222 void AddRefusedSocketData() {
7223 std::unique_ptr<StaticSocketDataProvider> refused_data(
7224 new StaticSocketDataProvider());
7225 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7226 refused_data->set_connect_data(refused_connect);
7227 socket_factory_.AddSocketDataProvider(refused_data.get());
7228 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7229 }
7230
7231 void AddHangingSocketData() {
7232 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7233 new StaticSocketDataProvider());
7234 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7235 hanging_data->set_connect_data(hanging_connect);
7236 socket_factory_.AddSocketDataProvider(hanging_data.get());
7237 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7238 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7239 }
7240
7241 bool AllDataConsumed() {
7242 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7243 if (!socket_data_ptr->AllReadDataConsumed() ||
7244 !socket_data_ptr->AllWriteDataConsumed()) {
7245 return false;
7246 }
7247 }
7248 return true;
7249 }
7250
7251 void SendRequestAndExpectQuicResponse(const std::string& host) {
7252 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7253 HttpRequestInfo request;
7254 std::string url("https://");
7255 url.append(host);
7256 request.url = GURL(url);
7257 request.load_flags = 0;
7258 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107259 request.traffic_annotation =
7260 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457261 TestCompletionCallback callback;
7262 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017263 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457264
7265 std::string response_data;
robpercival214763f2016-07-01 23:27:017266 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457267 EXPECT_EQ("hello", response_data);
7268
7269 const HttpResponseInfo* response = trans.GetResponseInfo();
7270 ASSERT_TRUE(response != nullptr);
7271 ASSERT_TRUE(response->headers.get() != nullptr);
7272 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7273 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527274 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:567275 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
7276 version_.transport_version),
bnc359ed2a2016-04-29 20:43:457277 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377278 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457279 }
7280
Fan Yang32c5a112018-12-10 20:06:337281 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567282 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7283 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367284 }
7285
Ryan Hamilton8d9ee76e2018-05-29 23:52:527286 quic::MockClock clock_;
Nick Harper23290b82019-05-02 00:02:567287 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057288 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567289 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457290 DestinationType destination_type_;
7291 std::string origin1_;
7292 std::string origin2_;
7293 std::unique_ptr<HttpNetworkSession> session_;
7294 MockClientSocketFactory socket_factory_;
7295 MockHostResolver host_resolver_;
7296 MockCertVerifier cert_verifier_;
7297 TransportSecurityState transport_security_state_;
7298 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237299 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457300 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077301 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597302 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457303 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527304 quic::test::MockRandom random_generator_;
Matt Menke609160742019-08-02 18:47:267305 HttpServerProperties http_server_properties_;
bnc359ed2a2016-04-29 20:43:457306 BoundTestNetLog net_log_;
7307 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7308 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7309 static_socket_data_provider_vector_;
7310 SSLSocketDataProvider ssl_data_;
7311};
7312
Victor Costane635086f2019-01-27 05:20:307313INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7314 QuicNetworkTransactionWithDestinationTest,
7315 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:457316
7317// A single QUIC request fails because the certificate does not match the origin
7318// hostname, regardless of whether it matches the alternative service hostname.
7319TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7320 if (destination_type_ == DIFFERENT)
7321 return;
7322
7323 GURL url("https://mail.example.com/");
7324 origin1_ = url.host();
7325
7326 // Not used for requests, but this provides a test case where the certificate
7327 // is valid for the hostname of the alternative service.
7328 origin2_ = "mail.example.org";
7329
zhongyie537a002017-06-27 16:48:217330 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457331
7332 scoped_refptr<X509Certificate> cert(
7333 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247334 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7335 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457336
7337 ProofVerifyDetailsChromium verify_details;
7338 verify_details.cert_verify_result.verified_cert = cert;
7339 verify_details.cert_verify_result.is_issued_by_known_root = true;
7340 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7341
Ryan Hamiltonabad59e2019-06-06 04:02:597342 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457343 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7344 mock_quic_data.AddRead(ASYNC, 0);
7345
7346 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7347
7348 AddRefusedSocketData();
7349
7350 HttpRequestInfo request;
7351 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107352 request.traffic_annotation =
7353 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457354
7355 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7356 TestCompletionCallback callback;
7357 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017358 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457359
7360 EXPECT_TRUE(AllDataConsumed());
7361}
7362
7363// First request opens QUIC session to alternative service. Second request
7364// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527365// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457366TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7367 origin1_ = "mail.example.org";
7368 origin2_ = "news.example.org";
7369
zhongyie537a002017-06-27 16:48:217370 SetQuicAlternativeService(origin1_);
7371 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457372
7373 scoped_refptr<X509Certificate> cert(
7374 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247375 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7376 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7377 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457378
7379 ProofVerifyDetailsChromium verify_details;
7380 verify_details.cert_verify_result.verified_cert = cert;
7381 verify_details.cert_verify_result.is_issued_by_known_root = true;
7382 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7383
Yixin Wang079ad542018-01-11 04:06:057384 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177385 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7386 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057387 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177388 QuicTestPacketMaker server_maker(
7389 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7390 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457391
Ryan Hamiltonabad59e2019-06-06 04:02:597392 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237393 int packet_num = 1;
7394 if (VersionUsesQpack(version_.transport_version)) {
7395 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7396 packet_num++, &client_maker));
7397 }
Fan Yang32c5a112018-12-10 20:06:337398 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237399 SYNCHRONOUS,
7400 ConstructClientRequestHeadersPacket(
7401 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7402 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:027403 mock_quic_data.AddRead(
7404 ASYNC,
7405 ConstructServerResponseHeadersPacket(
7406 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437407 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337408 ASYNC,
7409 ConstructServerDataPacket(
7410 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237411 mock_quic_data.AddWrite(
7412 SYNCHRONOUS,
7413 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457414
Yixin Wang079ad542018-01-11 04:06:057415 client_maker.set_hostname(origin2_);
7416 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457417
Zhongyi Shi32f2fd02018-04-16 18:23:437418 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027419 SYNCHRONOUS,
7420 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237421 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027422 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7423 mock_quic_data.AddRead(
7424 ASYNC,
7425 ConstructServerResponseHeadersPacket(
7426 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437427 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337428 ASYNC,
7429 ConstructServerDataPacket(
7430 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237431 mock_quic_data.AddWrite(
7432 SYNCHRONOUS,
7433 ConstructClientAckPacket(packet_num++, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457434 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7435 mock_quic_data.AddRead(ASYNC, 0); // EOF
7436
7437 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7438
7439 AddHangingSocketData();
7440 AddHangingSocketData();
7441
Nick Harpereb483e12019-05-14 00:18:097442 scoped_refptr<TestTaskRunner> quic_task_runner(new TestTaskRunner(&clock_));
Fan Yangc9e00dc2018-10-09 14:17:567443 QuicStreamFactoryPeer::SetAlarmFactory(
7444 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097445 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Fan Yangc9e00dc2018-10-09 14:17:567446 &clock_));
7447
bnc359ed2a2016-04-29 20:43:457448 SendRequestAndExpectQuicResponse(origin1_);
7449 SendRequestAndExpectQuicResponse(origin2_);
7450
7451 EXPECT_TRUE(AllDataConsumed());
7452}
7453
7454// First request opens QUIC session to alternative service. Second request does
7455// not pool to it, even though destination matches, because certificate is not
7456// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527457// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457458TEST_P(QuicNetworkTransactionWithDestinationTest,
7459 DoNotPoolIfCertificateInvalid) {
7460 origin1_ = "news.example.org";
7461 origin2_ = "mail.example.com";
7462
zhongyie537a002017-06-27 16:48:217463 SetQuicAlternativeService(origin1_);
7464 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457465
7466 scoped_refptr<X509Certificate> cert1(
7467 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247468 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7469 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7470 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457471
7472 scoped_refptr<X509Certificate> cert2(
7473 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247474 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7475 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457476
7477 ProofVerifyDetailsChromium verify_details1;
7478 verify_details1.cert_verify_result.verified_cert = cert1;
7479 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7480 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7481
7482 ProofVerifyDetailsChromium verify_details2;
7483 verify_details2.cert_verify_result.verified_cert = cert2;
7484 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7485 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7486
Yixin Wang079ad542018-01-11 04:06:057487 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177488 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7489 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057490 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177491 QuicTestPacketMaker server_maker1(
7492 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7493 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457494
Ryan Hamiltonabad59e2019-06-06 04:02:597495 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:237496 int packet_num = 1;
7497 if (VersionUsesQpack(version_.transport_version)) {
7498 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7499 packet_num++, &client_maker1));
7500 }
Fan Yang32c5a112018-12-10 20:06:337501 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237502 SYNCHRONOUS,
7503 ConstructClientRequestHeadersPacket(
7504 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7505 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437506 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337507 ASYNC,
7508 ConstructServerResponseHeadersPacket(
7509 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437510 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337511 ASYNC,
7512 ConstructServerDataPacket(
7513 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437514 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237515 SYNCHRONOUS,
7516 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457517 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7518 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7519
7520 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7521
Yixin Wang079ad542018-01-11 04:06:057522 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177523 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7524 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057525 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177526 QuicTestPacketMaker server_maker2(
7527 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7528 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457529
Ryan Hamiltonabad59e2019-06-06 04:02:597530 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:237531 int packet_num2 = 1;
7532 if (VersionUsesQpack(version_.transport_version)) {
7533 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7534 packet_num2++, &client_maker2));
7535 }
Fan Yang32c5a112018-12-10 20:06:337536 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237537 SYNCHRONOUS,
7538 ConstructClientRequestHeadersPacket(
7539 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7540 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437541 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337542 ASYNC,
7543 ConstructServerResponseHeadersPacket(
7544 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437545 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337546 ASYNC,
7547 ConstructServerDataPacket(
7548 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437549 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237550 SYNCHRONOUS,
7551 ConstructClientAckPacket(packet_num2++, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457552 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7553 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7554
7555 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7556
bnc359ed2a2016-04-29 20:43:457557 SendRequestAndExpectQuicResponse(origin1_);
7558 SendRequestAndExpectQuicResponse(origin2_);
7559
7560 EXPECT_TRUE(AllDataConsumed());
7561}
7562
ckrasicdee37572017-04-06 22:42:277563// crbug.com/705109 - this confirms that matching request with a body
7564// triggers a crash (pre-fix).
7565TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Nick Harper72ade192019-07-17 03:30:427566 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277567 HostPortPair::FromString("mail.example.org:443"));
7568
Ryan Hamiltonabad59e2019-06-06 04:02:597569 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237570 uint64_t client_packet_number = 1;
Renjie Tangaadb84b2019-08-31 01:00:237571 if (VersionUsesQpack(version_.transport_version)) {
7572 mock_quic_data.AddWrite(
7573 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7574 }
Zhongyi Shi32f2fd02018-04-16 18:23:437575 mock_quic_data.AddWrite(
7576 SYNCHRONOUS,
7577 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337578 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027579 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437580 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027581 ASYNC,
7582 ConstructServerPushPromisePacket(
7583 1, GetNthClientInitiatedBidirectionalStreamId(0),
7584 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7585 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:317586
7587 if ((client_headers_include_h2_stream_dependency_ &&
7588 version_.transport_version >= quic::QUIC_VERSION_43) ||
7589 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027590 mock_quic_data.AddWrite(
7591 SYNCHRONOUS,
7592 ConstructClientPriorityPacket(
7593 client_packet_number++, false,
7594 GetNthServerInitiatedUnidirectionalStreamId(0),
7595 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577596 }
Zhongyi Shi32f2fd02018-04-16 18:23:437597 mock_quic_data.AddRead(
7598 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337599 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027600 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:577601 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437602 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7603 mock_quic_data.AddRead(
7604 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337605 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027606 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437607 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437608 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337609 ASYNC, ConstructServerDataPacket(
7610 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177611 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577612 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437613 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417614
Victor Vasiliev076657c2019-03-12 02:46:437615 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437616 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337617 ASYNC, ConstructServerDataPacket(
7618 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177619 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277620
7621 // Because the matching request has a body, we will see the push
7622 // stream get cancelled, and the matching request go out on the
7623 // wire.
Fan Yang32c5a112018-12-10 20:06:337624 mock_quic_data.AddWrite(SYNCHRONOUS,
7625 ConstructClientAckAndRstPacket(
7626 client_packet_number++,
7627 GetNthServerInitiatedUnidirectionalStreamId(0),
7628 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277629 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437630 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567631 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417632 mock_quic_data.AddWrite(
7633 SYNCHRONOUS,
7634 ConstructClientRequestHeadersAndDataFramesPacket(
7635 client_packet_number++,
7636 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7637 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027638 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, {kBody}));
Renjief49758b2019-01-11 23:32:417639 } else {
7640 mock_quic_data.AddWrite(
7641 SYNCHRONOUS,
7642 ConstructClientRequestHeadersAndDataFramesPacket(
7643 client_packet_number++,
7644 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7645 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027646 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7647 {header3, kBody}));
Renjief49758b2019-01-11 23:32:417648 }
ckrasicdee37572017-04-06 22:42:277649
7650 // We see the same response as for the earlier pushed and cancelled
7651 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437652 mock_quic_data.AddRead(
7653 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337654 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027655 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:437656 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337657 ASYNC, ConstructServerDataPacket(
7658 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177659 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277660
Yixin Wangb470bc882018-02-15 18:43:577661 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437662 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277663 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7664 mock_quic_data.AddRead(ASYNC, 0); // EOF
7665 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7666
7667 // The non-alternate protocol job needs to hang in order to guarantee that
7668 // the alternate-protocol job will "win".
7669 AddHangingNonAlternateProtocolSocketData();
7670
7671 CreateSession();
7672
7673 // PUSH_PROMISE handling in the http layer gets exercised here.
7674 SendRequestAndExpectQuicResponse("hello!");
7675
7676 request_.url = GURL("https://mail.example.org/pushed.jpg");
7677 ChunkedUploadDataStream upload_data(0);
7678 upload_data.AppendData("1", 1, true);
7679 request_.upload_data_stream = &upload_data;
7680 SendRequestAndExpectQuicResponse("and hello!");
7681}
7682
Bence Béky7538a952018-02-01 16:59:527683// Regression test for https://crbug.com/797825: If pushed headers describe a
7684// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7685// not be called (otherwise a DCHECK fails).
7686TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137687 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527688 pushed_request_headers[":authority"] = "";
7689 pushed_request_headers[":method"] = "GET";
7690 pushed_request_headers[":path"] = "/";
7691 pushed_request_headers[":scheme"] = "nosuchscheme";
7692
Nick Harper72ade192019-07-17 03:30:427693 session_params_.quic_params.origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:527694 HostPortPair::FromString("mail.example.org:443"));
7695
Ryan Hamiltonabad59e2019-06-06 04:02:597696 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:527697
Renjie Tangaadb84b2019-08-31 01:00:237698 int packet_num = 1;
7699 if (VersionUsesQpack(version_.transport_version)) {
7700 mock_quic_data.AddWrite(SYNCHRONOUS,
7701 ConstructInitialSettingsPacket(packet_num++));
7702 }
Bence Béky7538a952018-02-01 16:59:527703 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237704 SYNCHRONOUS,
7705 ConstructClientRequestHeadersPacket(
7706 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7707 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:527708
Fan Yang32c5a112018-12-10 20:06:337709 mock_quic_data.AddRead(
7710 ASYNC, ConstructServerPushPromisePacket(
7711 1, GetNthClientInitiatedBidirectionalStreamId(0),
7712 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027713 std::move(pushed_request_headers), &server_maker_));
Renjie Tangaadb84b2019-08-31 01:00:237714 mock_quic_data.AddWrite(
7715 SYNCHRONOUS,
7716 ConstructClientRstPacket(packet_num++,
7717 GetNthServerInitiatedUnidirectionalStreamId(0),
7718 quic::QUIC_INVALID_PROMISE_URL));
Bence Béky7538a952018-02-01 16:59:527719
Zhongyi Shi32f2fd02018-04-16 18:23:437720 mock_quic_data.AddRead(
7721 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337722 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027723 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:237724 mock_quic_data.AddWrite(SYNCHRONOUS,
7725 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527726
Zhongyi Shi32f2fd02018-04-16 18:23:437727 mock_quic_data.AddRead(
7728 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337729 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027730 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437731 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437732 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337733 ASYNC, ConstructServerDataPacket(
7734 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177735 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:237736 mock_quic_data.AddWrite(SYNCHRONOUS,
7737 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527738
7739 mock_quic_data.AddRead(ASYNC, 0);
7740 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7741
7742 // The non-alternate protocol job needs to hang in order to guarantee that
7743 // the alternate-protocol job will "win".
7744 AddHangingNonAlternateProtocolSocketData();
7745
7746 CreateSession();
7747
7748 // PUSH_PROMISE handling in the http layer gets exercised here.
7749 SendRequestAndExpectQuicResponse("hello!");
7750
7751 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7752 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7753}
7754
Yixin Wang46a273ec302018-01-23 17:59:567755// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147756TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567757 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147758 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567759 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497760 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567761
Ryan Hamiltonabad59e2019-06-06 04:02:597762 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237763 int packet_num = 1;
7764 if (VersionUsesQpack(version_.transport_version)) {
7765 mock_quic_data.AddWrite(SYNCHRONOUS,
7766 ConstructInitialSettingsPacket(packet_num++));
7767 }
Fan Yang32c5a112018-12-10 20:06:337768 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237769 SYNCHRONOUS,
7770 ConstructClientRequestHeadersPacket(
7771 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7772 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7773 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337774 mock_quic_data.AddRead(
7775 ASYNC, ConstructServerResponseHeadersPacket(
7776 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7777 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567778
7779 const char get_request[] =
7780 "GET / HTTP/1.1\r\n"
7781 "Host: mail.example.org\r\n"
7782 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437783 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567784 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417785 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357786 SYNCHRONOUS,
7787 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237788 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7789 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417790 } else {
7791 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417792 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357793 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:237794 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7795 1, 1, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417796 }
7797
Yixin Wang46a273ec302018-01-23 17:59:567798 const char get_response[] =
7799 "HTTP/1.1 200 OK\r\n"
7800 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437801 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437802 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337803 ASYNC, ConstructServerDataPacket(
7804 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177805 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:437806 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337807 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417808 SYNCHRONOUS, ConstructServerDataPacket(
7809 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:177810 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:237811 mock_quic_data.AddWrite(SYNCHRONOUS,
7812 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567813 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7814
7815 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417816 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237817 ConstructClientRstPacket(packet_num++,
7818 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417819 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567820
7821 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7822
7823 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7824
7825 CreateSession();
7826
7827 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097828 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567829 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7830 HeadersHandler headers_handler;
7831 trans.SetBeforeHeadersSentCallback(
7832 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7833 base::Unretained(&headers_handler)));
7834 RunTransaction(&trans);
7835 CheckWasHttpResponse(&trans);
7836 CheckResponsePort(&trans, 70);
7837 CheckResponseData(&trans, "0123456789");
7838 EXPECT_TRUE(headers_handler.was_proxied());
7839 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7840
7841 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7842 // proxy socket to disconnect.
7843 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7844
7845 base::RunLoop().RunUntilIdle();
7846 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7847 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7848}
7849
7850// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147851TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567852 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147853 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567854 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497855 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567856
Ryan Hamiltonabad59e2019-06-06 04:02:597857 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237858 int packet_num = 1;
7859 if (VersionUsesQpack(version_.transport_version)) {
7860 mock_quic_data.AddWrite(SYNCHRONOUS,
7861 ConstructInitialSettingsPacket(packet_num++));
7862 }
Fan Yang32c5a112018-12-10 20:06:337863 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237864 SYNCHRONOUS,
7865 ConstructClientRequestHeadersPacket(
7866 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7867 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7868 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337869 mock_quic_data.AddRead(
7870 ASYNC, ConstructServerResponseHeadersPacket(
7871 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7872 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567873
7874 SpdyTestUtil spdy_util;
7875
Ryan Hamilton0239aac2018-05-19 00:03:137876 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567877 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437878 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567879 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417880 mock_quic_data.AddWrite(
7881 SYNCHRONOUS,
7882 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237883 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7884 1, 1, 1, false,
7885 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:417886 } else {
7887 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417888 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357889 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:237890 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7891 1, 1, 1, false,
7892 {header, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417893 }
Ryan Hamilton0239aac2018-05-19 00:03:137894 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567895 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437896 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437897 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177898 ASYNC, ConstructServerDataPacket(
7899 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7900 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567901
Ryan Hamilton0239aac2018-05-19 00:03:137902 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197903 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:437904 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437905 mock_quic_data.AddRead(
7906 SYNCHRONOUS,
7907 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337908 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437909 header3 + std::string(data_frame.data(), data_frame.size())));
Renjie Tangaadb84b2019-08-31 01:00:237910 mock_quic_data.AddWrite(SYNCHRONOUS,
7911 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567912 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7913
7914 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437915 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237916 ConstructClientRstPacket(packet_num++,
7917 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417918 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567919
7920 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7921
7922 SSLSocketDataProvider ssl_data(ASYNC, OK);
7923 ssl_data.next_proto = kProtoHTTP2;
7924 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7925
7926 CreateSession();
7927
7928 request_.url = GURL("https://mail.example.org/");
7929 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7930 HeadersHandler headers_handler;
7931 trans.SetBeforeHeadersSentCallback(
7932 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7933 base::Unretained(&headers_handler)));
7934 RunTransaction(&trans);
7935 CheckWasSpdyResponse(&trans);
7936 CheckResponsePort(&trans, 70);
7937 CheckResponseData(&trans, "0123456789");
7938 EXPECT_TRUE(headers_handler.was_proxied());
7939 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7940
Wez0e717112018-06-18 23:09:227941 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7942 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567943 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7944
7945 base::RunLoop().RunUntilIdle();
7946 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7947 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7948}
7949
7950// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7951// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147952TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567953 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147954 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567955 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497956 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567957
Ryan Hamiltonabad59e2019-06-06 04:02:597958 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:417959 int write_packet_index = 1;
Renjie Tangaadb84b2019-08-31 01:00:237960 if (VersionUsesQpack(version_.transport_version)) {
7961 mock_quic_data.AddWrite(
7962 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7963 }
Fan Yang32c5a112018-12-10 20:06:337964 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417965 SYNCHRONOUS,
7966 ConstructClientRequestHeadersPacket(
7967 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:047968 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027969 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337970 mock_quic_data.AddRead(
7971 ASYNC, ConstructServerResponseHeadersPacket(
7972 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7973 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567974
Ryan Hamilton8d9ee76e2018-05-29 23:52:527975 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567976 const char get_request_1[] =
7977 "GET / HTTP/1.1\r\n"
7978 "Host: mail.example.org\r\n"
7979 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437980 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:567981 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417982 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:177983 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7984 write_packet_index++, false,
7985 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7986 false, quic::QuicStringPiece(get_request_1)));
Renjief49758b2019-01-11 23:32:417987 } else {
7988 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:177989 SYNCHRONOUS, ConstructClientAckAndMultipleDataFramesPacket(
7990 write_packet_index++, false,
7991 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7992 false, {header, std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:417993 }
7994
Yixin Wang46a273ec302018-01-23 17:59:567995 const char get_response_1[] =
7996 "HTTP/1.1 200 OK\r\n"
7997 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437998 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437999 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438000 ASYNC, ConstructServerDataPacket(
8001 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178002 header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:418003 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:568004
Victor Vasiliev076657c2019-03-12 02:46:438005 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338006 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178007 SYNCHRONOUS, ConstructServerDataPacket(
8008 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
8009 false, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:418010 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:568011
Renjief49758b2019-01-11 23:32:418012 mock_quic_data.AddWrite(
8013 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568014
8015 const char get_request_2[] =
8016 "GET /2 HTTP/1.1\r\n"
8017 "Host: mail.example.org\r\n"
8018 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438019 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:568020 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418021 mock_quic_data.AddWrite(
8022 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358023 ConstructClientMultipleDataFramesPacket(
8024 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:178025 false, false, {header4, std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:358026 } else {
8027 mock_quic_data.AddWrite(
8028 SYNCHRONOUS,
Ryan Hamilton7505eb92019-06-08 00:22:178029 ConstructClientDataPacket(
8030 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
8031 false, false, quic::QuicStringPiece(get_request_2)));
Renjief49758b2019-01-11 23:32:418032 }
Yixin Wang46a273ec302018-01-23 17:59:568033
8034 const char get_response_2[] =
8035 "HTTP/1.1 200 OK\r\n"
8036 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438037 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:438038 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438039 ASYNC, ConstructServerDataPacket(
8040 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178041 header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:418042 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:568043
Victor Vasiliev076657c2019-03-12 02:46:438044 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528045 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178046 SYNCHRONOUS, ConstructServerDataPacket(
8047 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
8048 false, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:418049 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:568050
Renjief49758b2019-01-11 23:32:418051 mock_quic_data.AddWrite(
8052 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:568053 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8054
Renjief49758b2019-01-11 23:32:418055 mock_quic_data.AddWrite(
8056 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418057 ConstructClientRstPacket(write_packet_index++,
8058 GetNthClientInitiatedBidirectionalStreamId(0),
8059 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568060
8061 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8062
8063 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8064
8065 CreateSession();
8066
8067 request_.url = GURL("https://mail.example.org/");
8068 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8069 HeadersHandler headers_handler_1;
8070 trans_1.SetBeforeHeadersSentCallback(
8071 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8072 base::Unretained(&headers_handler_1)));
8073 RunTransaction(&trans_1);
8074 CheckWasHttpResponse(&trans_1);
8075 CheckResponsePort(&trans_1, 70);
8076 CheckResponseData(&trans_1, "0123456789");
8077 EXPECT_TRUE(headers_handler_1.was_proxied());
8078 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8079
8080 request_.url = GURL("https://mail.example.org/2");
8081 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8082 HeadersHandler headers_handler_2;
8083 trans_2.SetBeforeHeadersSentCallback(
8084 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8085 base::Unretained(&headers_handler_2)));
8086 RunTransaction(&trans_2);
8087 CheckWasHttpResponse(&trans_2);
8088 CheckResponsePort(&trans_2, 70);
8089 CheckResponseData(&trans_2, "0123456");
8090 EXPECT_TRUE(headers_handler_2.was_proxied());
8091 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8092
8093 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8094 // proxy socket to disconnect.
8095 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8096
8097 base::RunLoop().RunUntilIdle();
8098 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8099 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8100}
8101
8102// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
8103// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
8104// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:148105TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:568106 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148107 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568108 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498109 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568110
Ryan Hamiltonabad59e2019-06-06 04:02:598111 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238112 int packet_num = 1;
8113 if (VersionUsesQpack(version_.transport_version)) {
8114 mock_quic_data.AddWrite(SYNCHRONOUS,
8115 ConstructInitialSettingsPacket(packet_num++));
8116 }
Yixin Wang46a273ec302018-01-23 17:59:568117
8118 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:338119 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238120 SYNCHRONOUS,
8121 ConstructClientRequestHeadersPacket(
8122 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8123 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8124 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438125 mock_quic_data.AddRead(
8126 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338127 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028128 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568129
8130 // GET request, response, and data over QUIC tunnel for first request
8131 const char get_request[] =
8132 "GET / HTTP/1.1\r\n"
8133 "Host: mail.example.org\r\n"
8134 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438135 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568136 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418137 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358138 SYNCHRONOUS,
8139 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238140 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8141 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418142 } else {
8143 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418144 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358145 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238146 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8147 1, 1, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418148 }
8149
Yixin Wang46a273ec302018-01-23 17:59:568150 const char get_response[] =
8151 "HTTP/1.1 200 OK\r\n"
8152 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438153 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:568154 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338155 ASYNC, ConstructServerDataPacket(
8156 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178157 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:438158 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338159 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418160 SYNCHRONOUS, ConstructServerDataPacket(
8161 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178162 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238163 mock_quic_data.AddWrite(SYNCHRONOUS,
8164 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568165
8166 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438167 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238168 SYNCHRONOUS,
8169 ConstructClientRequestHeadersPacket(
8170 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8171 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8172 ConnectRequestHeaders("different.example.org:443"),
8173 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438174 mock_quic_data.AddRead(
8175 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338176 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028177 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568178
8179 // GET request, response, and data over QUIC tunnel for second request
8180 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138181 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568182 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438183 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:568184 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418185 mock_quic_data.AddWrite(
8186 SYNCHRONOUS,
8187 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238188 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8189 4, 4, 1, false,
8190 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
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 4, 4, 1, false,
8197 {header4, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418198 }
Yixin Wang46a273ec302018-01-23 17:59:568199
Ryan Hamilton0239aac2018-05-19 00:03:138200 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568201 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438202 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438203 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178204 ASYNC, ConstructServerDataPacket(
8205 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8206 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568207
Ryan Hamilton0239aac2018-05-19 00:03:138208 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198209 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:438210 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438211 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438212 ASYNC, ConstructServerDataPacket(
8213 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438214 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568215
Renjie Tangaadb84b2019-08-31 01:00:238216 mock_quic_data.AddWrite(SYNCHRONOUS,
8217 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:568218 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8219
8220 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418221 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238222 ConstructClientRstPacket(packet_num++,
8223 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418224 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568225 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438226 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238227 ConstructClientRstPacket(packet_num++,
8228 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418229 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568230
8231 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8232
8233 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8234
8235 SSLSocketDataProvider ssl_data(ASYNC, OK);
8236 ssl_data.next_proto = kProtoHTTP2;
8237 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8238
8239 CreateSession();
8240
8241 request_.url = GURL("https://mail.example.org/");
8242 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8243 HeadersHandler headers_handler_1;
8244 trans_1.SetBeforeHeadersSentCallback(
8245 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8246 base::Unretained(&headers_handler_1)));
8247 RunTransaction(&trans_1);
8248 CheckWasHttpResponse(&trans_1);
8249 CheckResponsePort(&trans_1, 70);
8250 CheckResponseData(&trans_1, "0123456789");
8251 EXPECT_TRUE(headers_handler_1.was_proxied());
8252 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8253
8254 request_.url = GURL("https://different.example.org/");
8255 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8256 HeadersHandler headers_handler_2;
8257 trans_2.SetBeforeHeadersSentCallback(
8258 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8259 base::Unretained(&headers_handler_2)));
8260 RunTransaction(&trans_2);
8261 CheckWasSpdyResponse(&trans_2);
8262 CheckResponsePort(&trans_2, 70);
8263 CheckResponseData(&trans_2, "0123456");
8264 EXPECT_TRUE(headers_handler_2.was_proxied());
8265 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8266
8267 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8268 // proxy socket to disconnect.
8269 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8270
8271 base::RunLoop().RunUntilIdle();
8272 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8273 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8274}
8275
8276// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148277TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568278 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148279 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568280 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498281 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568282
Ryan Hamiltonabad59e2019-06-06 04:02:598283 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238284 int packet_num = 1;
8285 if (VersionUsesQpack(version_.transport_version)) {
8286 mock_quic_data.AddWrite(SYNCHRONOUS,
8287 ConstructInitialSettingsPacket(packet_num++));
8288 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:528289 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238290 SYNCHRONOUS,
8291 ConstructClientRequestHeadersPacket(
8292 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8293 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8294 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338295 mock_quic_data.AddRead(
8296 ASYNC, ConstructServerResponseHeadersPacket(
8297 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8298 GetResponseHeaders("500")));
8299 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:238300 mock_quic_data.AddWrite(
8301 SYNCHRONOUS,
8302 ConstructClientAckAndRstPacket(
8303 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8304 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568305
8306 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8307
8308 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8309
8310 CreateSession();
8311
8312 request_.url = GURL("https://mail.example.org/");
8313 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8314 HeadersHandler headers_handler;
8315 trans.SetBeforeHeadersSentCallback(
8316 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8317 base::Unretained(&headers_handler)));
8318 TestCompletionCallback callback;
8319 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8320 EXPECT_EQ(ERR_IO_PENDING, rv);
8321 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8322 EXPECT_EQ(false, headers_handler.was_proxied());
8323
8324 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8325 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8326}
8327
8328// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148329TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568330 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148331 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568332 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498333 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568334
Ryan Hamiltonabad59e2019-06-06 04:02:598335 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238336 int packet_num = 1;
8337 if (VersionUsesQpack(version_.transport_version)) {
8338 mock_quic_data.AddWrite(SYNCHRONOUS,
8339 ConstructInitialSettingsPacket(packet_num++));
8340 }
Fan Yang32c5a112018-12-10 20:06:338341 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238342 SYNCHRONOUS,
8343 ConstructClientRequestHeadersPacket(
8344 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8345 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8346 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:568347 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8348
8349 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8350
8351 CreateSession();
8352
8353 request_.url = GURL("https://mail.example.org/");
8354 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8355 HeadersHandler headers_handler;
8356 trans.SetBeforeHeadersSentCallback(
8357 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8358 base::Unretained(&headers_handler)));
8359 TestCompletionCallback callback;
8360 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8361 EXPECT_EQ(ERR_IO_PENDING, rv);
8362 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8363
8364 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8365 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8366}
8367
8368// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8369// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148370TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568371 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148372 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568373 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498374 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568375
Ryan Hamiltonabad59e2019-06-06 04:02:598376 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238377 int packet_num = 1;
8378 if (VersionUsesQpack(version_.transport_version)) {
8379 mock_quic_data.AddWrite(SYNCHRONOUS,
8380 ConstructInitialSettingsPacket(packet_num++));
8381 }
Fan Yang32c5a112018-12-10 20:06:338382 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238383 SYNCHRONOUS,
8384 ConstructClientRequestHeadersPacket(
8385 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8386 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8387 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438388 mock_quic_data.AddRead(
8389 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338390 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028391 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238392 mock_quic_data.AddWrite(
8393 SYNCHRONOUS,
8394 ConstructClientAckAndRstPacket(
8395 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8396 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568397
Zhongyi Shi32f2fd02018-04-16 18:23:438398 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238399 SYNCHRONOUS,
8400 ConstructClientRequestHeadersPacket(
8401 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8402 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8403 ConnectRequestHeaders("mail.example.org:443"),
8404 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438405 mock_quic_data.AddRead(
8406 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338407 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028408 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568409
8410 const char get_request[] =
8411 "GET / HTTP/1.1\r\n"
8412 "Host: mail.example.org\r\n"
8413 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438414 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568415 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418416 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358417 SYNCHRONOUS,
8418 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238419 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8420 2, 2, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418421 } else {
8422 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418423 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358424 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238425 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8426 2, 2, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418427 }
Yixin Wang46a273ec302018-01-23 17:59:568428 const char get_response[] =
8429 "HTTP/1.1 200 OK\r\n"
8430 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438431 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438432 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338433 ASYNC, ConstructServerDataPacket(
8434 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178435 header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528436
Victor Vasiliev076657c2019-03-12 02:46:438437 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338438 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418439 SYNCHRONOUS, ConstructServerDataPacket(
8440 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178441 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238442 mock_quic_data.AddWrite(SYNCHRONOUS,
8443 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568444 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8445
8446 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418447 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238448 ConstructClientRstPacket(packet_num++,
8449 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418450 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568451
8452 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8453
8454 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8455 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8456
8457 SSLSocketDataProvider ssl_data(ASYNC, OK);
8458 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8459
8460 CreateSession();
8461
8462 request_.url = GURL("https://mail.example.org/");
8463 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8464 HeadersHandler headers_handler;
8465 trans.SetBeforeHeadersSentCallback(
8466 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8467 base::Unretained(&headers_handler)));
8468 TestCompletionCallback callback;
8469 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8470 EXPECT_EQ(ERR_IO_PENDING, rv);
8471 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8472
8473 rv = trans.RestartIgnoringLastError(callback.callback());
8474 EXPECT_EQ(ERR_IO_PENDING, rv);
8475 EXPECT_EQ(OK, callback.WaitForResult());
8476
8477 CheckWasHttpResponse(&trans);
8478 CheckResponsePort(&trans, 70);
8479 CheckResponseData(&trans, "0123456789");
8480 EXPECT_EQ(true, headers_handler.was_proxied());
8481 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8482
8483 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8484 // proxy socket to disconnect.
8485 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8486
8487 base::RunLoop().RunUntilIdle();
8488 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8489 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8490}
8491
8492// Checks if a request's specified "user-agent" header shows up correctly in the
8493// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148494TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008495 const char kConfiguredUserAgent[] = "Configured User-Agent";
8496 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568497 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148498 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568499 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498500 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568501
Ryan Hamiltonabad59e2019-06-06 04:02:598502 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238503 int packet_num = 1;
8504 if (VersionUsesQpack(version_.transport_version)) {
8505 mock_quic_data.AddWrite(SYNCHRONOUS,
8506 ConstructInitialSettingsPacket(packet_num++));
8507 }
Yixin Wang46a273ec302018-01-23 17:59:568508
Ryan Hamilton0239aac2018-05-19 00:03:138509 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008510 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338511 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028512 SYNCHRONOUS,
8513 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238514 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8515 false, HttpProxyConnectJob::kH2QuicTunnelPriority, std::move(headers),
8516 0));
Yixin Wang46a273ec302018-01-23 17:59:568517 // Return an error, so the transaction stops here (this test isn't interested
8518 // in the rest).
8519 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8520
8521 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8522
Matt Menked732ea42019-03-08 12:05:008523 StaticHttpUserAgentSettings http_user_agent_settings(
8524 std::string() /* accept_language */, kConfiguredUserAgent);
8525 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568526 CreateSession();
8527
8528 request_.url = GURL("https://mail.example.org/");
8529 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008530 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568531 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8532 HeadersHandler headers_handler;
8533 trans.SetBeforeHeadersSentCallback(
8534 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8535 base::Unretained(&headers_handler)));
8536 TestCompletionCallback callback;
8537 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8538 EXPECT_EQ(ERR_IO_PENDING, rv);
8539 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8540
8541 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8542 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8543}
8544
Yixin Wang00fc44c2018-01-23 21:12:208545// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8546// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148547TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208548 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148549 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208550 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498551 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208552
8553 const RequestPriority request_priority = MEDIUM;
8554
Ryan Hamiltonabad59e2019-06-06 04:02:598555 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238556 int packet_num = 1;
8557 if (VersionUsesQpack(version_.transport_version)) {
8558 mock_quic_data.AddWrite(SYNCHRONOUS,
8559 ConstructInitialSettingsPacket(packet_num++));
8560 }
Zhongyi Shi32f2fd02018-04-16 18:23:438561 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238562 SYNCHRONOUS,
8563 ConstructClientRequestHeadersPacket(
8564 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8565 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8566 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:208567 // Return an error, so the transaction stops here (this test isn't interested
8568 // in the rest).
8569 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8570
8571 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8572
8573 CreateSession();
8574
8575 request_.url = GURL("https://mail.example.org/");
8576 HttpNetworkTransaction trans(request_priority, session_.get());
8577 TestCompletionCallback callback;
8578 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8579 EXPECT_EQ(ERR_IO_PENDING, rv);
8580 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8581
8582 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8583 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8584}
8585
Matt Menkeedaf3b82019-03-14 21:39:448586// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8587// HTTP/2 stream dependency and weights given the request priority.
8588TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8589 session_params_.enable_quic = true;
8590 session_params_.enable_quic_proxies_for_https_urls = true;
8591 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8592 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8593
8594 const RequestPriority kRequestPriority = MEDIUM;
8595 const RequestPriority kRequestPriority2 = LOWEST;
8596
Ryan Hamiltonabad59e2019-06-06 04:02:598597 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238598 if (VersionUsesQpack(version_.transport_version)) {
8599 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
8600 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8601 } else {
8602 mock_quic_data.AddWrite(
8603 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8604 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
8605 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8606 ConnectRequestHeaders("mail.example.org:443"), 0));
8607 }
Matt Menkeedaf3b82019-03-14 21:39:448608 // This should never be reached.
8609 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8610 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8611
8612 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:598613 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:448614 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8615 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8616
8617 int original_max_sockets_per_group =
8618 ClientSocketPoolManager::max_sockets_per_group(
8619 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8620 ClientSocketPoolManager::set_max_sockets_per_group(
8621 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8622 int original_max_sockets_per_pool =
8623 ClientSocketPoolManager::max_sockets_per_pool(
8624 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8625 ClientSocketPoolManager::set_max_sockets_per_pool(
8626 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8627 CreateSession();
8628
8629 request_.url = GURL("https://mail.example.org/");
8630 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8631 TestCompletionCallback callback;
8632 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8633 EXPECT_EQ(ERR_IO_PENDING, rv);
8634
8635 HttpRequestInfo request2;
8636 request2.url = GURL("https://mail.example.org/some/other/path/");
8637 request2.traffic_annotation =
8638 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8639
8640 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8641 TestCompletionCallback callback2;
8642 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8643 EXPECT_EQ(ERR_IO_PENDING, rv2);
8644
8645 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8646 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8647
8648 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8649
8650 ClientSocketPoolManager::set_max_sockets_per_pool(
8651 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8652 original_max_sockets_per_pool);
8653 ClientSocketPoolManager::set_max_sockets_per_group(
8654 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8655 original_max_sockets_per_group);
8656}
8657
Yixin Wang46a273ec302018-01-23 17:59:568658// Test the request-challenge-retry sequence for basic auth, over a QUIC
8659// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148660TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568661 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8662 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:568663
8664 std::unique_ptr<QuicTestPacketMaker> client_maker;
8665 std::unique_ptr<QuicTestPacketMaker> server_maker;
8666
8667 // On the second pass, the body read of the auth challenge is synchronous, so
8668 // IsConnectedAndIdle returns false. The socket should still be drained and
8669 // reused. See http://crbug.com/544255.
8670 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338671 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178672 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8673 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338674 client_headers_include_h2_stream_dependency_));
8675 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178676 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8677 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568678
8679 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148680 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568681 proxy_resolution_service_ =
8682 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498683 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568684
Ryan Hamiltonabad59e2019-06-06 04:02:598685 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528686 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568687
Renjie Tangaadb84b2019-08-31 01:00:238688 int packet_num = 1;
8689 if (VersionUsesQpack(version_.transport_version)) {
8690 mock_quic_data.AddWrite(
8691 SYNCHRONOUS, client_maker->MakeInitialSettingsPacket(packet_num++));
8692 }
Yixin Wang46a273ec302018-01-23 17:59:568693
8694 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438695 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028696 client_maker->MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238697 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8698 false,
Matt Menke6e879bd2019-03-18 17:26:048699 ConvertRequestPriorityToQuicPriority(
8700 HttpProxyConnectJob::kH2QuicTunnelPriority),
Yixin Wang46a273ec302018-01-23 17:59:568701 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028702 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568703
Ryan Hamilton0239aac2018-05-19 00:03:138704 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568705 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8706 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8707 headers["content-length"] = "10";
8708 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028709 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338710 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028711 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568712
8713 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438714 mock_quic_data.AddRead(
8715 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338716 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178717 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568718 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438719 mock_quic_data.AddRead(
8720 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338721 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:178722 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568723 }
8724 server_data_offset += 10;
8725
Renjie Tangaadb84b2019-08-31 01:00:238726 mock_quic_data.AddWrite(
8727 SYNCHRONOUS, client_maker->MakeAckPacket(packet_num++, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568728
8729 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338730 SYNCHRONOUS,
8731 client_maker->MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:238732 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418733 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:188734 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568735
8736 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8737 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8738 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048739 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028740 client_maker->MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238741 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8742 false,
Matt Menke6e879bd2019-03-18 17:26:048743 ConvertRequestPriorityToQuicPriority(
8744 HttpProxyConnectJob::kH2QuicTunnelPriority),
8745 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:028746 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568747
8748 // Response to wrong password
8749 headers =
8750 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8751 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8752 headers["content-length"] = "10";
8753 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028754 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338755 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028756 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568757 mock_quic_data.AddRead(SYNCHRONOUS,
8758 ERR_IO_PENDING); // No more data to read
8759
Fan Yang32c5a112018-12-10 20:06:338760 mock_quic_data.AddWrite(
8761 SYNCHRONOUS,
8762 client_maker->MakeAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:238763 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Fan Yang32c5a112018-12-10 20:06:338764 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568765
8766 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8767 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8768
8769 CreateSession();
8770
8771 request_.url = GURL("https://mail.example.org/");
8772 // Ensure that proxy authentication is attempted even
8773 // when the no authentication data flag is set.
8774 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8775 {
8776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8777 HeadersHandler headers_handler;
8778 trans.SetBeforeHeadersSentCallback(
8779 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8780 base::Unretained(&headers_handler)));
8781 RunTransaction(&trans);
8782
8783 const HttpResponseInfo* response = trans.GetResponseInfo();
8784 ASSERT_TRUE(response != nullptr);
8785 ASSERT_TRUE(response->headers.get() != nullptr);
8786 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8787 response->headers->GetStatusLine());
8788 EXPECT_TRUE(response->headers->IsKeepAlive());
8789 EXPECT_EQ(407, response->headers->response_code());
8790 EXPECT_EQ(10, response->headers->GetContentLength());
8791 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588792 base::Optional<AuthChallengeInfo> auth_challenge =
8793 response->auth_challenge;
8794 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568795 EXPECT_TRUE(auth_challenge->is_proxy);
8796 EXPECT_EQ("https://proxy.example.org:70",
8797 auth_challenge->challenger.Serialize());
8798 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8799 EXPECT_EQ("basic", auth_challenge->scheme);
8800
8801 TestCompletionCallback callback;
8802 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8803 callback.callback());
8804 EXPECT_EQ(ERR_IO_PENDING, rv);
8805 EXPECT_EQ(OK, callback.WaitForResult());
8806
8807 response = trans.GetResponseInfo();
8808 ASSERT_TRUE(response != nullptr);
8809 ASSERT_TRUE(response->headers.get() != nullptr);
8810 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8811 response->headers->GetStatusLine());
8812 EXPECT_TRUE(response->headers->IsKeepAlive());
8813 EXPECT_EQ(407, response->headers->response_code());
8814 EXPECT_EQ(10, response->headers->GetContentLength());
8815 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588816 auth_challenge = response->auth_challenge;
8817 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568818 EXPECT_TRUE(auth_challenge->is_proxy);
8819 EXPECT_EQ("https://proxy.example.org:70",
8820 auth_challenge->challenger.Serialize());
8821 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8822 EXPECT_EQ("basic", auth_challenge->scheme);
8823 }
8824 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8825 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8826 // reused because it's not connected).
8827 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8828 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8829 }
8830}
8831
Yixin Wang385652a2018-02-16 02:37:238832TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8833 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8834 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:568835 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238836 !client_headers_include_h2_stream_dependency_) {
8837 return;
8838 }
8839
Ryan Hamiltone940bd12019-06-30 02:46:458840 if (quic::VersionUsesQpack(version_.transport_version)) {
8841 // TODO(rch): both stream_dependencies and priority frames need to be
8842 // supported in IETF QUIC.
8843 return;
8844 }
8845
Nick Harper72ade192019-07-17 03:30:428846 session_params_.quic_params.origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:238847 HostPortPair::FromString("mail.example.org:443"));
8848
Fan Yang32c5a112018-12-10 20:06:338849 const quic::QuicStreamId client_stream_0 =
8850 GetNthClientInitiatedBidirectionalStreamId(0);
8851 const quic::QuicStreamId client_stream_1 =
8852 GetNthClientInitiatedBidirectionalStreamId(1);
8853 const quic::QuicStreamId client_stream_2 =
8854 GetNthClientInitiatedBidirectionalStreamId(2);
8855 const quic::QuicStreamId push_stream_0 =
8856 GetNthServerInitiatedUnidirectionalStreamId(0);
8857 const quic::QuicStreamId push_stream_1 =
8858 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238859
Ryan Hamiltonabad59e2019-06-06 04:02:598860 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238861 int packet_num = 1;
8862 if (VersionUsesQpack(version_.transport_version)) {
8863 mock_quic_data.AddWrite(SYNCHRONOUS,
8864 ConstructInitialSettingsPacket(packet_num++));
8865 }
Yixin Wang385652a2018-02-16 02:37:238866
8867 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:238868 mock_quic_data.AddWrite(
8869 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8870 packet_num++, client_stream_0, true, true, HIGHEST,
8871 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:028872 mock_quic_data.AddWrite(
8873 SYNCHRONOUS,
8874 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238875 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028876 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
8877 mock_quic_data.AddWrite(
8878 SYNCHRONOUS,
8879 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238880 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028881 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:238882
8883 // Server replies "OK" for the three requests.
Ryan Hamilton0d65a8c2019-06-07 00:46:028884 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8885 1, client_stream_0, false, false,
8886 GetResponseHeaders("200 OK")));
8887 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8888 2, client_stream_1, false, false,
8889 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238890 mock_quic_data.AddWrite(SYNCHRONOUS,
8891 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton0d65a8c2019-06-07 00:46:028892 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8893 3, client_stream_2, false, false,
8894 GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:238895
8896 // Server sends two push promises associated with |client_stream_0|; client
8897 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8898 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:028899 mock_quic_data.AddRead(
8900 ASYNC,
8901 ConstructServerPushPromisePacket(
8902 4, client_stream_0, push_stream_0, false,
8903 GetRequestHeaders("GET", "https", "/pushed_0.jpg"), &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238904 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438905 SYNCHRONOUS,
8906 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238907 packet_num++, false, 4, 3, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:438908 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:028909 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
8910 mock_quic_data.AddRead(
8911 ASYNC,
8912 ConstructServerPushPromisePacket(
8913 5, client_stream_0, push_stream_1, false,
8914 GetRequestHeaders("GET", "https", "/pushed_1.jpg"), &server_maker_));
8915 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientPriorityPacket(
Renjie Tangaadb84b2019-08-31 01:00:238916 packet_num++, false, push_stream_1,
Ryan Hamilton0d65a8c2019-06-07 00:46:028917 push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:238918
8919 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438920 mock_quic_data.AddRead(
8921 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:028922 6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238923 mock_quic_data.AddWrite(SYNCHRONOUS,
8924 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:438925 mock_quic_data.AddRead(
8926 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:028927 7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:238928
8929 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8930 // priority updates to match the request's priority. Client sends PRIORITY
8931 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438932 mock_quic_data.AddWrite(
8933 SYNCHRONOUS,
8934 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238935 packet_num++, false, 7, 7, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:438936 {{push_stream_1, client_stream_2,
8937 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8938 {push_stream_0, client_stream_0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028939 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:238940
8941 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:438942 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438943 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178944 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Renjief49758b2019-01-11 23:32:418945 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438946 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178947 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Renjief49758b2019-01-11 23:32:418948 header + "hello 1!"));
Renjie Tangaadb84b2019-08-31 01:00:238949 mock_quic_data.AddWrite(SYNCHRONOUS,
8950 ConstructClientAckPacket(packet_num++, 9, 8, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:438951 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178952 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Renjief49758b2019-01-11 23:32:418953 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:438954 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438955 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178956 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true,
Renjief49758b2019-01-11 23:32:418957 header2 + "and hello 0!"));
Renjie Tangaadb84b2019-08-31 01:00:238958 mock_quic_data.AddWrite(SYNCHRONOUS,
8959 ConstructClientAckPacket(packet_num++, 11, 10, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:438960 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178961 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Renjief49758b2019-01-11 23:32:418962 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238963
Yixin Wang385652a2018-02-16 02:37:238964 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8965 mock_quic_data.AddRead(ASYNC, 0); // EOF
8966 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8967
8968 // The non-alternate protocol job needs to hang in order to guarantee that
8969 // the alternate-protocol job will "win".
8970 AddHangingNonAlternateProtocolSocketData();
8971
8972 CreateSession();
8973
8974 request_.url = GURL("https://mail.example.org/0.jpg");
8975 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8976 TestCompletionCallback callback_0;
8977 EXPECT_EQ(ERR_IO_PENDING,
8978 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8979 base::RunLoop().RunUntilIdle();
8980
8981 request_.url = GURL("https://mail.example.org/1.jpg");
8982 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8983 TestCompletionCallback callback_1;
8984 EXPECT_EQ(ERR_IO_PENDING,
8985 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8986 base::RunLoop().RunUntilIdle();
8987
8988 request_.url = GURL("https://mail.example.org/2.jpg");
8989 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8990 TestCompletionCallback callback_2;
8991 EXPECT_EQ(ERR_IO_PENDING,
8992 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8993 base::RunLoop().RunUntilIdle();
8994
8995 // Client makes request that matches resource pushed in |pushed_stream_0|.
8996 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8997 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8998 TestCompletionCallback callback_3;
8999 EXPECT_EQ(ERR_IO_PENDING,
9000 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
9001 base::RunLoop().RunUntilIdle();
9002
9003 EXPECT_TRUE(callback_0.have_result());
9004 EXPECT_EQ(OK, callback_0.WaitForResult());
9005 EXPECT_TRUE(callback_1.have_result());
9006 EXPECT_EQ(OK, callback_1.WaitForResult());
9007 EXPECT_TRUE(callback_2.have_result());
9008 EXPECT_EQ(OK, callback_2.WaitForResult());
9009
9010 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
9011 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
9012 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
9013 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
9014
9015 mock_quic_data.Resume();
9016 base::RunLoop().RunUntilIdle();
9017 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9018 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9019}
9020
Matt Menke26e41542019-06-05 01:09:519021// Test that NetworkIsolationKey is respected by QUIC connections, when
9022// kPartitionConnectionsByNetworkIsolationKey is enabled.
9023TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Shivani Sharma8ae506c2019-07-21 21:08:279024 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9025 const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
9026 NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
9027 NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
Matt Menke26e41542019-06-05 01:09:519028
Nick Harper72ade192019-07-17 03:30:429029 session_params_.quic_params.origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519030 HostPortPair::FromString("mail.example.org:443"));
9031
9032 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
9033 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
9034 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
9035 // the same way as the HTTP over H2 proxy case.
9036 for (bool use_proxy : {false, true}) {
9037 SCOPED_TRACE(use_proxy);
9038
9039 if (use_proxy) {
9040 proxy_resolution_service_ =
9041 ProxyResolutionService::CreateFixedFromPacResult(
9042 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
9043 } else {
9044 proxy_resolution_service_ = ProxyResolutionService::CreateDirect();
9045 }
9046
9047 GURL url1;
9048 GURL url2;
9049 GURL url3;
9050 if (use_proxy) {
9051 url1 = GURL("http://mail.example.org/1");
9052 url2 = GURL("http://mail.example.org/2");
9053 url3 = GURL("http://mail.example.org/3");
9054 } else {
9055 url1 = GURL("https://mail.example.org/1");
9056 url2 = GURL("https://mail.example.org/2");
9057 url3 = GURL("https://mail.example.org/3");
9058 }
9059
9060 for (bool partition_connections : {false, true}) {
9061 SCOPED_TRACE(partition_connections);
9062
9063 base::test::ScopedFeatureList feature_list;
9064 if (partition_connections) {
9065 feature_list.InitAndEnableFeature(
9066 features::kPartitionConnectionsByNetworkIsolationKey);
9067 } else {
9068 feature_list.InitAndDisableFeature(
9069 features::kPartitionConnectionsByNetworkIsolationKey);
9070 }
9071
9072 // Reads and writes for the unpartitioned case, where only one socket is
9073 // used.
9074
Nick Harper72ade192019-07-17 03:30:429075 session_params_.quic_params.origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519076 HostPortPair::FromString("mail.example.org:443"));
9077
Ryan Hamiltonabad59e2019-06-06 04:02:599078 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:519079 QuicTestPacketMaker client_maker1(
9080 version_,
9081 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9082 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9083 client_headers_include_h2_stream_dependency_);
9084 QuicTestPacketMaker server_maker1(
9085 version_,
9086 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9087 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
9088
Renjie Tangaadb84b2019-08-31 01:00:239089 int packet_num = 1;
9090 if (VersionUsesQpack(version_.transport_version)) {
9091 unpartitioned_mock_quic_data.AddWrite(
9092 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
9093 }
Matt Menke26e41542019-06-05 01:09:519094
9095 unpartitioned_mock_quic_data.AddWrite(
9096 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029097 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239098 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9099 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029100 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519101 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029102 ASYNC, server_maker1.MakeResponseHeadersPacket(
9103 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9104 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519105 unpartitioned_mock_quic_data.AddRead(
9106 ASYNC, server_maker1.MakeDataPacket(
9107 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179108 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519109 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239110 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke26e41542019-06-05 01:09:519111
9112 unpartitioned_mock_quic_data.AddWrite(
9113 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029114 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239115 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
9116 false, true,
Matt Menke26e41542019-06-05 01:09:519117 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029118 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519119 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029120 ASYNC, server_maker1.MakeResponseHeadersPacket(
9121 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9122 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519123 unpartitioned_mock_quic_data.AddRead(
9124 ASYNC, server_maker1.MakeDataPacket(
9125 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179126 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519127 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239128 SYNCHRONOUS,
9129 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
Matt Menke26e41542019-06-05 01:09:519130
9131 unpartitioned_mock_quic_data.AddWrite(
9132 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029133 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239134 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
9135 false, true,
Matt Menke26e41542019-06-05 01:09:519136 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029137 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519138 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029139 ASYNC, server_maker1.MakeResponseHeadersPacket(
9140 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
9141 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519142 unpartitioned_mock_quic_data.AddRead(
9143 ASYNC, server_maker1.MakeDataPacket(
9144 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Ryan Hamilton7505eb92019-06-08 00:22:179145 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519146 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239147 SYNCHRONOUS,
9148 ConstructClientAckAndConnectionClosePacket(packet_num++, 6, 5, 1));
Matt Menke26e41542019-06-05 01:09:519149
9150 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9151
9152 // Reads and writes for the partitioned case, where two sockets are used.
9153
Ryan Hamiltonabad59e2019-06-06 04:02:599154 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:519155 QuicTestPacketMaker client_maker2(
9156 version_,
9157 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9158 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9159 client_headers_include_h2_stream_dependency_);
9160 QuicTestPacketMaker server_maker2(
9161 version_,
9162 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9163 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
9164
Renjie Tangaadb84b2019-08-31 01:00:239165 int packet_num2 = 1;
9166 if (VersionUsesQpack(version_.transport_version)) {
9167 partitioned_mock_quic_data1.AddWrite(
9168 SYNCHRONOUS,
9169 client_maker2.MakeInitialSettingsPacket(packet_num2++));
9170 }
Matt Menke26e41542019-06-05 01:09:519171
9172 partitioned_mock_quic_data1.AddWrite(
9173 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029174 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239175 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
9176 true, true,
Matt Menke26e41542019-06-05 01:09:519177 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029178 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519179 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029180 ASYNC, server_maker2.MakeResponseHeadersPacket(
9181 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9182 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519183 partitioned_mock_quic_data1.AddRead(
9184 ASYNC, server_maker2.MakeDataPacket(
9185 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179186 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519187 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239188 SYNCHRONOUS,
9189 client_maker2.MakeAckPacket(packet_num2++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519190
9191 partitioned_mock_quic_data1.AddWrite(
9192 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029193 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239194 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
9195 false, true,
Matt Menke26e41542019-06-05 01:09:519196 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029197 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519198 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029199 ASYNC, server_maker2.MakeResponseHeadersPacket(
9200 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9201 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519202 partitioned_mock_quic_data1.AddRead(
9203 ASYNC, server_maker2.MakeDataPacket(
9204 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179205 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519206 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239207 SYNCHRONOUS,
9208 client_maker2.MakeAckPacket(packet_num2++, 4, 3, 1, true));
Matt Menke26e41542019-06-05 01:09:519209
9210 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9211
Ryan Hamiltonabad59e2019-06-06 04:02:599212 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:519213 QuicTestPacketMaker client_maker3(
9214 version_,
9215 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9216 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9217 client_headers_include_h2_stream_dependency_);
9218 QuicTestPacketMaker server_maker3(
9219 version_,
9220 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9221 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
9222
Renjie Tangaadb84b2019-08-31 01:00:239223 int packet_num3 = 1;
9224 if (VersionUsesQpack(version_.transport_version)) {
9225 partitioned_mock_quic_data2.AddWrite(
9226 SYNCHRONOUS,
9227 client_maker3.MakeInitialSettingsPacket(packet_num3++));
9228 }
Matt Menke26e41542019-06-05 01:09:519229
9230 partitioned_mock_quic_data2.AddWrite(
9231 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029232 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239233 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9234 true, true,
Matt Menke26e41542019-06-05 01:09:519235 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029236 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519237 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029238 ASYNC, server_maker3.MakeResponseHeadersPacket(
9239 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9240 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519241 partitioned_mock_quic_data2.AddRead(
9242 ASYNC, server_maker3.MakeDataPacket(
9243 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179244 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519245 partitioned_mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239246 SYNCHRONOUS,
9247 client_maker3.MakeAckPacket(packet_num3++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519248
9249 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9250
9251 if (partition_connections) {
9252 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9253 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9254 } else {
9255 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9256 }
9257
9258 CreateSession();
9259
9260 TestCompletionCallback callback;
9261 HttpRequestInfo request1;
9262 request1.method = "GET";
9263 request1.url = GURL(url1);
9264 request1.traffic_annotation =
9265 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9266 request1.network_isolation_key = network_isolation_key1;
9267 HttpNetworkTransaction trans1(LOWEST, session_.get());
9268 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9269 EXPECT_THAT(callback.GetResult(rv), IsOk());
9270 std::string response_data1;
9271 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9272 EXPECT_EQ("1", response_data1);
9273
9274 HttpRequestInfo request2;
9275 request2.method = "GET";
9276 request2.url = GURL(url2);
9277 request2.traffic_annotation =
9278 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9279 request2.network_isolation_key = network_isolation_key2;
9280 HttpNetworkTransaction trans2(LOWEST, session_.get());
9281 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9282 EXPECT_THAT(callback.GetResult(rv), IsOk());
9283 std::string response_data2;
9284 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9285 EXPECT_EQ("2", response_data2);
9286
9287 HttpRequestInfo request3;
9288 request3.method = "GET";
9289 request3.url = GURL(url3);
9290 request3.traffic_annotation =
9291 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9292 request3.network_isolation_key = network_isolation_key1;
9293 HttpNetworkTransaction trans3(LOWEST, session_.get());
9294 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9295 EXPECT_THAT(callback.GetResult(rv), IsOk());
9296 std::string response_data3;
9297 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9298 EXPECT_EQ("3", response_data3);
9299
9300 if (partition_connections) {
9301 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9302 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9303 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9304 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9305 } else {
9306 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9307 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9308 }
9309 }
9310 }
9311}
9312
9313// Test that two requests to the same origin over QUIC tunnels use different
9314// QUIC sessions if their NetworkIsolationKeys don't match, and
9315// kPartitionConnectionsByNetworkIsolationKey is enabled.
9316TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9317 base::test::ScopedFeatureList feature_list;
9318 feature_list.InitAndEnableFeature(
9319 features::kPartitionConnectionsByNetworkIsolationKey);
9320
9321 session_params_.enable_quic = true;
9322 session_params_.enable_quic_proxies_for_https_urls = true;
9323 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
9324 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9325
9326 const char kGetRequest[] =
9327 "GET / HTTP/1.1\r\n"
9328 "Host: mail.example.org\r\n"
9329 "Connection: keep-alive\r\n\r\n";
9330 const char kGetResponse[] =
9331 "HTTP/1.1 200 OK\r\n"
9332 "Content-Length: 10\r\n\r\n";
9333
Ryan Hamiltonabad59e2019-06-06 04:02:599334 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9335 std::make_unique<MockQuicData>(version_),
9336 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519337
9338 for (int index : {0, 1}) {
9339 QuicTestPacketMaker client_maker(
9340 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9341 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9342 client_headers_include_h2_stream_dependency_);
9343 QuicTestPacketMaker server_maker(
9344 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9345 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
9346
Renjie Tangaadb84b2019-08-31 01:00:239347 int packet_num = 1;
9348 if (VersionUsesQpack(version_.transport_version)) {
9349 mock_quic_data[index]->AddWrite(
9350 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
9351 }
Matt Menke26e41542019-06-05 01:09:519352
Ryan Hamiltonabad59e2019-06-06 04:02:599353 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519354 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029355 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239356 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9357 false,
Matt Menke26e41542019-06-05 01:09:519358 ConvertRequestPriorityToQuicPriority(
9359 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:029360 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:599361 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029362 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:519363 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9364 false, GetResponseHeaders("200 OK"), nullptr));
9365
9366 std::string header = ConstructDataHeader(strlen(kGetRequest));
9367 if (version_.transport_version != quic::QUIC_VERSION_99) {
Ryan Hamiltonabad59e2019-06-06 04:02:599368 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239369 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
9370 packet_num++, false,
9371 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
9372 1, false, quic::QuicStringPiece(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:519373 } else {
Ryan Hamiltonabad59e2019-06-06 04:02:599374 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239375 SYNCHRONOUS, client_maker.MakeAckAndMultipleDataFramesPacket(
9376 packet_num++, false,
9377 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
9378 1, false, {header, std::string(kGetRequest)}));
Matt Menke26e41542019-06-05 01:09:519379 }
9380
9381 std::string header2 = ConstructDataHeader(strlen(kGetResponse));
Ryan Hamiltonabad59e2019-06-06 04:02:599382 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519383 ASYNC, server_maker.MakeDataPacket(
9384 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179385 false, header2 + std::string(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599386 mock_quic_data[index]->AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179387 SYNCHRONOUS,
9388 server_maker.MakeDataPacket(
9389 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
9390 ConstructDataHeader(10) + std::string("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599391 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239392 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2, 1, true));
Ryan Hamiltonabad59e2019-06-06 04:02:599393 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9394 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:519395
Ryan Hamiltonabad59e2019-06-06 04:02:599396 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:519397 }
9398
9399 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9400 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9401 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9402
9403 CreateSession();
9404
9405 request_.url = GURL("https://mail.example.org/");
9406 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9407 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9408 RunTransaction(&trans);
9409 CheckResponseData(&trans, "0123456789");
9410
9411 HttpRequestInfo request2;
Shivani Sharma8ae506c2019-07-21 21:08:279412 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9413 request_.network_isolation_key = NetworkIsolationKey(kOrigin1, kOrigin1);
Matt Menke26e41542019-06-05 01:09:519414 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9415 RunTransaction(&trans2);
9416 CheckResponseData(&trans2, "0123456789");
9417
Ryan Hamiltonabad59e2019-06-06 04:02:599418 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9419 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9420 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9421 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:519422}
9423
[email protected]61a527782013-02-21 03:58:009424} // namespace test
9425} // namespace net