blob: 6cc402d470c34f7f6be029f429f02b827ea28b71 [file] [log] [blame]
[email protected]61a527782013-02-21 03:58:001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
rchbd089ab2017-05-26 23:05:045#include <algorithm>
bnc359ed2a2016-04-29 20:43:456#include <ostream>
bnc912a04b2016-04-20 14:19:507#include <string>
8#include <utility>
[email protected]1e960032013-12-20 19:00:209#include <vector>
10
Sebastien Marchand6d0558fd2019-01-25 16:49:3711#include "base/bind.h"
[email protected]61a527782013-02-21 03:58:0012#include "base/compiler_specific.h"
Avi Drissman13fc8932015-12-20 04:40:4613#include "base/macros.h"
mmenke651bae7f2015-12-18 21:26:4514#include "base/run_loop.h"
[email protected]98b20ce2013-05-10 05:55:2615#include "base/stl_util.h"
zhongyie537a002017-06-27 16:48:2116#include "base/strings/string_number_conversions.h"
Bence Békyd74f4382018-02-20 18:26:1917#include "base/strings/string_piece.h"
bnc8be55ebb2015-10-30 14:12:0718#include "base/strings/stringprintf.h"
Devlin Cronine4bcb40e2018-06-05 18:02:4719#include "base/test/metrics/histogram_tester.h"
Matt Menke26e41542019-06-05 01:09:5120#include "base/test/scoped_feature_list.h"
rtenneti56977812016-01-15 19:26:5621#include "net/base/chunked_upload_data_stream.h"
Bence Békyd8a21fc32018-06-27 18:29:5822#include "net/base/completion_once_callback.h"
Matt Menke26e41542019-06-05 01:09:5123#include "net/base/features.h"
Tsuyoshi Horo01faed62019-02-20 22:11:3724#include "net/base/ip_endpoint.h"
mgershaf9a9232017-04-13 20:19:0325#include "net/base/mock_network_change_notifier.h"
Matt Menke9aa86262019-08-21 15:52:0726#include "net/base/network_isolation_key.h"
[email protected]61a527782013-02-21 03:58:0027#include "net/base/test_completion_callback.h"
tbansalc3308d72016-08-27 10:25:0428#include "net/base/test_proxy_delegate.h"
rsleevid6de8302016-06-21 01:33:2029#include "net/cert/ct_policy_enforcer.h"
[email protected]6e7845ae2013-03-29 21:48:1130#include "net/cert/mock_cert_verifier.h"
rtenneti052774e2015-11-24 21:00:1231#include "net/cert/multi_log_ct_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5332#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0033#include "net/http/http_auth_handler_factory.h"
34#include "net/http/http_network_session.h"
35#include "net/http/http_network_transaction.h"
Matt Menke6e879bd2019-03-18 17:26:0436#include "net/http/http_proxy_connect_job.h"
Matt Menke609160742019-08-02 18:47:2637#include "net/http/http_server_properties.h"
[email protected]61a527782013-02-21 03:58:0038#include "net/http/http_stream.h"
39#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1940#include "net/http/http_transaction_test_util.h"
[email protected]b1c988b2013-06-13 06:48:1141#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0042#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5143#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4644#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4045#include "net/proxy_resolution/proxy_config_service_fixed.h"
Lily Houghtonffe89daa02018-03-09 18:30:0346#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4047#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0848#include "net/quic/crypto/proof_verifier_chromium.h"
49#include "net/quic/mock_crypto_client_stream_factory.h"
50#include "net/quic/mock_quic_data.h"
51#include "net/quic/quic_chromium_alarm_factory.h"
52#include "net/quic/quic_http_stream.h"
53#include "net/quic/quic_http_utils.h"
54#include "net/quic/quic_stream_factory_peer.h"
55#include "net/quic/quic_test_packet_maker.h"
56#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0057#include "net/socket/client_socket_factory.h"
58#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2159#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2860#include "net/socket/socket_performance_watcher.h"
61#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0062#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5863#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5764#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2965#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0166#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4367#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4068#include "net/test/test_with_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5169#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
70#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
71#include "net/third_party/quiche/src/quic/core/quic_framer.h"
72#include "net/third_party/quiche/src/quic/core/quic_utils.h"
73#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
74#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
75#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
76#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
77#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
78#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
79#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
80#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1481#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
82#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2983#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0084#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4885#include "net/url_request/url_request.h"
86#include "net/url_request/url_request_job_factory_impl.h"
87#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0188#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0089#include "testing/gtest/include/gtest/gtest.h"
90#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4691#include "url/gurl.h"
Matt Menke3233d8f22019-08-20 21:01:4992#include "url/origin.h"
[email protected]61a527782013-02-21 03:58:0093
Reilly Grant89a7e512018-01-20 01:57:1694using ::testing::ElementsAre;
95using ::testing::Key;
96
bnc508835902015-05-12 20:10:2997namespace net {
98namespace test {
[email protected]61a527782013-02-21 03:58:0099
100namespace {
101
bnc359ed2a2016-04-29 20:43:45102enum DestinationType {
103 // In pooling tests with two requests for different origins to the same
104 // destination, the destination should be
105 SAME_AS_FIRST, // the same as the first origin,
106 SAME_AS_SECOND, // the same as the second origin, or
107 DIFFERENT, // different from both.
108};
109
rchf114d982015-10-21 01:34:56110static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52111 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12112static const char kQuicAlternativeServiceWithProbabilityHeader[] =
113 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56114static const char kQuicAlternativeServiceDifferentPortHeader[] =
115 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20116
rch9ae5b3b2016-02-11 00:36:29117const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45118const char kDifferentHostname[] = "different.example.com";
119
120// Run QuicNetworkTransactionWithDestinationTest instances with all value
121// combinations of version and destination_type.
122struct PoolingTestParams {
123 friend std::ostream& operator<<(std::ostream& os,
124 const PoolingTestParams& p) {
Nick Harper23290b82019-05-02 00:02:56125 os << "{ version: " << ParsedQuicVersionToString(p.version)
bnc359ed2a2016-04-29 20:43:45126 << ", destination_type: ";
127 switch (p.destination_type) {
128 case SAME_AS_FIRST:
129 os << "SAME_AS_FIRST";
130 break;
131 case SAME_AS_SECOND:
132 os << "SAME_AS_SECOND";
133 break;
134 case DIFFERENT:
135 os << "DIFFERENT";
136 break;
137 }
Yixin Wang079ad542018-01-11 04:06:05138 os << ", client_headers_include_h2_stream_dependency: "
139 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45140 os << " }";
141 return os;
142 }
143
Nick Harper23290b82019-05-02 00:02:56144 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45145 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05146 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45147};
148
zhongyie537a002017-06-27 16:48:21149std::string GenerateQuicVersionsListForAltSvcHeader(
Nick Harper23290b82019-05-02 00:02:56150 const quic::ParsedQuicVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21151 std::string result = "";
Nick Harper23290b82019-05-02 00:02:56152 for (const quic::ParsedQuicVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21153 if (!result.empty())
154 result.append(",");
Nick Harper23290b82019-05-02 00:02:56155 result.append(base::NumberToString(version.transport_version));
zhongyie537a002017-06-27 16:48:21156 }
157 return result;
158}
159
bnc359ed2a2016-04-29 20:43:45160std::vector<PoolingTestParams> GetPoolingTestParams() {
161 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56162 quic::ParsedQuicVersionVector all_supported_versions =
Ryan Hamilton93424eb82019-08-23 04:28:40163 quic::AllSupportedVersions();
Nick Harper23290b82019-05-02 00:02:56164 for (const quic::ParsedQuicVersion version : all_supported_versions) {
Ryan Hamiltone940bd12019-06-30 02:46:45165 // TODO(rch): crbug.com/978745 - Make this work with TLS
166 if (version.handshake_protocol != quic::PROTOCOL_TLS1_3) {
167 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
168 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
169 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
170 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
171 params.push_back(PoolingTestParams{version, DIFFERENT, false});
172 params.push_back(PoolingTestParams{version, DIFFERENT, true});
173 }
bnc359ed2a2016-04-29 20:43:45174 }
175 return params;
176}
bncb07c05532015-05-14 19:07:20177
[email protected]61a527782013-02-21 03:58:00178} // namespace
179
ryansturm49a8cb12016-06-15 16:51:09180class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12181 public:
ryansturm49a8cb12016-06-15 16:51:09182 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12183
ryansturm49a8cb12016-06-15 16:51:09184 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12185
ryansturm49a8cb12016-06-15 16:51:09186 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
187 HttpRequestHeaders* request_headers) {
188 if (!proxy_info.is_http() && !proxy_info.is_https() &&
189 !proxy_info.is_quic()) {
190 return;
191 }
192 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12193 }
194
195 private:
ryansturm49a8cb12016-06-15 16:51:09196 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12197};
198
tbansal0f56a39a2016-04-07 22:03:38199class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40200 public:
tbansal180587c2017-02-16 15:13:23201 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
202 bool* rtt_notification_received)
203 : should_notify_updated_rtt_(should_notify_updated_rtt),
204 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38205 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40206
tbansal180587c2017-02-16 15:13:23207 bool ShouldNotifyUpdatedRTT() const override {
208 return *should_notify_updated_rtt_;
209 }
tbansalfdf5665b2015-09-21 22:46:40210
tbansal0f56a39a2016-04-07 22:03:38211 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
212 *rtt_notification_received_ = true;
213 }
214
215 void OnConnectionChanged() override {}
216
217 private:
tbansal180587c2017-02-16 15:13:23218 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38219 bool* rtt_notification_received_;
220
221 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
222};
223
224class TestSocketPerformanceWatcherFactory
225 : public SocketPerformanceWatcherFactory {
226 public:
227 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23228 : watcher_count_(0u),
229 should_notify_updated_rtt_(true),
230 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38231 ~TestSocketPerformanceWatcherFactory() override {}
232
233 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42234 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41235 const Protocol protocol,
236 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51237 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38238 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51239 }
240 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42241 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23242 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
243 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40244 }
245
tbansalc8a94ea2015-11-02 23:58:51246 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40247
tbansalc8a94ea2015-11-02 23:58:51248 bool rtt_notification_received() const { return rtt_notification_received_; }
249
tbansal180587c2017-02-16 15:13:23250 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
251 should_notify_updated_rtt_ = should_notify_updated_rtt;
252 }
253
tbansalc8a94ea2015-11-02 23:58:51254 private:
tbansal0f56a39a2016-04-07 22:03:38255 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23256 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51257 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38258
259 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51260};
261
Ryan Hamilton8d9ee76e2018-05-29 23:52:52262class QuicNetworkTransactionTest
263 : public PlatformTest,
264 public ::testing::WithParamInterface<
Nick Harper23290b82019-05-02 00:02:56265 std::tuple<quic::ParsedQuicVersion, bool>>,
Gabriel Charette694c3c332019-08-19 14:53:05266 public WithTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00267 protected:
[email protected]1c04f9522013-02-21 20:32:43268 QuicNetworkTransactionTest()
Yixin Wang079ad542018-01-11 04:06:05269 : version_(std::get<0>(GetParam())),
270 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Nick Harper23290b82019-05-02 00:02:56271 supported_versions_(quic::test::SupportedVersions(version_)),
David Schinazic8281052019-01-24 06:14:17272 random_generator_(0),
273 client_maker_(
274 version_,
275 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
276 &clock_,
277 kDefaultServerHostName,
278 quic::Perspective::IS_CLIENT,
279 client_headers_include_h2_stream_dependency_),
280 server_maker_(
281 version_,
282 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
283 &clock_,
284 kDefaultServerHostName,
285 quic::Perspective::IS_SERVER,
286 false),
Nick Harpereb483e12019-05-14 00:18:09287 quic_task_runner_(new TestTaskRunner(&clock_)),
rtenneti052774e2015-11-24 21:00:12288 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43289 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59290 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11291 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke3233d8f22019-08-20 21:01:49292 http_server_properties_(std::make_unique<HttpServerProperties>()),
rchf114d982015-10-21 01:34:56293 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19294 request_.method = "GET";
rchf114d982015-10-21 01:34:56295 std::string url("https://");
bncb07c05532015-05-14 19:07:20296 url.append(kDefaultServerHostName);
297 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19298 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10299 request_.traffic_annotation =
300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52301 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56302
303 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29304 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56305 verify_details_.cert_verify_result.verified_cert = cert;
306 verify_details_.cert_verify_result.is_issued_by_known_root = true;
307 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43308 }
[email protected]61a527782013-02-21 03:58:00309
dcheng67be2b1f2014-10-27 21:47:29310 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00311 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55312 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00313 }
314
dcheng67be2b1f2014-10-27 21:47:29315 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00316 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
317 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55318 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00319 PlatformTest::TearDown();
320 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55321 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40322 session_.reset();
[email protected]61a527782013-02-21 03:58:00323 }
324
Ryan Hamilton8d9ee76e2018-05-29 23:52:52325 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23326 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03327 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52328 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30329 }
330
Ryan Hamilton8d9ee76e2018-05-29 23:52:52331 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23332 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03333 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52334 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58335 }
336
Ryan Hamilton8d9ee76e2018-05-29 23:52:52337 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23338 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52339 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20340 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58341 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20342 }
343
Ryan Hamilton8d9ee76e2018-05-29 23:52:52344 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23345 uint64_t packet_number,
346 uint64_t largest_received,
347 uint64_t smallest_received,
348 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37349 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49350 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37351 }
352
Ryan Hamilton8d9ee76e2018-05-29 23:52:52353 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23354 uint64_t packet_number,
355 uint64_t largest_received,
356 uint64_t smallest_received,
357 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52358 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23359 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49360 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23361 ack_delay_time);
362 }
363
Ryan Hamilton8d9ee76e2018-05-29 23:52:52364 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23365 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52366 quic::QuicStreamId stream_id,
367 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23368 uint64_t largest_received,
369 uint64_t smallest_received,
370 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58371 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49372 num, false, stream_id, error_code, largest_received, smallest_received,
373 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20374 }
375
Ryan Hamilton8d9ee76e2018-05-29 23:52:52376 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23377 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52378 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41379 quic::QuicRstStreamErrorCode error_code) {
Yixin Wang46a273ec302018-01-23 17:59:56380 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18381 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56382 }
383
Ryan Hamilton8d9ee76e2018-05-29 23:52:52384 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23385 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
386 uint64_t largest_received,
387 uint64_t smallest_received,
388 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58389 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49390 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20391 }
[email protected]61a527782013-02-21 03:58:00392
Ryan Hamilton8d9ee76e2018-05-29 23:52:52393 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58394 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23395 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52396 quic::QuicTime::Delta delta_time_largest_observed,
Fan Yangac867502019-01-28 21:10:23397 uint64_t largest_received,
398 uint64_t smallest_received,
399 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52400 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29401 const std::string& quic_error_details,
402 uint64_t frame_type) {
alyssar2adf3ac2016-05-03 17:12:58403 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12404 num, false, delta_time_largest_observed, largest_received,
Renjie Tangff0d6372019-08-30 22:03:29405 smallest_received, least_unacked, quic_error, quic_error_details,
406 frame_type);
zhongyica364fbb2015-12-12 03:39:12407 }
408
Ryan Hamilton8d9ee76e2018-05-29 23:52:52409 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23410 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12411 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52412 quic::QuicStreamId stream_id,
413 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58414 return server_maker_.MakeRstPacket(num, include_version, stream_id,
415 error_code);
zhongyica364fbb2015-12-12 03:39:12416 }
417
Ryan Hamilton8d9ee76e2018-05-29 23:52:52418 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02419 uint64_t packet_number) {
420 return client_maker_.MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37421 }
422
Ryan Hamilton8d9ee76e2018-05-29 23:52:52423 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23424 uint64_t packet_number,
425 uint64_t largest_received,
426 uint64_t smallest_received,
427 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37428 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49429 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37430 }
431
Ryan Hamilton8d9ee76e2018-05-29 23:52:52432 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23433 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57434 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52435 quic::QuicStreamId id,
436 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02437 RequestPriority request_priority) {
Yixin Wangb470bc882018-02-15 18:43:57438 return client_maker_.MakePriorityPacket(
439 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02440 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wang385652a2018-02-16 02:37:23441 }
442
Ryan Hamilton8d9ee76e2018-05-29 23:52:52443 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25444 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23445 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23446 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23447 uint64_t largest_received,
448 uint64_t smallest_received,
449 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25450 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
Ryan Hamilton0d65a8c2019-06-07 00:46:02451 priority_frames) {
Yixin Wange7ecc472018-03-06 19:00:25452 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23453 packet_number, should_include_version, largest_received,
Ryan Hamilton0d65a8c2019-06-07 00:46:02454 smallest_received, least_unacked, priority_frames);
Yixin Wangb470bc882018-02-15 18:43:57455 }
456
zhongyi32569c62016-01-08 02:54:30457 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13458 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
459 const std::string& scheme,
460 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58461 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30462 }
463
464 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13465 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
466 const std::string& scheme,
467 const std::string& path,
468 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50469 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00470 }
471
Ryan Hamilton0239aac2018-05-19 00:03:13472 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56473 return client_maker_.ConnectRequestHeaders(host_port);
474 }
475
Ryan Hamilton0239aac2018-05-19 00:03:13476 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58477 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00478 }
479
zhongyi32569c62016-01-08 02:54:30480 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13481 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
482 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58483 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30484 }
485
Ryan Hamilton8d9ee76e2018-05-29 23:52:52486 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23487 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52488 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05489 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00490 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52491 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17492 return server_maker_.MakeDataPacket(packet_number, stream_id,
493 should_include_version, fin, data);
[email protected]61a527782013-02-21 03:58:00494 }
495
Ryan Hamilton8d9ee76e2018-05-29 23:52:52496 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23497 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52498 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36499 bool should_include_version,
500 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52501 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17502 return client_maker_.MakeDataPacket(packet_number, stream_id,
503 should_include_version, fin, data);
ckrasicda193a82016-07-09 00:39:36504 }
505
Renjied172e812019-01-16 05:12:35506 std::unique_ptr<quic::QuicEncryptedPacket>
507 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23508 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35509 quic::QuicStreamId stream_id,
510 bool should_include_version,
511 bool fin,
Renjied172e812019-01-16 05:12:35512 const std::vector<std::string> data_writes) {
Ryan Hamilton7505eb92019-06-08 00:22:17513 return client_maker_.MakeMultipleDataFramesPacket(
514 packet_number, stream_id, should_include_version, fin, data_writes);
Renjied172e812019-01-16 05:12:35515 }
516
Ryan Hamilton8d9ee76e2018-05-29 23:52:52517 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23518 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56519 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52520 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23521 uint64_t largest_received,
522 uint64_t smallest_received,
523 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56524 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52525 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56526 return client_maker_.MakeAckAndDataPacket(
527 packet_number, include_version, stream_id, largest_received,
Ryan Hamilton7505eb92019-06-08 00:22:17528 smallest_received, least_unacked, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56529 }
530
Renjied172e812019-01-16 05:12:35531 std::unique_ptr<quic::QuicEncryptedPacket>
532 ConstructClientAckAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23533 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35534 bool include_version,
535 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23536 uint64_t largest_received,
537 uint64_t smallest_received,
538 uint64_t least_unacked,
Renjied172e812019-01-16 05:12:35539 bool fin,
Renjied172e812019-01-16 05:12:35540 const std::vector<std::string> data_writes) {
541 return client_maker_.MakeAckAndMultipleDataFramesPacket(
542 packet_number, include_version, stream_id, largest_received,
Ryan Hamilton7505eb92019-06-08 00:22:17543 smallest_received, least_unacked, fin, data_writes);
Renjied172e812019-01-16 05:12:35544 }
545
Ryan Hamilton8d9ee76e2018-05-29 23:52:52546 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
Fan Yangac867502019-01-28 21:10:23547 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52548 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36549 bool should_include_version,
550 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52551 quic::QuicStreamOffset* offset,
552 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36553 return client_maker_.MakeForceHolDataPacket(
554 packet_number, stream_id, should_include_version, fin, offset, data);
555 }
556
Ryan Hamilton8d9ee76e2018-05-29 23:52:52557 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23558 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52559 quic::QuicStreamId stream_id,
560 bool should_include_version,
561 bool fin,
562 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56563 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
564 should_include_version, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02565 std::move(headers), 0);
Yixin Wang46a273ec302018-01-23 17:59:56566 }
567
Ryan Hamilton8d9ee76e2018-05-29 23:52:52568 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23569 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52570 quic::QuicStreamId stream_id,
571 bool should_include_version,
572 bool fin,
573 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02574 quic::QuicStreamId parent_stream_id) {
Yixin Wang46a273ec302018-01-23 17:59:56575 return ConstructClientRequestHeadersPacket(
576 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:02577 std::move(headers), parent_stream_id);
zhongyi32569c62016-01-08 02:54:30578 }
579
Ryan Hamilton8d9ee76e2018-05-29 23:52:52580 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23581 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52582 quic::QuicStreamId stream_id,
583 bool should_include_version,
584 bool fin,
585 RequestPriority request_priority,
586 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02587 quic::QuicStreamId parent_stream_id) {
Ryan Hamilton0239aac2018-05-19 00:03:13588 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56589 ConvertRequestPriorityToQuicPriority(request_priority);
Ryan Hamilton0d65a8c2019-06-07 00:46:02590 return client_maker_.MakeRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56591 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02592 std::move(headers), parent_stream_id, nullptr);
[email protected]61a527782013-02-21 03:58:00593 }
594
Ryan Hamilton8d9ee76e2018-05-29 23:52:52595 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25596 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23597 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52598 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25599 bool should_include_version,
600 bool fin,
601 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13602 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52603 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25604 size_t* spdy_headers_frame_length,
605 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13606 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25607 ConvertRequestPriorityToQuicPriority(request_priority);
608 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
609 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02610 std::move(headers), parent_stream_id, spdy_headers_frame_length,
Yixin Wange7ecc472018-03-06 19:00:25611 data_writes);
612 }
613
Ryan Hamilton8d9ee76e2018-05-29 23:52:52614 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23615 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52616 quic::QuicStreamId stream_id,
617 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13618 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13619 spdy::SpdyHeaderBlock headers,
ckrasic769733c2016-06-30 00:42:13620 QuicTestPacketMaker* maker) {
621 return maker->MakePushPromisePacket(
622 packet_number, stream_id, promised_stream_id, should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02623 false, std::move(headers), nullptr);
ckrasic769733c2016-06-30 00:42:13624 }
625
Ryan Hamilton8d9ee76e2018-05-29 23:52:52626 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23627 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52628 quic::QuicStreamId stream_id,
629 bool should_include_version,
630 bool fin,
631 spdy::SpdyHeaderBlock headers) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02632 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
633 should_include_version, fin,
634 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30635 }
636
Victor Vasiliev076657c2019-03-12 02:46:43637 std::string ConstructDataHeader(size_t body_len) {
Nick Harper23290b82019-05-02 00:02:56638 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:41639 return "";
640 }
641 quic::HttpEncoder encoder;
642 std::unique_ptr<char[]> buffer;
643 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43644 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41645 }
646
Nick Harper23290b82019-05-02 00:02:56647 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41648 session_params_.enable_quic = true;
Nick Harper72ade192019-07-17 03:30:42649 session_params_.quic_params.supported_versions = supported_versions;
Bence Béky1ceba552019-07-19 17:11:05650 session_params_.quic_params.max_allowed_push_id = quic::kMaxQuicStreamId;
Nick Harper72ade192019-07-17 03:30:42651 session_params_.quic_params.headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:05652 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00653
mmenke6ddfbea2017-05-31 21:48:41654 session_context_.quic_clock = &clock_;
655 session_context_.quic_random = &random_generator_;
656 session_context_.client_socket_factory = &socket_factory_;
657 session_context_.quic_crypto_client_stream_factory =
658 &crypto_client_stream_factory_;
659 session_context_.host_resolver = &host_resolver_;
660 session_context_.cert_verifier = &cert_verifier_;
661 session_context_.transport_security_state = &transport_security_state_;
662 session_context_.cert_transparency_verifier =
663 cert_transparency_verifier_.get();
664 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
665 session_context_.socket_performance_watcher_factory =
666 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59667 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41668 session_context_.ssl_config_service = ssl_config_service_.get();
669 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49670 session_context_.http_server_properties = http_server_properties_.get();
mmenke6ddfbea2017-05-31 21:48:41671 session_context_.net_log = net_log_.bound().net_log();
672
673 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12674 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56675 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
676 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00677 }
678
zhongyi86838d52017-06-30 01:19:44679 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21680
bnc691fda62016-08-12 00:43:16681 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19682 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42683 ASSERT_TRUE(response != nullptr);
684 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19685 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
686 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52687 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:56688 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
689 version_.transport_version),
[email protected]aa9b14d2013-05-10 23:45:19690 response->connection_info);
691 }
692
bnc691fda62016-08-12 00:43:16693 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41694 const HttpResponseInfo* response = trans->GetResponseInfo();
695 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37696 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41697 }
698
bnc691fda62016-08-12 00:43:16699 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19700 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42701 ASSERT_TRUE(response != nullptr);
702 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19703 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
704 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52705 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52706 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19707 response->connection_info);
708 }
709
Yixin Wang46a273ec302018-01-23 17:59:56710 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
711 const HttpResponseInfo* response = trans->GetResponseInfo();
712 ASSERT_TRUE(response != nullptr);
713 ASSERT_TRUE(response->headers.get() != nullptr);
714 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
715 EXPECT_TRUE(response->was_fetched_via_spdy);
716 EXPECT_TRUE(response->was_alpn_negotiated);
717 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
718 response->connection_info);
719 }
720
bnc691fda62016-08-12 00:43:16721 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19722 const std::string& expected) {
723 std::string response_data;
bnc691fda62016-08-12 00:43:16724 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19725 EXPECT_EQ(expected, response_data);
726 }
727
bnc691fda62016-08-12 00:43:16728 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19729 TestCompletionCallback callback;
730 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01731 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
732 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19733 }
734
735 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16736 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
737 RunTransaction(&trans);
738 CheckWasHttpResponse(&trans);
739 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19740 }
741
tbansalc3308d72016-08-27 10:25:04742 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
743 bool used_proxy,
744 uint16_t port) {
745 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
746 HeadersHandler headers_handler;
747 trans.SetBeforeHeadersSentCallback(
748 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
749 base::Unretained(&headers_handler)));
750 RunTransaction(&trans);
751 CheckWasHttpResponse(&trans);
752 CheckResponsePort(&trans, port);
753 CheckResponseData(&trans, expected);
754 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47755 if (used_proxy) {
756 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
757 } else {
758 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
759 }
tbansalc3308d72016-08-27 10:25:04760 }
761
[email protected]aa9b14d2013-05-10 23:45:19762 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56763 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12764 }
765
bnc62a44f022015-04-02 15:59:41766 void SendRequestAndExpectQuicResponseFromProxyOnPort(
767 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46768 uint16_t port) {
bnc62a44f022015-04-02 15:59:41769 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19770 }
771
772 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27773 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19774 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46775 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21776 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12777 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49778 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07779 server, NetworkIsolationKey(), alternative_service, expiration,
780 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19781 }
782
rchbe69cb902016-02-11 01:10:48783 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27784 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48785 const HostPortPair& alternative) {
786 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46787 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21788 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48789 alternative.port());
790 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49791 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07792 server, NetworkIsolationKey(), alternative_service, expiration,
793 supported_versions_);
rchbe69cb902016-02-11 01:10:48794 }
795
[email protected]aa9b14d2013-05-10 23:45:19796 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46797 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34798 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49799 http_server_properties_->GetAlternativeServiceInfos(
800 server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:34801 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49802 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54803 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19804 }
805
[email protected]4d590c9c2014-05-02 05:14:33806 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46807 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34808 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49809 http_server_properties_->GetAlternativeServiceInfos(
810 server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:34811 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54812 EXPECT_EQ(
813 kProtoQUIC,
814 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49815 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54816 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33817 }
818
[email protected]aa9b14d2013-05-10 23:45:19819 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42820 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30821 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30822 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30823 hanging_data->set_connect_data(hanging_connect);
824 hanging_data_.push_back(std::move(hanging_data));
825 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56826 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19827 }
828
Zhongyi Shia6b68d112018-09-24 07:49:03829 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Nick Harper72ade192019-07-17 03:30:42830 session_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
831 session_params_.quic_params.migrate_sessions_early_v2 = true;
832 session_params_.quic_params.retry_on_alternate_network_before_handshake =
833 true;
Zhongyi Shia6b68d112018-09-24 07:49:03834 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
835 MockNetworkChangeNotifier* mock_ncn =
836 scoped_mock_change_notifier_->mock_network_change_notifier();
837 mock_ncn->ForceNetworkHandlesSupported();
838 mock_ncn->SetConnectedNetworksList(
839 {kDefaultNetworkForTests, kNewNetworkForTests});
840 }
841
tbansalc3308d72016-08-27 10:25:04842 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
843 // alternative proxy. Verifies that if the alternative proxy job returns
844 // |error_code|, the request is fetched successfully by the main job.
845 void TestAlternativeProxy(int error_code) {
846 // Use a non-cryptographic scheme for the request URL since this request
847 // will be fetched via proxy with QUIC as the alternative service.
848 request_.url = GURL("http://example.org/");
849 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27850 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04851 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27852 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04853 };
854
Ryan Sleevib8d7ea02018-05-07 20:01:01855 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04856 socket_factory_.AddSocketDataProvider(&quic_data);
857
858 // Main job succeeds and the alternative job fails.
859 // Add data for two requests that will be read by the main job.
860 MockRead http_reads_1[] = {
861 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
862 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
863 MockRead(ASYNC, OK)};
864
865 MockRead http_reads_2[] = {
866 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
867 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
868 MockRead(ASYNC, OK)};
869
Ryan Sleevib8d7ea02018-05-07 20:01:01870 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
871 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04872 socket_factory_.AddSocketDataProvider(&http_data_1);
873 socket_factory_.AddSocketDataProvider(&http_data_2);
874 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
875 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
876
877 TestProxyDelegate test_proxy_delegate;
878 // Proxy URL is different from the request URL.
879 test_proxy_delegate.set_alternative_proxy_server(
880 ProxyServer::FromPacString("QUIC myproxy.org:443"));
881
Lily Houghton8c2f97d2018-01-22 05:06:59882 proxy_resolution_service_ =
883 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49884 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52885 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04886
887 CreateSession();
888 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
889
890 // The first request should be fetched via the HTTPS proxy.
891 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
892
Reilly Grant89a7e512018-01-20 01:57:16893 // Since the main job succeeded only the alternative proxy server should be
894 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59895 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16896 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04897
898 // Verify that the second request completes successfully, and the
899 // alternative proxy server job is not started.
900 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
901 }
902
Fan Yang32c5a112018-12-10 20:06:33903 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56904 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
905 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36906 }
907
Fan Yang32c5a112018-12-10 20:06:33908 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56909 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
910 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36911 }
912
Bence Béky230ac612017-08-30 19:17:08913 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49914 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08915 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49916 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08917 }
918
Nick Harper23290b82019-05-02 00:02:56919 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05920 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:56921 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01922 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52923 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:17924 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:58925 QuicTestPacketMaker client_maker_;
926 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:09927 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:42928 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00929 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56930 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05931 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43932 MockHostResolver host_resolver_;
933 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11934 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42935 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23936 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38937 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07938 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59939 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42940 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:49941 std::unique_ptr<HttpServerProperties> http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41942 HttpNetworkSession::Params session_params_;
943 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19944 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51945 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42946 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56947 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03948 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12949
950 private:
951 void SendRequestAndExpectQuicResponseMaybeFromProxy(
952 const std::string& expected,
bnc62a44f022015-04-02 15:59:41953 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46954 uint16_t port) {
bnc691fda62016-08-12 00:43:16955 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09956 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16957 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09958 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
959 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16960 RunTransaction(&trans);
961 CheckWasQuicResponse(&trans);
962 CheckResponsePort(&trans, port);
963 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09964 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47965 if (used_proxy) {
966 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
967 } else {
968 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
969 }
tbansal7cec3812015-02-05 21:25:12970 }
[email protected]61a527782013-02-21 03:58:00971};
972
Ryan Hamiltone940bd12019-06-30 02:46:45973quic::ParsedQuicVersionVector AllSupportedVersionsWithoutTls() {
974 quic::ParsedQuicVersionVector versions;
Ryan Hamilton93424eb82019-08-23 04:28:40975 for (auto version : quic::AllSupportedVersions()) {
Ryan Hamiltone940bd12019-06-30 02:46:45976 // TODO(rch): crbug.com/978745 - Make this work with TLS
977 if (version.handshake_protocol != quic::PROTOCOL_TLS1_3) {
978 versions.push_back(version);
979 }
980 }
981 return versions;
982}
983
Victor Costane635086f2019-01-27 05:20:30984INSTANTIATE_TEST_SUITE_P(
Yixin Wang385652a2018-02-16 02:37:23985 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05986 QuicNetworkTransactionTest,
Ryan Hamiltone940bd12019-06-30 02:46:45987 ::testing::Combine(::testing::ValuesIn(AllSupportedVersionsWithoutTls()),
Nick Harper23290b82019-05-02 00:02:56988 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:20989
Shivani Sharma8ae506c2019-07-21 21:08:27990// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
991// kAppendInitiatingFrameOriginToNetworkIsolationKey.
992
Ryan Hamiltona64a5bcf2017-11-30 07:35:28993TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:42994 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:28995 base::HistogramTester histograms;
Nick Harper72ade192019-07-17 03:30:42996 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:28997 HostPortPair::FromString("mail.example.org:443"));
998 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27999 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281000
Ryan Hamiltonabad59e2019-06-06 04:02:591001 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231002 if (VersionUsesQpack(version_.transport_version))
1003 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281004 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1005 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1006 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1007
1008 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1009
1010 CreateSession();
1011
1012 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1013 TestCompletionCallback callback;
1014 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1016 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1017
1018 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1019 -ERR_INTERNET_DISCONNECTED, 1);
1020 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1021 -ERR_INTERNET_DISCONNECTED, 1);
1022}
1023
1024TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Nick Harper72ade192019-07-17 03:30:421025 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281026 base::HistogramTester histograms;
Nick Harper72ade192019-07-17 03:30:421027 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281028 HostPortPair::FromString("mail.example.org:443"));
1029 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271030 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281031
Ryan Hamiltonabad59e2019-06-06 04:02:591032 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231033 if (VersionUsesQpack(version_.transport_version))
1034 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281035 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1036 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1037 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1038
1039 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1040
1041 CreateSession();
1042
1043 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1044 TestCompletionCallback callback;
1045 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1047 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1048
1049 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1050 -ERR_INTERNET_DISCONNECTED, 1);
1051 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1052 -ERR_INTERNET_DISCONNECTED, 1);
1053}
1054
tbansal180587c2017-02-16 15:13:231055TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Nick Harper72ade192019-07-17 03:30:421056 session_params_.quic_params.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231057 HostPortPair::FromString("mail.example.org:443"));
1058
Ryan Hamiltonabad59e2019-06-06 04:02:591059 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231060 int packet_num = 1;
1061 if (VersionUsesQpack(version_.transport_version)) {
1062 mock_quic_data.AddWrite(SYNCHRONOUS,
1063 ConstructInitialSettingsPacket(packet_num++));
1064 }
rch5cb522462017-04-25 20:18:361065 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231066 SYNCHRONOUS,
1067 ConstructClientRequestHeadersPacket(
1068 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1069 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431070 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331071 ASYNC, ConstructServerResponseHeadersPacket(
1072 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1073 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431074 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331075 mock_quic_data.AddRead(
1076 ASYNC, ConstructServerDataPacket(
1077 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171078 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231079 mock_quic_data.AddWrite(SYNCHRONOUS,
1080 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231081 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1082
1083 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1084
1085 CreateSession();
1086 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1087
1088 EXPECT_FALSE(
1089 test_socket_performance_watcher_factory_.rtt_notification_received());
1090 SendRequestAndExpectQuicResponse("hello!");
1091 EXPECT_TRUE(
1092 test_socket_performance_watcher_factory_.rtt_notification_received());
1093}
1094
1095TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Nick Harper72ade192019-07-17 03:30:421096 session_params_.quic_params.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231097 HostPortPair::FromString("mail.example.org:443"));
1098
Ryan Hamiltonabad59e2019-06-06 04:02:591099 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231100 int packet_num = 1;
1101 if (VersionUsesQpack(version_.transport_version)) {
1102 mock_quic_data.AddWrite(SYNCHRONOUS,
1103 ConstructInitialSettingsPacket(packet_num++));
1104 }
rch5cb522462017-04-25 20:18:361105 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231106 SYNCHRONOUS,
1107 ConstructClientRequestHeadersPacket(
1108 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1109 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431110 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331111 ASYNC, ConstructServerResponseHeadersPacket(
1112 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1113 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431114 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331115 mock_quic_data.AddRead(
1116 ASYNC, ConstructServerDataPacket(
1117 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171118 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231119 mock_quic_data.AddWrite(SYNCHRONOUS,
1120 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231121 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1122
1123 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1124
1125 CreateSession();
1126 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1127
1128 EXPECT_FALSE(
1129 test_socket_performance_watcher_factory_.rtt_notification_received());
1130 SendRequestAndExpectQuicResponse("hello!");
1131 EXPECT_FALSE(
1132 test_socket_performance_watcher_factory_.rtt_notification_received());
1133}
1134
[email protected]1e960032013-12-20 19:00:201135TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Nick Harper72ade192019-07-17 03:30:421136 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571137 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471138
Ryan Hamiltonabad59e2019-06-06 04:02:591139 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231140 int packet_num = 1;
1141 if (VersionUsesQpack(version_.transport_version)) {
1142 mock_quic_data.AddWrite(SYNCHRONOUS,
1143 ConstructInitialSettingsPacket(packet_num++));
1144 }
rch5cb522462017-04-25 20:18:361145 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231146 SYNCHRONOUS,
1147 ConstructClientRequestHeadersPacket(
1148 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1149 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431150 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331151 ASYNC, ConstructServerResponseHeadersPacket(
1152 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1153 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431154 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331155 mock_quic_data.AddRead(
1156 ASYNC, ConstructServerDataPacket(
1157 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171158 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231159 mock_quic_data.AddWrite(SYNCHRONOUS,
1160 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591161 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471162
rcha5399e02015-04-21 19:32:041163 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471164
[email protected]4dca587c2013-03-07 16:54:471165 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471166
[email protected]aa9b14d2013-05-10 23:45:191167 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471168
[email protected]98b20ce2013-05-10 05:55:261169 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:541170 auto entries = net_log_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261171 EXPECT_LT(0u, entries.size());
1172
1173 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291174 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001175 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1176 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261177 EXPECT_LT(0, pos);
1178
rchfd527212015-08-25 00:41:261179 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291180 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261181 entries, 0,
mikecirone8b85c432016-09-08 19:11:001182 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1183 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261184 EXPECT_LT(0, pos);
1185
Eric Roman79cc7552019-07-19 02:17:541186 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261187
rchfd527212015-08-25 00:41:261188 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1189 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001190 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1191 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261192 EXPECT_LT(0, pos);
1193
[email protected]98b20ce2013-05-10 05:55:261194 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291195 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001196 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1197 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261198 EXPECT_LT(0, pos);
1199
Eric Roman79cc7552019-07-19 02:17:541200 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Ryan Hamiltone940bd12019-06-30 02:46:451201 if (quic::VersionUsesQpack(version_.transport_version)) {
1202 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1203 static_cast<quic::QuicStreamId>(log_stream_id));
1204 } else {
1205 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1206 static_cast<quic::QuicStreamId>(log_stream_id));
1207 }
[email protected]4dca587c2013-03-07 16:54:471208}
1209
rchbd089ab2017-05-26 23:05:041210TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Ryan Hamiltone940bd12019-06-30 02:46:451211 // TODO(rch): honor the max header list size. b/136108828
1212 if (quic::VersionUsesQpack(version_.transport_version))
1213 return;
1214
Nick Harper72ade192019-07-17 03:30:421215 session_params_.quic_params.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041216 HostPortPair::FromString("mail.example.org:443"));
1217
Ryan Hamiltonabad59e2019-06-06 04:02:591218 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231219 int packet_num = 1;
1220 if (VersionUsesQpack(version_.transport_version)) {
1221 mock_quic_data.AddWrite(SYNCHRONOUS,
1222 ConstructInitialSettingsPacket(packet_num++));
1223 }
rchbd089ab2017-05-26 23:05:041224 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231225 SYNCHRONOUS,
1226 ConstructClientRequestHeadersPacket(
1227 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1228 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0239aac2018-05-19 00:03:131229 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041230 response_headers["key1"] = std::string(30000, 'A');
1231 response_headers["key2"] = std::string(30000, 'A');
1232 response_headers["key3"] = std::string(30000, 'A');
1233 response_headers["key4"] = std::string(30000, 'A');
1234 response_headers["key5"] = std::string(30000, 'A');
1235 response_headers["key6"] = std::string(30000, 'A');
1236 response_headers["key7"] = std::string(30000, 'A');
1237 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451238 quic::QuicStreamId stream_id;
1239 std::string response_data;
1240 if (quic::VersionUsesQpack(version_.transport_version)) {
1241 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1242 std::vector<std::string> encoded = server_maker_.QpackEncodeHeaders(
1243 stream_id, std::move(response_headers), nullptr);
1244 for (const auto& e : encoded) {
1245 response_data += e;
1246 }
1247 } else {
1248 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1249 spdy::SpdyHeadersIR headers_frame(
1250 GetNthClientInitiatedBidirectionalStreamId(0),
1251 std::move(response_headers));
1252 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1253 spdy::SpdySerializedFrame spdy_frame =
1254 response_framer.SerializeFrame(headers_frame);
1255 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1256 }
rchbd089ab2017-05-26 23:05:041257
Fan Yangac867502019-01-28 21:10:231258 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041259 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451260 for (size_t offset = 0; offset < response_data.length();
1261 offset += chunk_size) {
1262 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431263 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451264 ASYNC, ConstructServerDataPacket(
1265 packet_number++, stream_id, false, false,
1266 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041267 }
1268
Victor Vasiliev076657c2019-03-12 02:46:431269 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041270 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331271 ASYNC, ConstructServerDataPacket(
1272 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171273 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041274 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431275 mock_quic_data.AddWrite(ASYNC,
Renjie Tangaadb84b2019-08-31 01:00:231276 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1277 mock_quic_data.AddWrite(
1278 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041279
1280 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1281
1282 CreateSession();
1283
1284 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421285 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1286 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041287}
1288
1289TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Nick Harper72ade192019-07-17 03:30:421290 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
1291 session_params_.quic_params.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041292 HostPortPair::FromString("mail.example.org:443"));
1293
Ryan Hamiltonabad59e2019-06-06 04:02:591294 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231295 int packet_num = 1;
1296 if (VersionUsesQpack(version_.transport_version)) {
1297 mock_quic_data.AddWrite(SYNCHRONOUS,
1298 ConstructInitialSettingsPacket(packet_num++));
1299 }
rchbd089ab2017-05-26 23:05:041300 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231301 SYNCHRONOUS,
1302 ConstructClientRequestHeadersPacket(
1303 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1304 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451305
Ryan Hamilton0239aac2018-05-19 00:03:131306 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041307 response_headers["key1"] = std::string(30000, 'A');
1308 response_headers["key2"] = std::string(30000, 'A');
1309 response_headers["key3"] = std::string(30000, 'A');
1310 response_headers["key4"] = std::string(30000, 'A');
1311 response_headers["key5"] = std::string(30000, 'A');
1312 response_headers["key6"] = std::string(30000, 'A');
1313 response_headers["key7"] = std::string(30000, 'A');
1314 response_headers["key8"] = std::string(30000, 'A');
1315 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451316
1317 quic::QuicStreamId stream_id;
1318 std::string response_data;
1319 if (quic::VersionUsesQpack(version_.transport_version)) {
1320 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1321 std::vector<std::string> encoded = server_maker_.QpackEncodeHeaders(
1322 stream_id, std::move(response_headers), nullptr);
1323 for (const auto& e : encoded) {
1324 response_data += e;
1325 }
1326 } else {
1327 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1328 spdy::SpdyHeadersIR headers_frame(
1329 GetNthClientInitiatedBidirectionalStreamId(0),
1330 std::move(response_headers));
1331 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1332 spdy::SpdySerializedFrame spdy_frame =
1333 response_framer.SerializeFrame(headers_frame);
1334 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1335 }
rchbd089ab2017-05-26 23:05:041336
Fan Yangac867502019-01-28 21:10:231337 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041338 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451339 for (size_t offset = 0; offset < response_data.length();
1340 offset += chunk_size) {
1341 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431342 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451343 ASYNC, ConstructServerDataPacket(
1344 packet_number++, stream_id, false, false,
1345 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041346 }
1347
Victor Vasiliev076657c2019-03-12 02:46:431348 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411349
rchbd089ab2017-05-26 23:05:041350 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331351 ASYNC, ConstructServerDataPacket(
1352 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171353 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041354 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:231355 mock_quic_data.AddWrite(ASYNC,
1356 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431357 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331358 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231359 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:331360 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041361
1362 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1363
1364 CreateSession();
1365
1366 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1367 TestCompletionCallback callback;
1368 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1369 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1370 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1371}
1372
rcha2bd44b2016-07-02 00:42:551373TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Nick Harper72ade192019-07-17 03:30:421374 session_params_.quic_params.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551375
Ryan Hamilton9835e662018-08-02 05:36:271376 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551377
Ryan Hamiltonabad59e2019-06-06 04:02:591378 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231379 int packet_num = 1;
1380 if (VersionUsesQpack(version_.transport_version)) {
1381 mock_quic_data.AddWrite(SYNCHRONOUS,
1382 ConstructInitialSettingsPacket(packet_num++));
1383 }
rch5cb522462017-04-25 20:18:361384 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231385 SYNCHRONOUS,
1386 ConstructClientRequestHeadersPacket(
1387 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1388 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431389 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331390 ASYNC, ConstructServerResponseHeadersPacket(
1391 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1392 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431393 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331394 mock_quic_data.AddRead(
1395 ASYNC, ConstructServerDataPacket(
1396 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171397 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231398 mock_quic_data.AddWrite(SYNCHRONOUS,
1399 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551400 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1401
1402 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1403
1404 CreateSession();
1405
1406 SendRequestAndExpectQuicResponse("hello!");
1407 EXPECT_TRUE(
1408 test_socket_performance_watcher_factory_.rtt_notification_received());
1409}
1410
[email protected]cf3e3cd62014-02-05 16:16:161411TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411412 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591413 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491414 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161415
Ryan Hamiltonabad59e2019-06-06 04:02:591416 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231417 int packet_num = 1;
1418 if (VersionUsesQpack(version_.transport_version)) {
1419 mock_quic_data.AddWrite(SYNCHRONOUS,
1420 ConstructInitialSettingsPacket(packet_num++));
1421 }
rch5cb522462017-04-25 20:18:361422 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231423 SYNCHRONOUS,
1424 ConstructClientRequestHeadersPacket(
1425 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1426 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431427 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331428 ASYNC, ConstructServerResponseHeadersPacket(
1429 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1430 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431431 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331432 mock_quic_data.AddRead(
1433 ASYNC, ConstructServerDataPacket(
1434 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171435 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231436 mock_quic_data.AddWrite(SYNCHRONOUS,
1437 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501438 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591439 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161440
rcha5399e02015-04-21 19:32:041441 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161442
tbansal0f56a39a2016-04-07 22:03:381443 EXPECT_FALSE(
1444 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161445 // There is no need to set up an alternate protocol job, because
1446 // no attempt will be made to speak to the proxy over TCP.
1447
rch9ae5b3b2016-02-11 00:36:291448 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161449 CreateSession();
1450
bnc62a44f022015-04-02 15:59:411451 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381452 EXPECT_TRUE(
1453 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161454}
1455
bnc313ba9c2015-06-11 15:42:311456// Regression test for https://crbug.com/492458. Test that for an HTTP
1457// connection through a QUIC proxy, the certificate exhibited by the proxy is
1458// checked against the proxy hostname, not the origin hostname.
1459TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291460 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311461 const std::string proxy_host = "www.example.org";
1462
mmenke6ddfbea2017-05-31 21:48:411463 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591464 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491465 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311466
alyssar2adf3ac2016-05-03 17:12:581467 client_maker_.set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591468 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231469 int packet_num = 1;
1470 if (VersionUsesQpack(version_.transport_version)) {
1471 mock_quic_data.AddWrite(SYNCHRONOUS,
1472 ConstructInitialSettingsPacket(packet_num++));
1473 }
rch5cb522462017-04-25 20:18:361474 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231475 SYNCHRONOUS,
1476 ConstructClientRequestHeadersPacket(
1477 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1478 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431479 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331480 ASYNC, ConstructServerResponseHeadersPacket(
1481 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1482 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431483 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331484 mock_quic_data.AddRead(
1485 ASYNC, ConstructServerDataPacket(
1486 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171487 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231488 mock_quic_data.AddWrite(SYNCHRONOUS,
1489 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501490 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591491 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311492 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1493
1494 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291495 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311496 ASSERT_TRUE(cert.get());
1497 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241498 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1499 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311500 ProofVerifyDetailsChromium verify_details;
1501 verify_details.cert_verify_result.verified_cert = cert;
1502 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561503 ProofVerifyDetailsChromium verify_details2;
1504 verify_details2.cert_verify_result.verified_cert = cert;
1505 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311506
1507 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091508 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321509 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271510 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311511 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1512}
1513
rchbe69cb902016-02-11 01:10:481514TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Nick Harper72ade192019-07-17 03:30:421515 session_params_.quic_params.allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481516 HostPortPair origin("www.example.org", 443);
1517 HostPortPair alternative("mail.example.org", 443);
1518
1519 base::FilePath certs_dir = GetTestCertsDirectory();
1520 scoped_refptr<X509Certificate> cert(
1521 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1522 ASSERT_TRUE(cert.get());
1523 // TODO(rch): the connection should be "to" the origin, so if the cert is
1524 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241525 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1526 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481527 ProofVerifyDetailsChromium verify_details;
1528 verify_details.cert_verify_result.verified_cert = cert;
1529 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1530
alyssar2adf3ac2016-05-03 17:12:581531 client_maker_.set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591532 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021533
Renjie Tangaadb84b2019-08-31 01:00:231534 int packet_num = 1;
1535 if (VersionUsesQpack(version_.transport_version)) {
1536 mock_quic_data.AddWrite(SYNCHRONOUS,
1537 ConstructInitialSettingsPacket(packet_num++));
1538 }
rch5cb522462017-04-25 20:18:361539 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231540 SYNCHRONOUS,
1541 ConstructClientRequestHeadersPacket(
1542 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1543 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431544 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331545 ASYNC, ConstructServerResponseHeadersPacket(
1546 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1547 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431548 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331549 mock_quic_data.AddRead(
1550 ASYNC, ConstructServerDataPacket(
1551 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171552 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231553 mock_quic_data.AddWrite(SYNCHRONOUS,
1554 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481555 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1556 mock_quic_data.AddRead(ASYNC, 0);
1557 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1558
1559 request_.url = GURL("https://" + origin.host());
1560 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271561 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091562 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321563 CreateSession();
rchbe69cb902016-02-11 01:10:481564
1565 SendRequestAndExpectQuicResponse("hello!");
1566}
1567
zhongyief3f4ce52017-07-05 23:53:281568TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:561569 quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
zhongyief3f4ce52017-07-05 23:53:281570 // Add support for another QUIC version besides |version_|. Also find a
1571 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561572 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281573 if (version == version_)
1574 continue;
1575 if (supported_versions_.size() != 2) {
1576 supported_versions_.push_back(version);
1577 continue;
1578 }
1579 unsupported_version = version;
1580 break;
1581 }
Nick Harper23290b82019-05-02 00:02:561582 DCHECK_NE(unsupported_version, quic::UnsupportedQuicVersion());
zhongyief3f4ce52017-07-05 23:53:281583
1584 // Set up alternative service to use QUIC with a version that is not
1585 // supported.
1586 url::SchemeHostPort server(request_.url);
1587 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1588 443);
1589 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491590 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071591 server, NetworkIsolationKey(), alternative_service, expiration,
1592 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281593
1594 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491595 http_server_properties_->GetAlternativeServiceInfos(
1596 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281597 EXPECT_EQ(1u, alt_svc_info_vector.size());
1598 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1599 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1600 EXPECT_EQ(unsupported_version,
1601 alt_svc_info_vector[0].advertised_versions()[0]);
1602
1603 // First request should still be sent via TCP as the QUIC version advertised
1604 // in the stored AlternativeService is not supported by the client. However,
1605 // the response from the server will advertise new Alt-Svc with supported
1606 // versions.
Ryan Hamilton8380c652019-06-04 02:25:061607 quic::ParsedQuicVersionVector versions;
1608 for (quic::QuicTransportVersion version :
1609 quic::AllSupportedTransportVersions()) {
1610 versions.push_back(
1611 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
1612 }
zhongyief3f4ce52017-07-05 23:53:281613 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:061614 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyief3f4ce52017-07-05 23:53:281615 std::string altsvc_header =
1616 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1617 advertised_versions_list_str.c_str());
1618 MockRead http_reads[] = {
1619 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1620 MockRead("hello world"),
1621 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1622 MockRead(ASYNC, OK)};
1623
Ryan Sleevib8d7ea02018-05-07 20:01:011624 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281625 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081626 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281627 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1628
1629 // Second request should be sent via QUIC as a new list of verions supported
1630 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591631 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231632 int packet_num = 1;
1633 if (VersionUsesQpack(version_.transport_version)) {
1634 mock_quic_data.AddWrite(SYNCHRONOUS,
1635 ConstructInitialSettingsPacket(packet_num++));
1636 }
zhongyief3f4ce52017-07-05 23:53:281637 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231638 SYNCHRONOUS,
1639 ConstructClientRequestHeadersPacket(
1640 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1641 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431642 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331643 ASYNC, ConstructServerResponseHeadersPacket(
1644 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1645 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431646 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331647 mock_quic_data.AddRead(
1648 ASYNC, ConstructServerDataPacket(
1649 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171650 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231651 mock_quic_data.AddWrite(SYNCHRONOUS,
1652 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281653 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1654 mock_quic_data.AddRead(ASYNC, 0); // EOF
1655
1656 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1657
1658 AddHangingNonAlternateProtocolSocketData();
1659
1660 CreateSession(supported_versions_);
1661
1662 SendRequestAndExpectHttpResponse("hello world");
1663 SendRequestAndExpectQuicResponse("hello!");
1664
1665 // Check alternative service list is updated with new versions.
1666 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491667 session_->http_server_properties()->GetAlternativeServiceInfos(
1668 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281669 EXPECT_EQ(1u, alt_svc_info_vector.size());
1670 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1671 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1672 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:561673 std::sort(
1674 supported_versions_.begin(), supported_versions_.end(),
1675 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
1676 return a.transport_version < b.transport_version;
1677 });
zhongyief3f4ce52017-07-05 23:53:281678 EXPECT_EQ(supported_versions_[0],
1679 alt_svc_info_vector[0].advertised_versions()[0]);
1680 EXPECT_EQ(supported_versions_[1],
1681 alt_svc_info_vector[0].advertised_versions()[1]);
1682}
1683
bncaccd4962017-04-06 21:00:261684// Regression test for https://crbug.com/546991.
1685// The server might not be able to serve a request on an alternative connection,
1686// and might send a 421 Misdirected Request response status to indicate this.
1687// HttpNetworkTransaction should reset the request and retry without using
1688// alternative services.
1689TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1690 // Set up alternative service to use QUIC.
1691 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1692 // that overrides |enable_alternative_services|.
1693 url::SchemeHostPort server(request_.url);
1694 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1695 443);
1696 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491697 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071698 server, NetworkIsolationKey(), alternative_service, expiration,
1699 supported_versions_);
bncaccd4962017-04-06 21:00:261700
davidbena4449722017-05-05 23:30:531701 // First try: The alternative job uses QUIC and reports an HTTP 421
1702 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1703 // paused at Connect(), so it will never exit the socket pool. This ensures
1704 // that the alternate job always wins the race and keeps whether the
1705 // |http_data| exits the socket pool before the main job is aborted
1706 // deterministic. The first main job gets aborted without the socket pool ever
1707 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591708 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231709 int packet_num = 1;
1710 if (VersionUsesQpack(version_.transport_version)) {
1711 mock_quic_data.AddWrite(SYNCHRONOUS,
1712 ConstructInitialSettingsPacket(packet_num++));
1713 }
rch5cb522462017-04-25 20:18:361714 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231715 SYNCHRONOUS,
1716 ConstructClientRequestHeadersPacket(
1717 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1718 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331719 mock_quic_data.AddRead(
1720 ASYNC, ConstructServerResponseHeadersPacket(
1721 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021722 GetResponseHeaders("421")));
bncaccd4962017-04-06 21:00:261723 mock_quic_data.AddRead(ASYNC, OK);
1724 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1725
davidbena4449722017-05-05 23:30:531726 // Second try: The main job uses TCP, and there is no alternate job. Once the
1727 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1728 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261729 // Note that if there was an alternative QUIC Job created for the second try,
1730 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1731 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531732 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1733 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1734 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1735 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1736 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1737 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011738 reads, writes);
bncaccd4962017-04-06 21:00:261739 socket_factory_.AddSocketDataProvider(&http_data);
1740 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1741
bncaccd4962017-04-06 21:00:261742 CreateSession();
1743 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531744
1745 // Run until |mock_quic_data| has failed and |http_data| has paused.
1746 TestCompletionCallback callback;
1747 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1748 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1749 base::RunLoop().RunUntilIdle();
1750
1751 // |mock_quic_data| must have run to completion.
1752 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1753 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1754
1755 // Now that the QUIC data has been consumed, unblock |http_data|.
1756 http_data.socket()->OnConnectComplete(MockConnect());
1757
1758 // The retry logic must hide the 421 status. The transaction succeeds on
1759 // |http_data|.
1760 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261761 CheckWasHttpResponse(&trans);
1762 CheckResponsePort(&trans, 443);
1763 CheckResponseData(&trans, "hello!");
1764}
1765
[email protected]1e960032013-12-20 19:00:201766TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Nick Harper72ade192019-07-17 03:30:421767 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571768 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301769
Ryan Hamiltonabad59e2019-06-06 04:02:591770 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:231771 if (VersionUsesQpack(version_.transport_version))
1772 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401773 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Ryan Hamilton0d65a8c2019-06-07 00:46:021774 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591775 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:231776 if (VersionUsesQpack(version_.transport_version))
1777 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301778 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401779 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431780 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401781
1782 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1783 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301784
1785 CreateSession();
1786
tbansal0f56a39a2016-04-07 22:03:381787 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401788 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161789 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401790 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161791 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011792 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1793 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381794 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531795
1796 NetErrorDetails details;
1797 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521798 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401799 }
[email protected]cebe3282013-05-22 23:49:301800}
1801
tbansalc8a94ea2015-11-02 23:58:511802TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1803 // Attempt to "force" quic on 443, which will not be honored.
Nick Harper72ade192019-07-17 03:30:421804 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571805 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511806
1807 MockRead http_reads[] = {
1808 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1809 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1810 MockRead(ASYNC, OK)};
1811
Ryan Sleevib8d7ea02018-05-07 20:01:011812 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511813 socket_factory_.AddSocketDataProvider(&data);
1814 SSLSocketDataProvider ssl(ASYNC, OK);
1815 socket_factory_.AddSSLSocketDataProvider(&ssl);
1816
1817 CreateSession();
1818
1819 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381820 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511821}
1822
bncc958faa2015-07-31 18:14:521823TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521824 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561825 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1826 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521827 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1828 MockRead(ASYNC, OK)};
1829
Ryan Sleevib8d7ea02018-05-07 20:01:011830 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521831 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081832 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561833 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521834
Ryan Hamiltonabad59e2019-06-06 04:02:591835 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231836 int packet_num = 1;
1837 if (VersionUsesQpack(version_.transport_version)) {
1838 mock_quic_data.AddWrite(SYNCHRONOUS,
1839 ConstructInitialSettingsPacket(packet_num++));
1840 }
rch5cb522462017-04-25 20:18:361841 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231842 SYNCHRONOUS,
1843 ConstructClientRequestHeadersPacket(
1844 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1845 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431846 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331847 ASYNC, ConstructServerResponseHeadersPacket(
1848 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1849 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431850 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331851 mock_quic_data.AddRead(
1852 ASYNC, ConstructServerDataPacket(
1853 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171854 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231855 mock_quic_data.AddWrite(SYNCHRONOUS,
1856 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:521857 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591858 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521859
1860 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1861
rtennetib8e80fb2016-05-16 00:12:091862 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321863 CreateSession();
bncc958faa2015-07-31 18:14:521864
1865 SendRequestAndExpectHttpResponse("hello world");
1866 SendRequestAndExpectQuicResponse("hello!");
1867}
1868
Ryan Hamilton64f21d52019-08-31 07:10:511869TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
1870 std::string alt_svc_header =
1871 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
1872 MockRead http_reads[] = {
1873 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
1874 MockRead("hello world"),
1875 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1876 MockRead(ASYNC, OK)};
1877
1878 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
1879 socket_factory_.AddSocketDataProvider(&http_data);
1880 AddCertificate(&ssl_data_);
1881 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1882
1883 MockQuicData mock_quic_data(version_);
1884 int packet_num = 1;
1885 if (VersionUsesQpack(version_.transport_version)) {
1886 mock_quic_data.AddWrite(SYNCHRONOUS,
1887 ConstructInitialSettingsPacket(packet_num++));
1888 }
1889 mock_quic_data.AddWrite(
1890 SYNCHRONOUS,
1891 ConstructClientRequestHeadersPacket(
1892 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1893 true, GetRequestHeaders("GET", "https", "/")));
1894 mock_quic_data.AddRead(
1895 ASYNC, ConstructServerResponseHeadersPacket(
1896 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1897 GetResponseHeaders("200 OK")));
1898 std::string header = ConstructDataHeader(6);
1899 mock_quic_data.AddRead(
1900 ASYNC, ConstructServerDataPacket(
1901 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1902 header + "hello!"));
1903 mock_quic_data.AddWrite(SYNCHRONOUS,
1904 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1905 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1906 mock_quic_data.AddRead(ASYNC, 0); // EOF
1907
1908 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1909
1910 AddHangingNonAlternateProtocolSocketData();
1911 CreateSession();
1912
1913 SendRequestAndExpectHttpResponse("hello world");
1914 SendRequestAndExpectQuicResponse("hello!");
1915}
1916
Matt Menke3233d8f22019-08-20 21:01:491917// Much like above, but makes sure NetworkIsolationKey is respected.
1918TEST_P(QuicNetworkTransactionTest,
1919 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
1920 base::test::ScopedFeatureList feature_list;
1921 feature_list.InitAndEnableFeature(
1922 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
1923 // Since HttpServerProperties caches the feature value, have to create a new
1924 // one.
1925 http_server_properties_ = std::make_unique<HttpServerProperties>();
1926
1927 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
1928 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
1929 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
1930 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
1931
1932 MockRead http_reads[] = {
1933 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1934 MockRead("hello world"),
1935 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1936 MockRead(ASYNC, OK)};
1937
1938 AddCertificate(&ssl_data_);
1939
1940 // Request with empty NetworkIsolationKey.
1941 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
1942 socket_factory_.AddSocketDataProvider(&http_data1);
1943 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1944
1945 // First request with kNetworkIsolationKey1.
1946 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
1947 socket_factory_.AddSocketDataProvider(&http_data2);
1948 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1949
1950 // Request with kNetworkIsolationKey2.
1951 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
1952 socket_factory_.AddSocketDataProvider(&http_data3);
1953 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1954
1955 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
1956 // alternative service infrmation has been received in this context before.
1957 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231958 int packet_num = 1;
1959 if (VersionUsesQpack(version_.transport_version)) {
1960 mock_quic_data.AddWrite(SYNCHRONOUS,
1961 ConstructInitialSettingsPacket(packet_num++));
1962 }
Matt Menke3233d8f22019-08-20 21:01:491963 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231964 SYNCHRONOUS,
1965 ConstructClientRequestHeadersPacket(
1966 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1967 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:491968 mock_quic_data.AddRead(
1969 ASYNC, ConstructServerResponseHeadersPacket(
1970 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1971 GetResponseHeaders("200 OK")));
1972 std::string header = ConstructDataHeader(6);
1973 mock_quic_data.AddRead(
1974 ASYNC, ConstructServerDataPacket(
1975 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1976 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231977 mock_quic_data.AddWrite(SYNCHRONOUS,
1978 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke3233d8f22019-08-20 21:01:491979 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1980 mock_quic_data.AddRead(ASYNC, 0); // EOF
1981
1982 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1983
1984 AddHangingNonAlternateProtocolSocketData();
1985 CreateSession();
1986
1987 // This is first so that the test fails if alternative service info is
1988 // written with the right NetworkIsolationKey, but always queried with an
1989 // empty one.
1990 request_.network_isolation_key = NetworkIsolationKey();
1991 SendRequestAndExpectHttpResponse("hello world");
1992 request_.network_isolation_key = kNetworkIsolationKey1;
1993 SendRequestAndExpectHttpResponse("hello world");
1994 request_.network_isolation_key = kNetworkIsolationKey2;
1995 SendRequestAndExpectHttpResponse("hello world");
1996
1997 // Only use QUIC when using a NetworkIsolationKey which has been used when
1998 // alternative service information was received.
1999 request_.network_isolation_key = kNetworkIsolationKey1;
2000 SendRequestAndExpectQuicResponse("hello!");
2001}
2002
zhongyia00ca012017-07-06 23:36:392003TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
2004 // Both server advertises and client supports two QUIC versions.
2005 // Only |version_| is advertised and supported.
2006 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2007 // PacketMakers are using |version_|.
2008
2009 // Add support for another QUIC version besides |version_| on the client side.
2010 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:562011 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
2012 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392013 if (version == version_)
2014 continue;
2015 if (supported_versions_.size() != 2) {
2016 supported_versions_.push_back(version);
2017 continue;
2018 }
2019 advertised_version_2 = version;
2020 break;
2021 }
Nick Harper23290b82019-05-02 00:02:562022 DCHECK_NE(advertised_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392023
Nick Harper23290b82019-05-02 00:02:562024 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
2025 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2026 advertised_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392027
2028 MockRead http_reads[] = {
2029 MockRead("HTTP/1.1 200 OK\r\n"),
2030 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2031 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2032 MockRead(ASYNC, OK)};
2033
Ryan Sleevib8d7ea02018-05-07 20:01:012034 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392035 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082036 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392037 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2038
Ryan Hamiltonabad59e2019-06-06 04:02:592039 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232040 int packet_num = 1;
2041 if (VersionUsesQpack(version_.transport_version)) {
2042 mock_quic_data.AddWrite(SYNCHRONOUS,
2043 ConstructInitialSettingsPacket(packet_num++));
2044 }
zhongyia00ca012017-07-06 23:36:392045 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232046 SYNCHRONOUS,
2047 ConstructClientRequestHeadersPacket(
2048 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2049 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432050 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332051 ASYNC, ConstructServerResponseHeadersPacket(
2052 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2053 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432054 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332055 mock_quic_data.AddRead(
2056 ASYNC, ConstructServerDataPacket(
2057 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172058 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232059 mock_quic_data.AddWrite(SYNCHRONOUS,
2060 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392061 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2062 mock_quic_data.AddRead(ASYNC, 0); // EOF
2063
2064 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2065
2066 AddHangingNonAlternateProtocolSocketData();
2067 CreateSession(supported_versions_);
2068
2069 SendRequestAndExpectHttpResponse("hello world");
2070 SendRequestAndExpectQuicResponse("hello!");
2071}
2072
2073TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
2074 // Client and server mutually support more than one QUIC_VERSION.
2075 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
2076 // which is verified as the PacketMakers are using |version_|.
2077
Nick Harper23290b82019-05-02 00:02:562078 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
2079 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392080 if (version == version_)
2081 continue;
2082 common_version_2 = version;
2083 break;
2084 }
Nick Harper23290b82019-05-02 00:02:562085 DCHECK_NE(common_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392086
2087 supported_versions_.push_back(
2088 common_version_2); // Supported but unpreferred.
2089
2090 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:562091 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2092 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392093
2094 MockRead http_reads[] = {
2095 MockRead("HTTP/1.1 200 OK\r\n"),
2096 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2097 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2098 MockRead(ASYNC, OK)};
2099
Ryan Sleevib8d7ea02018-05-07 20:01:012100 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392101 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082102 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392103 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2104
Ryan Hamiltonabad59e2019-06-06 04:02:592105 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232106 int packet_num = 1;
2107 if (VersionUsesQpack(version_.transport_version)) {
2108 mock_quic_data.AddWrite(SYNCHRONOUS,
2109 ConstructInitialSettingsPacket(packet_num++));
2110 }
zhongyia00ca012017-07-06 23:36:392111 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232112 SYNCHRONOUS,
2113 ConstructClientRequestHeadersPacket(
2114 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2115 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432116 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332117 ASYNC, ConstructServerResponseHeadersPacket(
2118 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2119 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432120 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332121 mock_quic_data.AddRead(
2122 ASYNC, ConstructServerDataPacket(
2123 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172124 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232125 mock_quic_data.AddWrite(SYNCHRONOUS,
2126 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392127 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2128 mock_quic_data.AddRead(ASYNC, 0); // EOF
2129
2130 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2131
2132 AddHangingNonAlternateProtocolSocketData();
2133 CreateSession(supported_versions_);
2134
2135 SendRequestAndExpectHttpResponse("hello world");
2136 SendRequestAndExpectQuicResponse("hello!");
2137}
2138
rchf47265dc2016-03-21 21:33:122139TEST_P(QuicNetworkTransactionTest,
2140 UseAlternativeServiceWithProbabilityForQuic) {
2141 MockRead http_reads[] = {
2142 MockRead("HTTP/1.1 200 OK\r\n"),
2143 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
2144 MockRead("hello world"),
2145 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2146 MockRead(ASYNC, OK)};
2147
Ryan Sleevib8d7ea02018-05-07 20:01:012148 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:122149 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082150 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:122151 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2152
Ryan Hamiltonabad59e2019-06-06 04:02:592153 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232154 int packet_num = 1;
2155 if (VersionUsesQpack(version_.transport_version)) {
2156 mock_quic_data.AddWrite(SYNCHRONOUS,
2157 ConstructInitialSettingsPacket(packet_num++));
2158 }
rch5cb522462017-04-25 20:18:362159 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232160 SYNCHRONOUS,
2161 ConstructClientRequestHeadersPacket(
2162 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2163 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432164 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332165 ASYNC, ConstructServerResponseHeadersPacket(
2166 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2167 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432168 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332169 mock_quic_data.AddRead(
2170 ASYNC, ConstructServerDataPacket(
2171 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172172 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232173 mock_quic_data.AddWrite(SYNCHRONOUS,
2174 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchf47265dc2016-03-21 21:33:122175 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2176 mock_quic_data.AddRead(ASYNC, 0); // EOF
2177
2178 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2179
rtennetib8e80fb2016-05-16 00:12:092180 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:122181 CreateSession();
2182
2183 SendRequestAndExpectHttpResponse("hello world");
2184 SendRequestAndExpectQuicResponse("hello!");
2185}
2186
zhongyi3d4a55e72016-04-22 20:36:462187TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2188 MockRead http_reads[] = {
2189 MockRead("HTTP/1.1 200 OK\r\n"),
2190 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2191 MockRead("hello world"),
2192 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2193 MockRead(ASYNC, OK)};
2194
Ryan Sleevib8d7ea02018-05-07 20:01:012195 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462196 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082197 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462198 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2199
2200 CreateSession();
bncb26024382016-06-29 02:39:452201 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462202 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452203 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462204 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402205 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462206 session_->http_server_properties();
2207 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2208 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2209 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462210 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492211 2u, http_server_properties
2212 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2213 .size());
bncb26024382016-06-29 02:39:452214 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492215 http_server_properties
2216 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2217 .empty());
zhongyi3d4a55e72016-04-22 20:36:462218}
2219
2220TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2221 MockRead http_reads[] = {
2222 MockRead("HTTP/1.1 200 OK\r\n"),
2223 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2224 MockRead("hello world"),
2225 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2226 MockRead(ASYNC, OK)};
2227
Ryan Sleevib8d7ea02018-05-07 20:01:012228 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082229 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462230
2231 socket_factory_.AddSocketDataProvider(&http_data);
2232 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2233 socket_factory_.AddSocketDataProvider(&http_data);
2234 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2235
2236 CreateSession();
2237
2238 // Send https request and set alternative services if response header
2239 // advertises alternative service for mail.example.org.
2240 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402241 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462242 session_->http_server_properties();
2243
2244 const url::SchemeHostPort https_server(request_.url);
2245 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342246 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492247 2u, http_server_properties
2248 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2249 .size());
zhongyi3d4a55e72016-04-22 20:36:462250
2251 // Send http request to the same origin but with diffrent scheme, should not
2252 // use QUIC.
2253 request_.url = GURL("http://mail.example.org:443");
2254 SendRequestAndExpectHttpResponse("hello world");
2255}
2256
zhongyie537a002017-06-27 16:48:212257TEST_P(QuicNetworkTransactionTest,
2258 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442259 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562260 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyi86838d52017-06-30 01:19:442261 if (version == version_)
2262 continue;
2263 supported_versions_.push_back(version);
2264 break;
2265 }
2266
Ryan Hamilton8380c652019-06-04 02:25:062267 quic::ParsedQuicVersionVector versions;
2268 for (quic::QuicTransportVersion version :
2269 quic::AllSupportedTransportVersions()) {
2270 versions.push_back(
2271 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
2272 }
zhongyie537a002017-06-27 16:48:212273 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:062274 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyie537a002017-06-27 16:48:212275 std::string altsvc_header =
2276 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2277 advertised_versions_list_str.c_str());
2278 MockRead http_reads[] = {
2279 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2280 MockRead("hello world"),
2281 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2282 MockRead(ASYNC, OK)};
2283
Ryan Sleevib8d7ea02018-05-07 20:01:012284 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212285 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082286 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212287 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2288
Ryan Hamiltonabad59e2019-06-06 04:02:592289 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232290 int packet_num = 1;
2291 if (VersionUsesQpack(version_.transport_version)) {
2292 mock_quic_data.AddWrite(SYNCHRONOUS,
2293 ConstructInitialSettingsPacket(packet_num++));
2294 }
zhongyie537a002017-06-27 16:48:212295 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232296 SYNCHRONOUS,
2297 ConstructClientRequestHeadersPacket(
2298 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2299 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432300 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332301 ASYNC, ConstructServerResponseHeadersPacket(
2302 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2303 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432304 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332305 mock_quic_data.AddRead(
2306 ASYNC, ConstructServerDataPacket(
2307 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172308 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232309 mock_quic_data.AddWrite(SYNCHRONOUS,
2310 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212311 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2312 mock_quic_data.AddRead(ASYNC, 0); // EOF
2313
2314 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2315
2316 AddHangingNonAlternateProtocolSocketData();
2317
zhongyi86838d52017-06-30 01:19:442318 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212319
2320 SendRequestAndExpectHttpResponse("hello world");
2321 SendRequestAndExpectQuicResponse("hello!");
2322
2323 // Check alternative service is set with only mutually supported versions.
2324 const url::SchemeHostPort https_server(request_.url);
2325 const AlternativeServiceInfoVector alt_svc_info_vector =
2326 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492327 https_server, NetworkIsolationKey());
zhongyie537a002017-06-27 16:48:212328 EXPECT_EQ(1u, alt_svc_info_vector.size());
2329 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2330 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2331 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:562332 std::sort(
2333 supported_versions_.begin(), supported_versions_.end(),
2334 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
2335 return a.transport_version < b.transport_version;
2336 });
zhongyi86838d52017-06-30 01:19:442337 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212338 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442339 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212340 alt_svc_info_vector[0].advertised_versions()[1]);
2341}
2342
danzh3134c2562016-08-12 14:07:522343TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562344 std::string altsvc_header = base::StringPrintf(
2345 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_.transport_version);
bnc8be55ebb2015-10-30 14:12:072346 MockRead http_reads[] = {
2347 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2348 MockRead("hello world"),
2349 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2350 MockRead(ASYNC, OK)};
2351
Ryan Sleevib8d7ea02018-05-07 20:01:012352 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072353 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082354 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072355 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2356
Ryan Hamiltonabad59e2019-06-06 04:02:592357 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232358 int packet_num = 1;
2359 if (VersionUsesQpack(version_.transport_version)) {
2360 mock_quic_data.AddWrite(SYNCHRONOUS,
2361 ConstructInitialSettingsPacket(packet_num++));
2362 }
rch5cb522462017-04-25 20:18:362363 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232364 SYNCHRONOUS,
2365 ConstructClientRequestHeadersPacket(
2366 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2367 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432368 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332369 ASYNC, ConstructServerResponseHeadersPacket(
2370 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2371 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432372 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332373 mock_quic_data.AddRead(
2374 ASYNC, ConstructServerDataPacket(
2375 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172376 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232377 mock_quic_data.AddWrite(SYNCHRONOUS,
2378 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072379 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592380 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072381
2382 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2383
rtennetib8e80fb2016-05-16 00:12:092384 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322385 CreateSession();
bnc8be55ebb2015-10-30 14:12:072386
2387 SendRequestAndExpectHttpResponse("hello world");
2388 SendRequestAndExpectQuicResponse("hello!");
2389}
2390
zhongyi6b5a3892016-03-12 04:46:202391TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562392 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz6e4c5382018-06-21 23:00:092393 // Not available under version 99
2394 return;
2395 }
Ryan Hamiltonabad59e2019-06-06 04:02:592396 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232397 int packet_num = 1;
2398 if (VersionUsesQpack(version_.transport_version)) {
2399 mock_quic_data.AddWrite(SYNCHRONOUS,
2400 ConstructInitialSettingsPacket(packet_num++));
2401 }
rch5cb522462017-04-25 20:18:362402 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232403 SYNCHRONOUS,
2404 ConstructClientRequestHeadersPacket(
2405 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2406 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332407 mock_quic_data.AddRead(
2408 ASYNC, ConstructServerResponseHeadersPacket(
2409 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2410 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202411 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522412 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432413 mock_quic_data.AddRead(SYNCHRONOUS,
2414 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522415 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432416 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232417 mock_quic_data.AddWrite(SYNCHRONOUS,
2418 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432419 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332420 mock_quic_data.AddRead(
2421 SYNCHRONOUS, ConstructServerDataPacket(
2422 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:172423 true, header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232424 mock_quic_data.AddWrite(
2425 SYNCHRONOUS,
2426 ConstructClientAckAndRstPacket(
2427 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2428 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202429 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2430 mock_quic_data.AddRead(ASYNC, 0); // EOF
2431
2432 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2433
2434 // The non-alternate protocol job needs to hang in order to guarantee that
2435 // the alternate-protocol job will "win".
2436 AddHangingNonAlternateProtocolSocketData();
2437
2438 // In order for a new QUIC session to be established via alternate-protocol
2439 // without racing an HTTP connection, we need the host resolution to happen
2440 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2441 // connection to the the server, in this test we require confirmation
2442 // before encrypting so the HTTP job will still start.
2443 host_resolver_.set_synchronous_mode(true);
2444 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2445 "");
zhongyi6b5a3892016-03-12 04:46:202446
2447 CreateSession();
2448 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272449 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202450
bnc691fda62016-08-12 00:43:162451 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202452 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362453 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012454 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202455
2456 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522457 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012458 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202459
2460 // Check whether this transaction is correctly marked as received a go-away
2461 // because of migrating port.
2462 NetErrorDetails details;
2463 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162464 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202465 EXPECT_TRUE(details.quic_port_migration_detected);
2466}
2467
Zhongyi Shia6b68d112018-09-24 07:49:032468// This test verifies that a new QUIC connection will be attempted on the
2469// alternate network if the original QUIC connection fails with idle timeout
2470// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2471// alternate network as well, QUIC is marked as broken and the brokenness will
2472// not expire when default network changes.
2473TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2474 SetUpTestForRetryConnectionOnAlternateNetwork();
2475
Michael Warres167db3e2019-03-01 21:38:032476 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032477
2478 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592479 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032480 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2481 int packet_num = 1;
2482 quic_data.AddWrite(SYNCHRONOUS,
2483 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2484 // Retranmit the handshake messages.
2485 quic_data.AddWrite(SYNCHRONOUS,
2486 client_maker_.MakeDummyCHLOPacket(packet_num++));
2487 quic_data.AddWrite(SYNCHRONOUS,
2488 client_maker_.MakeDummyCHLOPacket(packet_num++));
2489 quic_data.AddWrite(SYNCHRONOUS,
2490 client_maker_.MakeDummyCHLOPacket(packet_num++));
2491 quic_data.AddWrite(SYNCHRONOUS,
2492 client_maker_.MakeDummyCHLOPacket(packet_num++));
2493 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562494 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032495 quic_data.AddWrite(SYNCHRONOUS,
2496 client_maker_.MakeDummyCHLOPacket(packet_num++));
2497 }
2498 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2499 quic_data.AddWrite(SYNCHRONOUS,
2500 client_maker_.MakeConnectionClosePacket(
2501 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2502 "No recent network activity."));
2503 quic_data.AddSocketDataToFactory(&socket_factory_);
2504
2505 // Add successful TCP data so that TCP job will succeed.
2506 MockWrite http_writes[] = {
2507 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2508 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2509 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2510
2511 MockRead http_reads[] = {
2512 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2513 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2514 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2515 SequencedSocketData http_data(http_reads, http_writes);
2516 socket_factory_.AddSocketDataProvider(&http_data);
2517 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2518
2519 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592520 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032521 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2522 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2523 quic_data2.AddSocketDataToFactory(&socket_factory_);
2524
2525 // Resolve the host resolution synchronously.
2526 host_resolver_.set_synchronous_mode(true);
2527 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2528 "");
Zhongyi Shia6b68d112018-09-24 07:49:032529
2530 CreateSession();
2531 session_->quic_stream_factory()->set_require_confirmation(true);
2532 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032533 QuicStreamFactoryPeer::SetAlarmFactory(
2534 session_->quic_stream_factory(),
2535 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2536 &clock_));
2537 // Add alternate protocol mapping to race QUIC and TCP.
2538 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2539 // peer.
2540 AddQuicAlternateProtocolMapping(
2541 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2542
2543 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2544 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362545 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032546 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2547
2548 // Pump the message loop to get the request started.
2549 // Request will be served with TCP job.
2550 base::RunLoop().RunUntilIdle();
2551 EXPECT_THAT(callback.WaitForResult(), IsOk());
2552 CheckResponseData(&trans, "TCP succeeds");
2553
Zhongyi Shia6b68d112018-09-24 07:49:032554 // Fast forward to idle timeout the original connection. A new connection will
2555 // be kicked off on the alternate network.
2556 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2557 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2558 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2559
2560 // Run the message loop to execute posted tasks, which will report job status.
2561 base::RunLoop().RunUntilIdle();
2562
2563 // Verify that QUIC is marked as broken.
2564 ExpectBrokenAlternateProtocolMapping();
2565
2566 // Deliver a message to notify the new network becomes default, the brokenness
2567 // will not expire as QUIC is broken on both networks.
2568 scoped_mock_change_notifier_->mock_network_change_notifier()
2569 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2570 ExpectBrokenAlternateProtocolMapping();
2571
2572 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2573 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2574}
2575
2576// This test verifies that a new QUIC connection will be attempted on the
2577// alternate network if the original QUIC connection fails with idle timeout
2578// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2579// alternate network, QUIC is marked as broken. The brokenness will expire when
2580// the default network changes.
2581TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2582 SetUpTestForRetryConnectionOnAlternateNetwork();
2583
Michael Warres167db3e2019-03-01 21:38:032584 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032585
2586 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592587 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032588 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2589 int packet_num = 1;
2590 quic_data.AddWrite(SYNCHRONOUS,
2591 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2592 // Retranmit the handshake messages.
2593 quic_data.AddWrite(SYNCHRONOUS,
2594 client_maker_.MakeDummyCHLOPacket(packet_num++));
2595 quic_data.AddWrite(SYNCHRONOUS,
2596 client_maker_.MakeDummyCHLOPacket(packet_num++));
2597 quic_data.AddWrite(SYNCHRONOUS,
2598 client_maker_.MakeDummyCHLOPacket(packet_num++));
2599 quic_data.AddWrite(SYNCHRONOUS,
2600 client_maker_.MakeDummyCHLOPacket(packet_num++));
2601 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562602 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032603 quic_data.AddWrite(SYNCHRONOUS,
2604 client_maker_.MakeDummyCHLOPacket(packet_num++));
2605 }
2606 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2607 quic_data.AddWrite(SYNCHRONOUS,
2608 client_maker_.MakeConnectionClosePacket(
2609 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2610 "No recent network activity."));
2611 quic_data.AddSocketDataToFactory(&socket_factory_);
2612
2613 // Add successful TCP data so that TCP job will succeed.
2614 MockWrite http_writes[] = {
2615 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2616 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2617 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2618
2619 MockRead http_reads[] = {
2620 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2621 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2622 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2623 SequencedSocketData http_data(http_reads, http_writes);
2624 socket_factory_.AddSocketDataProvider(&http_data);
2625 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2626
2627 // Quic connection will be retried on the alternate network after the initial
2628 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592629 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032630 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2631 quic_data2.AddWrite(SYNCHRONOUS,
2632 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2633
2634 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Renjie Tangaadb84b2019-08-31 01:00:232635 if (VersionUsesQpack(version_.transport_version))
2636 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032637 quic_data2.AddSocketDataToFactory(&socket_factory_);
2638
2639 // Resolve the host resolution synchronously.
2640 host_resolver_.set_synchronous_mode(true);
2641 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2642 "");
Zhongyi Shia6b68d112018-09-24 07:49:032643
2644 CreateSession();
2645 session_->quic_stream_factory()->set_require_confirmation(true);
2646 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032647 QuicStreamFactoryPeer::SetAlarmFactory(
2648 session_->quic_stream_factory(),
2649 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2650 &clock_));
2651 // Add alternate protocol mapping to race QUIC and TCP.
2652 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2653 // peer.
2654 AddQuicAlternateProtocolMapping(
2655 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2656
2657 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2658 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362659 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032660 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2661
2662 // Pump the message loop to get the request started.
2663 // Request will be served with TCP job.
2664 base::RunLoop().RunUntilIdle();
2665 EXPECT_THAT(callback.WaitForResult(), IsOk());
2666 CheckResponseData(&trans, "TCP succeeds");
2667
Zhongyi Shia6b68d112018-09-24 07:49:032668 // Fast forward to idle timeout the original connection. A new connection will
2669 // be kicked off on the alternate network.
2670 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2671 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2672 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2673
2674 // The second connection hasn't finish handshake, verify that QUIC is not
2675 // marked as broken.
2676 ExpectQuicAlternateProtocolMapping();
2677 // Explicitly confirm the handshake on the second connection.
2678 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2679 quic::QuicSession::HANDSHAKE_CONFIRMED);
2680 // Run message loop to execute posted tasks, which will notify JoController
2681 // about the orphaned job status.
2682 base::RunLoop().RunUntilIdle();
2683
2684 // Verify that QUIC is marked as broken.
2685 ExpectBrokenAlternateProtocolMapping();
2686
2687 // Deliver a message to notify the new network becomes default, the previous
2688 // brokenness will be clear as the brokenness is bond with old default
2689 // network.
2690 scoped_mock_change_notifier_->mock_network_change_notifier()
2691 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2692 ExpectQuicAlternateProtocolMapping();
2693
2694 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2695 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2696}
2697
2698// This test verifies that a new QUIC connection will be attempted on the
2699// alternate network if the original QUIC connection fails with idle timeout
2700// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2701// alternative network succeeds, QUIC is not marked as broken.
2702TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2703 SetUpTestForRetryConnectionOnAlternateNetwork();
2704
Michael Warres167db3e2019-03-01 21:38:032705 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032706
2707 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592708 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032709 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2710 int packet_num = 1;
2711 quic_data.AddWrite(SYNCHRONOUS,
2712 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2713 // Retranmit the handshake messages.
2714 quic_data.AddWrite(SYNCHRONOUS,
2715 client_maker_.MakeDummyCHLOPacket(packet_num++));
2716 quic_data.AddWrite(SYNCHRONOUS,
2717 client_maker_.MakeDummyCHLOPacket(packet_num++));
2718 quic_data.AddWrite(SYNCHRONOUS,
2719 client_maker_.MakeDummyCHLOPacket(packet_num++));
2720 quic_data.AddWrite(SYNCHRONOUS,
2721 client_maker_.MakeDummyCHLOPacket(packet_num++));
2722 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2723 // quic_fix_has_pending_crypto_data is introduced and enabled.
Nick Harper23290b82019-05-02 00:02:562724 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032725 quic_data.AddWrite(SYNCHRONOUS,
2726 client_maker_.MakeDummyCHLOPacket(packet_num++));
2727 }
2728 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2729 quic_data.AddWrite(SYNCHRONOUS,
2730 client_maker_.MakeConnectionClosePacket(
2731 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2732 "No recent network activity."));
2733 quic_data.AddSocketDataToFactory(&socket_factory_);
2734
2735 // Add hanging TCP data so that TCP job will never succeeded.
2736 AddHangingNonAlternateProtocolSocketData();
2737
2738 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:592739 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:232740 packet_num = 1;
Zhongyi Shia6b68d112018-09-24 07:49:032741 quic_data2.AddWrite(SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:232742 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:032743
Victor Vasiliev076657c2019-03-12 02:46:432744 const std::string body = "hello!";
2745 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:412746
Zhongyi Shia6b68d112018-09-24 07:49:032747 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Renjie Tangaadb84b2019-08-31 01:00:232748 if (VersionUsesQpack(version_.transport_version)) {
2749 quic_data2.AddWrite(SYNCHRONOUS,
2750 ConstructInitialSettingsPacket(packet_num++));
2751 }
Zhongyi Shia6b68d112018-09-24 07:49:032752 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232753 SYNCHRONOUS,
2754 ConstructClientRequestHeadersPacket(
2755 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2756 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:032757 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332758 ASYNC, ConstructServerResponseHeadersPacket(
2759 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2760 GetResponseHeaders("200 OK")));
2761 quic_data2.AddRead(
2762 ASYNC, ConstructServerDataPacket(
2763 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172764 header + body));
Renjie Tangaadb84b2019-08-31 01:00:232765 quic_data2.AddWrite(SYNCHRONOUS,
2766 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia6b68d112018-09-24 07:49:032767 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2768 quic_data2.AddSocketDataToFactory(&socket_factory_);
2769
2770 // Resolve the host resolution synchronously.
2771 host_resolver_.set_synchronous_mode(true);
2772 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2773 "");
Zhongyi Shia6b68d112018-09-24 07:49:032774
2775 CreateSession();
2776 session_->quic_stream_factory()->set_require_confirmation(true);
2777 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032778 QuicStreamFactoryPeer::SetAlarmFactory(
2779 session_->quic_stream_factory(),
2780 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2781 &clock_));
2782 // Add alternate protocol mapping to race QUIC and TCP.
2783 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2784 // peer.
2785 AddQuicAlternateProtocolMapping(
2786 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2787
2788 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2789 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362790 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032791 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2792
2793 // Pump the message loop to get the request started.
2794 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:032795
2796 // Fast forward to idle timeout the original connection. A new connection will
2797 // be kicked off on the alternate network.
2798 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2799 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2800 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2801
2802 // Verify that QUIC is not marked as broken.
2803 ExpectQuicAlternateProtocolMapping();
2804 // Explicitly confirm the handshake on the second connection.
2805 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2806 quic::QuicSession::HANDSHAKE_CONFIRMED);
2807
2808 // Read the response.
2809 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412810 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032811 // Verify that QUIC is not marked as broken.
2812 ExpectQuicAlternateProtocolMapping();
2813
2814 // Deliver a message to notify the new network becomes default.
2815 scoped_mock_change_notifier_->mock_network_change_notifier()
2816 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2817 ExpectQuicAlternateProtocolMapping();
2818 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2819 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2820}
2821
rch9ecde09b2017-04-08 00:18:232822// Verify that if a QUIC connection times out, the QuicHttpStream will
2823// return QUIC_PROTOCOL_ERROR.
2824TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:422825 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Sleevi2e8255b2019-07-17 21:02:212826 session_params_.quic_params.idle_connection_timeout =
2827 base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:232828
2829 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592830 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:132831 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232832 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2833
Ryan Hamiltone940bd12019-06-30 02:46:452834 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:032835 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:022836 quic_data.AddWrite(
2837 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:452838 client_maker_.MakeRequestHeadersPacket(
2839 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
2840 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
2841
2842 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:232843
Renjie Tangaadb84b2019-08-31 01:00:232844 // TLP 1
2845 quic_data.AddWrite(SYNCHRONOUS,
2846 client_maker_.MakeRetransmissionPacket(1, 2, true));
2847 // TLP 2
2848 quic_data.AddWrite(SYNCHRONOUS,
2849 client_maker_.MakeRetransmissionPacket(1, 3, true));
2850 // RTO 1
2851 quic_data.AddWrite(SYNCHRONOUS,
2852 client_maker_.MakeRetransmissionPacket(1, 4, true));
2853 // RTO 2
2854 quic_data.AddWrite(SYNCHRONOUS,
2855 client_maker_.MakeRetransmissionPacket(1, 5, true));
2856 // RTO 3
2857 quic_data.AddWrite(SYNCHRONOUS,
2858 client_maker_.MakeRetransmissionPacket(1, 6, true));
Ryan Hamilton3cc2c152019-07-09 19:36:012859
Renjie Tangaadb84b2019-08-31 01:00:232860 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
2861 7, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2862 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222863
rch9ecde09b2017-04-08 00:18:232864 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2865 quic_data.AddRead(ASYNC, OK);
2866 quic_data.AddSocketDataToFactory(&socket_factory_);
2867
2868 // In order for a new QUIC session to be established via alternate-protocol
2869 // without racing an HTTP connection, we need the host resolution to happen
2870 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2871 // connection to the the server, in this test we require confirmation
2872 // before encrypting so the HTTP job will still start.
2873 host_resolver_.set_synchronous_mode(true);
2874 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2875 "");
rch9ecde09b2017-04-08 00:18:232876
2877 CreateSession();
2878 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232879 QuicStreamFactoryPeer::SetAlarmFactory(
2880 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192881 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552882 &clock_));
rch9ecde09b2017-04-08 00:18:232883
Ryan Hamilton9835e662018-08-02 05:36:272884 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232885
2886 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2887 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362888 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232889 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2890
2891 // Pump the message loop to get the request started.
2892 base::RunLoop().RunUntilIdle();
2893 // Explicitly confirm the handshake.
2894 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522895 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232896
2897 // Run the QUIC session to completion.
2898 quic_task_runner_->RunUntilIdle();
2899
2900 ExpectQuicAlternateProtocolMapping();
2901 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2902 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2903}
2904
2905// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2906// return QUIC_PROTOCOL_ERROR.
2907TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:422908 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
2909 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232910
2911 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592912 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:132913 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232914 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2915
Ryan Hamiltone940bd12019-06-30 02:46:452916 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:032917 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:022918 quic_data.AddWrite(
2919 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:452920 client_maker_.MakeRequestHeadersPacket(
2921 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
2922 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
2923
2924 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Renjie Tangaadb84b2019-08-31 01:00:232925 // TLP 1
2926 quic_data.AddWrite(SYNCHRONOUS,
2927 client_maker_.MakeRetransmissionPacket(1, 2, true));
2928 // TLP 2
2929 quic_data.AddWrite(SYNCHRONOUS,
2930 client_maker_.MakeRetransmissionPacket(1, 3, true));
2931 // RTO 1
2932 quic_data.AddWrite(SYNCHRONOUS,
2933 client_maker_.MakeRetransmissionPacket(1, 4, true));
2934 // RTO 2
2935 quic_data.AddWrite(SYNCHRONOUS,
2936 client_maker_.MakeRetransmissionPacket(1, 5, true));
2937 // RTO 3
2938 quic_data.AddWrite(SYNCHRONOUS,
2939 client_maker_.MakeRetransmissionPacket(1, 6, true));
2940 // RTO 4
2941 quic_data.AddWrite(SYNCHRONOUS,
2942 client_maker_.MakeRetransmissionPacket(1, 7, true));
2943 // RTO 5
2944 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
2945 8, true, quic::QUIC_TOO_MANY_RTOS,
2946 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232947
2948 quic_data.AddRead(ASYNC, OK);
2949 quic_data.AddSocketDataToFactory(&socket_factory_);
2950
2951 // In order for a new QUIC session to be established via alternate-protocol
2952 // without racing an HTTP connection, we need the host resolution to happen
2953 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2954 // connection to the the server, in this test we require confirmation
2955 // before encrypting so the HTTP job will still start.
2956 host_resolver_.set_synchronous_mode(true);
2957 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2958 "");
rch9ecde09b2017-04-08 00:18:232959
2960 CreateSession();
2961 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232962 QuicStreamFactoryPeer::SetAlarmFactory(
2963 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192964 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552965 &clock_));
rch9ecde09b2017-04-08 00:18:232966
Ryan Hamilton9835e662018-08-02 05:36:272967 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232968
2969 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2970 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362971 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232972 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2973
2974 // Pump the message loop to get the request started.
2975 base::RunLoop().RunUntilIdle();
2976 // Explicitly confirm the handshake.
2977 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522978 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232979
2980 // Run the QUIC session to completion.
2981 quic_task_runner_->RunUntilIdle();
2982
2983 ExpectQuicAlternateProtocolMapping();
2984 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2985 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2986}
2987
2988// Verify that if a QUIC connection RTOs, while there are no active streams
2989// QUIC will not be marked as broken.
2990TEST_P(QuicNetworkTransactionTest,
2991 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Nick Harper72ade192019-07-17 03:30:422992 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232993
2994 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592995 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:132996 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232997 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2998
Ryan Hamiltone940bd12019-06-30 02:46:452999 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033000 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023001 quic_data.AddWrite(
3002 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453003 client_maker_.MakeRequestHeadersPacket(
3004 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3005 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3006
3007 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233008
Renjie Tangaadb84b2019-08-31 01:00:233009 quic_data.AddWrite(SYNCHRONOUS,
3010 client_maker_.MakeRstPacket(
Ryan Hamiltonb01f886f2019-07-10 02:25:553011 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
3012 quic::QUIC_STREAM_CANCELLED));
Renjie Tangaadb84b2019-08-31 01:00:233013 // Since the headers are sent on the data stream, when the stream is reset
3014 // the headers are no longer retransmitted.
3015 client_maker_.RemoveSavedStreamFrames(
3016 GetNthClientInitiatedBidirectionalStreamId(0));
3017 // TLP 1
3018 quic_data.AddWrite(SYNCHRONOUS,
3019 client_maker_.MakeRetransmissionPacket(1, 3, true));
3020 // TLP 2
3021 quic_data.AddWrite(SYNCHRONOUS,
3022 client_maker_.MakeRetransmissionPacket(2, 4, true));
3023 // RTO 1
3024 quic_data.AddWrite(SYNCHRONOUS,
3025 client_maker_.MakeRetransmissionPacket(1, 5, true));
3026 quic_data.AddWrite(SYNCHRONOUS,
3027 client_maker_.MakeRetransmissionPacket(2, 6, true));
3028 // RTO 2
3029 quic_data.AddWrite(SYNCHRONOUS,
3030 client_maker_.MakeRetransmissionPacket(1, 7, true));
3031 quic_data.AddWrite(SYNCHRONOUS,
3032 client_maker_.MakeRetransmissionPacket(2, 8, true));
3033 // RTO 3
3034 quic_data.AddWrite(SYNCHRONOUS,
3035 client_maker_.MakeRetransmissionPacket(1, 9, true));
3036 quic_data.AddWrite(SYNCHRONOUS,
3037 client_maker_.MakeRetransmissionPacket(2, 10, true));
3038 // RTO 4
3039 quic_data.AddWrite(SYNCHRONOUS,
3040 client_maker_.MakeRetransmissionPacket(1, 11, true));
3041 quic_data.AddWrite(SYNCHRONOUS,
3042 client_maker_.MakeRetransmissionPacket(2, 12, true));
rch9ecde09b2017-04-08 00:18:233043 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433044 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Renjie Tangaadb84b2019-08-31 01:00:233045 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433046 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233047
3048 quic_data.AddRead(ASYNC, OK);
3049 quic_data.AddSocketDataToFactory(&socket_factory_);
3050
3051 // In order for a new QUIC session to be established via alternate-protocol
3052 // without racing an HTTP connection, we need the host resolution to happen
3053 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3054 // connection to the the server, in this test we require confirmation
3055 // before encrypting so the HTTP job will still start.
3056 host_resolver_.set_synchronous_mode(true);
3057 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3058 "");
rch9ecde09b2017-04-08 00:18:233059
3060 CreateSession();
3061 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233062 QuicStreamFactoryPeer::SetAlarmFactory(
3063 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193064 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553065 &clock_));
rch9ecde09b2017-04-08 00:18:233066
Ryan Hamilton9835e662018-08-02 05:36:273067 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233068
Jeremy Roman0579ed62017-08-29 15:56:193069 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233070 session_.get());
3071 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363072 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3074
3075 // Pump the message loop to get the request started.
3076 base::RunLoop().RunUntilIdle();
3077 // Explicitly confirm the handshake.
3078 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523079 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233080
3081 // Now cancel the request.
3082 trans.reset();
3083
3084 // Run the QUIC session to completion.
3085 quic_task_runner_->RunUntilIdle();
3086
3087 ExpectQuicAlternateProtocolMapping();
3088
3089 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3090}
3091
rch2f2991c2017-04-13 19:28:173092// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3093// the request fails with QUIC_PROTOCOL_ERROR.
3094TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:423095 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173096 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593097 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033098 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433099 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:023100 ConstructClientRequestHeadersPacket(
3101 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3102 true, GetRequestHeaders("GET", "https", "/")));
3103 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton3cc2c152019-07-09 19:36:013104 uint64_t packet_number = 2;
Ryan Hamiltonb01f886f2019-07-10 02:25:553105 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173106 // Peer sending data from an non-existing stream causes this end to raise
3107 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333108 quic_data.AddRead(
3109 ASYNC, ConstructServerRstPacket(
3110 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3111 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173112 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton3cc2c152019-07-09 19:36:013113 quic_data.AddWrite(
3114 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
3115 packet_number++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
Renjie Tangff0d6372019-08-30 22:03:293116 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3117 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173118 quic_data.AddSocketDataToFactory(&socket_factory_);
3119
3120 // In order for a new QUIC session to be established via alternate-protocol
3121 // without racing an HTTP connection, we need the host resolution to happen
3122 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3123 // connection to the the server, in this test we require confirmation
3124 // before encrypting so the HTTP job will still start.
3125 host_resolver_.set_synchronous_mode(true);
3126 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3127 "");
rch2f2991c2017-04-13 19:28:173128
3129 CreateSession();
3130
Ryan Hamilton9835e662018-08-02 05:36:273131 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173132
3133 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3134 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363135 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173136 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3137
3138 // Pump the message loop to get the request started.
3139 base::RunLoop().RunUntilIdle();
3140 // Explicitly confirm the handshake.
3141 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523142 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173143
3144 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553145 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173146
3147 // Run the QUIC session to completion.
3148 base::RunLoop().RunUntilIdle();
3149 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3150 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3151
3152 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3153 ExpectQuicAlternateProtocolMapping();
3154 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3155}
3156
rch2f2991c2017-04-13 19:28:173157// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3158// connection times out, then QUIC will be marked as broken and the request
3159// retried over TCP.
3160TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Ryan Sleevi2e8255b2019-07-17 21:02:213161 session_params_.quic_params.idle_connection_timeout =
3162 base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173163
3164 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593165 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133166 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173167 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3168
Ryan Hamiltone940bd12019-06-30 02:46:453169 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033170 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023171 quic_data.AddWrite(
3172 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453173 client_maker_.MakeRequestHeadersPacket(
3174 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3175 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3176
3177 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Renjie Tangaadb84b2019-08-31 01:00:233178 // TLP 1
3179 quic_data.AddWrite(SYNCHRONOUS,
3180 client_maker_.MakeRetransmissionPacket(1, 2, true));
3181 // TLP 2
3182 quic_data.AddWrite(SYNCHRONOUS,
3183 client_maker_.MakeRetransmissionPacket(1, 3, true));
3184 // RTO 1
3185 quic_data.AddWrite(SYNCHRONOUS,
3186 client_maker_.MakeRetransmissionPacket(1, 4, true));
3187 // RTO 2
3188 quic_data.AddWrite(SYNCHRONOUS,
3189 client_maker_.MakeRetransmissionPacket(1, 5, true));
3190 // RTO 3
3191 quic_data.AddWrite(SYNCHRONOUS,
3192 client_maker_.MakeRetransmissionPacket(1, 6, true));
rch2f2991c2017-04-13 19:28:173193
Renjie Tangaadb84b2019-08-31 01:00:233194 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
3195 7, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3196 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223197
rch2f2991c2017-04-13 19:28:173198 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3199 quic_data.AddRead(ASYNC, OK);
3200 quic_data.AddSocketDataToFactory(&socket_factory_);
3201
3202 // After that fails, it will be resent via TCP.
3203 MockWrite http_writes[] = {
3204 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3205 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3206 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3207
3208 MockRead http_reads[] = {
3209 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3210 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3211 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013212 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173213 socket_factory_.AddSocketDataProvider(&http_data);
3214 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3215
3216 // In order for a new QUIC session to be established via alternate-protocol
3217 // without racing an HTTP connection, we need the host resolution to happen
3218 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3219 // connection to the the server, in this test we require confirmation
3220 // before encrypting so the HTTP job will still start.
3221 host_resolver_.set_synchronous_mode(true);
3222 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3223 "");
rch2f2991c2017-04-13 19:28:173224
3225 CreateSession();
3226 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173227 QuicStreamFactoryPeer::SetAlarmFactory(
3228 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193229 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553230 &clock_));
rch2f2991c2017-04-13 19:28:173231
Ryan Hamilton9835e662018-08-02 05:36:273232 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173233
3234 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3235 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363236 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173237 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3238
3239 // Pump the message loop to get the request started.
3240 base::RunLoop().RunUntilIdle();
3241 // Explicitly confirm the handshake.
3242 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523243 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173244
3245 // Run the QUIC session to completion.
3246 quic_task_runner_->RunUntilIdle();
3247 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3248
3249 ExpectQuicAlternateProtocolMapping();
3250
3251 // Let the transaction proceed which will result in QUIC being marked
3252 // as broken and the request falling back to TCP.
3253 EXPECT_THAT(callback.WaitForResult(), IsOk());
3254
3255 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3256 ASSERT_FALSE(http_data.AllReadDataConsumed());
3257
3258 // Read the response body over TCP.
3259 CheckResponseData(&trans, "hello world");
3260 ExpectBrokenAlternateProtocolMapping();
3261 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3262 ASSERT_TRUE(http_data.AllReadDataConsumed());
3263}
3264
rch2f2991c2017-04-13 19:28:173265// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3266// protocol error occurs after the handshake is confirmed, the request
3267// retried over TCP and the QUIC will be marked as broken.
3268TEST_P(QuicNetworkTransactionTest,
3269 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Ryan Sleevi2e8255b2019-07-17 21:02:213270 session_params_.quic_params.idle_connection_timeout =
3271 base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173272
3273 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593274 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033275 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433276 quic_data.AddWrite(SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:023277 ConstructClientRequestHeadersPacket(
3278 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3279 true, GetRequestHeaders("GET", "https", "/")));
3280 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553281 uint64_t packet_number = 2;
Ryan Hamiltonb01f886f2019-07-10 02:25:553282 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3283
rch2f2991c2017-04-13 19:28:173284 // Peer sending data from an non-existing stream causes this end to raise
3285 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333286 quic_data.AddRead(
3287 ASYNC, ConstructServerRstPacket(
3288 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3289 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173290 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamiltonb01f886f2019-07-10 02:25:553291 quic_data.AddWrite(
3292 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
3293 packet_number++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
Renjie Tangff0d6372019-08-30 22:03:293294 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3295 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173296 quic_data.AddSocketDataToFactory(&socket_factory_);
3297
3298 // After that fails, it will be resent via TCP.
3299 MockWrite http_writes[] = {
3300 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3301 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3302 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3303
3304 MockRead http_reads[] = {
3305 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3306 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3307 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013308 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173309 socket_factory_.AddSocketDataProvider(&http_data);
3310 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3311
3312 // In order for a new QUIC session to be established via alternate-protocol
3313 // without racing an HTTP connection, we need the host resolution to happen
3314 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3315 // connection to the the server, in this test we require confirmation
3316 // before encrypting so the HTTP job will still start.
3317 host_resolver_.set_synchronous_mode(true);
3318 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3319 "");
rch2f2991c2017-04-13 19:28:173320
3321 CreateSession();
3322
Ryan Hamilton9835e662018-08-02 05:36:273323 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173324
3325 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3326 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363327 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3329
3330 // Pump the message loop to get the request started.
3331 base::RunLoop().RunUntilIdle();
3332 // Explicitly confirm the handshake.
3333 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523334 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553335 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173336
3337 // Run the QUIC session to completion.
3338 base::RunLoop().RunUntilIdle();
3339 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3340
3341 ExpectQuicAlternateProtocolMapping();
3342
3343 // Let the transaction proceed which will result in QUIC being marked
3344 // as broken and the request falling back to TCP.
3345 EXPECT_THAT(callback.WaitForResult(), IsOk());
3346
3347 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3348 ASSERT_FALSE(http_data.AllReadDataConsumed());
3349
3350 // Read the response body over TCP.
3351 CheckResponseData(&trans, "hello world");
3352 ExpectBrokenAlternateProtocolMapping();
3353 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3354 ASSERT_TRUE(http_data.AllReadDataConsumed());
3355}
3356
rch30943ee2017-06-12 21:28:443357// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3358// request is reset from, then QUIC will be marked as broken and the request
3359// retried over TCP.
3360TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443361 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593362 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133363 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443364 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3365
Michael Warres167db3e2019-03-01 21:38:033366 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton0d65a8c2019-06-07 00:46:023367 quic_data.AddWrite(
3368 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453369 client_maker_.MakeRequestHeadersPacket(
3370 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
3371 priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
3372
3373 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553374 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443375
Fan Yang32c5a112018-12-10 20:06:333376 quic_data.AddRead(ASYNC,
3377 ConstructServerRstPacket(
3378 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3379 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443380
3381 quic_data.AddRead(ASYNC, OK);
3382 quic_data.AddSocketDataToFactory(&socket_factory_);
3383
3384 // After that fails, it will be resent via TCP.
3385 MockWrite http_writes[] = {
3386 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3387 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3388 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3389
3390 MockRead http_reads[] = {
3391 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3392 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3393 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013394 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443395 socket_factory_.AddSocketDataProvider(&http_data);
3396 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
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 "");
rch30943ee2017-06-12 21:28:443406
3407 CreateSession();
3408
Ryan Hamilton9835e662018-08-02 05:36:273409 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443410
3411 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3412 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363413 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443414 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3415
3416 // Pump the message loop to get the request started.
3417 base::RunLoop().RunUntilIdle();
3418 // Explicitly confirm the handshake.
3419 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523420 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553421 quic_data.Resume();
rch30943ee2017-06-12 21:28:443422
3423 // Run the QUIC session to completion.
3424 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3425
3426 ExpectQuicAlternateProtocolMapping();
3427
3428 // Let the transaction proceed which will result in QUIC being marked
3429 // as broken and the request falling back to TCP.
3430 EXPECT_THAT(callback.WaitForResult(), IsOk());
3431
3432 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3433 ASSERT_FALSE(http_data.AllReadDataConsumed());
3434
3435 // Read the response body over TCP.
3436 CheckResponseData(&trans, "hello world");
3437 ExpectBrokenAlternateProtocolMapping();
3438 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3439 ASSERT_TRUE(http_data.AllReadDataConsumed());
3440}
3441
Ryan Hamilton6c2a2a82017-12-15 02:06:283442// Verify that when an origin has two alt-svc advertisements, one local and one
3443// remote, that when the local is broken the request will go over QUIC via
3444// the remote Alt-Svc.
3445// This is a regression test for crbug/825646.
3446TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Nick Harper72ade192019-07-17 03:30:423447 session_params_.quic_params.allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:283448
3449 GURL origin1 = request_.url; // mail.example.org
3450 GURL origin2("https://www.example.org/");
3451 ASSERT_NE(origin1.host(), origin2.host());
3452
3453 scoped_refptr<X509Certificate> cert(
3454 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243455 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3456 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283457
3458 ProofVerifyDetailsChromium verify_details;
3459 verify_details.cert_verify_result.verified_cert = cert;
3460 verify_details.cert_verify_result.is_issued_by_known_root = true;
3461 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3462
Ryan Hamiltonabad59e2019-06-06 04:02:593463 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233464 int packet_num = 1;
3465 if (VersionUsesQpack(version_.transport_version)) {
3466 mock_quic_data.AddWrite(SYNCHRONOUS,
3467 ConstructInitialSettingsPacket(packet_num++));
3468 }
Ryan Hamilton6c2a2a82017-12-15 02:06:283469 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233470 SYNCHRONOUS,
3471 ConstructClientRequestHeadersPacket(
3472 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3473 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433474 mock_quic_data.AddRead(
3475 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333476 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:023477 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:433478 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433479 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333480 ASYNC, ConstructServerDataPacket(
3481 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173482 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:233483 mock_quic_data.AddWrite(SYNCHRONOUS,
3484 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283485 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3486 mock_quic_data.AddRead(ASYNC, 0); // EOF
3487
3488 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:593489 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:283490 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3491 AddHangingNonAlternateProtocolSocketData();
3492
3493 CreateSession();
3494
3495 // Set up alternative service for |origin1|.
3496 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3497 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
3498 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3499 AlternativeServiceInfoVector alternative_services;
3500 alternative_services.push_back(
3501 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3502 local_alternative, expiration,
Nick Harper72ade192019-07-17 03:30:423503 session_->params().quic_params.supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:283504 alternative_services.push_back(
3505 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3506 remote_alternative, expiration,
Nick Harper72ade192019-07-17 03:30:423507 session_->params().quic_params.supported_versions));
Matt Menke3233d8f22019-08-20 21:01:493508 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
3509 NetworkIsolationKey(),
3510 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:283511
Matt Menke3233d8f22019-08-20 21:01:493512 http_server_properties_->MarkAlternativeServiceBroken(local_alternative);
Ryan Hamilton6c2a2a82017-12-15 02:06:283513
3514 SendRequestAndExpectQuicResponse("hello!");
3515}
3516
rch30943ee2017-06-12 21:28:443517// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3518// request is reset from, then QUIC will be marked as broken and the request
3519// retried over TCP. Then, subsequent requests will go over a new QUIC
3520// connection instead of going back to the broken QUIC connection.
3521// This is a regression tests for crbug/731303.
3522TEST_P(QuicNetworkTransactionTest,
3523 ResetPooledAfterHandshakeConfirmedThenBroken) {
Nick Harper72ade192019-07-17 03:30:423524 session_params_.quic_params.allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:443525
3526 GURL origin1 = request_.url;
3527 GURL origin2("https://www.example.org/");
3528 ASSERT_NE(origin1.host(), origin2.host());
3529
Ryan Hamiltonabad59e2019-06-06 04:02:593530 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:443531
3532 scoped_refptr<X509Certificate> cert(
3533 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243534 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3535 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:443536
3537 ProofVerifyDetailsChromium verify_details;
3538 verify_details.cert_verify_result.verified_cert = cert;
3539 verify_details.cert_verify_result.is_issued_by_known_root = true;
3540 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3541
Renjie Tangaadb84b2019-08-31 01:00:233542 int packet_num = 1;
3543 if (VersionUsesQpack(version_.transport_version)) {
3544 mock_quic_data.AddWrite(SYNCHRONOUS,
3545 ConstructInitialSettingsPacket(packet_num++));
3546 }
rch30943ee2017-06-12 21:28:443547 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433548 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233549 SYNCHRONOUS,
3550 ConstructClientRequestHeadersPacket(
3551 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3552 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433553 mock_quic_data.AddRead(
3554 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333555 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:023556 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:433557 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433558 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333559 ASYNC, ConstructServerDataPacket(
3560 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173561 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:233562 mock_quic_data.AddWrite(SYNCHRONOUS,
3563 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rch30943ee2017-06-12 21:28:443564
3565 // Second request will go over the pooled QUIC connection, but will be
3566 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:053567 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:173568 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
3569 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:053570 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:173571 QuicTestPacketMaker server_maker2(
3572 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
3573 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:433574 mock_quic_data.AddWrite(
3575 SYNCHRONOUS,
3576 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:233577 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
3578 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:023579 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:333580 mock_quic_data.AddRead(
3581 ASYNC, ConstructServerRstPacket(
3582 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
3583 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443584 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3585 mock_quic_data.AddRead(ASYNC, 0); // EOF
3586
3587 mock_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: www.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);
rch30943ee2017-06-12 21:28:443600 socket_factory_.AddSocketDataProvider(&http_data);
3601 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3602
Ryan Hamilton6c2a2a82017-12-15 02:06:283603 // Then the next request to the second origin will be sent over TCP.
3604 socket_factory_.AddSocketDataProvider(&http_data);
3605 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:443606
3607 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563608 QuicStreamFactoryPeer::SetAlarmFactory(
3609 session_->quic_stream_factory(),
3610 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
3611 &clock_));
rch30943ee2017-06-12 21:28:443612
3613 // Set up alternative service for |origin1|.
3614 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:243615 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:493616 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:073617 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
3618 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:443619
3620 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:243621 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:493622 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:073623 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
3624 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:343625
rch30943ee2017-06-12 21:28:443626 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:523627 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:443628 SendRequestAndExpectQuicResponse("hello!");
3629
3630 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:523631 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:443632 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
3633 request_.url = origin2;
3634 SendRequestAndExpectHttpResponse("hello world");
Matt Menke3233d8f22019-08-20 21:01:493635 EXPECT_FALSE(
3636 http_server_properties_->IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:243637 << alternative1.ToString();
Matt Menke3233d8f22019-08-20 21:01:493638 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:243639 << alternative2.ToString();
rch30943ee2017-06-12 21:28:443640
3641 // The third request should use a new QUIC connection, not the broken
3642 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:283643 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:443644}
3645
bnc8be55ebb2015-10-30 14:12:073646TEST_P(QuicNetworkTransactionTest,
3647 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:563648 std::string altsvc_header =
3649 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
3650 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:073651 MockRead http_reads[] = {
3652 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
3653 MockRead("hello world"),
3654 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3655 MockRead(ASYNC, OK)};
3656
Ryan Sleevib8d7ea02018-05-07 20:01:013657 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:073658 socket_factory_.AddSocketDataProvider(&http_data);
3659 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3660 socket_factory_.AddSocketDataProvider(&http_data);
3661 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3662
rch3f4b8452016-02-23 16:59:323663 CreateSession();
bnc8be55ebb2015-10-30 14:12:073664
3665 SendRequestAndExpectHttpResponse("hello world");
3666 SendRequestAndExpectHttpResponse("hello world");
3667}
3668
Xida Chen9bfe0b62018-04-24 19:52:213669// When multiple alternative services are advertised, HttpStreamFactory should
3670// select the alternative service which uses existing QUIC session if available.
3671// If no existing QUIC session can be used, use the first alternative service
3672// from the list.
zhongyi32569c62016-01-08 02:54:303673TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Nick Harper72ade192019-07-17 03:30:423674 session_params_.quic_params.allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:523675 MockRead http_reads[] = {
3676 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:293677 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:523678 MockRead("hello world"),
3679 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
3680 MockRead(ASYNC, OK)};
3681
Ryan Sleevib8d7ea02018-05-07 20:01:013682 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:523683 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:083684 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:563685 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:523686
zhongyi32569c62016-01-08 02:54:303687 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:293688 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:303689 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:593690 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233691 int packet_num = 1;
3692 if (VersionUsesQpack(version_.transport_version)) {
3693 mock_quic_data.AddWrite(SYNCHRONOUS,
3694 ConstructInitialSettingsPacket(packet_num++));
3695 }
rch5cb522462017-04-25 20:18:363696 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233697 SYNCHRONOUS,
3698 ConstructClientRequestHeadersPacket(
3699 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3700 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:303701
3702 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:293703 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
3704 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:433705 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:023706 ASYNC, ConstructServerResponseHeadersPacket(
3707 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
3708 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:433709 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433710 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333711 ASYNC, ConstructServerDataPacket(
3712 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173713 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:233714 mock_quic_data.AddWrite(SYNCHRONOUS,
3715 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:303716
3717 // Second QUIC request data.
3718 // Connection pooling, using existing session, no need to include version
3719 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:583720 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233721 SYNCHRONOUS,
3722 ConstructClientRequestHeadersPacket(
3723 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
3724 true, GetRequestHeaders("GET", "https", "/"),
3725 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:433726 mock_quic_data.AddRead(
3727 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333728 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:023729 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433730 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333731 ASYNC, ConstructServerDataPacket(
3732 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173733 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:433734 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233735 SYNCHRONOUS,
3736 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bncc958faa2015-07-31 18:14:523737 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:593738 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:523739
3740 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3741
rtennetib8e80fb2016-05-16 00:12:093742 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:323743 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563744 QuicStreamFactoryPeer::SetAlarmFactory(
3745 session_->quic_stream_factory(),
3746 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
3747 &clock_));
bncc958faa2015-07-31 18:14:523748
3749 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:303750
bnc359ed2a2016-04-29 20:43:453751 SendRequestAndExpectQuicResponse("hello!");
3752 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:303753}
3754
tbansal6490783c2016-09-20 17:55:273755// Check that an existing QUIC connection to an alternative proxy server is
3756// used.
3757TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
3758 base::HistogramTester histogram_tester;
3759
tbansal6490783c2016-09-20 17:55:273760 // First QUIC request data.
3761 // Open a session to foo.example.org:443 using the first entry of the
3762 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:593763 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:233764 int packet_num = 1;
3765 if (VersionUsesQpack(version_.transport_version)) {
3766 mock_quic_data.AddWrite(SYNCHRONOUS,
3767 ConstructInitialSettingsPacket(packet_num++));
3768 }
rch5cb522462017-04-25 20:18:363769 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233770 SYNCHRONOUS,
3771 ConstructClientRequestHeadersPacket(
3772 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3773 true, GetRequestHeaders("GET", "http", "/")));
tbansal6490783c2016-09-20 17:55:273774
3775 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:433776 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:023777 ASYNC, ConstructServerResponseHeadersPacket(
3778 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
3779 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:433780 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433781 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333782 ASYNC, ConstructServerDataPacket(
3783 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173784 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:233785 mock_quic_data.AddWrite(SYNCHRONOUS,
3786 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:273787
3788 // Second QUIC request data.
3789 // Connection pooling, using existing session, no need to include version
3790 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:273791 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233792 SYNCHRONOUS,
3793 ConstructClientRequestHeadersPacket(
3794 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
3795 true, GetRequestHeaders("GET", "http", "/"),
3796 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:433797 mock_quic_data.AddRead(
3798 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333799 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:023800 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433801 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333802 ASYNC, ConstructServerDataPacket(
3803 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173804 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:433805 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233806 SYNCHRONOUS,
3807 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:273808 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3809 mock_quic_data.AddRead(ASYNC, 0); // EOF
3810
3811 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3812
3813 AddHangingNonAlternateProtocolSocketData();
3814
3815 TestProxyDelegate test_proxy_delegate;
3816
Lily Houghton8c2f97d2018-01-22 05:06:593817 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:493818 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:273819
3820 test_proxy_delegate.set_alternative_proxy_server(
3821 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:523822 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:273823
3824 request_.url = GURL("http://mail.example.org/");
3825
3826 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563827 QuicStreamFactoryPeer::SetAlarmFactory(
3828 session_->quic_stream_factory(),
3829 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
3830 &clock_));
tbansal6490783c2016-09-20 17:55:273831
3832 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
3833 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
3834 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
3835 1);
3836
3837 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
3838 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
3839 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
3840 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
3841 1);
3842}
3843
Ryan Hamilton8d9ee76e2018-05-29 23:52:523844// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:453845// even if alternative service destination is different.
3846TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Nick Harper72ade192019-07-17 03:30:423847 session_params_.quic_params.allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:593848 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:453849
Renjie Tangaadb84b2019-08-31 01:00:233850 int packet_num = 1;
3851 if (VersionUsesQpack(version_.transport_version)) {
3852 mock_quic_data.AddWrite(SYNCHRONOUS,
3853 ConstructInitialSettingsPacket(packet_num++));
3854 }
bnc359ed2a2016-04-29 20:43:453855 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433856 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233857 SYNCHRONOUS,
3858 ConstructClientRequestHeadersPacket(
3859 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3860 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433861 mock_quic_data.AddRead(
3862 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333863 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:023864 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:433865 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433866 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333867 ASYNC, ConstructServerDataPacket(
3868 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173869 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:233870 mock_quic_data.AddWrite(SYNCHRONOUS,
3871 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:303872
bnc359ed2a2016-04-29 20:43:453873 // Second request.
alyssar2adf3ac2016-05-03 17:12:583874 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233875 SYNCHRONOUS,
3876 ConstructClientRequestHeadersPacket(
3877 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
3878 true, GetRequestHeaders("GET", "https", "/"),
3879 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:433880 mock_quic_data.AddRead(
3881 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333882 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:023883 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433884 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333885 ASYNC, ConstructServerDataPacket(
3886 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173887 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:433888 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233889 SYNCHRONOUS,
3890 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:303891 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3892 mock_quic_data.AddRead(ASYNC, 0); // EOF
3893
3894 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:453895
3896 AddHangingNonAlternateProtocolSocketData();
3897 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:303898
rch3f4b8452016-02-23 16:59:323899 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563900 QuicStreamFactoryPeer::SetAlarmFactory(
3901 session_->quic_stream_factory(),
3902 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
3903 &clock_));
zhongyi32569c62016-01-08 02:54:303904
bnc359ed2a2016-04-29 20:43:453905 const char destination1[] = "first.example.com";
3906 const char destination2[] = "second.example.com";
3907
3908 // Set up alternative service entry to destination1.
3909 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:213910 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:453911 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:493912 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:073913 server, NetworkIsolationKey(), alternative_service, expiration,
3914 supported_versions_);
bnc359ed2a2016-04-29 20:43:453915 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:523916 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:453917 SendRequestAndExpectQuicResponse("hello!");
3918
3919 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:213920 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:493921 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:073922 server, NetworkIsolationKey(), alternative_service, expiration,
3923 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523924 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:453925 // even though alternative service destination is different.
3926 SendRequestAndExpectQuicResponse("hello!");
3927}
3928
3929// Pool to existing session with matching destination and matching certificate
3930// even if origin is different, and even if the alternative service with
3931// matching destination is not the first one on the list.
3932TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Nick Harper72ade192019-07-17 03:30:423933 session_params_.quic_params.allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:453934 GURL origin1 = request_.url;
3935 GURL origin2("https://www.example.org/");
3936 ASSERT_NE(origin1.host(), origin2.host());
3937
Ryan Hamiltonabad59e2019-06-06 04:02:593938 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:453939
Renjie Tangaadb84b2019-08-31 01:00:233940 int packet_num = 1;
3941 if (VersionUsesQpack(version_.transport_version)) {
3942 mock_quic_data.AddWrite(SYNCHRONOUS,
3943 ConstructInitialSettingsPacket(packet_num++));
3944 }
bnc359ed2a2016-04-29 20:43:453945 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:433946 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233947 SYNCHRONOUS,
3948 ConstructClientRequestHeadersPacket(
3949 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3950 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:433951 mock_quic_data.AddRead(
3952 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333953 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:023954 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:433955 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433956 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333957 ASYNC, ConstructServerDataPacket(
3958 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173959 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:233960 mock_quic_data.AddWrite(SYNCHRONOUS,
3961 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:453962
3963 // Second request.
Yixin Wang079ad542018-01-11 04:06:053964 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:173965 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
3966 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:053967 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:173968 QuicTestPacketMaker server_maker2(
3969 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
3970 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:583971 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433972 SYNCHRONOUS,
3973 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:233974 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
3975 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:023976 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:433977 mock_quic_data.AddRead(
3978 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333979 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:023980 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433981 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333982 ASYNC, ConstructServerDataPacket(
3983 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173984 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:433985 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233986 SYNCHRONOUS,
3987 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:453988 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3989 mock_quic_data.AddRead(ASYNC, 0); // EOF
3990
3991 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3992
3993 AddHangingNonAlternateProtocolSocketData();
3994 AddHangingNonAlternateProtocolSocketData();
3995
3996 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:563997 QuicStreamFactoryPeer::SetAlarmFactory(
3998 session_->quic_stream_factory(),
3999 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4000 &clock_));
bnc359ed2a2016-04-29 20:43:454001
4002 const char destination1[] = "first.example.com";
4003 const char destination2[] = "second.example.com";
4004
4005 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214006 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454007 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494008 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074009 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4010 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454011
4012 // Set up multiple alternative service entries for |origin2|,
4013 // the first one with a different destination as for |origin1|,
4014 // the second one with the same. The second one should be used,
4015 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214016 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454017 AlternativeServiceInfoVector alternative_services;
4018 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214019 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4020 alternative_service2, expiration,
Nick Harper72ade192019-07-17 03:30:424021 session_->params().quic_params.supported_versions));
bnc359ed2a2016-04-29 20:43:454022 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214023 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4024 alternative_service1, expiration,
Nick Harper72ade192019-07-17 03:30:424025 session_->params().quic_params.supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494026 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4027 NetworkIsolationKey(),
4028 alternative_services);
bnc359ed2a2016-04-29 20:43:454029 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524030 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454031 SendRequestAndExpectQuicResponse("hello!");
4032
4033 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524034 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454035 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584036
bnc359ed2a2016-04-29 20:43:454037 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304038}
4039
4040// Multiple origins have listed the same alternative services. When there's a
4041// existing QUIC session opened by a request to other origin,
4042// if the cert is valid, should select this QUIC session to make the request
4043// if this is also the first existing QUIC session.
4044TEST_P(QuicNetworkTransactionTest,
4045 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Nick Harper72ade192019-07-17 03:30:424046 session_params_.quic_params.allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294047 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304048
rch9ae5b3b2016-02-11 00:36:294049 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304050 MockRead http_reads[] = {
4051 MockRead("HTTP/1.1 200 OK\r\n"),
4052 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294053 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304054 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4055 MockRead(ASYNC, OK)};
4056
Ryan Sleevib8d7ea02018-05-07 20:01:014057 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304058 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084059 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304060 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4061
4062 // HTTP data for request to mail.example.org.
4063 MockRead http_reads2[] = {
4064 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294065 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304066 MockRead("hello world from mail.example.org"),
4067 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4068 MockRead(ASYNC, OK)};
4069
Ryan Sleevib8d7ea02018-05-07 20:01:014070 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304071 socket_factory_.AddSocketDataProvider(&http_data2);
4072 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4073
Yixin Wang079ad542018-01-11 04:06:054074 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174075 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4076 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054077 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584078 server_maker_.set_hostname("www.example.org");
4079 client_maker_.set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594080 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234081 int packet_num = 1;
4082 if (VersionUsesQpack(version_.transport_version)) {
4083 mock_quic_data.AddWrite(SYNCHRONOUS,
4084 ConstructInitialSettingsPacket(packet_num++));
4085 }
zhongyi32569c62016-01-08 02:54:304086 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584087 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234088 SYNCHRONOUS,
4089 ConstructClientRequestHeadersPacket(
4090 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4091 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434092
4093 mock_quic_data.AddRead(
4094 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334095 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024096 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434097 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334098 mock_quic_data.AddRead(
4099 ASYNC, ConstructServerDataPacket(
4100 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174101 header + "hello from mail QUIC!"));
Renjie Tangaadb84b2019-08-31 01:00:234102 mock_quic_data.AddWrite(SYNCHRONOUS,
4103 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434104 // Second QUIC request data.
4105 mock_quic_data.AddWrite(
4106 SYNCHRONOUS,
4107 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234108 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4109 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024110 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434111 mock_quic_data.AddRead(
4112 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334113 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024114 GetResponseHeaders("200 OK")));
Fan Yang32c5a112018-12-10 20:06:334115 mock_quic_data.AddRead(
4116 ASYNC, ConstructServerDataPacket(
4117 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174118 header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434119 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234120 SYNCHRONOUS,
4121 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304122 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4123 mock_quic_data.AddRead(ASYNC, 0); // EOF
4124
4125 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304126
rtennetib8e80fb2016-05-16 00:12:094127 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324128 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564129 QuicStreamFactoryPeer::SetAlarmFactory(
4130 session_->quic_stream_factory(),
4131 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4132 &clock_));
zhongyi32569c62016-01-08 02:54:304133
4134 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294135 request_.url = GURL("https://www.example.org/");
4136 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304137 request_.url = GURL("https://mail.example.org/");
4138 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4139
rch9ae5b3b2016-02-11 00:36:294140 // Open a QUIC session to mail.example.org:443 when making request
4141 // to mail.example.org.
4142 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454143 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304144
rch9ae5b3b2016-02-11 00:36:294145 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304146 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454147 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524148}
4149
4150TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524151 MockRead http_reads[] = {
4152 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564153 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524154 MockRead("hello world"),
4155 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4156 MockRead(ASYNC, OK)};
4157
Ryan Sleevib8d7ea02018-05-07 20:01:014158 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524159 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084160 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564161 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524162
rtennetib8e80fb2016-05-16 00:12:094163 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324164 CreateSession();
bncc958faa2015-07-31 18:14:524165
4166 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454167
4168 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344169 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494170 http_server_properties_->GetAlternativeServiceInfos(
4171 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344172 ASSERT_EQ(1u, alternative_service_info_vector.size());
4173 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544174 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344175 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4176 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4177 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524178}
4179
4180TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524181 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564182 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4183 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524184 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4185 MockRead(ASYNC, OK)};
4186
Ryan Sleevib8d7ea02018-05-07 20:01:014187 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524188 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084189 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564190 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524191
Ryan Hamiltonabad59e2019-06-06 04:02:594192 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234193 int packet_num = 1;
4194 if (VersionUsesQpack(version_.transport_version)) {
4195 mock_quic_data.AddWrite(SYNCHRONOUS,
4196 ConstructInitialSettingsPacket(packet_num++));
4197 }
rch5cb522462017-04-25 20:18:364198 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234199 SYNCHRONOUS,
4200 ConstructClientRequestHeadersPacket(
4201 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4202 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434203 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334204 ASYNC, ConstructServerResponseHeadersPacket(
4205 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4206 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434207 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334208 mock_quic_data.AddRead(
4209 ASYNC, ConstructServerDataPacket(
4210 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174211 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234212 mock_quic_data.AddWrite(SYNCHRONOUS,
4213 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524214 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4215 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524216
4217 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4218
rtennetib8e80fb2016-05-16 00:12:094219 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324220 CreateSession();
bncc958faa2015-07-31 18:14:524221
bnc3472afd2016-11-17 15:27:214222 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524223 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494224 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
bncc958faa2015-07-31 18:14:524225 alternative_service);
Matt Menke3233d8f22019-08-20 21:01:494226 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
bncc958faa2015-07-31 18:14:524227 alternative_service));
4228
4229 SendRequestAndExpectHttpResponse("hello world");
4230 SendRequestAndExpectQuicResponse("hello!");
4231
mmenkee24011922015-12-17 22:12:594232 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524233
Matt Menke3233d8f22019-08-20 21:01:494234 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
bncc958faa2015-07-31 18:14:524235 alternative_service));
Matt Menke19475f72019-08-21 18:57:444236 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4237 url::SchemeHostPort("https", request_.url.host(), 443),
4238 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524239}
4240
bncc958faa2015-07-31 18:14:524241TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524242 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564243 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4244 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524245 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4246 MockRead(ASYNC, OK)};
4247
Ryan Sleevib8d7ea02018-05-07 20:01:014248 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524249 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564250 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524251
Ryan Hamiltonabad59e2019-06-06 04:02:594252 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234253 int packet_num = 1;
4254 if (VersionUsesQpack(version_.transport_version)) {
4255 mock_quic_data.AddWrite(SYNCHRONOUS,
4256 ConstructInitialSettingsPacket(packet_num++));
4257 }
rch5cb522462017-04-25 20:18:364258 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234259 SYNCHRONOUS,
4260 ConstructClientRequestHeadersPacket(
4261 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4262 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434263 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334264 ASYNC, ConstructServerResponseHeadersPacket(
4265 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4266 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434267 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334268 mock_quic_data.AddRead(
4269 ASYNC, ConstructServerDataPacket(
4270 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174271 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234272 mock_quic_data.AddWrite(SYNCHRONOUS,
4273 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524274 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4275
4276 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4277
4278 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324279 CreateSession();
bncc958faa2015-07-31 18:14:524280
4281 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4282 SendRequestAndExpectHttpResponse("hello world");
4283}
4284
tbansalc3308d72016-08-27 10:25:044285// Tests that the connection to an HTTPS proxy is raced with an available
4286// alternative proxy server.
4287TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274288 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594289 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494290 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044291
Ryan Hamiltonabad59e2019-06-06 04:02:594292 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234293 int packet_num = 1;
4294 if (VersionUsesQpack(version_.transport_version)) {
4295 mock_quic_data.AddWrite(SYNCHRONOUS,
4296 ConstructInitialSettingsPacket(packet_num++));
4297 }
rch5cb522462017-04-25 20:18:364298 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234299 SYNCHRONOUS,
4300 ConstructClientRequestHeadersPacket(
4301 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4302 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434303 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334304 ASYNC, ConstructServerResponseHeadersPacket(
4305 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4306 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434307 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334308 mock_quic_data.AddRead(
4309 ASYNC, ConstructServerDataPacket(
4310 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174311 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234312 mock_quic_data.AddWrite(SYNCHRONOUS,
4313 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044314 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4315 mock_quic_data.AddRead(ASYNC, 0); // EOF
4316
4317 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4318
4319 // There is no need to set up main job, because no attempt will be made to
4320 // speak to the proxy over TCP.
4321 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044322 TestProxyDelegate test_proxy_delegate;
4323 const HostPortPair host_port_pair("mail.example.org", 443);
4324
4325 test_proxy_delegate.set_alternative_proxy_server(
4326 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524327 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044328 CreateSession();
4329 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4330
4331 // The main job needs to hang in order to guarantee that the alternative
4332 // proxy server job will "win".
4333 AddHangingNonAlternateProtocolSocketData();
4334
4335 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4336
4337 // Verify that the alternative proxy server is not marked as broken.
4338 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4339
4340 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594341 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274342
4343 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4344 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4345 1);
tbansalc3308d72016-08-27 10:25:044346}
4347
bnc1c196c6e2016-05-28 13:51:484348TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304349 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274350 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304351
4352 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564353 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294354 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564355 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304356
4357 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564358 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484359 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564360 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304361
Ryan Sleevib8d7ea02018-05-07 20:01:014362 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504363 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084364 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504365 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304366
4367 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454368 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304369 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454370 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304371 };
Ryan Sleevib8d7ea02018-05-07 20:01:014372 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504373 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304374
4375 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014376 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504377 socket_factory_.AddSocketDataProvider(&http_data2);
4378 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304379
bnc912a04b2016-04-20 14:19:504380 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304381
4382 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304383 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174384 ASSERT_TRUE(http_data.AllReadDataConsumed());
4385 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304386
4387 // Now run the second request in which the QUIC socket hangs,
4388 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304389 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454390 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304391
rch37de576c2015-05-17 20:28:174392 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4393 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454394 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304395}
4396
[email protected]1e960032013-12-20 19:00:204397TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594398 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:034399 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:434400 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024401 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4402 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4403 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434404 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334405 ASYNC, ConstructServerResponseHeadersPacket(
4406 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4407 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434408 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334409 mock_quic_data.AddRead(
4410 ASYNC, ConstructServerDataPacket(
4411 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174412 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434413 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504414 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594415 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484416
rcha5399e02015-04-21 19:32:044417 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484418
rtennetib8e80fb2016-05-16 00:12:094419 // The non-alternate protocol job needs to hang in order to guarantee that
4420 // the alternate-protocol job will "win".
4421 AddHangingNonAlternateProtocolSocketData();
4422
rch3f4b8452016-02-23 16:59:324423 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274424 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194425 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304426
Matt Menke19475f72019-08-21 18:57:444427 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
4428 url::SchemeHostPort("https", request_.url.host(), 443),
4429 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:484430}
4431
[email protected]1e960032013-12-20 19:00:204432TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594433 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:034434 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Fan Yang32c5a112018-12-10 20:06:334435 mock_quic_data.AddWrite(
4436 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4437 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4438 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434439 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334440 ASYNC, ConstructServerResponseHeadersPacket(
4441 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4442 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434443 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334444 mock_quic_data.AddRead(
4445 ASYNC, ConstructServerDataPacket(
4446 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174447 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434448 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504449 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594450 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044451 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274452
4453 // In order for a new QUIC session to be established via alternate-protocol
4454 // without racing an HTTP connection, we need the host resolution to happen
4455 // synchronously.
4456 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294457 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564458 "");
[email protected]3a120a6b2013-06-25 01:08:274459
rtennetib8e80fb2016-05-16 00:12:094460 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324461 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274462 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274463 SendRequestAndExpectQuicResponse("hello!");
4464}
4465
[email protected]0fc924b2014-03-31 04:34:154466TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494467 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4468 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154469
4470 // Since we are using a proxy, the QUIC job will not succeed.
4471 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294472 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4473 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564474 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154475
4476 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564477 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484478 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564479 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154480
Ryan Sleevib8d7ea02018-05-07 20:01:014481 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154482 socket_factory_.AddSocketDataProvider(&http_data);
4483
4484 // In order for a new QUIC session to be established via alternate-protocol
4485 // without racing an HTTP connection, we need the host resolution to happen
4486 // synchronously.
4487 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294488 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564489 "");
[email protected]0fc924b2014-03-31 04:34:154490
rch9ae5b3b2016-02-11 00:36:294491 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324492 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274493 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154494 SendRequestAndExpectHttpResponse("hello world");
4495}
4496
[email protected]1e960032013-12-20 19:00:204497TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:594498 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234499 int packet_num = 1;
4500 if (VersionUsesQpack(version_.transport_version)) {
4501 mock_quic_data.AddWrite(SYNCHRONOUS,
4502 ConstructInitialSettingsPacket(packet_num++));
4503 }
rch5cb522462017-04-25 20:18:364504 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234505 SYNCHRONOUS,
4506 ConstructClientRequestHeadersPacket(
4507 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4508 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434509 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334510 ASYNC, ConstructServerResponseHeadersPacket(
4511 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4512 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434513 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334514 mock_quic_data.AddRead(
4515 ASYNC, ConstructServerDataPacket(
4516 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174517 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234518 mock_quic_data.AddWrite(SYNCHRONOUS,
4519 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:594520 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044521 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124522
rtennetib8e80fb2016-05-16 00:12:094523 // The non-alternate protocol job needs to hang in order to guarantee that
4524 // the alternate-protocol job will "win".
4525 AddHangingNonAlternateProtocolSocketData();
4526
[email protected]11c05872013-08-20 02:04:124527 // In order for a new QUIC session to be established via alternate-protocol
4528 // without racing an HTTP connection, we need the host resolution to happen
4529 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4530 // connection to the the server, in this test we require confirmation
4531 // before encrypting so the HTTP job will still start.
4532 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294533 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564534 "");
[email protected]11c05872013-08-20 02:04:124535
rch3f4b8452016-02-23 16:59:324536 CreateSession();
[email protected]11c05872013-08-20 02:04:124537 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274538 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:124539
bnc691fda62016-08-12 00:43:164540 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:124541 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364542 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014543 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:124544
4545 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524546 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:014547 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:504548
bnc691fda62016-08-12 00:43:164549 CheckWasQuicResponse(&trans);
4550 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:124551}
4552
Steven Valdez58097ec32018-07-16 18:29:044553TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:014554 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594555 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:034556 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:044557 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014558 SYNCHRONOUS,
4559 ConstructClientRequestHeadersPacket(
4560 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4561 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334562 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024563 ASYNC, ConstructServerResponseHeadersPacket(
4564 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4565 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:014566 mock_quic_data.AddWrite(
4567 SYNCHRONOUS,
4568 ConstructClientAckAndRstPacket(
4569 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
4570 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:044571
4572 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4573
Steven Valdez58097ec32018-07-16 18:29:044574 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014575 SYNCHRONOUS,
4576 ConstructClientRequestHeadersPacket(
4577 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4578 true, GetRequestHeaders("GET", "https", "/"),
4579 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:044580 mock_quic_data.AddRead(
4581 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334582 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024583 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434584 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:044585 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334586 ASYNC, ConstructServerDataPacket(
4587 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174588 header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:044589 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014590 SYNCHRONOUS,
4591 ConstructClientAckAndConnectionClosePacket(packet_number++, 3, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:044592 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4593 mock_quic_data.AddRead(ASYNC, 0); // EOF
4594
4595 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4596
4597 // In order for a new QUIC session to be established via alternate-protocol
4598 // without racing an HTTP connection, we need the host resolution to happen
4599 // synchronously.
4600 host_resolver_.set_synchronous_mode(true);
4601 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4602 "");
Steven Valdez58097ec32018-07-16 18:29:044603
4604 AddHangingNonAlternateProtocolSocketData();
4605 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274606 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:564607 QuicStreamFactoryPeer::SetAlarmFactory(
4608 session_->quic_stream_factory(),
4609 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4610 &clock_));
Steven Valdez58097ec32018-07-16 18:29:044611
4612 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4613 TestCompletionCallback callback;
4614 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
4615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4616
4617 // Confirm the handshake after the 425 Too Early.
4618 base::RunLoop().RunUntilIdle();
4619
4620 // The handshake hasn't been confirmed yet, so the retry should not have
4621 // succeeded.
4622 EXPECT_FALSE(callback.have_result());
4623
4624 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
4625 quic::QuicSession::HANDSHAKE_CONFIRMED);
4626
4627 EXPECT_THAT(callback.WaitForResult(), IsOk());
4628 CheckWasQuicResponse(&trans);
4629 CheckResponseData(&trans, "hello!");
4630}
4631
4632TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamilton3cc2c152019-07-09 19:36:014633 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594634 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:034635 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:044636 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014637 SYNCHRONOUS,
4638 ConstructClientRequestHeadersPacket(
4639 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4640 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334641 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024642 ASYNC, ConstructServerResponseHeadersPacket(
4643 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4644 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:014645 mock_quic_data.AddWrite(
4646 SYNCHRONOUS,
4647 ConstructClientAckAndRstPacket(
4648 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
4649 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:044650
4651 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4652
Steven Valdez58097ec32018-07-16 18:29:044653 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:014654 SYNCHRONOUS,
4655 ConstructClientRequestHeadersPacket(
4656 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4657 true, GetRequestHeaders("GET", "https", "/"),
4658 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334659 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024660 ASYNC, ConstructServerResponseHeadersPacket(
4661 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
4662 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:014663 mock_quic_data.AddWrite(
4664 SYNCHRONOUS,
4665 ConstructClientAckAndRstPacket(
4666 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
4667 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:044668 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4669 mock_quic_data.AddRead(ASYNC, 0); // EOF
4670
4671 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4672
4673 // In order for a new QUIC session to be established via alternate-protocol
4674 // without racing an HTTP connection, we need the host resolution to happen
4675 // synchronously.
4676 host_resolver_.set_synchronous_mode(true);
4677 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4678 "");
Steven Valdez58097ec32018-07-16 18:29:044679
4680 AddHangingNonAlternateProtocolSocketData();
4681 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274682 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:564683 QuicStreamFactoryPeer::SetAlarmFactory(
4684 session_->quic_stream_factory(),
4685 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4686 &clock_));
Steven Valdez58097ec32018-07-16 18:29:044687
4688 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4689 TestCompletionCallback callback;
4690 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
4691 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4692
4693 // Confirm the handshake after the 425 Too Early.
4694 base::RunLoop().RunUntilIdle();
4695
4696 // The handshake hasn't been confirmed yet, so the retry should not have
4697 // succeeded.
4698 EXPECT_FALSE(callback.have_result());
4699
4700 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
4701 quic::QuicSession::HANDSHAKE_CONFIRMED);
4702
4703 EXPECT_THAT(callback.WaitForResult(), IsOk());
4704 const HttpResponseInfo* response = trans.GetResponseInfo();
4705 ASSERT_TRUE(response != nullptr);
4706 ASSERT_TRUE(response->headers.get() != nullptr);
4707 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
4708 EXPECT_TRUE(response->was_fetched_via_spdy);
4709 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:564710 EXPECT_EQ(
4711 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
4712 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:044713}
4714
zhongyica364fbb2015-12-12 03:39:124715TEST_P(QuicNetworkTransactionTest,
4716 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Nick Harper72ade192019-07-17 03:30:424717 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
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", "/")));
zhongyica364fbb2015-12-12 03:39:124729 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:524730 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:434731 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:124732 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4733
4734 // The non-alternate protocol job needs to hang in order to guarantee that
4735 // the alternate-protocol job will "win".
4736 AddHangingNonAlternateProtocolSocketData();
4737
4738 // In order for a new QUIC session to be established via alternate-protocol
4739 // without racing an HTTP connection, we need the host resolution to happen
4740 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4741 // connection to the the server, in this test we require confirmation
4742 // before encrypting so the HTTP job will still start.
4743 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294744 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:124745 "");
zhongyica364fbb2015-12-12 03:39:124746
rch3f4b8452016-02-23 16:59:324747 CreateSession();
zhongyica364fbb2015-12-12 03:39:124748 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274749 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:124750
bnc691fda62016-08-12 00:43:164751 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:124752 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364753 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014754 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:124755
4756 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524757 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:014758 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:124759
4760 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524761 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124762
bnc691fda62016-08-12 00:43:164763 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:124764 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:524765 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
4766 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124767}
4768
4769TEST_P(QuicNetworkTransactionTest,
4770 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Nick Harper72ade192019-07-17 03:30:424771 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:594772 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234773 int packet_num = 1;
4774 if (VersionUsesQpack(version_.transport_version)) {
4775 mock_quic_data.AddWrite(SYNCHRONOUS,
4776 ConstructInitialSettingsPacket(packet_num++));
4777 }
rch5cb522462017-04-25 20:18:364778 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234779 SYNCHRONOUS,
4780 ConstructClientRequestHeadersPacket(
4781 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4782 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:214783 // Peer sending data from an non-existing stream causes this end to raise
4784 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:334785 mock_quic_data.AddRead(
4786 ASYNC, ConstructServerRstPacket(
4787 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
4788 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:214789 std::string quic_error_details = "Data for nonexistent stream";
Renjie Tangaadb84b2019-08-31 01:00:234790 mock_quic_data.AddWrite(
4791 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
4792 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
4793 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
4794 quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:124795 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4796
4797 // The non-alternate protocol job needs to hang in order to guarantee that
4798 // the alternate-protocol job will "win".
4799 AddHangingNonAlternateProtocolSocketData();
4800
4801 // In order for a new QUIC session to be established via alternate-protocol
4802 // without racing an HTTP connection, we need the host resolution to happen
4803 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4804 // connection to the the server, in this test we require confirmation
4805 // before encrypting so the HTTP job will still start.
4806 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294807 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:124808 "");
zhongyica364fbb2015-12-12 03:39:124809
rch3f4b8452016-02-23 16:59:324810 CreateSession();
zhongyica364fbb2015-12-12 03:39:124811 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274812 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:124813
bnc691fda62016-08-12 00:43:164814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:124815 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364816 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014817 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:124818
4819 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524820 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:014821 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:124822 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524823 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124824
bnc691fda62016-08-12 00:43:164825 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524826 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:124827}
4828
rchcd5f1c62016-06-23 02:43:484829TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:594830 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234831 int packet_num = 1;
4832 if (VersionUsesQpack(version_.transport_version)) {
4833 mock_quic_data.AddWrite(SYNCHRONOUS,
4834 ConstructInitialSettingsPacket(packet_num++));
4835 }
rch5cb522462017-04-25 20:18:364836 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234837 SYNCHRONOUS,
4838 ConstructClientRequestHeadersPacket(
4839 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4840 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:484841 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:334842 mock_quic_data.AddRead(
4843 ASYNC, ConstructServerResponseHeadersPacket(
4844 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4845 GetResponseHeaders("200 OK")));
4846 mock_quic_data.AddRead(
4847 ASYNC, ConstructServerRstPacket(
4848 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
4849 quic::QUIC_STREAM_CANCELLED));
Renjie Tangaadb84b2019-08-31 01:00:234850 mock_quic_data.AddWrite(SYNCHRONOUS,
4851 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:484852 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
4853 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4854
4855 // The non-alternate protocol job needs to hang in order to guarantee that
4856 // the alternate-protocol job will "win".
4857 AddHangingNonAlternateProtocolSocketData();
4858
4859 // In order for a new QUIC session to be established via alternate-protocol
4860 // without racing an HTTP connection, we need the host resolution to happen
4861 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4862 // connection to the the server, in this test we require confirmation
4863 // before encrypting so the HTTP job will still start.
4864 host_resolver_.set_synchronous_mode(true);
4865 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4866 "");
rchcd5f1c62016-06-23 02:43:484867
4868 CreateSession();
4869 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274870 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:484871
bnc691fda62016-08-12 00:43:164872 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:484873 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364874 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014875 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:484876
4877 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524878 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:484879 // Read the headers.
robpercival214763f2016-07-01 23:27:014880 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:484881
bnc691fda62016-08-12 00:43:164882 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:484883 ASSERT_TRUE(response != nullptr);
4884 ASSERT_TRUE(response->headers.get() != nullptr);
4885 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4886 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:524887 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:564888 EXPECT_EQ(
4889 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
4890 response->connection_info);
rchcd5f1c62016-06-23 02:43:484891
4892 std::string response_data;
bnc691fda62016-08-12 00:43:164893 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:484894}
4895
4896TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Nick Harper72ade192019-07-17 03:30:424897 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:594898 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234899 int packet_num = 1;
4900 if (VersionUsesQpack(version_.transport_version)) {
4901 mock_quic_data.AddWrite(SYNCHRONOUS,
4902 ConstructInitialSettingsPacket(packet_num++));
4903 }
rch5cb522462017-04-25 20:18:364904 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234905 SYNCHRONOUS,
4906 ConstructClientRequestHeadersPacket(
4907 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4908 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:334909 mock_quic_data.AddRead(
4910 ASYNC, ConstructServerRstPacket(
4911 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
4912 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:484913 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
4914 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4915
4916 // The non-alternate protocol job needs to hang in order to guarantee that
4917 // the alternate-protocol job will "win".
4918 AddHangingNonAlternateProtocolSocketData();
4919
4920 // In order for a new QUIC session to be established via alternate-protocol
4921 // without racing an HTTP connection, we need the host resolution to happen
4922 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4923 // connection to the the server, in this test we require confirmation
4924 // before encrypting so the HTTP job will still start.
4925 host_resolver_.set_synchronous_mode(true);
4926 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4927 "");
rchcd5f1c62016-06-23 02:43:484928
4929 CreateSession();
4930 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274931 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:484932
bnc691fda62016-08-12 00:43:164933 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:484934 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364935 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014936 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:484937
4938 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524939 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:484940 // Read the headers.
robpercival214763f2016-07-01 23:27:014941 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:484942}
4943
[email protected]1e960032013-12-20 19:00:204944TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:304945 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:524946 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:584947 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:304948 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:504949 MockRead(ASYNC, close->data(), close->length()),
4950 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
4951 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:304952 };
Ryan Sleevib8d7ea02018-05-07 20:01:014953 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:304954 socket_factory_.AddSocketDataProvider(&quic_data);
4955
4956 // Main job which will succeed even though the alternate job fails.
4957 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:024958 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
4959 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4960 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:304961
Ryan Sleevib8d7ea02018-05-07 20:01:014962 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:304963 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564964 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:304965
rch3f4b8452016-02-23 16:59:324966 CreateSession();
David Schinazic8281052019-01-24 06:14:174967 AddQuicAlternateProtocolMapping(
4968 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:194969 SendRequestAndExpectHttpResponse("hello from http");
4970 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:304971}
4972
[email protected]1e960032013-12-20 19:00:204973TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:594974 // Alternate-protocol job
4975 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:024976 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:594977 };
Ryan Sleevib8d7ea02018-05-07 20:01:014978 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:594979 socket_factory_.AddSocketDataProvider(&quic_data);
4980
4981 // Main job which will succeed even though the alternate job fails.
4982 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:024983 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
4984 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4985 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:594986
Ryan Sleevib8d7ea02018-05-07 20:01:014987 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:594988 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564989 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:594990
rch3f4b8452016-02-23 16:59:324991 CreateSession();
[email protected]d03a66d2013-05-06 12:55:594992
Ryan Hamilton9835e662018-08-02 05:36:274993 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:194994 SendRequestAndExpectHttpResponse("hello from http");
4995 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:594996}
4997
[email protected]00c159f2014-05-21 22:38:164998TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:534999 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165000 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025001 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165002 };
Ryan Sleevib8d7ea02018-05-07 20:01:015003 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165004 socket_factory_.AddSocketDataProvider(&quic_data);
5005
[email protected]eb71ab62014-05-23 07:57:535006 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165007 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025008 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165009 };
5010
Ryan Sleevib8d7ea02018-05-07 20:01:015011 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165012 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5013 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565014 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165015
rtennetib8e80fb2016-05-16 00:12:095016 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325017 CreateSession();
[email protected]00c159f2014-05-21 22:38:165018
Ryan Hamilton9835e662018-08-02 05:36:275019 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165020 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165021 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165022 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5024 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165025 ExpectQuicAlternateProtocolMapping();
5026}
5027
Zhongyi Shia0cef1082017-08-25 01:49:505028TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5029 // Tests that TCP job is delayed and QUIC job does not require confirmation
5030 // if QUIC was recently supported on the same IP on start.
5031
5032 // Set QUIC support on the last IP address, which is same with the local IP
5033 // address. Require confirmation mode will be turned off immediately when
5034 // local IP address is sorted out after we configure the UDP socket.
Matt Menke3233d8f22019-08-20 21:01:495035 http_server_properties_->SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:505036
Ryan Hamiltonabad59e2019-06-06 04:02:595037 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035038 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:435039 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025040 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5041 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5042 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435043 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335044 ASYNC, ConstructServerResponseHeadersPacket(
5045 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5046 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435047 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335048 mock_quic_data.AddRead(
5049 ASYNC, ConstructServerDataPacket(
5050 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175051 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435052 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505053 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5054 mock_quic_data.AddRead(ASYNC, 0); // EOF
5055
5056 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5057 // No HTTP data is mocked as TCP job never starts in this case.
5058
5059 CreateSession();
5060 // QuicStreamFactory by default requires confirmation on construction.
5061 session_->quic_stream_factory()->set_require_confirmation(true);
5062
Ryan Hamilton9835e662018-08-02 05:36:275063 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505064
5065 // Stall host resolution so that QUIC job will not succeed synchronously.
5066 // Socket will not be configured immediately and QUIC support is not sorted
5067 // out, TCP job will still be delayed as server properties indicates QUIC
5068 // support on last IP address.
5069 host_resolver_.set_synchronous_mode(false);
5070
5071 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5072 TestCompletionCallback callback;
5073 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5074 IsError(ERR_IO_PENDING));
5075 // Complete host resolution in next message loop so that QUIC job could
5076 // proceed.
5077 base::RunLoop().RunUntilIdle();
5078 EXPECT_THAT(callback.WaitForResult(), IsOk());
5079
5080 CheckWasQuicResponse(&trans);
5081 CheckResponseData(&trans, "hello!");
5082}
5083
5084TEST_P(QuicNetworkTransactionTest,
5085 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5086 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5087 // was recently supported on a different IP address on start.
5088
5089 // Set QUIC support on the last IP address, which is different with the local
5090 // IP address. Require confirmation mode will remain when local IP address is
5091 // sorted out after we configure the UDP socket.
Matt Menke3233d8f22019-08-20 21:01:495092 http_server_properties_->SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:505093
Ryan Hamiltonabad59e2019-06-06 04:02:595094 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235095 int packet_num = 1;
5096 if (VersionUsesQpack(version_.transport_version)) {
5097 mock_quic_data.AddWrite(SYNCHRONOUS,
5098 ConstructInitialSettingsPacket(packet_num++));
5099 }
Zhongyi Shia0cef1082017-08-25 01:49:505100 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235101 SYNCHRONOUS,
5102 ConstructClientRequestHeadersPacket(
5103 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5104 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435105 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335106 ASYNC, ConstructServerResponseHeadersPacket(
5107 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5108 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435109 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335110 mock_quic_data.AddRead(
5111 ASYNC, ConstructServerDataPacket(
5112 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175113 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235114 mock_quic_data.AddWrite(SYNCHRONOUS,
5115 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505116 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5117 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5118 // No HTTP data is mocked as TCP job will be delayed and never starts.
5119
5120 CreateSession();
5121 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275122 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505123
5124 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5125 // Socket will not be configured immediately and QUIC support is not sorted
5126 // out, TCP job will still be delayed as server properties indicates QUIC
5127 // support on last IP address.
5128 host_resolver_.set_synchronous_mode(false);
5129
5130 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5131 TestCompletionCallback callback;
5132 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5133 IsError(ERR_IO_PENDING));
5134
5135 // Complete host resolution in next message loop so that QUIC job could
5136 // proceed.
5137 base::RunLoop().RunUntilIdle();
5138 // Explicitly confirm the handshake so that QUIC job could succeed.
5139 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525140 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505141 EXPECT_THAT(callback.WaitForResult(), IsOk());
5142
5143 CheckWasQuicResponse(&trans);
5144 CheckResponseData(&trans, "hello!");
5145}
5146
Ryan Hamilton75f197262017-08-17 14:00:075147TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5148 // Test that NetErrorDetails is correctly populated, even if the
5149 // handshake has not yet been confirmed and no stream has been created.
5150
5151 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595152 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075153 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5154 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5155 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5156
5157 // Main job will also fail.
5158 MockRead http_reads[] = {
5159 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5160 };
5161
Ryan Sleevib8d7ea02018-05-07 20:01:015162 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075163 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5164 socket_factory_.AddSocketDataProvider(&http_data);
5165 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5166
5167 AddHangingNonAlternateProtocolSocketData();
5168 CreateSession();
5169 // Require handshake confirmation to ensure that no QUIC streams are
5170 // created, and to ensure that the TCP job does not wait for the QUIC
5171 // job to fail before it starts.
5172 session_->quic_stream_factory()->set_require_confirmation(true);
5173
Ryan Hamilton9835e662018-08-02 05:36:275174 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075175 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5176 TestCompletionCallback callback;
5177 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5178 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5179 // Allow the TCP job to fail.
5180 base::RunLoop().RunUntilIdle();
5181 // Now let the QUIC job fail.
5182 mock_quic_data.Resume();
5183 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5184 ExpectQuicAlternateProtocolMapping();
5185 NetErrorDetails details;
5186 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525187 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075188}
5189
[email protected]1e960032013-12-20 19:00:205190TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455191 // Alternate-protocol job
5192 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025193 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455194 };
Ryan Sleevib8d7ea02018-05-07 20:01:015195 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455196 socket_factory_.AddSocketDataProvider(&quic_data);
5197
[email protected]c92c1b52014-05-31 04:16:065198 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015199 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065200 socket_factory_.AddSocketDataProvider(&quic_data2);
5201
[email protected]4d283b32013-10-17 12:57:275202 // Final job that will proceed when the QUIC job fails.
5203 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025204 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5205 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5206 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275207
Ryan Sleevib8d7ea02018-05-07 20:01:015208 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275209 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565210 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275211
rtennetiafccbc062016-05-16 18:21:145212 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325213 CreateSession();
[email protected]77c6c162013-08-17 02:57:455214
Ryan Hamilton9835e662018-08-02 05:36:275215 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455216
[email protected]4d283b32013-10-17 12:57:275217 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455218
5219 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275220
rch37de576c2015-05-17 20:28:175221 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5222 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455223}
5224
[email protected]93b31772014-06-19 08:03:355225TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035226 // Alternate-protocol job
5227 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595228 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035229 };
Ryan Sleevib8d7ea02018-05-07 20:01:015230 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035231 socket_factory_.AddSocketDataProvider(&quic_data);
5232
5233 // Main job that will proceed when the QUIC job fails.
5234 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025235 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5236 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5237 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035238
Ryan Sleevib8d7ea02018-05-07 20:01:015239 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035240 socket_factory_.AddSocketDataProvider(&http_data);
5241
rtennetib8e80fb2016-05-16 00:12:095242 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325243 CreateSession();
[email protected]65768442014-06-06 23:37:035244
Ryan Hamilton9835e662018-08-02 05:36:275245 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035246
5247 SendRequestAndExpectHttpResponse("hello from http");
5248}
5249
[email protected]eb71ab62014-05-23 07:57:535250TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335251 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015252 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495253 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335254 socket_factory_.AddSocketDataProvider(&quic_data);
5255
5256 // Main job which will succeed even though the alternate job fails.
5257 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025258 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5259 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5260 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335261
Ryan Sleevib8d7ea02018-05-07 20:01:015262 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335263 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565264 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335265
rch3f4b8452016-02-23 16:59:325266 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275267 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335268 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535269
5270 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335271}
5272
[email protected]4fee9672014-01-08 14:47:155273TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltonabad59e2019-06-06 04:02:595274 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:175275 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5276 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045277 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155278
5279 // When the QUIC connection fails, we will try the request again over HTTP.
5280 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485281 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565282 MockRead("hello world"),
5283 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5284 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155285
Ryan Sleevib8d7ea02018-05-07 20:01:015286 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155287 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565288 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155289
5290 // In order for a new QUIC session to be established via alternate-protocol
5291 // without racing an HTTP connection, we need the host resolution to happen
5292 // synchronously.
5293 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295294 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565295 "");
[email protected]4fee9672014-01-08 14:47:155296
rch3f4b8452016-02-23 16:59:325297 CreateSession();
David Schinazic8281052019-01-24 06:14:175298 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5299 AddQuicAlternateProtocolMapping(
5300 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155301 SendRequestAndExpectHttpResponse("hello world");
5302}
5303
tbansalc3308d72016-08-27 10:25:045304// For an alternative proxy that supports QUIC, test that the request is
5305// successfully fetched by the main job when the alternate proxy job encounters
5306// an error.
5307TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5308 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5309}
5310TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5311 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5312}
5313TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5314 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5315}
5316TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5317 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5318}
5319TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5320 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5321}
5322TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5323 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5324}
5325TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5326 TestAlternativeProxy(ERR_IO_PENDING);
5327}
5328TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5329 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5330}
5331
5332TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltonabad59e2019-06-06 04:02:595333 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:175334 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5335 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335336 mock_quic_data.AddWrite(
5337 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5338 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5339 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435340 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045341 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5342
5343 // When the QUIC connection fails, we will try the request again over HTTP.
5344 MockRead http_reads[] = {
5345 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5346 MockRead("hello world"),
5347 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5348 MockRead(ASYNC, OK)};
5349
Ryan Sleevib8d7ea02018-05-07 20:01:015350 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045351 socket_factory_.AddSocketDataProvider(&http_data);
5352 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5353
5354 TestProxyDelegate test_proxy_delegate;
5355 const HostPortPair host_port_pair("myproxy.org", 443);
5356 test_proxy_delegate.set_alternative_proxy_server(
5357 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5358 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5359
Ramin Halavatica8d5252018-03-12 05:33:495360 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5361 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525362 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045363 request_.url = GURL("http://mail.example.org/");
5364
5365 // In order for a new QUIC session to be established via alternate-protocol
5366 // without racing an HTTP connection, we need the host resolution to happen
5367 // synchronously.
5368 host_resolver_.set_synchronous_mode(true);
5369 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045370
5371 CreateSession();
David Schinazic8281052019-01-24 06:14:175372 crypto_client_stream_factory_.set_handshake_mode(
5373 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045374 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595375 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165376 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045377}
5378
bnc508835902015-05-12 20:10:295379TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585380 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385381 EXPECT_FALSE(
5382 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:595383 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235384 int packet_num = 1;
5385 if (VersionUsesQpack(version_.transport_version)) {
5386 mock_quic_data.AddWrite(SYNCHRONOUS,
5387 ConstructInitialSettingsPacket(packet_num++));
5388 }
rch5cb522462017-04-25 20:18:365389 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235390 SYNCHRONOUS,
5391 ConstructClientRequestHeadersPacket(
5392 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5393 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435394 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335395 ASYNC, ConstructServerResponseHeadersPacket(
5396 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5397 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435398 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335399 mock_quic_data.AddRead(
5400 ASYNC, ConstructServerDataPacket(
5401 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175402 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235403 mock_quic_data.AddWrite(SYNCHRONOUS,
5404 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505405 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295406 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5407
bncb07c05532015-05-14 19:07:205408 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095409 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325410 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275411 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295412 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385413 EXPECT_TRUE(
5414 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295415}
5416
zhongyi363c91c2017-03-23 23:16:085417// TODO(zhongyi): disabled this broken test as it was not testing the correct
5418// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5419TEST_P(QuicNetworkTransactionTest,
5420 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275421 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595422 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495423 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045424
5425 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045426
5427 test_proxy_delegate.set_alternative_proxy_server(
5428 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525429 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045430
5431 request_.url = GURL("http://mail.example.org/");
5432
5433 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5434 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015435 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045436 socket_factory_.AddSocketDataProvider(&socket_data);
5437
5438 // The non-alternate protocol job needs to hang in order to guarantee that
5439 // the alternate-protocol job will "win".
5440 AddHangingNonAlternateProtocolSocketData();
5441
5442 CreateSession();
5443 request_.method = "POST";
5444 ChunkedUploadDataStream upload_data(0);
5445 upload_data.AppendData("1", 1, true);
5446
5447 request_.upload_data_stream = &upload_data;
5448
5449 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5450 TestCompletionCallback callback;
5451 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5452 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5453 EXPECT_NE(OK, callback.WaitForResult());
5454
5455 // Verify that the alternative proxy server is not marked as broken.
5456 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5457
5458 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595459 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275460
5461 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5462 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5463 1);
tbansalc3308d72016-08-27 10:25:045464}
5465
rtenneti56977812016-01-15 19:26:565466TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Nick Harper72ade192019-07-17 03:30:425467 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575468 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565469
Renjie Tangaadb84b2019-08-31 01:00:235470 MockQuicData mock_quic_data(version_);
5471 if (!VersionUsesQpack(version_.transport_version))
5472 mock_quic_data.AddRead(SYNCHRONOUS, OK);
5473 else
5474 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5475 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5476 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5477
5478 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5479 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
5480 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:015481 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:235482 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:565483
rtennetib8e80fb2016-05-16 00:12:095484 // The non-alternate protocol job needs to hang in order to guarantee that
5485 // the alternate-protocol job will "win".
5486 AddHangingNonAlternateProtocolSocketData();
5487
rtenneti56977812016-01-15 19:26:565488 CreateSession();
5489 request_.method = "POST";
5490 ChunkedUploadDataStream upload_data(0);
5491 upload_data.AppendData("1", 1, true);
5492
5493 request_.upload_data_stream = &upload_data;
5494
bnc691fda62016-08-12 00:43:165495 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:565496 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165497 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015498 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:565499 EXPECT_NE(OK, callback.WaitForResult());
5500}
5501
rche11300ef2016-09-02 01:44:285502TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Nick Harper72ade192019-07-17 03:30:425503 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:285504 ScopedMockNetworkChangeNotifier network_change_notifier;
5505 MockNetworkChangeNotifier* mock_ncn =
5506 network_change_notifier.mock_network_change_notifier();
5507 mock_ncn->ForceNetworkHandlesSupported();
5508 mock_ncn->SetConnectedNetworksList(
5509 {kDefaultNetworkForTests, kNewNetworkForTests});
5510
Nick Harper72ade192019-07-17 03:30:425511 session_params_.quic_params.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:285512 HostPortPair::FromString("mail.example.org:443"));
Nick Harper72ade192019-07-17 03:30:425513 session_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:285514
Ryan Hamiltonabad59e2019-06-06 04:02:595515 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:285516 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:235517 int packet_num = 1;
5518 if (VersionUsesQpack(version_.transport_version)) {
5519 socket_data.AddWrite(SYNCHRONOUS,
5520 ConstructInitialSettingsPacket(packet_num++));
5521 }
Fan Yang32c5a112018-12-10 20:06:335522 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235523 SYNCHRONOUS,
5524 ConstructClientRequestHeadersPacket(
5525 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5526 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:285527 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5528 socket_data.AddSocketDataToFactory(&socket_factory_);
5529
Ryan Hamiltonabad59e2019-06-06 04:02:595530 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:285531 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
5532 socket_data2.AddSocketDataToFactory(&socket_factory_);
5533
5534 // The non-alternate protocol job needs to hang in order to guarantee that
5535 // the alternate-protocol job will "win".
5536 AddHangingNonAlternateProtocolSocketData();
5537
5538 CreateSession();
5539 request_.method = "POST";
5540 ChunkedUploadDataStream upload_data(0);
5541
5542 request_.upload_data_stream = &upload_data;
5543
rdsmith1d343be52016-10-21 20:37:505544 std::unique_ptr<HttpNetworkTransaction> trans(
5545 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:285546 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:505547 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:285548 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5549
5550 base::RunLoop().RunUntilIdle();
5551 upload_data.AppendData("1", 1, true);
5552 base::RunLoop().RunUntilIdle();
5553
5554 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:505555 trans.reset();
rche11300ef2016-09-02 01:44:285556 session_.reset();
5557}
5558
Ryan Hamilton4b3574532017-10-30 20:17:255559TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:425560 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255561 HostPortPair::FromString("mail.example.org:443"));
5562
Ryan Hamiltonabad59e2019-06-06 04:02:595563 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235564 int packet_num = 1;
5565 if (VersionUsesQpack(version_.transport_version)) {
5566 socket_data.AddWrite(SYNCHRONOUS,
5567 ConstructInitialSettingsPacket(packet_num++));
5568 }
Ryan Hamilton4b3574532017-10-30 20:17:255569 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:335570 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235571 SYNCHRONOUS,
5572 ConstructClientRequestHeadersPacket(
5573 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5574 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435575 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335576 ASYNC, ConstructServerResponseHeadersPacket(
5577 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5578 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435579 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335580 socket_data.AddRead(
5581 ASYNC, ConstructServerDataPacket(
5582 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175583 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235584 socket_data.AddWrite(SYNCHRONOUS,
5585 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:255586 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:165587 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235588 SYNCHRONOUS,
5589 client_maker_.MakeAckAndConnectionClosePacket(
5590 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2, 1,
5591 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:255592
5593 socket_data.AddSocketDataToFactory(&socket_factory_);
5594
5595 CreateSession();
5596
5597 SendRequestAndExpectQuicResponse("hello!");
5598 session_.reset();
5599}
5600
5601TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:425602 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255603 HostPortPair::FromString("mail.example.org:443"));
5604
Ryan Hamiltonabad59e2019-06-06 04:02:595605 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235606 int packet_num = 1;
5607 if (VersionUsesQpack(version_.transport_version)) {
5608 socket_data.AddWrite(SYNCHRONOUS,
5609 ConstructInitialSettingsPacket(packet_num++));
5610 }
Ryan Hamilton4b3574532017-10-30 20:17:255611 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:335612 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235613 SYNCHRONOUS,
5614 ConstructClientRequestHeadersPacket(
5615 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5616 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435617 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335618 ASYNC, ConstructServerResponseHeadersPacket(
5619 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5620 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435621 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335622 socket_data.AddRead(
5623 ASYNC, ConstructServerDataPacket(
5624 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175625 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235626 socket_data.AddWrite(SYNCHRONOUS,
5627 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:255628 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:165629 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235630 SYNCHRONOUS,
5631 client_maker_.MakeAckAndConnectionClosePacket(
5632 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2, 1,
5633 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Ryan Hamilton4b3574532017-10-30 20:17:255634
5635 socket_data.AddSocketDataToFactory(&socket_factory_);
5636
5637 CreateSession();
5638
5639 SendRequestAndExpectQuicResponse("hello!");
5640 session_.reset();
5641}
5642
Ryan Hamilton9edcf1a2017-11-22 05:55:175643TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:425644 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
5645 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255646 HostPortPair::FromString("mail.example.org:443"));
5647
Ryan Hamiltonabad59e2019-06-06 04:02:595648 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:255649 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:235650 if (VersionUsesQpack(version_.transport_version))
5651 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:175652 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:255653 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
5654 }
5655 socket_data.AddSocketDataToFactory(&socket_factory_);
5656
5657 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:175658 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:175659 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
5660 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:255661
Ryan Hamilton8d9ee76e2018-05-29 23:52:525662 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:255663 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5664 TestCompletionCallback callback;
5665 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5666 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:175667 while (!callback.have_result()) {
5668 base::RunLoop().RunUntilIdle();
5669 quic_task_runner_->RunUntilIdle();
5670 }
5671 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:255672 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:175673 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5674 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5675 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525676 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
5677 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:255678}
5679
Ryan Hamilton9edcf1a2017-11-22 05:55:175680TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:425681 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
5682 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:255683 HostPortPair::FromString("mail.example.org:443"));
5684
Ryan Hamiltonabad59e2019-06-06 04:02:595685 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:255686 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:235687 if (VersionUsesQpack(version_.transport_version))
5688 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:175689 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:255690 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
5691 }
5692 socket_data.AddSocketDataToFactory(&socket_factory_);
5693
5694 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:175695 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:175696 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
5697 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:255698
Ryan Hamilton8d9ee76e2018-05-29 23:52:525699 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:255700 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5701 TestCompletionCallback callback;
5702 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5703 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:175704 while (!callback.have_result()) {
5705 base::RunLoop().RunUntilIdle();
5706 quic_task_runner_->RunUntilIdle();
5707 }
5708 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:255709 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:175710 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5711 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5712 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525713 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
5714 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:255715}
5716
Cherie Shi7596de632018-02-22 07:28:185717TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Nick Harper72ade192019-07-17 03:30:425718 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
5719 session_params_.quic_params.origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:185720 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:435721 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:525722 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
5723 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:185724
Ryan Hamiltonabad59e2019-06-06 04:02:595725 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:185726 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:235727 int packet_num = 1;
5728 if (VersionUsesQpack(version_.transport_version)) {
5729 socket_data.AddWrite(SYNCHRONOUS,
5730 ConstructInitialSettingsPacket(packet_num++));
5731 }
Cherie Shi7596de632018-02-22 07:28:185732 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
5733 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525734 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235735 SYNCHRONOUS,
5736 client_maker_.MakeConnectionClosePacket(
5737 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:185738 socket_data.AddSocketDataToFactory(&socket_factory_);
5739
5740 CreateSession();
5741
5742 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5743 TestCompletionCallback callback;
5744 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5745 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5746 base::RunLoop().RunUntilIdle();
5747 ASSERT_TRUE(callback.have_result());
5748 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5749 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5750 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5751}
5752
ckrasic769733c2016-06-30 00:42:135753// Adds coverage to catch regression such as https://crbug.com/622043
5754TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Nick Harper72ade192019-07-17 03:30:425755 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:135756 HostPortPair::FromString("mail.example.org:443"));
5757
Ryan Hamiltonabad59e2019-06-06 04:02:595758 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:235759 uint64_t client_packet_number = 1;
Renjie Tangaadb84b2019-08-31 01:00:235760 if (VersionUsesQpack(version_.transport_version)) {
5761 mock_quic_data.AddWrite(
5762 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
5763 }
Zhongyi Shi32f2fd02018-04-16 18:23:435764 mock_quic_data.AddWrite(
5765 SYNCHRONOUS,
5766 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335767 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:025768 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435769 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025770 ASYNC,
5771 ConstructServerPushPromisePacket(
5772 1, GetNthClientInitiatedBidirectionalStreamId(0),
5773 GetNthServerInitiatedUnidirectionalStreamId(0), false,
5774 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:315775 if ((client_headers_include_h2_stream_dependency_ &&
5776 version_.transport_version >= quic::QUIC_VERSION_43) ||
5777 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:025778 mock_quic_data.AddWrite(
5779 SYNCHRONOUS,
5780 ConstructClientPriorityPacket(
5781 client_packet_number++, false,
5782 GetNthServerInitiatedUnidirectionalStreamId(0),
5783 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:575784 }
Zhongyi Shi32f2fd02018-04-16 18:23:435785 mock_quic_data.AddRead(
5786 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335787 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025788 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:575789 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435790 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
5791 mock_quic_data.AddRead(
5792 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335793 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025794 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435795 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:435796 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335797 ASYNC, ConstructServerDataPacket(
5798 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175799 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:575800 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435801 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:435802 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:435803 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335804 ASYNC, ConstructServerDataPacket(
5805 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175806 header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:335807 mock_quic_data.AddWrite(SYNCHRONOUS,
5808 ConstructClientAckAndRstPacket(
5809 client_packet_number++,
5810 GetNthServerInitiatedUnidirectionalStreamId(0),
5811 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:135812 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5813 mock_quic_data.AddRead(ASYNC, 0); // EOF
5814 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5815
5816 // The non-alternate protocol job needs to hang in order to guarantee that
5817 // the alternate-protocol job will "win".
5818 AddHangingNonAlternateProtocolSocketData();
5819
5820 CreateSession();
5821
5822 // PUSH_PROMISE handling in the http layer gets exercised here.
5823 SendRequestAndExpectQuicResponse("hello!");
5824
5825 request_.url = GURL("https://mail.example.org/pushed.jpg");
5826 SendRequestAndExpectQuicResponse("and hello!");
5827
5828 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:545829 auto entries = net_log_.GetEntries();
ckrasic769733c2016-06-30 00:42:135830 EXPECT_LT(0u, entries.size());
5831
5832 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
5833 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:005834 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
5835 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:135836 EXPECT_LT(0, pos);
5837}
5838
rch56ec40a2017-06-23 14:48:445839// Regression test for http://crbug.com/719461 in which a promised stream
5840// is closed before the pushed headers arrive, but after the connection
5841// is closed and before the callbacks are executed.
5842TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Nick Harper72ade192019-07-17 03:30:425843 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
5844 session_params_.quic_params.origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:445845 HostPortPair::FromString("mail.example.org:443"));
5846
Ryan Hamiltonabad59e2019-06-06 04:02:595847 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:235848 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:445849 // Initial SETTINGS frame.
Renjie Tangaadb84b2019-08-31 01:00:235850 if (VersionUsesQpack(version_.transport_version)) {
5851 mock_quic_data.AddWrite(
5852 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
5853 }
rch56ec40a2017-06-23 14:48:445854 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:435855 mock_quic_data.AddWrite(
5856 SYNCHRONOUS,
5857 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335858 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:025859 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:445860 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:435861 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025862 ASYNC,
5863 ConstructServerPushPromisePacket(
5864 1, GetNthClientInitiatedBidirectionalStreamId(0),
5865 GetNthServerInitiatedUnidirectionalStreamId(0), false,
5866 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:315867 if ((client_headers_include_h2_stream_dependency_ &&
5868 version_.transport_version >= quic::QUIC_VERSION_43) ||
5869 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:025870 mock_quic_data.AddWrite(
5871 SYNCHRONOUS,
5872 ConstructClientPriorityPacket(
5873 client_packet_number++, false,
5874 GetNthServerInitiatedUnidirectionalStreamId(0),
5875 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:575876 }
rch56ec40a2017-06-23 14:48:445877 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:435878 mock_quic_data.AddRead(
5879 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335880 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025881 GetResponseHeaders("200 OK")));
rch56ec40a2017-06-23 14:48:445882 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:575883 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435884 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:445885 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:435886 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:435887 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335888 ASYNC, ConstructServerDataPacket(
5889 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175890 header + "hello!"));
rch56ec40a2017-06-23 14:48:445891 // Write error for the third request.
5892 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5893 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5894 mock_quic_data.AddRead(ASYNC, 0); // EOF
5895 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5896
5897 CreateSession();
5898
5899 // Send a request which triggers a push promise from the server.
5900 SendRequestAndExpectQuicResponse("hello!");
5901
5902 // Start a push transaction that will be cancelled after the connection
5903 // is closed, but before the callback is executed.
5904 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:195905 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:445906 session_.get());
5907 TestCompletionCallback callback2;
5908 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
5909 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5910 base::RunLoop().RunUntilIdle();
5911
5912 // Cause the connection to close on a write error.
5913 HttpRequestInfo request3;
5914 request3.method = "GET";
5915 request3.url = GURL("https://mail.example.org/");
5916 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:105917 request3.traffic_annotation =
5918 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:445919 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
5920 TestCompletionCallback callback3;
5921 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
5922 IsError(ERR_IO_PENDING));
5923
5924 base::RunLoop().RunUntilIdle();
5925
5926 // When |trans2| is destroyed, the underlying stream will be closed.
5927 EXPECT_FALSE(callback2.have_result());
5928 trans2 = nullptr;
5929
5930 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5931}
5932
ckrasicda193a82016-07-09 00:39:365933TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Nick Harper72ade192019-07-17 03:30:425934 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:365935 HostPortPair::FromString("mail.example.org:443"));
5936
Ryan Hamiltonabad59e2019-06-06 04:02:595937 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:365938
Renjief49758b2019-01-11 23:32:415939 int write_packet_index = 1;
Renjie Tangaadb84b2019-08-31 01:00:235940 if (VersionUsesQpack(version_.transport_version)) {
5941 mock_quic_data.AddWrite(
5942 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
5943 }
ckrasicda193a82016-07-09 00:39:365944
Victor Vasiliev076657c2019-03-12 02:46:435945 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:565946 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:415947 mock_quic_data.AddWrite(
5948 SYNCHRONOUS,
5949 ConstructClientRequestHeadersAndDataFramesPacket(
5950 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
5951 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:025952 GetRequestHeaders("POST", "https", "/"), 0, nullptr, {"1"}));
Renjief49758b2019-01-11 23:32:415953 } else {
5954 mock_quic_data.AddWrite(
5955 SYNCHRONOUS,
5956 ConstructClientRequestHeadersAndDataFramesPacket(
5957 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
5958 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:025959 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
Renjief49758b2019-01-11 23:32:415960 {header, "1"}));
5961 }
ckrasicda193a82016-07-09 00:39:365962
Zhongyi Shi32f2fd02018-04-16 18:23:435963 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335964 ASYNC, ConstructServerResponseHeadersPacket(
5965 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5966 GetResponseHeaders("200 OK")));
5967
Victor Vasiliev076657c2019-03-12 02:46:435968 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335969 mock_quic_data.AddRead(
5970 ASYNC, ConstructServerDataPacket(
5971 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175972 header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:365973
Renjief49758b2019-01-11 23:32:415974 mock_quic_data.AddWrite(
5975 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:365976
5977 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5978 mock_quic_data.AddRead(ASYNC, 0); // EOF
5979 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5980
5981 // The non-alternate protocol job needs to hang in order to guarantee that
5982 // the alternate-protocol job will "win".
5983 AddHangingNonAlternateProtocolSocketData();
5984
5985 CreateSession();
5986 request_.method = "POST";
5987 ChunkedUploadDataStream upload_data(0);
5988 upload_data.AppendData("1", 1, true);
5989
5990 request_.upload_data_stream = &upload_data;
5991
5992 SendRequestAndExpectQuicResponse("hello!");
5993}
5994
allada71b2efb2016-09-09 04:57:485995class QuicURLRequestContext : public URLRequestContext {
5996 public:
5997 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
5998 MockClientSocketFactory* socket_factory)
5999 : storage_(this) {
6000 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076001 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046002 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486003 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046004 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596005 storage_.set_proxy_resolution_service(
6006 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076007 storage_.set_ssl_config_service(
6008 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486009 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:116010 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:486011 storage_.set_http_server_properties(
Matt Menke609160742019-08-02 18:47:266012 std::make_unique<HttpServerProperties>());
Bence Béky8f9d7d3952017-10-09 19:58:046013 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486014 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046015 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6016 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6017 false));
allada71b2efb2016-09-09 04:57:486018 }
6019
6020 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6021
6022 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6023
6024 private:
6025 MockClientSocketFactory* socket_factory_;
6026 URLRequestContextStorage storage_;
6027};
6028
6029TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
Nick Harper72ade192019-07-17 03:30:426030 session_params_.quic_params.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486031 HostPortPair::FromString("mail.example.org:443"));
6032
Ryan Hamiltonabad59e2019-06-06 04:02:596033 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236034 int packet_num = 1;
6035 if (VersionUsesQpack(version_.transport_version)) {
6036 mock_quic_data.AddWrite(SYNCHRONOUS,
6037 ConstructInitialSettingsPacket(packet_num++));
6038 }
Ryan Hamilton0239aac2018-05-19 00:03:136039 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486040 headers["user-agent"] = "";
6041 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336042 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236043 SYNCHRONOUS,
6044 ConstructClientRequestHeadersPacket(
6045 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6046 true, std::move(headers)));
allada71b2efb2016-09-09 04:57:486047
Fan Yang32c5a112018-12-10 20:06:336048 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026049 ASYNC, ConstructServerResponseHeadersPacket(
6050 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6051 GetResponseHeaders("200 OK")));
6052 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:456053 server_maker_.stream_offset(
6054 quic::VersionUsesQpack(version_.transport_version)
6055 ? GetNthClientInitiatedBidirectionalStreamId(0)
6056 : quic::QuicUtils::GetHeadersStreamId(
6057 version_.transport_version));
allada71b2efb2016-09-09 04:57:486058
Victor Vasiliev076657c2019-03-12 02:46:436059 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366060 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336061 ASYNC, ConstructServerDataPacket(
6062 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176063 "Main Resource Data"));
Renjie Tangaadb84b2019-08-31 01:00:236064 mock_quic_data.AddWrite(SYNCHRONOUS,
6065 ConstructClientAckPacket(packet_num++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486066
6067 mock_quic_data.AddRead(ASYNC, 0); // EOF
6068
6069 CreateSession();
6070
6071 TestDelegate delegate;
6072 QuicURLRequestContext quic_url_request_context(std::move(session_),
6073 &socket_factory_);
6074
6075 mock_quic_data.AddSocketDataToFactory(
6076 &quic_url_request_context.socket_factory());
6077 TestNetworkDelegate network_delegate;
6078 quic_url_request_context.set_network_delegate(&network_delegate);
6079
6080 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296081 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6082 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486083 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6084 &ssl_data_);
6085
6086 request->Start();
Wez2a31b222018-06-07 22:07:156087 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486088
6089 EXPECT_LT(0, request->GetTotalSentBytes());
6090 EXPECT_LT(0, request->GetTotalReceivedBytes());
6091 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6092 request->GetTotalSentBytes());
6093 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6094 request->GetTotalReceivedBytes());
6095 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6096 request->raw_header_size());
Wez0e717112018-06-18 23:09:226097
6098 // Pump the message loop to allow all data to be consumed.
6099 base::RunLoop().RunUntilIdle();
6100
allada71b2efb2016-09-09 04:57:486101 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6102 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6103}
6104
6105TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
Nick Harper72ade192019-07-17 03:30:426106 session_params_.quic_params.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486107 HostPortPair::FromString("mail.example.org:443"));
6108
Ryan Hamiltonabad59e2019-06-06 04:02:596109 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236110 uint64_t client_packet_number = 1;
Renjie Tangaadb84b2019-08-31 01:00:236111 if (VersionUsesQpack(version_.transport_version)) {
6112 mock_quic_data.AddWrite(
6113 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6114 }
Ryan Hamilton0239aac2018-05-19 00:03:136115 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486116 headers["user-agent"] = "";
6117 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436118 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336119 SYNCHRONOUS,
6120 ConstructClientRequestHeadersPacket(
6121 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026122 true, true, std::move(headers)));
allada71b2efb2016-09-09 04:57:486123
Fan Yang2330d182019-08-05 14:50:506124 const quic::QuicStreamOffset initial = server_maker_.stream_offset(
6125 GetNthClientInitiatedBidirectionalStreamId(0));
Zhongyi Shi32f2fd02018-04-16 18:23:436126 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026127 ASYNC,
6128 ConstructServerPushPromisePacket(
6129 1, GetNthClientInitiatedBidirectionalStreamId(0),
6130 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6131 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Fan Yang2330d182019-08-05 14:50:506132 quic::QuicStreamOffset push_promise_offset = 0;
6133 if (VersionUsesQpack(version_.transport_version)) {
6134 push_promise_offset = server_maker_.stream_offset(
6135 GetNthClientInitiatedBidirectionalStreamId(0)) -
6136 initial;
6137 }
allada71b2efb2016-09-09 04:57:486138
Renjie Tang703fea92019-07-23 21:08:316139 if ((client_headers_include_h2_stream_dependency_ &&
6140 version_.transport_version >= quic::QUIC_VERSION_43) ||
6141 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026142 mock_quic_data.AddWrite(
6143 SYNCHRONOUS,
6144 ConstructClientPriorityPacket(
6145 client_packet_number++, false,
6146 GetNthServerInitiatedUnidirectionalStreamId(0),
6147 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576148 }
6149
Ryan Hamiltone940bd12019-06-30 02:46:456150 const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
6151 quic::VersionUsesQpack(version_.transport_version)
6152 ? GetNthClientInitiatedBidirectionalStreamId(0)
6153 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Zhongyi Shi32f2fd02018-04-16 18:23:436154 mock_quic_data.AddRead(
6155 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336156 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026157 GetResponseHeaders("200 OK")));
Ryan Hamiltone940bd12019-06-30 02:46:456158 const quic::QuicStreamOffset final_offset = server_maker_.stream_offset(
6159 quic::VersionUsesQpack(version_.transport_version)
6160 ? GetNthClientInitiatedBidirectionalStreamId(0)
6161 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Ryan Hamilton0d65a8c2019-06-07 00:46:026162 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:456163 final_offset - initial_offset;
allada71b2efb2016-09-09 04:57:486164
Yixin Wangb470bc882018-02-15 18:43:576165 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436166 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486167
ckrasicbf2f59c2017-05-04 23:54:366168 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436169 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336170 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026171 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436172 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436173 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336174 ASYNC, ConstructServerDataPacket(
6175 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176176 header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486177
Yixin Wangb470bc882018-02-15 18:43:576178 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436179 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436180 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366181 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336182 ASYNC, ConstructServerDataPacket(
6183 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176184 header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486185
Zhongyi Shi32f2fd02018-04-16 18:23:436186 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486187
6188 CreateSession();
6189
6190 TestDelegate delegate;
6191 QuicURLRequestContext quic_url_request_context(std::move(session_),
6192 &socket_factory_);
6193
6194 mock_quic_data.AddSocketDataToFactory(
6195 &quic_url_request_context.socket_factory());
6196 TestNetworkDelegate network_delegate;
6197 quic_url_request_context.set_network_delegate(&network_delegate);
6198
6199 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296200 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6201 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486202 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6203 &ssl_data_);
6204
6205 request->Start();
Wez2a31b222018-06-07 22:07:156206 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486207
6208 EXPECT_LT(0, request->GetTotalSentBytes());
6209 EXPECT_LT(0, request->GetTotalReceivedBytes());
6210 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6211 request->GetTotalSentBytes());
6212 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6213 request->GetTotalReceivedBytes());
Fan Yang2330d182019-08-05 14:50:506214 EXPECT_EQ(
6215 static_cast<int>(expected_raw_header_response_size + push_promise_offset),
6216 request->raw_header_size());
Wez0e717112018-06-18 23:09:226217
6218 // Pump the message loop to allow all data to be consumed.
6219 base::RunLoop().RunUntilIdle();
6220
allada71b2efb2016-09-09 04:57:486221 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6222 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6223}
6224
Ryan Sleevia9d6aa62019-07-26 13:32:186225TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
6226 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:206227
6228 MockRead http_reads[] = {
6229 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6230 MockRead("hello world"),
6231 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6232 MockRead(ASYNC, OK)};
6233
Ryan Sleevib8d7ea02018-05-07 20:01:016234 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206235 socket_factory_.AddSocketDataProvider(&http_data);
6236 AddCertificate(&ssl_data_);
6237 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6238
Ryan Hamiltonabad59e2019-06-06 04:02:596239 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236240 int packet_num = 1;
6241 if (VersionUsesQpack(version_.transport_version)) {
6242 mock_quic_data.AddWrite(SYNCHRONOUS,
6243 ConstructInitialSettingsPacket(packet_num++));
6244 }
Yixin Wang10f477ed2017-11-21 04:20:206245 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236246 SYNCHRONOUS,
6247 ConstructClientRequestHeadersPacket(
6248 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6249 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436250 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336251 ASYNC, ConstructServerResponseHeadersPacket(
6252 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6253 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436254 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336255 mock_quic_data.AddRead(
6256 ASYNC, ConstructServerDataPacket(
6257 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176258 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236259 mock_quic_data.AddWrite(SYNCHRONOUS,
6260 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206261 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6262 mock_quic_data.AddRead(ASYNC, 0); // EOF
6263
6264 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6265
6266 AddHangingNonAlternateProtocolSocketData();
6267 CreateSession();
6268
6269 SendRequestAndExpectHttpResponse("hello world");
6270 SendRequestAndExpectQuicResponse("hello!");
6271}
6272
Ryan Sleevia9d6aa62019-07-26 13:32:186273TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
6274 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:206275
6276 MockRead http_reads[] = {
6277 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6278 MockRead("hello world"),
6279 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6280 MockRead(ASYNC, OK)};
6281
Ryan Sleevib8d7ea02018-05-07 20:01:016282 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206283 socket_factory_.AddSocketDataProvider(&http_data);
6284 AddCertificate(&ssl_data_);
6285 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6286 socket_factory_.AddSocketDataProvider(&http_data);
6287 AddCertificate(&ssl_data_);
6288 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6289
6290 AddHangingNonAlternateProtocolSocketData();
6291 CreateSession();
6292
6293 SendRequestAndExpectHttpResponse("hello world");
6294 SendRequestAndExpectHttpResponse("hello world");
6295}
6296
bnc359ed2a2016-04-29 20:43:456297class QuicNetworkTransactionWithDestinationTest
6298 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016299 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:056300 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456301 protected:
6302 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556303 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056304 client_headers_include_h2_stream_dependency_(
6305 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:566306 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:456307 destination_type_(GetParam().destination_type),
6308 cert_transparency_verifier_(new MultiLogCTVerifier()),
6309 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596310 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:116311 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:456312 random_generator_(0),
6313 ssl_data_(ASYNC, OK) {}
6314
6315 void SetUp() override {
6316 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556317 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456318
mmenke6ddfbea2017-05-31 21:48:416319 HttpNetworkSession::Params session_params;
6320 session_params.enable_quic = true;
Nick Harper72ade192019-07-17 03:30:426321 session_params.quic_params.allow_remote_alt_svc = true;
6322 session_params.quic_params.supported_versions = supported_versions_;
6323 session_params.quic_params.headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:056324 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416325
6326 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456327
Ryan Hamilton8d9ee76e2018-05-29 23:52:526328 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416329 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456330
6331 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276332 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416333 session_context.quic_crypto_client_stream_factory =
6334 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456335
mmenke6ddfbea2017-05-31 21:48:416336 session_context.quic_random = &random_generator_;
6337 session_context.client_socket_factory = &socket_factory_;
6338 session_context.host_resolver = &host_resolver_;
6339 session_context.cert_verifier = &cert_verifier_;
6340 session_context.transport_security_state = &transport_security_state_;
6341 session_context.cert_transparency_verifier =
6342 cert_transparency_verifier_.get();
6343 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6344 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456345 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416346 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596347 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416348 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6349 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456350
mmenke6ddfbea2017-05-31 21:48:416351 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456352 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456353 }
6354
6355 void TearDown() override {
6356 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6357 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556358 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456359 PlatformTest::TearDown();
6360 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556361 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406362 session_.reset();
bnc359ed2a2016-04-29 20:43:456363 }
6364
zhongyie537a002017-06-27 16:48:216365 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456366 HostPortPair destination;
6367 switch (destination_type_) {
6368 case SAME_AS_FIRST:
6369 destination = HostPortPair(origin1_, 443);
6370 break;
6371 case SAME_AS_SECOND:
6372 destination = HostPortPair(origin2_, 443);
6373 break;
6374 case DIFFERENT:
6375 destination = HostPortPair(kDifferentHostname, 443);
6376 break;
6377 }
bnc3472afd2016-11-17 15:27:216378 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456379 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216380 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:076381 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
6382 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456383 }
6384
Ryan Hamilton8d9ee76e2018-05-29 23:52:526385 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236386 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526387 quic::QuicStreamId stream_id,
6388 bool should_include_version,
6389 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526390 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136391 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456392 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136393 spdy::SpdyHeaderBlock headers(
6394 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:026395 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456396 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:026397 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:456398 }
6399
Ryan Hamilton8d9ee76e2018-05-29 23:52:526400 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236401 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526402 quic::QuicStreamId stream_id,
6403 bool should_include_version,
6404 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586405 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:026406 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:456407 }
6408
Ryan Hamilton8d9ee76e2018-05-29 23:52:526409 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236410 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526411 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526412 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136413 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
Ryan Hamilton0d65a8c2019-06-07 00:46:026414 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
6415 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:456416 }
6417
Ryan Hamilton8d9ee76e2018-05-29 23:52:526418 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:236419 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526420 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456421 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:436422 std::string header = "";
Nick Harper23290b82019-05-02 00:02:566423 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416424 quic::HttpEncoder encoder;
6425 std::unique_ptr<char[]> buffer;
6426 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:436427 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:416428 }
Ryan Hamilton7505eb92019-06-08 00:22:176429 return maker->MakeDataPacket(packet_number, stream_id, false, true,
Renjief49758b2019-01-11 23:32:416430 header + "hello");
bnc359ed2a2016-04-29 20:43:456431 }
6432
Ryan Hamilton8d9ee76e2018-05-29 23:52:526433 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:236434 uint64_t packet_number,
6435 uint64_t largest_received,
6436 uint64_t smallest_received,
6437 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:456438 QuicTestPacketMaker* maker) {
6439 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496440 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456441 }
6442
Ryan Hamilton8d9ee76e2018-05-29 23:52:526443 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:236444 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:376445 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026446 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:376447 }
6448
bnc359ed2a2016-04-29 20:43:456449 void AddRefusedSocketData() {
6450 std::unique_ptr<StaticSocketDataProvider> refused_data(
6451 new StaticSocketDataProvider());
6452 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6453 refused_data->set_connect_data(refused_connect);
6454 socket_factory_.AddSocketDataProvider(refused_data.get());
6455 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6456 }
6457
6458 void AddHangingSocketData() {
6459 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6460 new StaticSocketDataProvider());
6461 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6462 hanging_data->set_connect_data(hanging_connect);
6463 socket_factory_.AddSocketDataProvider(hanging_data.get());
6464 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6465 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6466 }
6467
6468 bool AllDataConsumed() {
6469 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6470 if (!socket_data_ptr->AllReadDataConsumed() ||
6471 !socket_data_ptr->AllWriteDataConsumed()) {
6472 return false;
6473 }
6474 }
6475 return true;
6476 }
6477
6478 void SendRequestAndExpectQuicResponse(const std::string& host) {
6479 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6480 HttpRequestInfo request;
6481 std::string url("https://");
6482 url.append(host);
6483 request.url = GURL(url);
6484 request.load_flags = 0;
6485 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106486 request.traffic_annotation =
6487 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456488 TestCompletionCallback callback;
6489 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016490 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456491
6492 std::string response_data;
robpercival214763f2016-07-01 23:27:016493 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456494 EXPECT_EQ("hello", response_data);
6495
6496 const HttpResponseInfo* response = trans.GetResponseInfo();
6497 ASSERT_TRUE(response != nullptr);
6498 ASSERT_TRUE(response->headers.get() != nullptr);
6499 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6500 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526501 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:566502 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
6503 version_.transport_version),
bnc359ed2a2016-04-29 20:43:456504 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:376505 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:456506 }
6507
Fan Yang32c5a112018-12-10 20:06:336508 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:566509 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
6510 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:366511 }
6512
Ryan Hamilton8d9ee76e2018-05-29 23:52:526513 quic::MockClock clock_;
Nick Harper23290b82019-05-02 00:02:566514 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:056515 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:566516 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:456517 DestinationType destination_type_;
6518 std::string origin1_;
6519 std::string origin2_;
6520 std::unique_ptr<HttpNetworkSession> session_;
6521 MockClientSocketFactory socket_factory_;
6522 MockHostResolver host_resolver_;
6523 MockCertVerifier cert_verifier_;
6524 TransportSecurityState transport_security_state_;
6525 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:236526 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:456527 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:076528 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:596529 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:456530 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526531 quic::test::MockRandom random_generator_;
Matt Menke609160742019-08-02 18:47:266532 HttpServerProperties http_server_properties_;
bnc359ed2a2016-04-29 20:43:456533 BoundTestNetLog net_log_;
6534 MockCryptoClientStreamFactory crypto_client_stream_factory_;
6535 std::vector<std::unique_ptr<StaticSocketDataProvider>>
6536 static_socket_data_provider_vector_;
6537 SSLSocketDataProvider ssl_data_;
6538};
6539
Victor Costane635086f2019-01-27 05:20:306540INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
6541 QuicNetworkTransactionWithDestinationTest,
6542 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:456543
6544// A single QUIC request fails because the certificate does not match the origin
6545// hostname, regardless of whether it matches the alternative service hostname.
6546TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
6547 if (destination_type_ == DIFFERENT)
6548 return;
6549
6550 GURL url("https://mail.example.com/");
6551 origin1_ = url.host();
6552
6553 // Not used for requests, but this provides a test case where the certificate
6554 // is valid for the hostname of the alternative service.
6555 origin2_ = "mail.example.org";
6556
zhongyie537a002017-06-27 16:48:216557 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:456558
6559 scoped_refptr<X509Certificate> cert(
6560 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246561 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
6562 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:456563
6564 ProofVerifyDetailsChromium verify_details;
6565 verify_details.cert_verify_result.verified_cert = cert;
6566 verify_details.cert_verify_result.is_issued_by_known_root = true;
6567 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6568
Ryan Hamiltonabad59e2019-06-06 04:02:596569 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:456570 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
6571 mock_quic_data.AddRead(ASYNC, 0);
6572
6573 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6574
6575 AddRefusedSocketData();
6576
6577 HttpRequestInfo request;
6578 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:106579 request.traffic_annotation =
6580 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456581
6582 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6583 TestCompletionCallback callback;
6584 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016585 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:456586
6587 EXPECT_TRUE(AllDataConsumed());
6588}
6589
6590// First request opens QUIC session to alternative service. Second request
6591// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:526592// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:456593TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
6594 origin1_ = "mail.example.org";
6595 origin2_ = "news.example.org";
6596
zhongyie537a002017-06-27 16:48:216597 SetQuicAlternativeService(origin1_);
6598 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:456599
6600 scoped_refptr<X509Certificate> cert(
6601 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246602 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
6603 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
6604 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456605
6606 ProofVerifyDetailsChromium verify_details;
6607 verify_details.cert_verify_result.verified_cert = cert;
6608 verify_details.cert_verify_result.is_issued_by_known_root = true;
6609 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6610
Yixin Wang079ad542018-01-11 04:06:056611 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:176612 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
6613 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:056614 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:176615 QuicTestPacketMaker server_maker(
6616 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
6617 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:456618
Ryan Hamiltonabad59e2019-06-06 04:02:596619 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236620 int packet_num = 1;
6621 if (VersionUsesQpack(version_.transport_version)) {
6622 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6623 packet_num++, &client_maker));
6624 }
Fan Yang32c5a112018-12-10 20:06:336625 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236626 SYNCHRONOUS,
6627 ConstructClientRequestHeadersPacket(
6628 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6629 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:026630 mock_quic_data.AddRead(
6631 ASYNC,
6632 ConstructServerResponseHeadersPacket(
6633 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:436634 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336635 ASYNC,
6636 ConstructServerDataPacket(
6637 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:236638 mock_quic_data.AddWrite(
6639 SYNCHRONOUS,
6640 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:456641
Yixin Wang079ad542018-01-11 04:06:056642 client_maker.set_hostname(origin2_);
6643 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:456644
Zhongyi Shi32f2fd02018-04-16 18:23:436645 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026646 SYNCHRONOUS,
6647 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:236648 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026649 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
6650 mock_quic_data.AddRead(
6651 ASYNC,
6652 ConstructServerResponseHeadersPacket(
6653 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:436654 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336655 ASYNC,
6656 ConstructServerDataPacket(
6657 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:236658 mock_quic_data.AddWrite(
6659 SYNCHRONOUS,
6660 ConstructClientAckPacket(packet_num++, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:456661 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6662 mock_quic_data.AddRead(ASYNC, 0); // EOF
6663
6664 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6665
6666 AddHangingSocketData();
6667 AddHangingSocketData();
6668
Nick Harpereb483e12019-05-14 00:18:096669 scoped_refptr<TestTaskRunner> quic_task_runner(new TestTaskRunner(&clock_));
Fan Yangc9e00dc2018-10-09 14:17:566670 QuicStreamFactoryPeer::SetAlarmFactory(
6671 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:096672 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Fan Yangc9e00dc2018-10-09 14:17:566673 &clock_));
6674
bnc359ed2a2016-04-29 20:43:456675 SendRequestAndExpectQuicResponse(origin1_);
6676 SendRequestAndExpectQuicResponse(origin2_);
6677
6678 EXPECT_TRUE(AllDataConsumed());
6679}
6680
6681// First request opens QUIC session to alternative service. Second request does
6682// not pool to it, even though destination matches, because certificate is not
6683// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:526684// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:456685TEST_P(QuicNetworkTransactionWithDestinationTest,
6686 DoNotPoolIfCertificateInvalid) {
6687 origin1_ = "news.example.org";
6688 origin2_ = "mail.example.com";
6689
zhongyie537a002017-06-27 16:48:216690 SetQuicAlternativeService(origin1_);
6691 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:456692
6693 scoped_refptr<X509Certificate> cert1(
6694 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246695 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
6696 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
6697 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456698
6699 scoped_refptr<X509Certificate> cert2(
6700 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246701 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
6702 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456703
6704 ProofVerifyDetailsChromium verify_details1;
6705 verify_details1.cert_verify_result.verified_cert = cert1;
6706 verify_details1.cert_verify_result.is_issued_by_known_root = true;
6707 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
6708
6709 ProofVerifyDetailsChromium verify_details2;
6710 verify_details2.cert_verify_result.verified_cert = cert2;
6711 verify_details2.cert_verify_result.is_issued_by_known_root = true;
6712 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
6713
Yixin Wang079ad542018-01-11 04:06:056714 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:176715 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
6716 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:056717 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:176718 QuicTestPacketMaker server_maker1(
6719 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
6720 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:456721
Ryan Hamiltonabad59e2019-06-06 04:02:596722 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:236723 int packet_num = 1;
6724 if (VersionUsesQpack(version_.transport_version)) {
6725 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6726 packet_num++, &client_maker1));
6727 }
Fan Yang32c5a112018-12-10 20:06:336728 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236729 SYNCHRONOUS,
6730 ConstructClientRequestHeadersPacket(
6731 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6732 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:436733 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336734 ASYNC,
6735 ConstructServerResponseHeadersPacket(
6736 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:436737 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336738 ASYNC,
6739 ConstructServerDataPacket(
6740 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:436741 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236742 SYNCHRONOUS,
6743 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:456744 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6745 mock_quic_data1.AddRead(ASYNC, 0); // EOF
6746
6747 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
6748
Yixin Wang079ad542018-01-11 04:06:056749 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:176750 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
6751 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:056752 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:176753 QuicTestPacketMaker server_maker2(
6754 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
6755 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:456756
Ryan Hamiltonabad59e2019-06-06 04:02:596757 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:236758 int packet_num2 = 1;
6759 if (VersionUsesQpack(version_.transport_version)) {
6760 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6761 packet_num2++, &client_maker2));
6762 }
Fan Yang32c5a112018-12-10 20:06:336763 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236764 SYNCHRONOUS,
6765 ConstructClientRequestHeadersPacket(
6766 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6767 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:436768 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:336769 ASYNC,
6770 ConstructServerResponseHeadersPacket(
6771 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:436772 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:336773 ASYNC,
6774 ConstructServerDataPacket(
6775 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:436776 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236777 SYNCHRONOUS,
6778 ConstructClientAckPacket(packet_num2++, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:456779 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6780 mock_quic_data2.AddRead(ASYNC, 0); // EOF
6781
6782 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
6783
bnc359ed2a2016-04-29 20:43:456784 SendRequestAndExpectQuicResponse(origin1_);
6785 SendRequestAndExpectQuicResponse(origin2_);
6786
6787 EXPECT_TRUE(AllDataConsumed());
6788}
6789
ckrasicdee37572017-04-06 22:42:276790// crbug.com/705109 - this confirms that matching request with a body
6791// triggers a crash (pre-fix).
6792TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Nick Harper72ade192019-07-17 03:30:426793 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:276794 HostPortPair::FromString("mail.example.org:443"));
6795
Ryan Hamiltonabad59e2019-06-06 04:02:596796 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236797 uint64_t client_packet_number = 1;
Renjie Tangaadb84b2019-08-31 01:00:236798 if (VersionUsesQpack(version_.transport_version)) {
6799 mock_quic_data.AddWrite(
6800 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6801 }
Zhongyi Shi32f2fd02018-04-16 18:23:436802 mock_quic_data.AddWrite(
6803 SYNCHRONOUS,
6804 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336805 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026806 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436807 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026808 ASYNC,
6809 ConstructServerPushPromisePacket(
6810 1, GetNthClientInitiatedBidirectionalStreamId(0),
6811 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6812 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316813
6814 if ((client_headers_include_h2_stream_dependency_ &&
6815 version_.transport_version >= quic::QUIC_VERSION_43) ||
6816 VersionHasStreamType(version_.transport_version)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026817 mock_quic_data.AddWrite(
6818 SYNCHRONOUS,
6819 ConstructClientPriorityPacket(
6820 client_packet_number++, false,
6821 GetNthServerInitiatedUnidirectionalStreamId(0),
6822 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576823 }
Zhongyi Shi32f2fd02018-04-16 18:23:436824 mock_quic_data.AddRead(
6825 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336826 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026827 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:576828 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436829 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6830 mock_quic_data.AddRead(
6831 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336832 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026833 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436834 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436835 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336836 ASYNC, ConstructServerDataPacket(
6837 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176838 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576839 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436840 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416841
Victor Vasiliev076657c2019-03-12 02:46:436842 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436843 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336844 ASYNC, ConstructServerDataPacket(
6845 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176846 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:276847
6848 // Because the matching request has a body, we will see the push
6849 // stream get cancelled, and the matching request go out on the
6850 // wire.
Fan Yang32c5a112018-12-10 20:06:336851 mock_quic_data.AddWrite(SYNCHRONOUS,
6852 ConstructClientAckAndRstPacket(
6853 client_packet_number++,
6854 GetNthServerInitiatedUnidirectionalStreamId(0),
6855 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:276856 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:436857 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:566858 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416859 mock_quic_data.AddWrite(
6860 SYNCHRONOUS,
6861 ConstructClientRequestHeadersAndDataFramesPacket(
6862 client_packet_number++,
6863 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
6864 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:026865 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, {kBody}));
Renjief49758b2019-01-11 23:32:416866 } else {
6867 mock_quic_data.AddWrite(
6868 SYNCHRONOUS,
6869 ConstructClientRequestHeadersAndDataFramesPacket(
6870 client_packet_number++,
6871 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
6872 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:026873 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
6874 {header3, kBody}));
Renjief49758b2019-01-11 23:32:416875 }
ckrasicdee37572017-04-06 22:42:276876
6877 // We see the same response as for the earlier pushed and cancelled
6878 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:436879 mock_quic_data.AddRead(
6880 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336881 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026882 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:436883 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336884 ASYNC, ConstructServerDataPacket(
6885 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176886 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:276887
Yixin Wangb470bc882018-02-15 18:43:576888 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436889 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:276890 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6891 mock_quic_data.AddRead(ASYNC, 0); // EOF
6892 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6893
6894 // The non-alternate protocol job needs to hang in order to guarantee that
6895 // the alternate-protocol job will "win".
6896 AddHangingNonAlternateProtocolSocketData();
6897
6898 CreateSession();
6899
6900 // PUSH_PROMISE handling in the http layer gets exercised here.
6901 SendRequestAndExpectQuicResponse("hello!");
6902
6903 request_.url = GURL("https://mail.example.org/pushed.jpg");
6904 ChunkedUploadDataStream upload_data(0);
6905 upload_data.AppendData("1", 1, true);
6906 request_.upload_data_stream = &upload_data;
6907 SendRequestAndExpectQuicResponse("and hello!");
6908}
6909
Bence Béky7538a952018-02-01 16:59:526910// Regression test for https://crbug.com/797825: If pushed headers describe a
6911// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
6912// not be called (otherwise a DCHECK fails).
6913TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:136914 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:526915 pushed_request_headers[":authority"] = "";
6916 pushed_request_headers[":method"] = "GET";
6917 pushed_request_headers[":path"] = "/";
6918 pushed_request_headers[":scheme"] = "nosuchscheme";
6919
Nick Harper72ade192019-07-17 03:30:426920 session_params_.quic_params.origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:526921 HostPortPair::FromString("mail.example.org:443"));
6922
Ryan Hamiltonabad59e2019-06-06 04:02:596923 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:526924
Renjie Tangaadb84b2019-08-31 01:00:236925 int packet_num = 1;
6926 if (VersionUsesQpack(version_.transport_version)) {
6927 mock_quic_data.AddWrite(SYNCHRONOUS,
6928 ConstructInitialSettingsPacket(packet_num++));
6929 }
Bence Béky7538a952018-02-01 16:59:526930 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236931 SYNCHRONOUS,
6932 ConstructClientRequestHeadersPacket(
6933 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6934 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:526935
Fan Yang32c5a112018-12-10 20:06:336936 mock_quic_data.AddRead(
6937 ASYNC, ConstructServerPushPromisePacket(
6938 1, GetNthClientInitiatedBidirectionalStreamId(0),
6939 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026940 std::move(pushed_request_headers), &server_maker_));
Renjie Tangaadb84b2019-08-31 01:00:236941 mock_quic_data.AddWrite(
6942 SYNCHRONOUS,
6943 ConstructClientRstPacket(packet_num++,
6944 GetNthServerInitiatedUnidirectionalStreamId(0),
6945 quic::QUIC_INVALID_PROMISE_URL));
Bence Béky7538a952018-02-01 16:59:526946
Zhongyi Shi32f2fd02018-04-16 18:23:436947 mock_quic_data.AddRead(
6948 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336949 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026950 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:236951 mock_quic_data.AddWrite(SYNCHRONOUS,
6952 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:526953
Zhongyi Shi32f2fd02018-04-16 18:23:436954 mock_quic_data.AddRead(
6955 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336956 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026957 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436958 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436959 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336960 ASYNC, ConstructServerDataPacket(
6961 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176962 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236963 mock_quic_data.AddWrite(SYNCHRONOUS,
6964 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:526965
6966 mock_quic_data.AddRead(ASYNC, 0);
6967 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6968
6969 // The non-alternate protocol job needs to hang in order to guarantee that
6970 // the alternate-protocol job will "win".
6971 AddHangingNonAlternateProtocolSocketData();
6972
6973 CreateSession();
6974
6975 // PUSH_PROMISE handling in the http layer gets exercised here.
6976 SendRequestAndExpectQuicResponse("hello!");
6977
6978 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6979 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6980}
6981
Yixin Wang46a273ec302018-01-23 17:59:566982// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:146983TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:566984 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:146985 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:566986 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496987 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:566988
Ryan Hamiltonabad59e2019-06-06 04:02:596989 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236990 int packet_num = 1;
6991 if (VersionUsesQpack(version_.transport_version)) {
6992 mock_quic_data.AddWrite(SYNCHRONOUS,
6993 ConstructInitialSettingsPacket(packet_num++));
6994 }
Fan Yang32c5a112018-12-10 20:06:336995 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236996 SYNCHRONOUS,
6997 ConstructClientRequestHeadersPacket(
6998 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6999 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7000 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337001 mock_quic_data.AddRead(
7002 ASYNC, ConstructServerResponseHeadersPacket(
7003 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7004 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567005
7006 const char get_request[] =
7007 "GET / HTTP/1.1\r\n"
7008 "Host: mail.example.org\r\n"
7009 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437010 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567011 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417012 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357013 SYNCHRONOUS,
7014 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237015 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7016 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417017 } else {
7018 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417019 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357020 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:237021 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7022 1, 1, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417023 }
7024
Yixin Wang46a273ec302018-01-23 17:59:567025 const char get_response[] =
7026 "HTTP/1.1 200 OK\r\n"
7027 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437028 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437029 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337030 ASYNC, ConstructServerDataPacket(
7031 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177032 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:437033 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337034 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417035 SYNCHRONOUS, ConstructServerDataPacket(
7036 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:177037 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:237038 mock_quic_data.AddWrite(SYNCHRONOUS,
7039 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567040 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7041
7042 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417043 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237044 ConstructClientRstPacket(packet_num++,
7045 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417046 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567047
7048 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7049
7050 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7051
7052 CreateSession();
7053
7054 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097055 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567056 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7057 HeadersHandler headers_handler;
7058 trans.SetBeforeHeadersSentCallback(
7059 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7060 base::Unretained(&headers_handler)));
7061 RunTransaction(&trans);
7062 CheckWasHttpResponse(&trans);
7063 CheckResponsePort(&trans, 70);
7064 CheckResponseData(&trans, "0123456789");
7065 EXPECT_TRUE(headers_handler.was_proxied());
7066 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7067
7068 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7069 // proxy socket to disconnect.
7070 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7071
7072 base::RunLoop().RunUntilIdle();
7073 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7074 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7075}
7076
7077// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147078TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567079 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147080 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567081 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497082 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567083
Ryan Hamiltonabad59e2019-06-06 04:02:597084 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237085 int packet_num = 1;
7086 if (VersionUsesQpack(version_.transport_version)) {
7087 mock_quic_data.AddWrite(SYNCHRONOUS,
7088 ConstructInitialSettingsPacket(packet_num++));
7089 }
Fan Yang32c5a112018-12-10 20:06:337090 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237091 SYNCHRONOUS,
7092 ConstructClientRequestHeadersPacket(
7093 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7094 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7095 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337096 mock_quic_data.AddRead(
7097 ASYNC, ConstructServerResponseHeadersPacket(
7098 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7099 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567100
7101 SpdyTestUtil spdy_util;
7102
Ryan Hamilton0239aac2018-05-19 00:03:137103 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567104 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437105 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567106 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417107 mock_quic_data.AddWrite(
7108 SYNCHRONOUS,
7109 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237110 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7111 1, 1, 1, false,
7112 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:417113 } else {
7114 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417115 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357116 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:237117 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7118 1, 1, 1, false,
7119 {header, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417120 }
Ryan Hamilton0239aac2018-05-19 00:03:137121 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567122 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437123 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437124 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177125 ASYNC, ConstructServerDataPacket(
7126 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7127 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567128
Ryan Hamilton0239aac2018-05-19 00:03:137129 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197130 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:437131 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437132 mock_quic_data.AddRead(
7133 SYNCHRONOUS,
7134 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337135 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437136 header3 + std::string(data_frame.data(), data_frame.size())));
Renjie Tangaadb84b2019-08-31 01:00:237137 mock_quic_data.AddWrite(SYNCHRONOUS,
7138 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567139 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7140
7141 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437142 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237143 ConstructClientRstPacket(packet_num++,
7144 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417145 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567146
7147 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7148
7149 SSLSocketDataProvider ssl_data(ASYNC, OK);
7150 ssl_data.next_proto = kProtoHTTP2;
7151 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7152
7153 CreateSession();
7154
7155 request_.url = GURL("https://mail.example.org/");
7156 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7157 HeadersHandler headers_handler;
7158 trans.SetBeforeHeadersSentCallback(
7159 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7160 base::Unretained(&headers_handler)));
7161 RunTransaction(&trans);
7162 CheckWasSpdyResponse(&trans);
7163 CheckResponsePort(&trans, 70);
7164 CheckResponseData(&trans, "0123456789");
7165 EXPECT_TRUE(headers_handler.was_proxied());
7166 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7167
Wez0e717112018-06-18 23:09:227168 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7169 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567170 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7171
7172 base::RunLoop().RunUntilIdle();
7173 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7174 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7175}
7176
7177// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7178// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147179TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567180 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147181 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567182 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497183 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567184
Ryan Hamiltonabad59e2019-06-06 04:02:597185 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:417186 int write_packet_index = 1;
Renjie Tangaadb84b2019-08-31 01:00:237187 if (VersionUsesQpack(version_.transport_version)) {
7188 mock_quic_data.AddWrite(
7189 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7190 }
Fan Yang32c5a112018-12-10 20:06:337191 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417192 SYNCHRONOUS,
7193 ConstructClientRequestHeadersPacket(
7194 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:047195 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027196 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337197 mock_quic_data.AddRead(
7198 ASYNC, ConstructServerResponseHeadersPacket(
7199 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7200 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567201
Ryan Hamilton8d9ee76e2018-05-29 23:52:527202 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567203 const char get_request_1[] =
7204 "GET / HTTP/1.1\r\n"
7205 "Host: mail.example.org\r\n"
7206 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437207 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:567208 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417209 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:177210 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7211 write_packet_index++, false,
7212 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7213 false, quic::QuicStringPiece(get_request_1)));
Renjief49758b2019-01-11 23:32:417214 } else {
7215 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:177216 SYNCHRONOUS, ConstructClientAckAndMultipleDataFramesPacket(
7217 write_packet_index++, false,
7218 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7219 false, {header, std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:417220 }
7221
Yixin Wang46a273ec302018-01-23 17:59:567222 const char get_response_1[] =
7223 "HTTP/1.1 200 OK\r\n"
7224 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437225 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437226 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437227 ASYNC, ConstructServerDataPacket(
7228 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177229 header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:417230 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567231
Victor Vasiliev076657c2019-03-12 02:46:437232 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337233 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177234 SYNCHRONOUS, ConstructServerDataPacket(
7235 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7236 false, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:417237 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567238
Renjief49758b2019-01-11 23:32:417239 mock_quic_data.AddWrite(
7240 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567241
7242 const char get_request_2[] =
7243 "GET /2 HTTP/1.1\r\n"
7244 "Host: mail.example.org\r\n"
7245 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437246 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:567247 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417248 mock_quic_data.AddWrite(
7249 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357250 ConstructClientMultipleDataFramesPacket(
7251 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:177252 false, false, {header4, std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:357253 } else {
7254 mock_quic_data.AddWrite(
7255 SYNCHRONOUS,
Ryan Hamilton7505eb92019-06-08 00:22:177256 ConstructClientDataPacket(
7257 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7258 false, false, quic::QuicStringPiece(get_request_2)));
Renjief49758b2019-01-11 23:32:417259 }
Yixin Wang46a273ec302018-01-23 17:59:567260
7261 const char get_response_2[] =
7262 "HTTP/1.1 200 OK\r\n"
7263 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437264 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437265 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437266 ASYNC, ConstructServerDataPacket(
7267 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177268 header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:417269 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567270
Victor Vasiliev076657c2019-03-12 02:46:437271 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527272 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177273 SYNCHRONOUS, ConstructServerDataPacket(
7274 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
7275 false, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:417276 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567277
Renjief49758b2019-01-11 23:32:417278 mock_quic_data.AddWrite(
7279 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567280 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7281
Renjief49758b2019-01-11 23:32:417282 mock_quic_data.AddWrite(
7283 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417284 ConstructClientRstPacket(write_packet_index++,
7285 GetNthClientInitiatedBidirectionalStreamId(0),
7286 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567287
7288 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7289
7290 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7291
7292 CreateSession();
7293
7294 request_.url = GURL("https://mail.example.org/");
7295 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7296 HeadersHandler headers_handler_1;
7297 trans_1.SetBeforeHeadersSentCallback(
7298 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7299 base::Unretained(&headers_handler_1)));
7300 RunTransaction(&trans_1);
7301 CheckWasHttpResponse(&trans_1);
7302 CheckResponsePort(&trans_1, 70);
7303 CheckResponseData(&trans_1, "0123456789");
7304 EXPECT_TRUE(headers_handler_1.was_proxied());
7305 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7306
7307 request_.url = GURL("https://mail.example.org/2");
7308 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7309 HeadersHandler headers_handler_2;
7310 trans_2.SetBeforeHeadersSentCallback(
7311 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7312 base::Unretained(&headers_handler_2)));
7313 RunTransaction(&trans_2);
7314 CheckWasHttpResponse(&trans_2);
7315 CheckResponsePort(&trans_2, 70);
7316 CheckResponseData(&trans_2, "0123456");
7317 EXPECT_TRUE(headers_handler_2.was_proxied());
7318 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7319
7320 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7321 // proxy socket to disconnect.
7322 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7323
7324 base::RunLoop().RunUntilIdle();
7325 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7326 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7327}
7328
7329// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7330// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7331// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147332TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567333 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147334 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567335 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497336 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567337
Ryan Hamiltonabad59e2019-06-06 04:02:597338 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237339 int packet_num = 1;
7340 if (VersionUsesQpack(version_.transport_version)) {
7341 mock_quic_data.AddWrite(SYNCHRONOUS,
7342 ConstructInitialSettingsPacket(packet_num++));
7343 }
Yixin Wang46a273ec302018-01-23 17:59:567344
7345 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337346 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237347 SYNCHRONOUS,
7348 ConstructClientRequestHeadersPacket(
7349 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7350 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7351 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:437352 mock_quic_data.AddRead(
7353 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337354 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027355 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567356
7357 // GET request, response, and data over QUIC tunnel for first request
7358 const char get_request[] =
7359 "GET / HTTP/1.1\r\n"
7360 "Host: mail.example.org\r\n"
7361 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437362 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567363 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417364 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357365 SYNCHRONOUS,
7366 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237367 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7368 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417369 } else {
7370 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417371 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357372 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:237373 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
7374 1, 1, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417375 }
7376
Yixin Wang46a273ec302018-01-23 17:59:567377 const char get_response[] =
7378 "HTTP/1.1 200 OK\r\n"
7379 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437380 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567381 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337382 ASYNC, ConstructServerDataPacket(
7383 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177384 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:437385 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337386 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417387 SYNCHRONOUS, ConstructServerDataPacket(
7388 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:177389 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:237390 mock_quic_data.AddWrite(SYNCHRONOUS,
7391 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567392
7393 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437394 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237395 SYNCHRONOUS,
7396 ConstructClientRequestHeadersPacket(
7397 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
7398 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7399 ConnectRequestHeaders("different.example.org:443"),
7400 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:437401 mock_quic_data.AddRead(
7402 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337403 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027404 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567405
7406 // GET request, response, and data over QUIC tunnel for second request
7407 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137408 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567409 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437410 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567411 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417412 mock_quic_data.AddWrite(
7413 SYNCHRONOUS,
7414 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237415 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
7416 4, 4, 1, false,
7417 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:417418 } else {
7419 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417420 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357421 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:237422 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
7423 4, 4, 1, false,
7424 {header4, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417425 }
Yixin Wang46a273ec302018-01-23 17:59:567426
Ryan Hamilton0239aac2018-05-19 00:03:137427 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567428 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437429 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437430 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:177431 ASYNC, ConstructServerDataPacket(
7432 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7433 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567434
Ryan Hamilton0239aac2018-05-19 00:03:137435 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197436 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:437437 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437438 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437439 ASYNC, ConstructServerDataPacket(
7440 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437441 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567442
Renjie Tangaadb84b2019-08-31 01:00:237443 mock_quic_data.AddWrite(SYNCHRONOUS,
7444 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567445 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7446
7447 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417448 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237449 ConstructClientRstPacket(packet_num++,
7450 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417451 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567452 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437453 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237454 ConstructClientRstPacket(packet_num++,
7455 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417456 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567457
7458 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7459
7460 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7461
7462 SSLSocketDataProvider ssl_data(ASYNC, OK);
7463 ssl_data.next_proto = kProtoHTTP2;
7464 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7465
7466 CreateSession();
7467
7468 request_.url = GURL("https://mail.example.org/");
7469 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7470 HeadersHandler headers_handler_1;
7471 trans_1.SetBeforeHeadersSentCallback(
7472 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7473 base::Unretained(&headers_handler_1)));
7474 RunTransaction(&trans_1);
7475 CheckWasHttpResponse(&trans_1);
7476 CheckResponsePort(&trans_1, 70);
7477 CheckResponseData(&trans_1, "0123456789");
7478 EXPECT_TRUE(headers_handler_1.was_proxied());
7479 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7480
7481 request_.url = GURL("https://different.example.org/");
7482 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7483 HeadersHandler headers_handler_2;
7484 trans_2.SetBeforeHeadersSentCallback(
7485 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7486 base::Unretained(&headers_handler_2)));
7487 RunTransaction(&trans_2);
7488 CheckWasSpdyResponse(&trans_2);
7489 CheckResponsePort(&trans_2, 70);
7490 CheckResponseData(&trans_2, "0123456");
7491 EXPECT_TRUE(headers_handler_2.was_proxied());
7492 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7493
7494 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7495 // proxy socket to disconnect.
7496 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7497
7498 base::RunLoop().RunUntilIdle();
7499 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7500 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7501}
7502
7503// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:147504TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:567505 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147506 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567507 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497508 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567509
Ryan Hamiltonabad59e2019-06-06 04:02:597510 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237511 int packet_num = 1;
7512 if (VersionUsesQpack(version_.transport_version)) {
7513 mock_quic_data.AddWrite(SYNCHRONOUS,
7514 ConstructInitialSettingsPacket(packet_num++));
7515 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:527516 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237517 SYNCHRONOUS,
7518 ConstructClientRequestHeadersPacket(
7519 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7520 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7521 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:337522 mock_quic_data.AddRead(
7523 ASYNC, ConstructServerResponseHeadersPacket(
7524 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7525 GetResponseHeaders("500")));
7526 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:237527 mock_quic_data.AddWrite(
7528 SYNCHRONOUS,
7529 ConstructClientAckAndRstPacket(
7530 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
7531 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567532
7533 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7534
7535 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7536
7537 CreateSession();
7538
7539 request_.url = GURL("https://mail.example.org/");
7540 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7541 HeadersHandler headers_handler;
7542 trans.SetBeforeHeadersSentCallback(
7543 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7544 base::Unretained(&headers_handler)));
7545 TestCompletionCallback callback;
7546 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7547 EXPECT_EQ(ERR_IO_PENDING, rv);
7548 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
7549 EXPECT_EQ(false, headers_handler.was_proxied());
7550
7551 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7552 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7553}
7554
7555// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:147556TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:567557 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147558 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567559 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497560 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567561
Ryan Hamiltonabad59e2019-06-06 04:02:597562 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237563 int packet_num = 1;
7564 if (VersionUsesQpack(version_.transport_version)) {
7565 mock_quic_data.AddWrite(SYNCHRONOUS,
7566 ConstructInitialSettingsPacket(packet_num++));
7567 }
Fan Yang32c5a112018-12-10 20:06:337568 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237569 SYNCHRONOUS,
7570 ConstructClientRequestHeadersPacket(
7571 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7572 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7573 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:567574 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7575
7576 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7577
7578 CreateSession();
7579
7580 request_.url = GURL("https://mail.example.org/");
7581 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7582 HeadersHandler headers_handler;
7583 trans.SetBeforeHeadersSentCallback(
7584 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7585 base::Unretained(&headers_handler)));
7586 TestCompletionCallback callback;
7587 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7588 EXPECT_EQ(ERR_IO_PENDING, rv);
7589 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7590
7591 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7592 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7593}
7594
7595// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
7596// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:147597TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:567598 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147599 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567600 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497601 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567602
Ryan Hamiltonabad59e2019-06-06 04:02:597603 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237604 int packet_num = 1;
7605 if (VersionUsesQpack(version_.transport_version)) {
7606 mock_quic_data.AddWrite(SYNCHRONOUS,
7607 ConstructInitialSettingsPacket(packet_num++));
7608 }
Fan Yang32c5a112018-12-10 20:06:337609 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237610 SYNCHRONOUS,
7611 ConstructClientRequestHeadersPacket(
7612 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7613 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7614 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:437615 mock_quic_data.AddRead(
7616 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337617 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027618 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:237619 mock_quic_data.AddWrite(
7620 SYNCHRONOUS,
7621 ConstructClientAckAndRstPacket(
7622 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
7623 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567624
Zhongyi Shi32f2fd02018-04-16 18:23:437625 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237626 SYNCHRONOUS,
7627 ConstructClientRequestHeadersPacket(
7628 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
7629 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7630 ConnectRequestHeaders("mail.example.org:443"),
7631 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:437632 mock_quic_data.AddRead(
7633 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337634 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027635 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567636
7637 const char get_request[] =
7638 "GET / HTTP/1.1\r\n"
7639 "Host: mail.example.org\r\n"
7640 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437641 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567642 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417643 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357644 SYNCHRONOUS,
7645 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:237646 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
7647 2, 2, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417648 } else {
7649 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417650 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357651 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:237652 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
7653 2, 2, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417654 }
Yixin Wang46a273ec302018-01-23 17:59:567655 const char get_response[] =
7656 "HTTP/1.1 200 OK\r\n"
7657 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437658 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437659 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337660 ASYNC, ConstructServerDataPacket(
7661 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:177662 header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527663
Victor Vasiliev076657c2019-03-12 02:46:437664 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337665 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417666 SYNCHRONOUS, ConstructServerDataPacket(
7667 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:177668 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:237669 mock_quic_data.AddWrite(SYNCHRONOUS,
7670 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:567671 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7672
7673 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417674 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:237675 ConstructClientRstPacket(packet_num++,
7676 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417677 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:567678
7679 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7680
7681 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7682 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
7683
7684 SSLSocketDataProvider ssl_data(ASYNC, OK);
7685 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7686
7687 CreateSession();
7688
7689 request_.url = GURL("https://mail.example.org/");
7690 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7691 HeadersHandler headers_handler;
7692 trans.SetBeforeHeadersSentCallback(
7693 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7694 base::Unretained(&headers_handler)));
7695 TestCompletionCallback callback;
7696 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7697 EXPECT_EQ(ERR_IO_PENDING, rv);
7698 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
7699
7700 rv = trans.RestartIgnoringLastError(callback.callback());
7701 EXPECT_EQ(ERR_IO_PENDING, rv);
7702 EXPECT_EQ(OK, callback.WaitForResult());
7703
7704 CheckWasHttpResponse(&trans);
7705 CheckResponsePort(&trans, 70);
7706 CheckResponseData(&trans, "0123456789");
7707 EXPECT_EQ(true, headers_handler.was_proxied());
7708 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7709
7710 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7711 // proxy socket to disconnect.
7712 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7713
7714 base::RunLoop().RunUntilIdle();
7715 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7716 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7717}
7718
7719// Checks if a request's specified "user-agent" header shows up correctly in the
7720// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:147721TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:007722 const char kConfiguredUserAgent[] = "Configured User-Agent";
7723 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:567724 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147725 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567726 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497727 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567728
Ryan Hamiltonabad59e2019-06-06 04:02:597729 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237730 int packet_num = 1;
7731 if (VersionUsesQpack(version_.transport_version)) {
7732 mock_quic_data.AddWrite(SYNCHRONOUS,
7733 ConstructInitialSettingsPacket(packet_num++));
7734 }
Yixin Wang46a273ec302018-01-23 17:59:567735
Ryan Hamilton0239aac2018-05-19 00:03:137736 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:007737 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:337738 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027739 SYNCHRONOUS,
7740 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237741 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7742 false, HttpProxyConnectJob::kH2QuicTunnelPriority, std::move(headers),
7743 0));
Yixin Wang46a273ec302018-01-23 17:59:567744 // Return an error, so the transaction stops here (this test isn't interested
7745 // in the rest).
7746 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7747
7748 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7749
Matt Menked732ea42019-03-08 12:05:007750 StaticHttpUserAgentSettings http_user_agent_settings(
7751 std::string() /* accept_language */, kConfiguredUserAgent);
7752 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:567753 CreateSession();
7754
7755 request_.url = GURL("https://mail.example.org/");
7756 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:007757 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:567758 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7759 HeadersHandler headers_handler;
7760 trans.SetBeforeHeadersSentCallback(
7761 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7762 base::Unretained(&headers_handler)));
7763 TestCompletionCallback callback;
7764 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7765 EXPECT_EQ(ERR_IO_PENDING, rv);
7766 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7767
7768 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7769 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7770}
7771
Yixin Wang00fc44c2018-01-23 21:12:207772// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
7773// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:147774TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:207775 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147776 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:207777 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497778 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:207779
7780 const RequestPriority request_priority = MEDIUM;
7781
Ryan Hamiltonabad59e2019-06-06 04:02:597782 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237783 int packet_num = 1;
7784 if (VersionUsesQpack(version_.transport_version)) {
7785 mock_quic_data.AddWrite(SYNCHRONOUS,
7786 ConstructInitialSettingsPacket(packet_num++));
7787 }
Zhongyi Shi32f2fd02018-04-16 18:23:437788 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237789 SYNCHRONOUS,
7790 ConstructClientRequestHeadersPacket(
7791 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7792 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7793 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:207794 // Return an error, so the transaction stops here (this test isn't interested
7795 // in the rest).
7796 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7797
7798 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7799
7800 CreateSession();
7801
7802 request_.url = GURL("https://mail.example.org/");
7803 HttpNetworkTransaction trans(request_priority, session_.get());
7804 TestCompletionCallback callback;
7805 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7806 EXPECT_EQ(ERR_IO_PENDING, rv);
7807 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7808
7809 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7810 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7811}
7812
Matt Menkeedaf3b82019-03-14 21:39:447813// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
7814// HTTP/2 stream dependency and weights given the request priority.
7815TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
7816 session_params_.enable_quic = true;
7817 session_params_.enable_quic_proxies_for_https_urls = true;
7818 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
7819 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
7820
7821 const RequestPriority kRequestPriority = MEDIUM;
7822 const RequestPriority kRequestPriority2 = LOWEST;
7823
Ryan Hamiltonabad59e2019-06-06 04:02:597824 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237825 if (VersionUsesQpack(version_.transport_version)) {
7826 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
7827 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
7828 } else {
7829 mock_quic_data.AddWrite(
7830 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7831 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
7832 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7833 ConnectRequestHeaders("mail.example.org:443"), 0));
7834 }
Matt Menkeedaf3b82019-03-14 21:39:447835 // This should never be reached.
7836 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7837 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7838
7839 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:597840 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:447841 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
7842 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7843
7844 int original_max_sockets_per_group =
7845 ClientSocketPoolManager::max_sockets_per_group(
7846 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
7847 ClientSocketPoolManager::set_max_sockets_per_group(
7848 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
7849 int original_max_sockets_per_pool =
7850 ClientSocketPoolManager::max_sockets_per_pool(
7851 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
7852 ClientSocketPoolManager::set_max_sockets_per_pool(
7853 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
7854 CreateSession();
7855
7856 request_.url = GURL("https://mail.example.org/");
7857 HttpNetworkTransaction trans(kRequestPriority, session_.get());
7858 TestCompletionCallback callback;
7859 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7860 EXPECT_EQ(ERR_IO_PENDING, rv);
7861
7862 HttpRequestInfo request2;
7863 request2.url = GURL("https://mail.example.org/some/other/path/");
7864 request2.traffic_annotation =
7865 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7866
7867 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
7868 TestCompletionCallback callback2;
7869 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
7870 EXPECT_EQ(ERR_IO_PENDING, rv2);
7871
7872 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7873 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7874
7875 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
7876
7877 ClientSocketPoolManager::set_max_sockets_per_pool(
7878 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
7879 original_max_sockets_per_pool);
7880 ClientSocketPoolManager::set_max_sockets_per_group(
7881 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
7882 original_max_sockets_per_group);
7883}
7884
Yixin Wang46a273ec302018-01-23 17:59:567885// Test the request-challenge-retry sequence for basic auth, over a QUIC
7886// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147887TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:567888 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
7889 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:567890
7891 std::unique_ptr<QuicTestPacketMaker> client_maker;
7892 std::unique_ptr<QuicTestPacketMaker> server_maker;
7893
7894 // On the second pass, the body read of the auth challenge is synchronous, so
7895 // IsConnectedAndIdle returns false. The socket should still be drained and
7896 // reused. See http://crbug.com/544255.
7897 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:337898 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:177899 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7900 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:337901 client_headers_include_h2_stream_dependency_));
7902 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:177903 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7904 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:567905
7906 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147907 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567908 proxy_resolution_service_ =
7909 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497910 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567911
Ryan Hamiltonabad59e2019-06-06 04:02:597912 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527913 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567914
Renjie Tangaadb84b2019-08-31 01:00:237915 int packet_num = 1;
7916 if (VersionUsesQpack(version_.transport_version)) {
7917 mock_quic_data.AddWrite(
7918 SYNCHRONOUS, client_maker->MakeInitialSettingsPacket(packet_num++));
7919 }
Yixin Wang46a273ec302018-01-23 17:59:567920
7921 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437922 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027923 client_maker->MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237924 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7925 false,
Matt Menke6e879bd2019-03-18 17:26:047926 ConvertRequestPriorityToQuicPriority(
7927 HttpProxyConnectJob::kH2QuicTunnelPriority),
Yixin Wang46a273ec302018-01-23 17:59:567928 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:027929 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:567930
Ryan Hamilton0239aac2018-05-19 00:03:137931 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:567932 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
7933 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
7934 headers["content-length"] = "10";
7935 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027936 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337937 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027938 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:567939
7940 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:437941 mock_quic_data.AddRead(
7942 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:337943 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:177944 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:567945 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:437946 mock_quic_data.AddRead(
7947 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:337948 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:177949 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:567950 }
7951 server_data_offset += 10;
7952
Renjie Tangaadb84b2019-08-31 01:00:237953 mock_quic_data.AddWrite(
7954 SYNCHRONOUS, client_maker->MakeAckPacket(packet_num++, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:567955
7956 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337957 SYNCHRONOUS,
7958 client_maker->MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:237959 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:417960 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:187961 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:567962
7963 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
7964 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
7965 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:047966 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:027967 client_maker->MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237968 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
7969 false,
Matt Menke6e879bd2019-03-18 17:26:047970 ConvertRequestPriorityToQuicPriority(
7971 HttpProxyConnectJob::kH2QuicTunnelPriority),
7972 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027973 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:567974
7975 // Response to wrong password
7976 headers =
7977 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
7978 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
7979 headers["content-length"] = "10";
7980 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027981 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337982 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027983 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:567984 mock_quic_data.AddRead(SYNCHRONOUS,
7985 ERR_IO_PENDING); // No more data to read
7986
Fan Yang32c5a112018-12-10 20:06:337987 mock_quic_data.AddWrite(
7988 SYNCHRONOUS,
7989 client_maker->MakeAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:237990 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Fan Yang32c5a112018-12-10 20:06:337991 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:567992
7993 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7994 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
7995
7996 CreateSession();
7997
7998 request_.url = GURL("https://mail.example.org/");
7999 // Ensure that proxy authentication is attempted even
8000 // when the no authentication data flag is set.
8001 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8002 {
8003 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8004 HeadersHandler headers_handler;
8005 trans.SetBeforeHeadersSentCallback(
8006 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8007 base::Unretained(&headers_handler)));
8008 RunTransaction(&trans);
8009
8010 const HttpResponseInfo* response = trans.GetResponseInfo();
8011 ASSERT_TRUE(response != nullptr);
8012 ASSERT_TRUE(response->headers.get() != nullptr);
8013 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8014 response->headers->GetStatusLine());
8015 EXPECT_TRUE(response->headers->IsKeepAlive());
8016 EXPECT_EQ(407, response->headers->response_code());
8017 EXPECT_EQ(10, response->headers->GetContentLength());
8018 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588019 base::Optional<AuthChallengeInfo> auth_challenge =
8020 response->auth_challenge;
8021 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568022 EXPECT_TRUE(auth_challenge->is_proxy);
8023 EXPECT_EQ("https://proxy.example.org:70",
8024 auth_challenge->challenger.Serialize());
8025 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8026 EXPECT_EQ("basic", auth_challenge->scheme);
8027
8028 TestCompletionCallback callback;
8029 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8030 callback.callback());
8031 EXPECT_EQ(ERR_IO_PENDING, rv);
8032 EXPECT_EQ(OK, callback.WaitForResult());
8033
8034 response = trans.GetResponseInfo();
8035 ASSERT_TRUE(response != nullptr);
8036 ASSERT_TRUE(response->headers.get() != nullptr);
8037 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8038 response->headers->GetStatusLine());
8039 EXPECT_TRUE(response->headers->IsKeepAlive());
8040 EXPECT_EQ(407, response->headers->response_code());
8041 EXPECT_EQ(10, response->headers->GetContentLength());
8042 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588043 auth_challenge = response->auth_challenge;
8044 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568045 EXPECT_TRUE(auth_challenge->is_proxy);
8046 EXPECT_EQ("https://proxy.example.org:70",
8047 auth_challenge->challenger.Serialize());
8048 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8049 EXPECT_EQ("basic", auth_challenge->scheme);
8050 }
8051 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8052 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8053 // reused because it's not connected).
8054 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8055 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8056 }
8057}
8058
Yixin Wang385652a2018-02-16 02:37:238059TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8060 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8061 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:568062 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238063 !client_headers_include_h2_stream_dependency_) {
8064 return;
8065 }
8066
Ryan Hamiltone940bd12019-06-30 02:46:458067 if (quic::VersionUsesQpack(version_.transport_version)) {
8068 // TODO(rch): both stream_dependencies and priority frames need to be
8069 // supported in IETF QUIC.
8070 return;
8071 }
8072
Nick Harper72ade192019-07-17 03:30:428073 session_params_.quic_params.origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:238074 HostPortPair::FromString("mail.example.org:443"));
8075
Fan Yang32c5a112018-12-10 20:06:338076 const quic::QuicStreamId client_stream_0 =
8077 GetNthClientInitiatedBidirectionalStreamId(0);
8078 const quic::QuicStreamId client_stream_1 =
8079 GetNthClientInitiatedBidirectionalStreamId(1);
8080 const quic::QuicStreamId client_stream_2 =
8081 GetNthClientInitiatedBidirectionalStreamId(2);
8082 const quic::QuicStreamId push_stream_0 =
8083 GetNthServerInitiatedUnidirectionalStreamId(0);
8084 const quic::QuicStreamId push_stream_1 =
8085 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238086
Ryan Hamiltonabad59e2019-06-06 04:02:598087 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238088 int packet_num = 1;
8089 if (VersionUsesQpack(version_.transport_version)) {
8090 mock_quic_data.AddWrite(SYNCHRONOUS,
8091 ConstructInitialSettingsPacket(packet_num++));
8092 }
Yixin Wang385652a2018-02-16 02:37:238093
8094 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:238095 mock_quic_data.AddWrite(
8096 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8097 packet_num++, client_stream_0, true, true, HIGHEST,
8098 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:028099 mock_quic_data.AddWrite(
8100 SYNCHRONOUS,
8101 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238102 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028103 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
8104 mock_quic_data.AddWrite(
8105 SYNCHRONOUS,
8106 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238107 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:028108 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:238109
8110 // Server replies "OK" for the three requests.
Ryan Hamilton0d65a8c2019-06-07 00:46:028111 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8112 1, client_stream_0, false, false,
8113 GetResponseHeaders("200 OK")));
8114 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8115 2, client_stream_1, false, false,
8116 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238117 mock_quic_data.AddWrite(SYNCHRONOUS,
8118 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton0d65a8c2019-06-07 00:46:028119 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
8120 3, client_stream_2, false, false,
8121 GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:238122
8123 // Server sends two push promises associated with |client_stream_0|; client
8124 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8125 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:028126 mock_quic_data.AddRead(
8127 ASYNC,
8128 ConstructServerPushPromisePacket(
8129 4, client_stream_0, push_stream_0, false,
8130 GetRequestHeaders("GET", "https", "/pushed_0.jpg"), &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238131 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438132 SYNCHRONOUS,
8133 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238134 packet_num++, false, 4, 3, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:438135 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:028136 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
8137 mock_quic_data.AddRead(
8138 ASYNC,
8139 ConstructServerPushPromisePacket(
8140 5, client_stream_0, push_stream_1, false,
8141 GetRequestHeaders("GET", "https", "/pushed_1.jpg"), &server_maker_));
8142 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientPriorityPacket(
Renjie Tangaadb84b2019-08-31 01:00:238143 packet_num++, false, push_stream_1,
Ryan Hamilton0d65a8c2019-06-07 00:46:028144 push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:238145
8146 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438147 mock_quic_data.AddRead(
8148 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:028149 6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238150 mock_quic_data.AddWrite(SYNCHRONOUS,
8151 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:438152 mock_quic_data.AddRead(
8153 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:028154 7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:238155
8156 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8157 // priority updates to match the request's priority. Client sends PRIORITY
8158 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438159 mock_quic_data.AddWrite(
8160 SYNCHRONOUS,
8161 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238162 packet_num++, false, 7, 7, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:438163 {{push_stream_1, client_stream_2,
8164 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8165 {push_stream_0, client_stream_0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028166 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:238167
8168 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:438169 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438170 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178171 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Renjief49758b2019-01-11 23:32:418172 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438173 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178174 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Renjief49758b2019-01-11 23:32:418175 header + "hello 1!"));
Renjie Tangaadb84b2019-08-31 01:00:238176 mock_quic_data.AddWrite(SYNCHRONOUS,
8177 ConstructClientAckPacket(packet_num++, 9, 8, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:438178 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178179 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Renjief49758b2019-01-11 23:32:418180 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:438181 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438182 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178183 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true,
Renjief49758b2019-01-11 23:32:418184 header2 + "and hello 0!"));
Renjie Tangaadb84b2019-08-31 01:00:238185 mock_quic_data.AddWrite(SYNCHRONOUS,
8186 ConstructClientAckPacket(packet_num++, 11, 10, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:438187 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178188 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Renjief49758b2019-01-11 23:32:418189 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238190
Yixin Wang385652a2018-02-16 02:37:238191 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8192 mock_quic_data.AddRead(ASYNC, 0); // EOF
8193 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8194
8195 // The non-alternate protocol job needs to hang in order to guarantee that
8196 // the alternate-protocol job will "win".
8197 AddHangingNonAlternateProtocolSocketData();
8198
8199 CreateSession();
8200
8201 request_.url = GURL("https://mail.example.org/0.jpg");
8202 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8203 TestCompletionCallback callback_0;
8204 EXPECT_EQ(ERR_IO_PENDING,
8205 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8206 base::RunLoop().RunUntilIdle();
8207
8208 request_.url = GURL("https://mail.example.org/1.jpg");
8209 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8210 TestCompletionCallback callback_1;
8211 EXPECT_EQ(ERR_IO_PENDING,
8212 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8213 base::RunLoop().RunUntilIdle();
8214
8215 request_.url = GURL("https://mail.example.org/2.jpg");
8216 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8217 TestCompletionCallback callback_2;
8218 EXPECT_EQ(ERR_IO_PENDING,
8219 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8220 base::RunLoop().RunUntilIdle();
8221
8222 // Client makes request that matches resource pushed in |pushed_stream_0|.
8223 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8224 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8225 TestCompletionCallback callback_3;
8226 EXPECT_EQ(ERR_IO_PENDING,
8227 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8228 base::RunLoop().RunUntilIdle();
8229
8230 EXPECT_TRUE(callback_0.have_result());
8231 EXPECT_EQ(OK, callback_0.WaitForResult());
8232 EXPECT_TRUE(callback_1.have_result());
8233 EXPECT_EQ(OK, callback_1.WaitForResult());
8234 EXPECT_TRUE(callback_2.have_result());
8235 EXPECT_EQ(OK, callback_2.WaitForResult());
8236
8237 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8238 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8239 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8240 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8241
8242 mock_quic_data.Resume();
8243 base::RunLoop().RunUntilIdle();
8244 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8245 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8246}
8247
Matt Menke26e41542019-06-05 01:09:518248// Test that NetworkIsolationKey is respected by QUIC connections, when
8249// kPartitionConnectionsByNetworkIsolationKey is enabled.
8250TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Shivani Sharma8ae506c2019-07-21 21:08:278251 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
8252 const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
8253 NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
8254 NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
Matt Menke26e41542019-06-05 01:09:518255
Nick Harper72ade192019-07-17 03:30:428256 session_params_.quic_params.origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:518257 HostPortPair::FromString("mail.example.org:443"));
8258
8259 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
8260 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
8261 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
8262 // the same way as the HTTP over H2 proxy case.
8263 for (bool use_proxy : {false, true}) {
8264 SCOPED_TRACE(use_proxy);
8265
8266 if (use_proxy) {
8267 proxy_resolution_service_ =
8268 ProxyResolutionService::CreateFixedFromPacResult(
8269 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
8270 } else {
8271 proxy_resolution_service_ = ProxyResolutionService::CreateDirect();
8272 }
8273
8274 GURL url1;
8275 GURL url2;
8276 GURL url3;
8277 if (use_proxy) {
8278 url1 = GURL("http://mail.example.org/1");
8279 url2 = GURL("http://mail.example.org/2");
8280 url3 = GURL("http://mail.example.org/3");
8281 } else {
8282 url1 = GURL("https://mail.example.org/1");
8283 url2 = GURL("https://mail.example.org/2");
8284 url3 = GURL("https://mail.example.org/3");
8285 }
8286
8287 for (bool partition_connections : {false, true}) {
8288 SCOPED_TRACE(partition_connections);
8289
8290 base::test::ScopedFeatureList feature_list;
8291 if (partition_connections) {
8292 feature_list.InitAndEnableFeature(
8293 features::kPartitionConnectionsByNetworkIsolationKey);
8294 } else {
8295 feature_list.InitAndDisableFeature(
8296 features::kPartitionConnectionsByNetworkIsolationKey);
8297 }
8298
8299 // Reads and writes for the unpartitioned case, where only one socket is
8300 // used.
8301
Nick Harper72ade192019-07-17 03:30:428302 session_params_.quic_params.origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:518303 HostPortPair::FromString("mail.example.org:443"));
8304
Ryan Hamiltonabad59e2019-06-06 04:02:598305 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:518306 QuicTestPacketMaker client_maker1(
8307 version_,
8308 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8309 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8310 client_headers_include_h2_stream_dependency_);
8311 QuicTestPacketMaker server_maker1(
8312 version_,
8313 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8314 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8315
Renjie Tangaadb84b2019-08-31 01:00:238316 int packet_num = 1;
8317 if (VersionUsesQpack(version_.transport_version)) {
8318 unpartitioned_mock_quic_data.AddWrite(
8319 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
8320 }
Matt Menke26e41542019-06-05 01:09:518321
8322 unpartitioned_mock_quic_data.AddWrite(
8323 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028324 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238325 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8326 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028327 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518328 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028329 ASYNC, server_maker1.MakeResponseHeadersPacket(
8330 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8331 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518332 unpartitioned_mock_quic_data.AddRead(
8333 ASYNC, server_maker1.MakeDataPacket(
8334 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178335 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:518336 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238337 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke26e41542019-06-05 01:09:518338
8339 unpartitioned_mock_quic_data.AddWrite(
8340 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028341 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238342 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
8343 false, true,
Matt Menke26e41542019-06-05 01:09:518344 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028345 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518346 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028347 ASYNC, server_maker1.MakeResponseHeadersPacket(
8348 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8349 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518350 unpartitioned_mock_quic_data.AddRead(
8351 ASYNC, server_maker1.MakeDataPacket(
8352 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178353 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:518354 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238355 SYNCHRONOUS,
8356 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
Matt Menke26e41542019-06-05 01:09:518357
8358 unpartitioned_mock_quic_data.AddWrite(
8359 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028360 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238361 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
8362 false, true,
Matt Menke26e41542019-06-05 01:09:518363 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028364 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518365 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028366 ASYNC, server_maker1.MakeResponseHeadersPacket(
8367 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
8368 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518369 unpartitioned_mock_quic_data.AddRead(
8370 ASYNC, server_maker1.MakeDataPacket(
8371 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Ryan Hamilton7505eb92019-06-08 00:22:178372 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:518373 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238374 SYNCHRONOUS,
8375 ConstructClientAckAndConnectionClosePacket(packet_num++, 6, 5, 1));
Matt Menke26e41542019-06-05 01:09:518376
8377 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8378
8379 // Reads and writes for the partitioned case, where two sockets are used.
8380
Ryan Hamiltonabad59e2019-06-06 04:02:598381 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:518382 QuicTestPacketMaker client_maker2(
8383 version_,
8384 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8385 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8386 client_headers_include_h2_stream_dependency_);
8387 QuicTestPacketMaker server_maker2(
8388 version_,
8389 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8390 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8391
Renjie Tangaadb84b2019-08-31 01:00:238392 int packet_num2 = 1;
8393 if (VersionUsesQpack(version_.transport_version)) {
8394 partitioned_mock_quic_data1.AddWrite(
8395 SYNCHRONOUS,
8396 client_maker2.MakeInitialSettingsPacket(packet_num2++));
8397 }
Matt Menke26e41542019-06-05 01:09:518398
8399 partitioned_mock_quic_data1.AddWrite(
8400 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028401 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238402 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
8403 true, true,
Matt Menke26e41542019-06-05 01:09:518404 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028405 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518406 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028407 ASYNC, server_maker2.MakeResponseHeadersPacket(
8408 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8409 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518410 partitioned_mock_quic_data1.AddRead(
8411 ASYNC, server_maker2.MakeDataPacket(
8412 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178413 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:518414 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238415 SYNCHRONOUS,
8416 client_maker2.MakeAckPacket(packet_num2++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:518417
8418 partitioned_mock_quic_data1.AddWrite(
8419 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028420 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238421 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
8422 false, true,
Matt Menke26e41542019-06-05 01:09:518423 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028424 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518425 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028426 ASYNC, server_maker2.MakeResponseHeadersPacket(
8427 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8428 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518429 partitioned_mock_quic_data1.AddRead(
8430 ASYNC, server_maker2.MakeDataPacket(
8431 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178432 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:518433 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238434 SYNCHRONOUS,
8435 client_maker2.MakeAckPacket(packet_num2++, 4, 3, 1, true));
Matt Menke26e41542019-06-05 01:09:518436
8437 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8438
Ryan Hamiltonabad59e2019-06-06 04:02:598439 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:518440 QuicTestPacketMaker client_maker3(
8441 version_,
8442 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8443 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8444 client_headers_include_h2_stream_dependency_);
8445 QuicTestPacketMaker server_maker3(
8446 version_,
8447 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8448 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8449
Renjie Tangaadb84b2019-08-31 01:00:238450 int packet_num3 = 1;
8451 if (VersionUsesQpack(version_.transport_version)) {
8452 partitioned_mock_quic_data2.AddWrite(
8453 SYNCHRONOUS,
8454 client_maker3.MakeInitialSettingsPacket(packet_num3++));
8455 }
Matt Menke26e41542019-06-05 01:09:518456
8457 partitioned_mock_quic_data2.AddWrite(
8458 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028459 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238460 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
8461 true, true,
Matt Menke26e41542019-06-05 01:09:518462 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:028463 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:518464 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028465 ASYNC, server_maker3.MakeResponseHeadersPacket(
8466 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8467 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:518468 partitioned_mock_quic_data2.AddRead(
8469 ASYNC, server_maker3.MakeDataPacket(
8470 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178471 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:518472 partitioned_mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238473 SYNCHRONOUS,
8474 client_maker3.MakeAckPacket(packet_num3++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:518475
8476 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8477
8478 if (partition_connections) {
8479 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
8480 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8481 } else {
8482 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8483 }
8484
8485 CreateSession();
8486
8487 TestCompletionCallback callback;
8488 HttpRequestInfo request1;
8489 request1.method = "GET";
8490 request1.url = GURL(url1);
8491 request1.traffic_annotation =
8492 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8493 request1.network_isolation_key = network_isolation_key1;
8494 HttpNetworkTransaction trans1(LOWEST, session_.get());
8495 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
8496 EXPECT_THAT(callback.GetResult(rv), IsOk());
8497 std::string response_data1;
8498 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
8499 EXPECT_EQ("1", response_data1);
8500
8501 HttpRequestInfo request2;
8502 request2.method = "GET";
8503 request2.url = GURL(url2);
8504 request2.traffic_annotation =
8505 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8506 request2.network_isolation_key = network_isolation_key2;
8507 HttpNetworkTransaction trans2(LOWEST, session_.get());
8508 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
8509 EXPECT_THAT(callback.GetResult(rv), IsOk());
8510 std::string response_data2;
8511 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
8512 EXPECT_EQ("2", response_data2);
8513
8514 HttpRequestInfo request3;
8515 request3.method = "GET";
8516 request3.url = GURL(url3);
8517 request3.traffic_annotation =
8518 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8519 request3.network_isolation_key = network_isolation_key1;
8520 HttpNetworkTransaction trans3(LOWEST, session_.get());
8521 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
8522 EXPECT_THAT(callback.GetResult(rv), IsOk());
8523 std::string response_data3;
8524 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
8525 EXPECT_EQ("3", response_data3);
8526
8527 if (partition_connections) {
8528 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
8529 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
8530 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
8531 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
8532 } else {
8533 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
8534 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
8535 }
8536 }
8537 }
8538}
8539
8540// Test that two requests to the same origin over QUIC tunnels use different
8541// QUIC sessions if their NetworkIsolationKeys don't match, and
8542// kPartitionConnectionsByNetworkIsolationKey is enabled.
8543TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
8544 base::test::ScopedFeatureList feature_list;
8545 feature_list.InitAndEnableFeature(
8546 features::kPartitionConnectionsByNetworkIsolationKey);
8547
8548 session_params_.enable_quic = true;
8549 session_params_.enable_quic_proxies_for_https_urls = true;
8550 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8551 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8552
8553 const char kGetRequest[] =
8554 "GET / HTTP/1.1\r\n"
8555 "Host: mail.example.org\r\n"
8556 "Connection: keep-alive\r\n\r\n";
8557 const char kGetResponse[] =
8558 "HTTP/1.1 200 OK\r\n"
8559 "Content-Length: 10\r\n\r\n";
8560
Ryan Hamiltonabad59e2019-06-06 04:02:598561 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
8562 std::make_unique<MockQuicData>(version_),
8563 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:518564
8565 for (int index : {0, 1}) {
8566 QuicTestPacketMaker client_maker(
8567 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8568 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8569 client_headers_include_h2_stream_dependency_);
8570 QuicTestPacketMaker server_maker(
8571 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8572 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8573
Renjie Tangaadb84b2019-08-31 01:00:238574 int packet_num = 1;
8575 if (VersionUsesQpack(version_.transport_version)) {
8576 mock_quic_data[index]->AddWrite(
8577 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
8578 }
Matt Menke26e41542019-06-05 01:09:518579
Ryan Hamiltonabad59e2019-06-06 04:02:598580 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:518581 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028582 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238583 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8584 false,
Matt Menke26e41542019-06-05 01:09:518585 ConvertRequestPriorityToQuicPriority(
8586 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:028587 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:598588 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028589 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:518590 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8591 false, GetResponseHeaders("200 OK"), nullptr));
8592
8593 std::string header = ConstructDataHeader(strlen(kGetRequest));
8594 if (version_.transport_version != quic::QUIC_VERSION_99) {
Ryan Hamiltonabad59e2019-06-06 04:02:598595 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238596 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
8597 packet_num++, false,
8598 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
8599 1, false, quic::QuicStringPiece(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:518600 } else {
Ryan Hamiltonabad59e2019-06-06 04:02:598601 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238602 SYNCHRONOUS, client_maker.MakeAckAndMultipleDataFramesPacket(
8603 packet_num++, false,
8604 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
8605 1, false, {header, std::string(kGetRequest)}));
Matt Menke26e41542019-06-05 01:09:518606 }
8607
8608 std::string header2 = ConstructDataHeader(strlen(kGetResponse));
Ryan Hamiltonabad59e2019-06-06 04:02:598609 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:518610 ASYNC, server_maker.MakeDataPacket(
8611 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178612 false, header2 + std::string(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:598613 mock_quic_data[index]->AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178614 SYNCHRONOUS,
8615 server_maker.MakeDataPacket(
8616 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8617 ConstructDataHeader(10) + std::string("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:598618 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238619 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2, 1, true));
Ryan Hamiltonabad59e2019-06-06 04:02:598620 mock_quic_data[index]->AddRead(SYNCHRONOUS,
8621 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:518622
Ryan Hamiltonabad59e2019-06-06 04:02:598623 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:518624 }
8625
8626 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8627 SSLSocketDataProvider ssl_data2(ASYNC, OK);
8628 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
8629
8630 CreateSession();
8631
8632 request_.url = GURL("https://mail.example.org/");
8633 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
8634 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8635 RunTransaction(&trans);
8636 CheckResponseData(&trans, "0123456789");
8637
8638 HttpRequestInfo request2;
Shivani Sharma8ae506c2019-07-21 21:08:278639 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
8640 request_.network_isolation_key = NetworkIsolationKey(kOrigin1, kOrigin1);
Matt Menke26e41542019-06-05 01:09:518641 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
8642 RunTransaction(&trans2);
8643 CheckResponseData(&trans2, "0123456789");
8644
Ryan Hamiltonabad59e2019-06-06 04:02:598645 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
8646 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
8647 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
8648 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:518649}
8650
[email protected]61a527782013-02-21 03:58:008651} // namespace test
8652} // namespace net